mirror of
https://github.com/LibreOffice/online.git
synced 2025-07-21 23:44:49 +00:00
Make various bits of the UI configurable.
This adds the infrastructure to be able to pass the info which elements like the statusbar / ruler / sidebar are supposed to be shown or hidden on startup of the editor. Change-Id: I188264dec6961074444934ff5fd7088e23b170d4 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/103169 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Mert Tumer <mert.tumer@collabora.com>
This commit is contained in:

committed by
Mert Tumer

parent
2b546f72de
commit
4ad8773821
@ -118,6 +118,7 @@ loolwsd_sources = common/Crypto.cpp \
|
|||||||
wsd/LOOLWSD.cpp \
|
wsd/LOOLWSD.cpp \
|
||||||
wsd/ClientSession.cpp \
|
wsd/ClientSession.cpp \
|
||||||
wsd/FileServer.cpp \
|
wsd/FileServer.cpp \
|
||||||
|
wsd/FileServerUtil.cpp \
|
||||||
wsd/RequestDetails.cpp \
|
wsd/RequestDetails.cpp \
|
||||||
wsd/Storage.cpp \
|
wsd/Storage.cpp \
|
||||||
wsd/TileCache.cpp \
|
wsd/TileCache.cpp \
|
||||||
|
@ -260,7 +260,8 @@ m4_ifelse(MOBILEAPP,[true],
|
|||||||
window.protocolDebug = false;
|
window.protocolDebug = false;
|
||||||
window.frameAncestors = '';
|
window.frameAncestors = '';
|
||||||
window.socketProxy = false;
|
window.socketProxy = false;
|
||||||
window.tileSize = 256;],
|
window.tileSize = 256;
|
||||||
|
window.uiDefaults = {};],
|
||||||
[window.host = '%HOST%';
|
[window.host = '%HOST%';
|
||||||
window.serviceRoot = '%SERVICE_ROOT%';
|
window.serviceRoot = '%SERVICE_ROOT%';
|
||||||
window.versionPath = '%VERSION%';
|
window.versionPath = '%VERSION%';
|
||||||
@ -277,7 +278,8 @@ m4_ifelse(MOBILEAPP,[true],
|
|||||||
window.protocolDebug = %PROTOCOL_DEBUG%;
|
window.protocolDebug = %PROTOCOL_DEBUG%;
|
||||||
window.frameAncestors = '%FRAME_ANCESTORS%';
|
window.frameAncestors = '%FRAME_ANCESTORS%';
|
||||||
window.socketProxy = %SOCKET_PROXY%;
|
window.socketProxy = %SOCKET_PROXY%;
|
||||||
window.tileSize = 256;])
|
window.tileSize = 256;
|
||||||
|
window.uiDefaults = %UI_DEFAULTS%;])
|
||||||
m4_syscmd([cat ]GLOBAL_JS)m4_dnl
|
m4_syscmd([cat ]GLOBAL_JS)m4_dnl
|
||||||
|
|
||||||
// Dynamically load the appropriate *-mobile.css, *-tablet.css or *-desktop.css
|
// Dynamically load the appropriate *-mobile.css, *-tablet.css or *-desktop.css
|
||||||
|
@ -67,6 +67,7 @@ wsd_sources = \
|
|||||||
../common/Authorization.cpp \
|
../common/Authorization.cpp \
|
||||||
../kit/Kit.cpp \
|
../kit/Kit.cpp \
|
||||||
../kit/TestStubs.cpp \
|
../kit/TestStubs.cpp \
|
||||||
|
../wsd/FileServerUtil.cpp \
|
||||||
../wsd/RequestDetails.cpp \
|
../wsd/RequestDetails.cpp \
|
||||||
../wsd/TileCache.cpp \
|
../wsd/TileCache.cpp \
|
||||||
../wsd/ProofKey.cpp
|
../wsd/ProofKey.cpp
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <RequestDetails.hpp>
|
#include <RequestDetails.hpp>
|
||||||
|
|
||||||
#include <common/Authorization.hpp>
|
#include <common/Authorization.hpp>
|
||||||
|
#include <wsd/FileServer.hpp>
|
||||||
|
|
||||||
/// WhiteBox unit-tests.
|
/// WhiteBox unit-tests.
|
||||||
class WhiteBoxTests : public CPPUNIT_NS::TestFixture
|
class WhiteBoxTests : public CPPUNIT_NS::TestFixture
|
||||||
@ -48,6 +49,7 @@ class WhiteBoxTests : public CPPUNIT_NS::TestFixture
|
|||||||
CPPUNIT_TEST(testRequestDetails_loleafletURI);
|
CPPUNIT_TEST(testRequestDetails_loleafletURI);
|
||||||
CPPUNIT_TEST(testRequestDetails_local);
|
CPPUNIT_TEST(testRequestDetails_local);
|
||||||
CPPUNIT_TEST(testRequestDetails);
|
CPPUNIT_TEST(testRequestDetails);
|
||||||
|
CPPUNIT_TEST(testUIDefaults);
|
||||||
|
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
|
||||||
@ -70,6 +72,7 @@ class WhiteBoxTests : public CPPUNIT_NS::TestFixture
|
|||||||
void testRequestDetails_loleafletURI();
|
void testRequestDetails_loleafletURI();
|
||||||
void testRequestDetails_local();
|
void testRequestDetails_local();
|
||||||
void testRequestDetails();
|
void testRequestDetails();
|
||||||
|
void testUIDefaults();
|
||||||
};
|
};
|
||||||
|
|
||||||
void WhiteBoxTests::testLOOLProtocolFunctions()
|
void WhiteBoxTests::testLOOLProtocolFunctions()
|
||||||
@ -1563,6 +1566,18 @@ void WhiteBoxTests::testRequestDetails()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WhiteBoxTests::testUIDefaults()
|
||||||
|
{
|
||||||
|
LOK_ASSERT_EQUAL(std::string("{\"uiMode\":\"classic\"}"),
|
||||||
|
FileServerRequestHandler::uiDefaultsToJSON("UIMode=classic;huh=bleh;"));
|
||||||
|
|
||||||
|
LOK_ASSERT_EQUAL(std::string("{\"spreadsheet\":{\"ShowSidebar\":false},\"text\":{\"ShowRuler\":true}}"),
|
||||||
|
FileServerRequestHandler::uiDefaultsToJSON("TextRuler=true;SpreadsheetSidebar=false"));
|
||||||
|
|
||||||
|
LOK_ASSERT_EQUAL(std::string("{\"presentation\":{\"ShowStatusbar\":false},\"spreadsheet\":{\"ShowSidebar\":false},\"text\":{\"ShowRuler\":true},\"uiMode\":\"notebookbar\"}"),
|
||||||
|
FileServerRequestHandler::uiDefaultsToJSON(";;UIMode=notebookbar;;PresentationStatusbar=false;;TextRuler=true;;bah=ugh;;SpreadsheetSidebar=false"));
|
||||||
|
}
|
||||||
|
|
||||||
CPPUNIT_TEST_SUITE_REGISTRATION(WhiteBoxTests);
|
CPPUNIT_TEST_SUITE_REGISTRATION(WhiteBoxTests);
|
||||||
|
|
||||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||||
|
@ -677,6 +677,8 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request,
|
|||||||
LOG_TRC("access_token=" << accessToken << ", access_token_ttl=" << accessTokenTtl);
|
LOG_TRC("access_token=" << accessToken << ", access_token_ttl=" << accessTokenTtl);
|
||||||
const std::string accessHeader = form.get("access_header", "");
|
const std::string accessHeader = form.get("access_header", "");
|
||||||
LOG_TRC("access_header=" << accessHeader);
|
LOG_TRC("access_header=" << accessHeader);
|
||||||
|
const std::string uiDefaults = form.get("ui_defaults", "");
|
||||||
|
LOG_TRC("ui_defaults=" << uiDefaults);
|
||||||
|
|
||||||
// Escape bad characters in access token.
|
// Escape bad characters in access token.
|
||||||
// This is placed directly in javascript in loleaflet.html, we need to make sure
|
// This is placed directly in javascript in loleaflet.html, we need to make sure
|
||||||
@ -718,6 +720,7 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request,
|
|||||||
Poco::replaceInPlace(preprocess, std::string("%HOST%"), cnxDetails.getWebSocketUrl());
|
Poco::replaceInPlace(preprocess, std::string("%HOST%"), cnxDetails.getWebSocketUrl());
|
||||||
Poco::replaceInPlace(preprocess, std::string("%VERSION%"), std::string(LOOLWSD_VERSION_HASH));
|
Poco::replaceInPlace(preprocess, std::string("%VERSION%"), std::string(LOOLWSD_VERSION_HASH));
|
||||||
Poco::replaceInPlace(preprocess, std::string("%SERVICE_ROOT%"), responseRoot);
|
Poco::replaceInPlace(preprocess, std::string("%SERVICE_ROOT%"), responseRoot);
|
||||||
|
Poco::replaceInPlace(preprocess, std::string("%UI_DEFAULTS%"), uiDefaultsToJSON(uiDefaults));
|
||||||
|
|
||||||
const auto& config = Application::instance().config();
|
const auto& config = Application::instance().config();
|
||||||
std::string protocolDebug = "false";
|
std::string protocolDebug = "false";
|
||||||
|
@ -18,6 +18,8 @@ class RequestDetails;
|
|||||||
/// Handles file requests over HTTP(S).
|
/// Handles file requests over HTTP(S).
|
||||||
class FileServerRequestHandler
|
class FileServerRequestHandler
|
||||||
{
|
{
|
||||||
|
friend class WhiteBoxTests; // for unit testing
|
||||||
|
|
||||||
static std::string getRequestPathname(const Poco::Net::HTTPRequest& request);
|
static std::string getRequestPathname(const Poco::Net::HTTPRequest& request);
|
||||||
|
|
||||||
static void preprocessFile(const Poco::Net::HTTPRequest& request,
|
static void preprocessFile(const Poco::Net::HTTPRequest& request,
|
||||||
@ -27,6 +29,12 @@ class FileServerRequestHandler
|
|||||||
static void preprocessAdminFile(const Poco::Net::HTTPRequest& request,
|
static void preprocessAdminFile(const Poco::Net::HTTPRequest& request,
|
||||||
const RequestDetails &requestDetails,
|
const RequestDetails &requestDetails,
|
||||||
const std::shared_ptr<StreamSocket>& socket);
|
const std::shared_ptr<StreamSocket>& socket);
|
||||||
|
|
||||||
|
/// Construct a JSON to be accepted by the loleflet.html from a list like
|
||||||
|
/// UIMode=classic;TextRuler=true;PresentationStatusbar=false
|
||||||
|
/// that is passed as "ui_defaults" hidden input during the iframe setup.
|
||||||
|
static std::string uiDefaultsToJSON(const std::string& uiDefaults);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Evaluate if the cookie exists, and if not, ask for the credentials.
|
/// Evaluate if the cookie exists, and if not, ask for the credentials.
|
||||||
static bool isAdminLoggedIn(const Poco::Net::HTTPRequest& request, Poco::Net::HTTPResponse& response);
|
static bool isAdminLoggedIn(const Poco::Net::HTTPRequest& request, Poco::Net::HTTPResponse& response);
|
||||||
|
104
wsd/FileServerUtil.cpp
Normal file
104
wsd/FileServerUtil.cpp
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
||||||
|
/*
|
||||||
|
* This file is part of the LibreOffice project.
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <Poco/JSON/Object.h>
|
||||||
|
|
||||||
|
#include "FileServer.hpp"
|
||||||
|
|
||||||
|
std::string FileServerRequestHandler::uiDefaultsToJSON(const std::string& uiDefaults)
|
||||||
|
{
|
||||||
|
static std::string previousUIDefaults;
|
||||||
|
static std::string previousJSON("{}");
|
||||||
|
|
||||||
|
// early exit if we are serving the same thing
|
||||||
|
if (uiDefaults == previousUIDefaults)
|
||||||
|
return previousJSON;
|
||||||
|
|
||||||
|
Poco::JSON::Object json;
|
||||||
|
Poco::JSON::Object textDefs;
|
||||||
|
Poco::JSON::Object spreadsheetDefs;
|
||||||
|
Poco::JSON::Object presentationDefs;
|
||||||
|
|
||||||
|
StringVector tokens(Util::tokenize(uiDefaults, ';'));
|
||||||
|
for (const auto& token : tokens)
|
||||||
|
{
|
||||||
|
StringVector keyValue(Util::tokenize(tokens.getParam(token), '='));
|
||||||
|
Poco::JSON::Object* currentDef = nullptr;
|
||||||
|
std::string key;
|
||||||
|
|
||||||
|
// detect the UIMode or component
|
||||||
|
if (keyValue[0] == "UIMode")
|
||||||
|
{
|
||||||
|
if (keyValue[1] == "classic" || keyValue[1] == "notebookbar")
|
||||||
|
json.set("uiMode", keyValue[1]);
|
||||||
|
else
|
||||||
|
LOG_WRN("unknown UIMode value " << keyValue[1]);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (Util::startsWith(keyValue[0], "Text"))
|
||||||
|
{
|
||||||
|
currentDef = &textDefs;
|
||||||
|
key = keyValue[0].substr(4);
|
||||||
|
}
|
||||||
|
else if (Util::startsWith(keyValue[0], "Spreadsheet"))
|
||||||
|
{
|
||||||
|
currentDef = &spreadsheetDefs;
|
||||||
|
key = keyValue[0].substr(11);
|
||||||
|
}
|
||||||
|
else if (Util::startsWith(keyValue[0], "Presentation"))
|
||||||
|
{
|
||||||
|
currentDef = &presentationDefs;
|
||||||
|
key = keyValue[0].substr(12);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_WRN("unknown UI default's component " << keyValue[0]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(currentDef);
|
||||||
|
|
||||||
|
// detect the actual UI widget we want to hide or show
|
||||||
|
if (key == "Ruler" || key == "Sidebar" || key == "Statusbar")
|
||||||
|
{
|
||||||
|
bool value(true);
|
||||||
|
if (keyValue[1] == "false" || keyValue[1] == "False" || keyValue[1] == "0")
|
||||||
|
value = false;
|
||||||
|
|
||||||
|
currentDef->set("Show" + key, value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_WRN("unknown UI default " << keyValue[0]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (textDefs.size() > 0)
|
||||||
|
json.set("text", textDefs);
|
||||||
|
|
||||||
|
if (spreadsheetDefs.size() > 0)
|
||||||
|
json.set("spreadsheet", spreadsheetDefs);
|
||||||
|
|
||||||
|
if (presentationDefs.size() > 0)
|
||||||
|
json.set("presentation", presentationDefs);
|
||||||
|
|
||||||
|
std::ostringstream oss;
|
||||||
|
Poco::JSON::Stringifier::stringify(json, oss);
|
||||||
|
|
||||||
|
previousUIDefaults = uiDefaults;
|
||||||
|
previousJSON = oss.str();
|
||||||
|
|
||||||
|
return previousJSON;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
@ -128,6 +128,27 @@ PostMessage extensions
|
|||||||
### App_LoadingStatus
|
### App_LoadingStatus
|
||||||
Was extended with field 'Status' with 'Document_Loaded' value when document was loaded successfully and 'Failed' in other case.
|
Was extended with field 'Status' with 'Document_Loaded' value when document was loaded successfully and 'Failed' in other case.
|
||||||
|
|
||||||
|
User Interface modifications
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Some parts of the user interface can be hidden or shown based or what the
|
||||||
|
integration needs. This is controlled by:
|
||||||
|
|
||||||
|
<input name="ui_defaults" value="VALUES" type="hidden"/>'
|
||||||
|
|
||||||
|
during sending the form when the iframe is being set up (similarly as the
|
||||||
|
access_token). The VALUES can have a form like:
|
||||||
|
|
||||||
|
UIMode=notebookbar;TextRuler=false;PresentationStatusbar=false;SpreadsheetSidebar=false
|
||||||
|
|
||||||
|
where the:
|
||||||
|
|
||||||
|
* UIMode specifies the general mode of operatior (classic or notebookbar)
|
||||||
|
|
||||||
|
* Text, Presentation or Spreadsheet - are prefixes to identify the component
|
||||||
|
|
||||||
|
* Ruler, Statusbar, Sidebar - are the UI parts that can be affected by this.
|
||||||
|
|
||||||
Alternative authentication possibility
|
Alternative authentication possibility
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user