common/Session.cpp | 1 kit/ChildSession.cpp | 42 +++ kit/ChildSession.hpp | 3 kit/Kit.cpp | 5 loleaflet/Makefile.am | 1 loleaflet/README | 23 ++ loleaflet/css/leaflet.css | 5 loleaflet/css/loleaflet.css | 46 ++++ loleaflet/css/partsPreviewControl.css | 4 loleaflet/css/sidebar.css | 3 loleaflet/css/toolbar.css | 1 loleaflet/debug/document/loleaflet.html | 2 loleaflet/html/framed.doc.html | 114 ++++++++-- loleaflet/html/loleaflet.html.m4 | 4 loleaflet/images/lc_formproperties.svg | 1 loleaflet/reference.html | 125 +++++++++++ loleaflet/src/control/Control.LokDialog.js | 312 ++++++++++++++++++++++++++--- loleaflet/src/control/Control.Menubar.js | 75 ++++++ loleaflet/src/control/Control.Toolbar.js | 43 +++ loleaflet/src/control/Parts.js | 1 loleaflet/src/control/Toolbar.js | 14 - loleaflet/src/core/Socket.js | 6 loleaflet/src/layer/tile/TileLayer.js | 4 loleaflet/src/main.js | 4 loleaflet/src/map/Map.js | 72 ++++++ loleaflet/src/map/handler/Map.Keyboard.js | 12 - loleaflet/src/map/handler/Map.WOPI.js | 170 +++++++++------ net/Socket.cpp | 1 wsd/ClientSession.cpp | 21 + wsd/DocumentBroker.cpp | 4 wsd/DocumentBroker.hpp | 2 wsd/FileServer.cpp | 5 wsd/Storage.cpp | 3 wsd/Storage.hpp | 6 34 files changed, 979 insertions(+), 156 deletions(-)
New commits: commit 8deb0fbcbd2b6095b5ceda65215e7c9b32ae91ed Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Tue Sep 3 00:47:27 2019 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 leaflet: minor cleanup of sidebar Change-Id: I0c3e9e0a35a093f529346ea3b3afbd44ed875570 diff --git a/loleaflet/src/control/Control.LokDialog.js b/loleaflet/src/control/Control.LokDialog.js index a5cfb01f2..e71e0c256 100644 --- a/loleaflet/src/control/Control.LokDialog.js +++ b/loleaflet/src/control/Control.LokDialog.js @@ -168,12 +168,12 @@ L.Control.LokDialog = L.Control.extend({ }, _isOpen: function(id) { - return this._dialogs[id] && + return (id in this._dialogs) && this._dialogs[id] && $('#' + this._toStrId(id)).length > 0; }, _isSidebar: function(id) { - return this._dialogs[id].isSidebar; + return (id in this._dialogs) && this._dialogs[id].isSidebar; }, // Given a prefixed dialog id like 'lokdialog-323', gives a raw id, 323. @@ -253,6 +253,7 @@ L.Control.LokDialog = L.Control.extend({ }, _onDialogMsg: function(e) { + console.log('onDialogMsg: id: ' + e.id + ', winType: ' + e.winType + ', action: ' + e.action + ', size: ' + e.size + ', rectangle: ' + e.rectangle); if (e.winType != undefined && e.winType !== 'dialog' && e.winType !== 'child' && e.winType !== 'deck') { return; } @@ -659,7 +660,7 @@ L.Control.LokDialog = L.Control.extend({ // 'mousedown' -> 'buttondown' var lokEventType = e.type.replace('mouse', 'button'); this._postWindowMouseEvent(lokEventType, id, e.offsetX, e.offsetY, 1, buttons, 0); - this.focus(id, !this._dialogs[id].isSidebar); + this.focus(id, !this._isSidebar(id)); // Keep map active while user is playing with sidebar/dialog. this._map.lastActiveTime = Date.now(); }, this); @@ -806,12 +807,6 @@ L.Control.LokDialog = L.Control.extend({ }, _onSidebarClose: function(dialogId) { - this._resizeSidebar(dialogId, 0); - $('#' + this._currentDeck.strId).remove(); - this._map.focus(); - delete this._dialogs[dialogId]; - this._currentDeck = null; - //play slide animation to right if this is a mobile or tablet if (L.Browser.mobile) { var sidebar = $('#sidebar-dock-wrapper'); @@ -827,6 +822,14 @@ L.Control.LokDialog = L.Control.extend({ $('#toolbar-down').show(); }); } + + this._resizeSidebar(dialogId, 0); + $('#' + this._currentDeck.strId).remove(); + this._map.focus(); + delete this._dialogs[dialogId]; + this._currentDeck = null; + + $('#sidebar-dock-wrapper').css({display: ''}); }, _onDialogClose: function(dialogId, notifyBackend) { @@ -843,25 +846,24 @@ L.Control.LokDialog = L.Control.extend({ }, _onClosePopups: function() { - for (var dialog in this._dialogs) { - if (this._dialogs[dialog].isSidebar != true) { - this._onDialogClose(this._dialogs[dialog].id, true); + for (var dialogId in this._dialogs) { + if (!this._isSidebar(dialogId)) { + this._onDialogClose(dialogId, true); } } }, onCloseCurrentPopUp: function() { // for title-less dialog only (context menu, pop-up) - if (!this._currentId || !this._isOpen(this._currentId) || - this._dialogs[this._currentId].title || this._isSidebar(this._currentId)) - return; - this._onDialogClose(this._currentId, true); + if (this._currentId && this._isOpen(this._currentId) && + this._dialogs[this._currentId].title && !this._isSidebar(this._currentId)) + this._onDialogClose(this._currentId, true); }, _closeSidebar: function() { - for (var dialog in this._dialogs) { - if (this._dialogs[dialog].isSidebar == true) { - this._onSidebarClose(dialog); + for (var dialogId in this._dialogs) { + if (this._isSidebar(dialogId)) { + this._onSidebarClose(dialogId); } } $('#sidebar-dock-wrapper').css({display: ''}); commit 2dbb7e23d98afca6b454ab3b79e43f98bc18bac1 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Mon Sep 2 13:46:02 2019 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 leaflet: support creating size_changed on sidebars too Change-Id: Iee13732838ac2c5b80256c1d2c2e8ece720244dc diff --git a/loleaflet/src/control/Control.LokDialog.js b/loleaflet/src/control/Control.LokDialog.js index 4d97cb80f..a5cfb01f2 100644 --- a/loleaflet/src/control/Control.LokDialog.js +++ b/loleaflet/src/control/Control.LokDialog.js @@ -329,7 +329,10 @@ L.Control.LokDialog = L.Control.extend({ // FIXME: we don't really have to destroy and launch the dialog again but do it for // now because the size sent to us previously in 'created' cb is not correct $('#' + strId).remove(); - this._launchDialog(e.id, null, null, width, height, this._dialogs[parseInt(e.id)].title); + if (e.winType === 'deck' || this._isSidebar(e.id)) + this._launchSidebar(e.id, width, height); + else + this._launchDialog(e.id, null, null, width, height, this._dialogs[parseInt(e.id)].title); } else if (e.action === 'cursor_invalidate') { if (this._isOpen(e.id) && !!e.rectangle) { rectangle = e.rectangle.split(','); commit 53bd11c8e74f9242b91771dd7c2da183e0a62dc6 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Sun Sep 1 22:13:58 2019 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 leaflet: Sidebar is not a popup window Change-Id: Ib786a4038bfb55ee71e7e66a0e195fd43c9603af diff --git a/loleaflet/src/control/Control.LokDialog.js b/loleaflet/src/control/Control.LokDialog.js index 0dd42476b..4d97cb80f 100644 --- a/loleaflet/src/control/Control.LokDialog.js +++ b/loleaflet/src/control/Control.LokDialog.js @@ -849,7 +849,8 @@ L.Control.LokDialog = L.Control.extend({ onCloseCurrentPopUp: function() { // for title-less dialog only (context menu, pop-up) - if (!this._currentId || !this._isOpen(this._currentId) || this._dialogs[this._currentId].title) + if (!this._currentId || !this._isOpen(this._currentId) || + this._dialogs[this._currentId].title || this._isSidebar(this._currentId)) return; this._onDialogClose(this._currentId, true); }, commit 97a7b1f170e14c3fbbaed795ba8591a10831fa4e Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Wed Aug 28 21:18:53 2019 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 wsd: sanitize url when error reporting (cherry picked from commit 2b35ae713943abd5f51de383fb2d26ab96f73988) Change-Id: I7937429f2f987212beaeb9a97b48bfedb0a7ac58 diff --git a/wsd/FileServer.cpp b/wsd/FileServer.cpp index bfde038c9..01e73cb79 100644 --- a/wsd/FileServer.cpp +++ b/wsd/FileServer.cpp @@ -460,8 +460,10 @@ void FileServerRequestHandler::sendError(int errorCode, const Poco::Net::HTTPReq << "\r\n"; if (!shortMessage.empty()) { + std::string pathSanitized; + Poco::URI::encode(path, "", pathSanitized); oss << "<h1>Error: " << shortMessage << "</h1>" - "<p>" << longMessage << " " << path << "</p>" + "<p>" << longMessage << ' ' << pathSanitized << "</p>" "<p>Please contact your system administrator.</p>"; } socket->send(oss.str()); @@ -740,6 +742,7 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco:: LOG_TRC("Denied all frame ancestors"); cspOss << "img-src 'self' data: none;"; } + cspOss << "\r\n"; // Append CSP to response headers too oss << cspOss.str(); commit 5772bbd8c9de6bb38d7c341b93b6757ab0c63dd7 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Sat Aug 17 11:13:57 2019 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 leaflet: save only when not read-only Change-Id: I0cff68d2a2e8354b8c5a6888faa9fa823295c98e diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js index ba3fe0b98..9ac0e8fb2 100644 --- a/loleaflet/src/control/Control.Menubar.js +++ b/loleaflet/src/control/Control.Menubar.js @@ -767,9 +767,12 @@ L.Control.Menubar = L.Control.extend({ _executeAction: function(item) { var id = $(item).data('id'); if (id === 'save') { - this._map.fire('postMessage', {msgId: 'UI_Save'}); - if (!this._map._disableDefaultAction['UI_Save']) { - this._map.save(true, true); + // Save only when not read-only. + if (map._permission !== 'readonly') { + this._map.fire('postMessage', {msgId: 'UI_Save'}); + if (!this._map._disableDefaultAction['UI_Save']) { + this._map.save(true, true); + } } } else if (id === 'saveas') { this._map.fire('postMessage', {msgId: 'UI_SaveAs'}); diff --git a/loleaflet/src/control/Control.Toolbar.js b/loleaflet/src/control/Control.Toolbar.js index 7b3343156..e7af7aa81 100644 --- a/loleaflet/src/control/Control.Toolbar.js +++ b/loleaflet/src/control/Control.Toolbar.js @@ -141,9 +141,12 @@ function onClick(e, id, item, subItem) { map.print(); } else if (id === 'save') { - map.fire('postMessage', {msgId: 'UI_Save'}); - if (!map._disableDefaultAction['UI_Save']) { - map.save(false /* An explicit save should terminate cell edit */, false /* An explicit save should save it again */); + // Save only when not read-only. + if (map._permission !== 'readonly') { + map.fire('postMessage', {msgId: 'UI_Save'}); + if (!map._disableDefaultAction['UI_Save']) { + map.save(false /* An explicit save should terminate cell edit */, false /* An explicit save should save it again */); + } } } else if (id === 'repair') { diff --git a/loleaflet/src/map/handler/Map.Keyboard.js b/loleaflet/src/map/handler/Map.Keyboard.js index b9456b9fa..968a8c8ba 100644 --- a/loleaflet/src/map/handler/Map.Keyboard.js +++ b/loleaflet/src/map/handler/Map.Keyboard.js @@ -539,10 +539,13 @@ L.Map.Keyboard = L.Handler.extend({ this._map.print(); return true; case 83: // s - this._map.fire('postMessage', {msgId: 'UI_Save'}); - if (!this._map._disableDefaultAction['UI_Save']) { - this._map.save(false /* An explicit save should terminate cell edit */, - false /* An explicit save should save it again */); + // Save only when not read-only. + if (this._map._permission !== 'readonly') { + this._map.fire('postMessage', {msgId: 'UI_Save'}); + if (!this._map._disableDefaultAction['UI_Save']) { + this._map.save(false /* An explicit save should terminate cell edit */, + false /* An explicit save should save it again */); + } } return true; case 86: // v commit ee0f9c8d5348e48f4d7da851447370c71845cb15 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Tue Jul 30 00:01:24 2019 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 leaflet: add id to Format menu Change-Id: I16569eadefde1d4bd9d841688cbb5a2a43c25f44 (cherry picked from commit 78ad91b92348dd56388c3cb7512cb67edc0688cb) diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js index 46ab7543b..ba3fe0b98 100644 --- a/loleaflet/src/control/Control.Menubar.js +++ b/loleaflet/src/control/Control.Menubar.js @@ -113,7 +113,7 @@ L.Control.Menubar = L.Control.extend({ {uno: '.uno:InsertIndexesEntry'}, {uno: '.uno:InsertAuthoritiesEntry'}]}, ]}, - {name: _UNO('.uno:FormatMenu', 'text'), type: 'menu', menu: [ + {name: _UNO('.uno:FormatMenu', 'text'), id: 'format', type: 'menu', menu: [ {name: _UNO('.uno:FormatTextMenu', 'text'), type: 'menu', menu: [ {uno: '.uno:Bold'}, {uno: '.uno:Italic'}, commit ae9c1a67c9bbecd6915af8a00d31638c7fe12d2c Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Fri Jul 12 19:14:21 2019 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 leaflet: support show/hide of Insert>Section menu entry Change-Id: I89ccfcb7f9e091b26f1f67ec889556bfc07295a3 (cherry picked from commit ca7246a05639572d5c1ff133ca7dd6847ca8c7b0) diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js index bb5eb8b6c..46ab7543b 100644 --- a/loleaflet/src/control/Control.Menubar.js +++ b/loleaflet/src/control/Control.Menubar.js @@ -77,7 +77,7 @@ L.Control.Menubar = L.Control.extend({ {name: _UNO('.uno:InsertAnnotation', 'text'), id: 'insertcomment', type: 'action'}, {uno: '.uno:InsertObjectChart'}, {type: 'separator'}, - {uno: '.uno:InsertSection'}, + {uno: '.uno:InsertSection', id: 'insertsection'}, {name: _UNO('.uno:InsertField', 'text'), type: 'menu', menu: [ {uno: '.uno:InsertPageNumberField'}, {uno: '.uno:InsertPageCountField'}, commit 22993464b835810db7eb089394cb82c39f8fbc61 Author: Jan Holesovsky <ke...@collabora.com> AuthorDate: Wed Jul 10 16:08:39 2019 +0200 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 android: Needs the same treatment of .uno:Sidebar as iOS. And when at that, do that actually at the same place as where it is handled for browser on desktop. Reviewed-on: https://gerrit.libreoffice.org/75361 Reviewed-by: Jan Holesovsky <ke...@collabora.com> Tested-by: Jan Holesovsky <ke...@collabora.com> (cherry picked from commit fa50758a782348f031750c643cd512433c9e7aff) Change-Id: I41612e29d15de0fdc9c0e4013f6375ffcb4c3ae4 diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js index 735857bf7..bb5eb8b6c 100644 --- a/loleaflet/src/control/Control.Menubar.js +++ b/loleaflet/src/control/Control.Menubar.js @@ -547,18 +547,8 @@ L.Control.Menubar = L.Control.extend({ var docType = this._map.getDocType(); if (docType === 'text') { this._initializeMenu(this.options.text); - if (window.ThisIsTheiOSApp) { - // The sidebar initially thinks it is visible but actually it isn't, - // so to make its internal state match its visible state, toggle it - // to be non-visible. - this._map.sendUnoCommand('.uno:Sidebar') - } } else if (docType === 'spreadsheet') { this._initializeMenu(this.options.spreadsheet); - if (window.ThisIsTheiOSApp) { - // As above. - this._map.sendUnoCommand('.uno:Sidebar'); - } } else if (docType === 'presentation' || docType === 'drawing') { this._initializeMenu(this.options.presentation); } diff --git a/loleaflet/src/map/Map.js b/loleaflet/src/map/Map.js index f2dc469e1..118e74833 100644 --- a/loleaflet/src/map/Map.js +++ b/loleaflet/src/map/Map.js @@ -265,7 +265,7 @@ L.Map = L.Evented.extend({ this.initializeModificationIndicator(); // Show sidebar. - if (this._docLayer && !this._docLoadedOnce && !window.mode.isMobile() && !window.mode.isTablet() && + if (this._docLayer && !this._docLoadedOnce && (this._docLayer._docType === 'spreadsheet' || this._docLayer._docType === 'text')) { // Let the first page finish loading then load the sidebar. var map = this; @@ -274,7 +274,15 @@ L.Map = L.Evented.extend({ // be loaded and show rather quickly on first use. // Also, triggers sidebar window creation in the client. map._socket.sendMessage('uno .uno:Sidebar'); - map._socket.sendMessage('uno .uno:Sidebar'); + + // HACK: The initial state of sidebar is that the core + // thinks it is shown, so the command has to be triggered + // once again for it to be visible on the desktop + // (because the first .uno:Sidebar has actually hidden + // that) + if (!window.mode.isMobile() && !window.mode.isTablet() && !window.ThisIsAMobileApp) { + map._socket.sendMessage('uno .uno:Sidebar'); + } }, 200); } commit a0ca9120850836a0cca4e27f5073b55f44a8fcb4 Author: Tor Lillqvist <t...@collabora.com> AuthorDate: Wed Jul 10 13:38:57 2019 +0300 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 Show the View menu in the iOS app for Calc docs Also sync the sidebar state on initialization, as for Writer docs. We want View > Sidebar to show up and work also for Calc docs in the iOS app. Change-Id: Iaf50d03a50940a0d414b512ad55419c52c87943e Reviewed-on: https://gerrit.libreoffice.org/75345 Reviewed-by: Tor Lillqvist <t...@collabora.com> Tested-by: Tor Lillqvist <t...@collabora.com> (cherry picked from commit 9c900398f3f1c95f9e30f9714c748a9d464ffb95) diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js index 0b079ada4..735857bf7 100644 --- a/loleaflet/src/control/Control.Menubar.js +++ b/loleaflet/src/control/Control.Menubar.js @@ -358,9 +358,9 @@ L.Control.Menubar = L.Control.extend({ {type: 'separator'}, {uno: '.uno:SearchDialog'} ]}, - {name: _UNO('.uno:ViewMenu', 'spreadsheet'), id: 'view', type: 'menu', mobileapp: false, menu: [ - {name: _UNO('.uno:FullScreen', 'spreadsheet'), id: 'fullscreen', type: 'action'}, - {type: 'separator'}, + {name: _UNO('.uno:ViewMenu', 'spreadsheet'), id: 'view', type: 'menu', menu: [ + {name: _UNO('.uno:FullScreen', 'spreadsheet'), id: 'fullscreen', type: 'action', mobileapp: false}, + {type: 'separator', mobileapp: false}, {uno: '.uno:Sidebar'} ]}, {name: _UNO('.uno:InsertMenu', 'spreadsheet'), type: 'menu', menu: [ @@ -555,6 +555,10 @@ L.Control.Menubar = L.Control.extend({ } } else if (docType === 'spreadsheet') { this._initializeMenu(this.options.spreadsheet); + if (window.ThisIsTheiOSApp) { + // As above. + this._map.sendUnoCommand('.uno:Sidebar'); + } } else if (docType === 'presentation' || docType === 'drawing') { this._initializeMenu(this.options.presentation); } commit a93c89d66616e64da597035b93b66980214d593b Author: Tor Lillqvist <t...@collabora.com> AuthorDate: Tue Jul 9 17:51:52 2019 +0300 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 Sync the initial internal and apparent state of the sidebar in the iOS app Avoids having to use View > Sidebar twice for it to show up. I am told that the sidebar initially thinks it is visible, but it actually isn't, so the first View > Sidebar invocation caused it to become internally non-visible, and then the second View > Sidebar caused it to become visible for real, too. Now the first View > Sidebar invocation is enough for it to become visible. Change-Id: I4bc88f5b4d488e5fb12d89106bbd113f34347dfd Reviewed-on: https://gerrit.libreoffice.org/75310 Reviewed-by: Tor Lillqvist <t...@collabora.com> Tested-by: Tor Lillqvist <t...@collabora.com> (cherry picked from commit 23df55ca8f0f145b5c0eb819f2f87a6d909d7f91) diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js index 3c4296565..0b079ada4 100644 --- a/loleaflet/src/control/Control.Menubar.js +++ b/loleaflet/src/control/Control.Menubar.js @@ -547,6 +547,12 @@ L.Control.Menubar = L.Control.extend({ var docType = this._map.getDocType(); if (docType === 'text') { this._initializeMenu(this.options.text); + if (window.ThisIsTheiOSApp) { + // The sidebar initially thinks it is visible but actually it isn't, + // so to make its internal state match its visible state, toggle it + // to be non-visible. + this._map.sendUnoCommand('.uno:Sidebar') + } } else if (docType === 'spreadsheet') { this._initializeMenu(this.options.spreadsheet); } else if (docType === 'presentation' || docType === 'drawing') { commit 8f312862ca1e3d472820b70c852ff5c7afa62ddc Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Sat Jun 29 10:52:11 2019 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 leaflet: fire Doc_ModifiedStatus with modified state of the document When .uno:ModifiedStatus is received, now Doc_ModifiedStatus is fired to inform the client of the modified state of the document. This is useful in case the integration needs to prompt the user to save before closing the document (which they can catch with the onunload or onbeforeunload events in the browser, as well as with our UI_Close when the default handler is disabled). Includes working sample and documentation. Change-Id: Ief30483e2f078b0aa9f3c006a1ecb4093375174c Reviewed-on: https://gerrit.libreoffice.org/74891 Reviewed-by: Jan Holesovsky <ke...@collabora.com> Tested-by: Jan Holesovsky <ke...@collabora.com> diff --git a/loleaflet/html/framed.doc.html b/loleaflet/html/framed.doc.html index d89a1a98f..80f842c40 100644 --- a/loleaflet/html/framed.doc.html +++ b/loleaflet/html/framed.doc.html @@ -87,12 +87,30 @@ function receiveMessage(event) { console.log('==== framed.doc.html receiveMessage: ' + event.data); var msg = JSON.parse(event.data); - if (msg && msg.MessageId == 'App_LoadingStatus') { + if (!msg) { + return; + } + if (msg.MessageId == 'App_LoadingStatus') { if (msg.Values) { if (msg.Values.Status == 'Document_Loaded') { window.frames[0].postMessage(JSON.stringify({'MessageId': 'Host_PostmessageReady'}), '*'); } } + } else if (msg.MessageId == 'Doc_ModifiedStatus') { + if (msg.Values) { + if (msg.Values.Modified == true) { + document.getElementById("ModifiedStatus").innerHTML = "Modified"; + } + else { + document.getElementById("ModifiedStatus").innerHTML = "Saved"; + } + } + } else if (msg.MessageId == 'Action_Save_Resp') { + if (msg.Values) { + if (msg.Values.success == true) { + document.getElementById("ModifiedStatus").innerHTML = "Saved"; + } + } } } @@ -125,6 +143,10 @@ <button onclick="disable_default_uiaction('UI_Save', false); return false;">Enable default save action</button></br></br> </form> + <p>Modified Status: + <span id="ModifiedStatus">Saved</span> + </p> + <!-- The hostname and pathnames below are obviously specific to my personal environment and need to be changed appropriately. Also the hex string needs to be changed of course, to the right one as diff --git a/loleaflet/reference.html b/loleaflet/reference.html index 3e47008f2..f472d46f7 100644 --- a/loleaflet/reference.html +++ b/loleaflet/reference.html @@ -3395,6 +3395,21 @@ Note that they usually don't change but there is no guarantee that they are stab Response to this query is sent via <code>Action_SaveAs</code> message. </td> </tr> + <tr> + <td><code><b>Doc_ModifiedStatus</b></code></td> + <td></td> + <td> + Notification to update the modified status of the document. + Values.Modified will be true, if the document has been modified + since the last save, otherwise, it will be false if the document + has been saved. + + Note that this notification may be published without a change + from the prior value, so care must be taken to check the Values.Modified + value and not assume the notifiaction itself implies the + modified state of the document on its own. + </td> + </tr> </table> <h3 id='loleaflet-postmessage-python'>Calling Python scripts</h3> diff --git a/loleaflet/src/map/Map.js b/loleaflet/src/map/Map.js index 0b8a00c3b..f2dc469e1 100644 --- a/loleaflet/src/map/Map.js +++ b/loleaflet/src/map/Map.js @@ -239,8 +239,12 @@ L.Map = L.Evented.extend({ this._docLoadedOnce = false; this.on('commandstatechanged', function(e) { - if (e.commandName === '.uno:ModifiedStatus') + if (e.commandName === '.uno:ModifiedStatus') { this._everModified = this._everModified || (e.state === 'true'); + + // Fire an event to let the client know whether the document needs saving or not. + this.fire('postMessage', {msgId: 'Doc_ModifiedStatus', args: { Modified: e.state === 'true' }}); + } }, this); this.on('docloaded', function(e) { diff --git a/test/data/empty.odt b/test/data/empty.odt index 208d2f874..6b0747507 100644 Binary files a/test/data/empty.odt and b/test/data/empty.odt differ commit 3dcc68e6f12a1b0d2e1c586a6d4c8ccdfeb8a15b Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Sun Jun 16 14:42:11 2019 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 Pass Extended Data in Action_Save from the client to the WOPI host Clients often need to communicate with their wopi hosts when invoking Action_Save to provide more context when storing the document in question. Action_Save now support passing arbitrary string as ExtendedData entry that can be used by client to pass any context or otherwise flags to the WOPI host, which will receive it via the X-LOOL-WOPI-ExtendedData custom header. See reference.html for more details. Change-Id: I1814d1f3d984a553ffa60cec13d23b014ba59eb3 Reviewed-on: https://gerrit.libreoffice.org/74135 Reviewed-by: Andras Timar <andras.ti...@collabora.com> Tested-by: Andras Timar <andras.ti...@collabora.com> diff --git a/loleaflet/html/framed.doc.html b/loleaflet/html/framed.doc.html index bd62fddeb..d89a1a98f 100644 --- a/loleaflet/html/framed.doc.html +++ b/loleaflet/html/framed.doc.html @@ -48,7 +48,7 @@ function save() { post({'MessageId': 'Action_Save', - 'Values': { 'Notify': true, } + 'Values': { 'Notify': true, 'ExtendedData': 'CustomFlag=CustomValue;AnotherFlag=AnotherValue' } }); } diff --git a/loleaflet/reference.html b/loleaflet/reference.html index 0dc2286c5..3e47008f2 100644 --- a/loleaflet/reference.html +++ b/loleaflet/reference.html @@ -2938,6 +2938,7 @@ Editor to WOPI host <nobr>DontTerminateEdit: <boolean></nobr> <nobr>DontSaveIfUnmodified: <boolean></nobr> <nobr>Notify: <boolean></nobr> + <nobr>ExtendedData: <String></nobr> </code></td> <td>Saves the document.<br/> <code>DontTerminateEdit</code> is relevant for spreadsheets where saving @@ -2946,10 +2947,16 @@ Editor to WOPI host user's editing session in spreadsheets.<br/> <code>DontSaveIfUnmodified</code> prevents loolwsd to save the file back to storage if document is unmodified (only cursor position changed etc.) but still saved. This can be helpful - to prevent creating unnecessary file revisions. + to prevent creating unnecessary file revisions.<br/> <code>Notify</code> when present and set to true notifies the host when document is saved. See <code>Action_Save_Resp</code> - for details. + for details.<br/> + <code>ExtendedData</code> optional data carried over to the WOPI host if provided + in the X-LOOL-WOPI-ExtendedData header. The contents are preserved as-is, + however, care must be taken to avoid using anything that HTTP headers do + not allow, also, special values such as new-line, null character, non-printable + characters, etc. are not allowed. The client can use this to pass multiple values + to the WOPI host which can then act on them.<br/> </td> </tr> <tr> diff --git a/loleaflet/src/control/Toolbar.js b/loleaflet/src/control/Toolbar.js index f4ffa86f3..b57bb7dc4 100644 --- a/loleaflet/src/control/Toolbar.js +++ b/loleaflet/src/control/Toolbar.js @@ -144,10 +144,16 @@ L.Map.include({ } }, - save: function(dontTerminateEdit, dontSaveIfUnmodified) { - this._socket.sendMessage('save' + - ' dontTerminateEdit=' + (dontTerminateEdit ? 1 : 0) + - ' dontSaveIfUnmodified=' + (dontSaveIfUnmodified ? 1 : 0)); + save: function(dontTerminateEdit, dontSaveIfUnmodified, extendedData) { + var msg = 'save' + + ' dontTerminateEdit=' + (dontTerminateEdit ? 1 : 0) + + ' dontSaveIfUnmodified=' + (dontSaveIfUnmodified ? 1 : 0); + + if (extendedData !== undefined) { + msg += ' extendedData=' + extendedData; + } + + this._socket.sendMessage(msg); }, sendUnoCommand: function (command, json) { diff --git a/loleaflet/src/map/handler/Map.WOPI.js b/loleaflet/src/map/handler/Map.WOPI.js index cd3a5ace0..8891866de 100644 --- a/loleaflet/src/map/handler/Map.WOPI.js +++ b/loleaflet/src/map/handler/Map.WOPI.js @@ -320,9 +320,10 @@ L.Map.WOPI = L.Handler.extend({ else if (msg.MessageId === 'Action_Save') { var dontTerminateEdit = msg.Values && msg.Values['DontTerminateEdit']; var dontSaveIfUnmodified = msg.Values && msg.Values['DontSaveIfUnmodified']; + var extendedData = msg.Values && msg.Values['ExtendedData']; this._notifySave = msg.Values && msg.Values['Notify']; - this._map.save(dontTerminateEdit, dontSaveIfUnmodified); + this._map.save(dontTerminateEdit, dontSaveIfUnmodified, extendedData); } else if (msg.MessageId === 'Action_Close') { this._map.remove(); diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp index c1f84ffee..baaa177d9 100644 --- a/wsd/ClientSession.cpp +++ b/wsd/ClientSession.cpp @@ -521,7 +521,14 @@ bool ClientSession::_handleInput(const char *buffer, int length) if (tokens.size() > 2) getTokenInteger(tokens[2], "dontSaveIfUnmodified", dontSaveIfUnmodified); - docBroker->sendUnoSave(getId(), dontTerminateEdit != 0, dontSaveIfUnmodified != 0); + std::string extendedData; + if (tokens.size() > 3) + getTokenString(tokens[3], "extendedData", extendedData); + + constexpr bool isAutosave = false; + constexpr bool isExitSave = false; + docBroker->sendUnoSave(getId(), dontTerminateEdit != 0, dontSaveIfUnmodified != 0, + isAutosave, isExitSave, extendedData); } } else if (tokens[0] == "savetostorage") @@ -749,7 +756,7 @@ bool ClientSession::loadDocument(const char* /*buffer*/, int /*length*/, { std::string encodedUserExtraInfo; Poco::URI::encode(getUserExtraInfo(), "", encodedUserExtraInfo); - oss << " authorextrainfo=" << encodedUserExtraInfo; //TODO: could this include user-data? + oss << " authorextrainfo=" << encodedUserExtraInfo; //TODO: could this include PII? } oss << " readonly=" << isReadOnly(); diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp index 046f916cb..dffe5ea7f 100644 --- a/wsd/DocumentBroker.cpp +++ b/wsd/DocumentBroker.cpp @@ -1101,7 +1101,8 @@ bool DocumentBroker::autoSave(const bool force, const bool dontSaveIfUnmodified) } bool DocumentBroker::sendUnoSave(const std::string& sessionId, bool dontTerminateEdit, - bool dontSaveIfUnmodified, bool isAutosave, bool isExitSave) + bool dontSaveIfUnmodified, bool isAutosave, bool isExitSave, + const std::string& extendedData) { assertCorrectThread(); @@ -1145,6 +1146,7 @@ bool DocumentBroker::sendUnoSave(const std::string& sessionId, bool dontTerminat assert(_storage); _storage->setIsAutosave(isAutosave || UnitWSD::get().isAutosave()); _storage->setIsExitSave(isExitSave); + _storage->setExtendedData(extendedData); const std::string saveArgs = oss.str(); LOG_TRC(".uno:Save arguments: " << saveArgs); diff --git a/wsd/DocumentBroker.hpp b/wsd/DocumentBroker.hpp index d3bdaa6d9..576906d9e 100644 --- a/wsd/DocumentBroker.hpp +++ b/wsd/DocumentBroker.hpp @@ -363,7 +363,7 @@ public: /// Sends the .uno:Save command to LoKit. bool sendUnoSave(const std::string& sessionId, bool dontTerminateEdit = true, bool dontSaveIfUnmodified = true, bool isAutosave = false, - bool isExitSave = false); + bool isExitSave = false, const std::string& extendedData = std::string()); /// Sends a message to all sessions void broadcastMessage(const std::string& message); diff --git a/wsd/Storage.cpp b/wsd/Storage.cpp index e4b4e1029..db82d913a 100644 --- a/wsd/Storage.cpp +++ b/wsd/Storage.cpp @@ -720,6 +720,8 @@ StorageBase::SaveResult WopiStorage::saveLocalFileToStorage(const Authorization& request.set("X-LOOL-WOPI-IsModifiedByUser", isUserModified()? "true": "false"); request.set("X-LOOL-WOPI-IsAutosave", getIsAutosave()? "true": "false"); request.set("X-LOOL-WOPI-IsExitSave", isExitSave()? "true": "false"); + if (!getExtendedData().empty()) + request.set("X-LOOL-WOPI-ExtendedData", getExtendedData()); if (!getForceSave()) { diff --git a/wsd/Storage.hpp b/wsd/Storage.hpp index 06887c657..21eee8dab 100644 --- a/wsd/Storage.hpp +++ b/wsd/Storage.hpp @@ -180,6 +180,7 @@ public: bool getIsAutosave() const { return _isAutosave; } void setIsExitSave(bool exitSave) { _isExitSave = exitSave; } bool isExitSave() const { return _isExitSave; } + void setExtendedData(const std::string& extendedData) { _extendedData = extendedData; } void setFileInfo(const FileInfo& fileInfo) { _fileInfo = fileInfo; } @@ -212,6 +213,9 @@ protected: /// Returns the root path of the jail directory of docs. std::string getLocalRootPath() const; + /// Returns the client-provided extended data to send to the WOPI host. + const std::string& getExtendedData() const { return _extendedData; } + private: const Poco::URI _uri; std::string _localStorePath; @@ -229,6 +233,8 @@ private: bool _isAutosave; /// Saving on exit (when the document is cleaned up from memory) bool _isExitSave; + /// The client-provided saving extended data to send to the WOPI host. + std::string _extendedData; static bool FilesystemEnabled; static bool WopiEnabled; commit 5ff0a42b94bc06723a2e592b649c28717c88512f Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Sun Jun 16 14:16:06 2019 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 leaflet: Support notifying the client on Action_SaveAs completion Clients expect a consistent notification API for Action_Save and Action_SaveAs. Unfortunately, Action_SaveAs didn't support notifying the client as Action_Save does. Now, when Notify is set to true in the Action_SaveAs message, the client will be notified with Action_Save_Resp. Change-Id: Ib8eb946c3bc642cfd46124e1190e931c21f88de0 Reviewed-on: https://gerrit.libreoffice.org/74134 Reviewed-by: Andras Timar <andras.ti...@collabora.com> Tested-by: Andras Timar <andras.ti...@collabora.com> diff --git a/loleaflet/reference.html b/loleaflet/reference.html index 2d797b10a..0dc2286c5 100644 --- a/loleaflet/reference.html +++ b/loleaflet/reference.html @@ -2956,9 +2956,13 @@ Editor to WOPI host <td><code><b>Action_SaveAs</b></code></td> <td><code> <nobr>Filename: <String></nobr> + <nobr>Notify: <boolean></nobr> </code></td> <td>Creates copy of the document with given Filename.<br/> <code>Filename</code> is the requested filename for the new file.<br/> + <code>Notify</code> when present and set to true notifies the + host when document is saved. See <code>Action_Save_Resp</code> + for details. </td> </tr> <tr> diff --git a/loleaflet/src/core/Socket.js b/loleaflet/src/core/Socket.js index c4ba559d1..2b24ab49d 100644 --- a/loleaflet/src/core/Socket.js +++ b/loleaflet/src/core/Socket.js @@ -680,6 +680,12 @@ L.Socket = L.Class.extend({ } }); } + + // Issue the save response to be consistent with normal save. + var postMessageObj = { + success: true + }; + this._map.fire('postMessage', {msgId: 'Action_Save_Resp', args: postMessageObj}); } // var name = command.name; - ignored, we get the new name via the wopi's BaseFileName } diff --git a/loleaflet/src/map/handler/Map.WOPI.js b/loleaflet/src/map/handler/Map.WOPI.js index 200730c30..cd3a5ace0 100644 --- a/loleaflet/src/map/handler/Map.WOPI.js +++ b/loleaflet/src/map/handler/Map.WOPI.js @@ -366,6 +366,7 @@ L.Map.WOPI = L.Handler.extend({ else if (msg.MessageId === 'Action_SaveAs') { if (msg.Values) { if (msg.Values.Filename !== null && msg.Values.Filename !== undefined) { + this._notifySave = msg.Values['Notify']; this._map.showBusy(_('Creating copy...'), false); this._map.saveAs(msg.Values.Filename); } commit d80fdefcbeafd28e22b3256281d9ec54bbeac93d Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Sun Jun 16 14:05:33 2019 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 wsd: don't use DocBrokers marked to be destroyed There are cases when we do get client-requests while we are about to unload and destroy the DocBroker. This protects against the use of partially-destroyed DocBroker (specifically, when TileCache is already destroyed). Change-Id: I963f2239fd62280e70b1938d3c6f653e8af91b1e Reviewed-on: https://gerrit.libreoffice.org/74132 Reviewed-by: Andras Timar <andras.ti...@collabora.com> Tested-by: Andras Timar <andras.ti...@collabora.com> diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp index 2623f3585..c1f84ffee 100644 --- a/wsd/ClientSession.cpp +++ b/wsd/ClientSession.cpp @@ -316,9 +316,9 @@ bool ClientSession::_handleInput(const char *buffer, int length) const std::vector<std::string> tokens = LOOLProtocol::tokenize(firstLine.data(), firstLine.size()); std::shared_ptr<DocumentBroker> docBroker = getDocumentBroker(); - if (!docBroker) + if (!docBroker || docBroker->isMarkedToDestroy()) { - LOG_ERR("No DocBroker found. Terminating session " << getName()); + LOG_ERR("No DocBroker found, or DocBroker marked to be destroyed. Terminating session " << getName()); return false; } commit 4dc312f5492c75d4afdc6e333dd4d85079e84dfc Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Sun Jun 16 13:28:58 2019 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 Cleanup framed.doc.html sample Now Host_PostmessageReady is automatically issued upon loading and the postMessage calls are more modular, allowing for expansion with more functionality. Change-Id: I22b50f7228e0fd32c4cb880f4981c1a455038d48 Reviewed-on: https://gerrit.libreoffice.org/74129 Reviewed-by: Andras Timar <andras.ti...@collabora.com> Tested-by: Andras Timar <andras.ti...@collabora.com> diff --git a/loleaflet/html/framed.doc.html b/loleaflet/html/framed.doc.html index 1dfe7f27b..bd62fddeb 100644 --- a/loleaflet/html/framed.doc.html +++ b/loleaflet/html/framed.doc.html @@ -10,9 +10,9 @@ To test this, do 'make run', and then in your browser open the equivalent of - http://snorken.local:9980/loleaflet/3304e9093/framed.html if the + http://snorken.local:9980/loleaflet/3304e9093/framed.doc.html if the browser is running on a different machine, or - http://localhost:9980/loleaflet/3304e9093/framed.html if running + http://localhost:9980/loleaflet/3304e9093/framed.doc.html if running on the same machine. --> @@ -24,26 +24,26 @@ <script> + function post(msg) { + window.frames[0].postMessage(JSON.stringify(msg), '*'); + } + function insertText(text) { - window.frames[0].postMessage(JSON.stringify({'MessageId': 'Host_PostmessageReady'}), '*'); - window.frames[0].postMessage(JSON.stringify({'MessageId': 'CallPythonScript', - 'SendTime': Date.now(), - 'ScriptFile': 'InsertText.py', - 'Function': 'InsertText', - 'Values': { 'text': {'type': 'string', 'value': text}} - }), - '*'); + post({'MessageId': 'CallPythonScript', + 'SendTime': Date.now(), + 'ScriptFile': 'InsertText.py', + 'Function': 'InsertText', + 'Values': { 'text': {'type': 'string', 'value': text}} + }); } function capitalize() { - window.frames[0].postMessage(JSON.stringify({'MessageId': 'Host_PostmessageReady'}), '*'); - window.frames[0].postMessage(JSON.stringify({'MessageId': 'CallPythonScript', - 'SendTime': Date.now(), - 'ScriptFile': 'Capitalise.py', - 'Function': 'capitalisePython', - 'Values': null - }), - '*'); + post({'MessageId': 'CallPythonScript', + 'SendTime': Date.now(), + 'ScriptFile': 'Capitalise.py', + 'Function': 'capitalisePython', + 'Values': null + }); } function save() { @@ -85,9 +85,15 @@ // This function is invoked when the iframe posts a message back. function receiveMessage(event) { + console.log('==== framed.doc.html receiveMessage: ' + event.data); var msg = JSON.parse(event.data); - console.log('==== framed.html receiveMessage: ' + event.data); - console.log(' ' + msg); + if (msg && msg.MessageId == 'App_LoadingStatus') { + if (msg.Values) { + if (msg.Values.Status == 'Document_Loaded') { + window.frames[0].postMessage(JSON.stringify({'MessageId': 'Host_PostmessageReady'}), '*'); + } + } + } } // 'main' code of this <script> block, run when page is being commit df6cc01c325f215ba90afe7665365d269c582fd1 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Sun Jun 16 13:16:20 2019 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 leaflet: support disabling default action Clients often need to handle certain commands themselves. This is especially true for Action_Save and Action_Close. A new postMessage command, Disable_Default_UIAction, is now available to support disabling/enabling the default action for certain commands (as of this patch, only Action_Save and Action_Close are supported). The actions in question issue a notification and, when the default handler is disabled, the client is expected to handle the notification for which they disabled the default handler and act as necessary. See reference.html for more details. Change-Id: Ia6ce4e2d7578f79cc2069097e0b968e6c4aeabd1 Reviewed-on: https://gerrit.libreoffice.org/74136 Reviewed-by: Andras Timar <andras.ti...@collabora.com> Tested-by: Andras Timar <andras.ti...@collabora.com> diff --git a/loleaflet/html/framed.doc.html b/loleaflet/html/framed.doc.html index 5501d5df6..1dfe7f27b 100644 --- a/loleaflet/html/framed.doc.html +++ b/loleaflet/html/framed.doc.html @@ -76,6 +76,12 @@ }); } + function disable_default_uiaction(action, disable) { + post({'MessageId': 'Disable_Default_UIAction', + 'Values': { 'action': action, 'disable': disable } + }); + } + // This function is invoked when the iframe posts a message back. function receiveMessage(event) { @@ -109,6 +115,8 @@ <button onclick="show_commands('save'); return false;">Show Save Commands</button></br> <button onclick="hide_commands('print'); return false;">Hide Print Commands</button> <button onclick="show_commands('print'); return false;">Show Print Commands</button></br></br> + <button onclick="disable_default_uiaction('UI_Save', true); return false;">Disable default save action</button></br> + <button onclick="disable_default_uiaction('UI_Save', false); return false;">Enable default save action</button></br></br> </form> <!-- The hostname and pathnames below are obviously specific to my diff --git a/loleaflet/reference.html b/loleaflet/reference.html index e6a0b448f..2d797b10a 100644 --- a/loleaflet/reference.html +++ b/loleaflet/reference.html @@ -3277,6 +3277,47 @@ Editor to WOPI host <a href="https://opengrok.libreoffice.org/xref/online/loleaflet/src/control/Control.Menubar.js">loleaflet/src/control/Control.Menubar.js</a>. </td> </tr> + <tr> + <td><code><b>Disable_Default_UIAction</b></code></td> + <td> + <code><nobr>action: <string></nobr></code> + <code><nobr>disable: <Boolean></nobr></code> + </td> + <td> + Disable the default handler and action for a UI command.<br/> + + <code>action</code> is the action name to enable/disable the + default action for.<br/> + + <code>disable</code> controls whether to disable (true) or + enable (false) the default action.<br/> + + When set to true, the given UI command will only issue a postMessage + without invoking the default action, leaving it up to the client + to intercept the postMessage event and handle as necessary. + Notice that some actions do not have any default handler to + begin with (such as UI_SaveAs and UI_Share) and therefore this + will have no effect on them; they only issue postMessage notification + anyway without taking any action beyond that.<br/> + + For example, UI_Save will be issued for invoking the save + command (from the menu, toolbar, or keyboard shortcut) and no + action will take place if 'UI_Save' is disabled via + the Disable_Default_UIAction command. Clients who disable + UI_Save should then issue Action_Save themselves, when and + if they desire to save the document. + Similarly, when disabling UI_Close, the document will not + close upon invoking the UI_Close action, instead a postMessage + notification will be issued and it will be up to the client + to issue Action_Close when they desire.<br/> + + Clients must be careful not to issue duplicate actions when + the default handler is enabled, instead, they should only + issue actions themselves when the default is disabled. + + Note: currently only UI_Save and UI_Close are supported.<br/> + </td> + </tr> </table> <h5><a name="toolbar-button-ids">Finding toolbar button IDs</a></h5> diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js index f711e5aec..3c4296565 100644 --- a/loleaflet/src/control/Control.Menubar.js +++ b/loleaflet/src/control/Control.Menubar.js @@ -767,7 +767,10 @@ L.Control.Menubar = L.Control.extend({ _executeAction: function(item) { var id = $(item).data('id'); if (id === 'save') { - this._map.save(true, true); + this._map.fire('postMessage', {msgId: 'UI_Save'}); + if (!this._map._disableDefaultAction['UI_Save']) { + this._map.save(true, true); + } } else if (id === 'saveas') { this._map.fire('postMessage', {msgId: 'UI_SaveAs'}); } else if (id === 'shareas') { @@ -832,7 +835,9 @@ L.Control.Menubar = L.Control.extend({ this._map.fire('postMessage', {msgId: 'close', args: {EverModified: this._map._everModified, Deprecated: true}}); this._map.fire('postMessage', {msgId: 'UI_Close', args: {EverModified: this._map._everModified}}); } - this._map.remove(); + if (!this._map._disableDefaultAction['UI_Close']) { + this._map.remove(); + } } else if (id === 'repair') { this._map._socket.sendMessage('commandvalues command=.uno:DocumentRepair'); } else if (!window.ThisIsAMobileApp && id === 'warn-copy-paste') { diff --git a/loleaflet/src/control/Control.Toolbar.js b/loleaflet/src/control/Control.Toolbar.js index de4b5fcb1..7b3343156 100644 --- a/loleaflet/src/control/Control.Toolbar.js +++ b/loleaflet/src/control/Control.Toolbar.js @@ -141,7 +141,10 @@ function onClick(e, id, item, subItem) { map.print(); } else if (id === 'save') { - map.save(false /* An explicit save should terminate cell edit */, false /* An explicit save should save it again */); + map.fire('postMessage', {msgId: 'UI_Save'}); + if (!map._disableDefaultAction['UI_Save']) { + map.save(false /* An explicit save should terminate cell edit */, false /* An explicit save should save it again */); + } } else if (id === 'repair') { map._socket.sendMessage('commandvalues command=.uno:DocumentRepair'); @@ -303,7 +306,9 @@ function onClick(e, id, item, subItem) { map.fire('postMessage', {msgId: 'close', args: {EverModified: map._everModified, Deprecated: true}}); map.fire('postMessage', {msgId: 'UI_Close', args: {EverModified: map._everModified}}); } - map.remove(); + if (!map._disableDefaultAction['UI_Close']) { + map.remove(); + } } else { map.handleSigningClickEvent(id, item); // this handles a bunch of signing bar click events @@ -2295,7 +2300,9 @@ $(document).ready(function() { $('#closebutton').click(function() { map.fire('postMessage', {msgId: 'close', args: {EverModified: map._everModified, Deprecated: true}}); map.fire('postMessage', {msgId: 'UI_Close', args: {EverModified: map._everModified}}); - map.remove(); + if (!map._disableDefaultAction['UI_Close']) { + map.remove(); + } }); // Attach insert file action diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js index 95b489b84..6851333c5 100644 --- a/loleaflet/src/layer/tile/TileLayer.js +++ b/loleaflet/src/layer/tile/TileLayer.js @@ -540,7 +540,9 @@ L.TileLayer = L.GridLayer.extend({ if (this._map._docLayer._viewId === viewId) { this._map.fire('postMessage', {msgId: 'close', args: {EverModified: this._map._everModified, Deprecated: true}}); this._map.fire('postMessage', {msgId: 'UI_Close', args: {EverModified: this._map._everModified}}); - this._map.remove(); + if (!this._map._disableDefaultAction['UI_Close']) { + this._map.remove(); + } } } }, diff --git a/loleaflet/src/map/Map.js b/loleaflet/src/map/Map.js index e176e0d10..0b8a00c3b 100644 --- a/loleaflet/src/map/Map.js +++ b/loleaflet/src/map/Map.js @@ -107,6 +107,7 @@ L.Map = L.Evented.extend({ this._serverRecycling = false; this._documentIdle = false; this._helpTarget = null; // help page that fits best the current context + this._disableDefaultAction = {}; // The events for which the default handler is disabled and only issues postMessage. this.callInitHooks(); diff --git a/loleaflet/src/map/handler/Map.Keyboard.js b/loleaflet/src/map/handler/Map.Keyboard.js index 8097f9c74..b9456b9fa 100644 --- a/loleaflet/src/map/handler/Map.Keyboard.js +++ b/loleaflet/src/map/handler/Map.Keyboard.js @@ -185,7 +185,7 @@ L.Map.Keyboard = L.Handler.extend({ /* * Returns true whenever the key event shall be ignored. * This means shift+insert and shift+delete (or "insert or delete when holding - * shift down"). Those events are handled elsewhere to trigger "cut" and + * shift down"). Those events are handled elsewhere to trigger "cut" and * "paste" events, and need to be ignored in order to avoid double-handling them. */ _ignoreKeyEvent: function(e) { @@ -539,8 +539,11 @@ L.Map.Keyboard = L.Handler.extend({ this._map.print(); return true; case 83: // s - this._map.save(false /* An explicit save should terminate cell edit */, - false /* An explicit save should save it again */); + this._map.fire('postMessage', {msgId: 'UI_Save'}); + if (!this._map._disableDefaultAction['UI_Save']) { + this._map.save(false /* An explicit save should terminate cell edit */, + false /* An explicit save should save it again */); + } return true; case 86: // v case 118: // v (Safari) diff --git a/loleaflet/src/map/handler/Map.WOPI.js b/loleaflet/src/map/handler/Map.WOPI.js index 7cc9f7241..200730c30 100644 --- a/loleaflet/src/map/handler/Map.WOPI.js +++ b/loleaflet/src/map/handler/Map.WOPI.js @@ -269,6 +269,17 @@ L.Map.WOPI = L.Handler.extend({ } } } + else if (msg.MessageId === 'Disable_Default_UIAction') { + // Disable the default handler and action for a UI command. + // When set to true, the given UI command will issue a postmessage + // only. For example, UI_Save will be issued for invoking the save + // command (from the menu, toolbar, or keyboard shortcut) and no + // action will take place if 'UI_Save' is disabled via + // the Disable_Default_UIAction command. + if (msg.Values && msg.Values.action && msg.Values.disable !== undefined) { + this._map._disableDefaultAction[msg.Values.action] = msg.Values.disable; + } + } // All following actions must be done after initialization is completed. if (!window.WOPIPostmessageReady) { diff --git a/test/data/empty.odt b/test/data/empty.odt index 6b0747507..208d2f874 100644 Binary files a/test/data/empty.odt and b/test/data/empty.odt differ commit 0852f62f5650f6c07e6fbd90040bf5b9176e6cb3 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Sat Jun 15 20:58:49 2019 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 leaflet: support Action_Close This allows for clients to issue a document close programmatically, which is useful when they have custom buttons or commands, or external events/triggers, that might result in cleanly closing the document. A demo of how to use it is included in framed.doc.html. Change-Id: Ib889bb01bbcaaa91fd0f341c989aeb1a6fceec28 Reviewed-on: https://gerrit.libreoffice.org/74131 Reviewed-by: Andras Timar <andras.ti...@collabora.com> Tested-by: Andras Timar <andras.ti...@collabora.com> diff --git a/loleaflet/html/framed.doc.html b/loleaflet/html/framed.doc.html index 93c606cdc..5501d5df6 100644 --- a/loleaflet/html/framed.doc.html +++ b/loleaflet/html/framed.doc.html @@ -52,6 +52,12 @@ }); } + function closeDocument() { + post({'MessageId': 'Action_Close', + 'Values': null + }); + } + function hide_commands(id) { post({'MessageId': 'Hide_Menu_Item', 'Values': { 'id': id, } @@ -97,7 +103,8 @@ <form id="insert-text-form"> Click <button onclick="capitalize(); return false;">here</button> to capitalize selected text in the document.</br></br> - <button onclick="save(); return false;">Save</button></br></br> + <button onclick="save(); return false;">Save</button> + <button onclick="closeDocument(); return false;">Close</button></br></br> <button onclick="hide_commands('save'); return false;">Hide Save Commands</button> <button onclick="show_commands('save'); return false;">Show Save Commands</button></br> <button onclick="hide_commands('print'); return false;">Hide Print Commands</button> diff --git a/loleaflet/reference.html b/loleaflet/reference.html index 686c2854b..e6a0b448f 100644 --- a/loleaflet/reference.html +++ b/loleaflet/reference.html @@ -2973,6 +2973,14 @@ Editor to WOPI host </td> </tr> <tr> + <td><code><b>Action_Close</b></code></td> + <td><code> + </code></td> + <td> + Closes the document. + </td> + </tr> + <tr> <td><code><b>Action_Print</b></code></td> <td><code> </code></td> diff --git a/loleaflet/src/map/handler/Map.WOPI.js b/loleaflet/src/map/handler/Map.WOPI.js index e8c591b9f..7cc9f7241 100644 --- a/loleaflet/src/map/handler/Map.WOPI.js +++ b/loleaflet/src/map/handler/Map.WOPI.js @@ -313,6 +313,9 @@ L.Map.WOPI = L.Handler.extend({ this._map.save(dontTerminateEdit, dontSaveIfUnmodified); } + else if (msg.MessageId === 'Action_Close') { + this._map.remove(); + } else if (msg.MessageId === 'Action_Print') { this._map.print(); } commit 89ae4278e849cd950f7df984e69715649dc724fb Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Sat Jun 15 20:56:28 2019 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 leaflet: show/hide commands demo This demonstrates the use of show and hide functionality via Show/Hide_Button and Show/Hide_Menu_Item postMessage events. Save and Print buttons and menu items are controlled in the demo. Change-Id: I81dfea816765da50a1c20699b460765ae35f60a6 Reviewed-on: https://gerrit.libreoffice.org/74130 Reviewed-by: Andras Timar <andras.ti...@collabora.com> Tested-by: Andras Timar <andras.ti...@collabora.com> diff --git a/loleaflet/html/framed.doc.html b/loleaflet/html/framed.doc.html index 8fa875db4..93c606cdc 100644 --- a/loleaflet/html/framed.doc.html +++ b/loleaflet/html/framed.doc.html @@ -46,6 +46,30 @@ '*'); } + function save() { + post({'MessageId': 'Action_Save', + 'Values': { 'Notify': true, } + }); + } + + function hide_commands(id) { + post({'MessageId': 'Hide_Menu_Item', + 'Values': { 'id': id, } + }); + post({'MessageId': 'Hide_Button', + 'Values': { 'id': id, } + }); + } + + function show_commands(id) { + post({'MessageId': 'Show_Menu_Item', + 'Values': { 'id': id, } + }); + post({'MessageId': 'Show_Button', + 'Values': { 'id': id, } + }); + } + // This function is invoked when the iframe posts a message back. function receiveMessage(event) { @@ -72,7 +96,12 @@ </form> <form id="insert-text-form"> - Click <button onclick="capitalize(); return false;">here</button> to capitalize selected text in the document: + Click <button onclick="capitalize(); return false;">here</button> to capitalize selected text in the document.</br></br> + <button onclick="save(); return false;">Save</button></br></br> + <button onclick="hide_commands('save'); return false;">Hide Save Commands</button> + <button onclick="show_commands('save'); return false;">Show Save Commands</button></br> + <button onclick="hide_commands('print'); return false;">Hide Print Commands</button> + <button onclick="show_commands('print'); return false;">Show Print Commands</button></br></br> </form> <!-- The hostname and pathnames below are obviously specific to my commit f454b240ec26cd117e4a96212a493d05768e394b Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Fri Jun 14 06:05:46 2019 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 Alow to modify UI before WOPIPostmessageReady Since UI customization doesn't depend on the document being fully loaded, while at the same time we wouldn't want to display misleading/incomplete UI while the document loads, only to change it right after. Change-Id: Ib8178a1d0033659cbeb79bd4827b528e13890095 Reviewed-on: https://gerrit.libreoffice.org/74133 Reviewed-by: Andras Timar <andras.ti...@collabora.com> Tested-by: Andras Timar <andras.ti...@collabora.com> diff --git a/loleaflet/src/map/handler/Map.WOPI.js b/loleaflet/src/map/handler/Map.WOPI.js index c2783b2f7..e8c591b9f 100644 --- a/loleaflet/src/map/handler/Map.WOPI.js +++ b/loleaflet/src/map/handler/Map.WOPI.js @@ -142,7 +142,7 @@ L.Map.WOPI = L.Handler.extend({ }, _postMessageListener: function(e) { - if (!window.WOPIPostmessageReady || (e.origin !== window.parent.origin)) { + if (e.origin !== window.parent.origin) { return; } @@ -154,29 +154,81 @@ L.Map.WOPI = L.Handler.extend({ return; } - if (msg.MessageId === 'Host_PostmessageReady') { - // We already have a listener for this in loleaflet.html, so ignore it here - return; - } - - if (msg.MessageId === 'Grab_Focus') { - this._map.makeActive(); - return; - } - // allow closing documents before they are completely loaded if (msg.MessageId === 'Close_Session') { this._map._socket.sendMessage('closedocument'); return; } - // For all other messages, warn if trying to interact before we are completely loaded - if (!this._appLoaded) { - console.error('LibreOffice Online not loaded yet. Listen for App_LoadingStatus (Document_Loaded) event before using PostMessage API. Ignoring post message \'' + msg.MessageId + '\'.'); - return; + // Exception: UI modification can be done before WOPIPostmessageReady was fullfiled + if (msg.MessageId === 'Show_Button' || msg.MessageId === 'Hide_Button' || msg.MessageId === 'Remove_Button') { + if (!msg.Values) { + console.error('Property "Values" not set'); + return; + } + if (!msg.Values.id) { + console.error('Property "Values.id" not set'); + return; + } + var toolbar = w2ui['editbar']; + if (!toolbar || !toolbar.get(msg.Values.id)) { + console.error('Toolbar button with id "' + msg.Values.id + '" not found.'); + return; + } + if (msg.MessageId === 'Show_Button') { + toolbar.show(msg.Values.id); + } else { + toolbar.hide(msg.Values.id); + } + } + else if (msg.MessageId === 'Remove_Statusbar_Element') { + if (!msg.Values) { + console.error('Property "Values" not set'); + return; + } + if (!msg.Values.id) { + console.error('Property "Values.id" not set'); + return; + } + if (!w2ui['actionbar'].get(msg.Values.id)) { + console.error('Statusbar element with id "' + msg.Values.id + '" not found.'); + return; + } + w2ui['actionbar'].remove(msg.Values.id); + } + else if (msg.MessageId === 'Show_Menubar') { + this._map.showMenubar(); + } + else if (msg.MessageId === 'Hide_Menubar') { + this._map.hideMenubar(); + } + else if (msg.MessageId === 'Show_Ruler') { + this._map.showRuler(); } + else if (msg.MessageId === 'Hide_Ruler') { + this._map.hideRuler(); + } + else if (msg.MessageId === 'Show_Menu_Item' || msg.MessageId === 'Hide_Menu_Item') { + if (!msg.Values) { + console.error('Property "Values" not set'); + return; + } + if (!msg.Values.id) { + console.error('Property "Values.id" not set'); + return; + } + if (!this._map.menubar || !this._map.menubar.hasItem(msg.Values.id)) { + console.error('Menu item with id "' + msg.Values.id + '" not found.'); + return; + } - if (msg.MessageId === 'Insert_Button') { + if (msg.MessageId === 'Show_Menu_Item') { + this._map.menubar.showItem(msg.Values.id); + } else { + this._map.menubar.hideItem(msg.Values.id); + } + } + else if (msg.MessageId === 'Insert_Button') { if (msg.Values) { if (msg.Values.id && !w2ui['editbar'].get(msg.Values.id) && msg.Values.imgurl) { @@ -217,59 +269,35 @@ L.Map.WOPI = L.Handler.extend({ } } } - if (msg.MessageId === 'Show_Button' || msg.MessageId === 'Hide_Button' || msg.MessageId === 'Remove_Button') { - if (!msg.Values) { - console.error('Property "Values" not set'); - return; - } - if (!msg.Values.id) { - console.error('Property "Values.id" not set'); - return; - } - if (this._map._permission !== 'edit') { - console.log('No toolbar in readonly mode - ignoring request.'); - return; - } - if (!w2ui['editbar'].get(msg.Values.id)) { - console.error('Toolbar button with id "' + msg.Values.id + '" not found.'); - return; - } - if (msg.MessageId === 'Show_Button') { - w2ui['editbar'].show(msg.Values.id); - } else if (msg.MessageId === 'Hide_Button') { - w2ui['editbar'].hide(msg.Values.id); - } else { - w2ui['editbar'].remove(msg.Values.id); - } - } - if (msg.MessageId === 'Remove_Statusbar_Element') { - if (!msg.Values) { - console.error('Property "Values" not set'); - return; - } - if (!msg.Values.id) { - console.error('Property "Values.id" not set'); - return; - } - if (!w2ui['actionbar'].get(msg.Values.id)) { - console.error('Statusbar element with id "' + msg.Values.id + '" not found.'); - return; - } - w2ui['actionbar'].remove(msg.Values.id); + + // All following actions must be done after initialization is completed. + if (!window.WOPIPostmessageReady) { + return; } - else if (msg.MessageId === 'Show_Menubar') { - this._map.showMenubar(); + + if (msg.MessageId === 'Host_PostmessageReady') { + // We already have a listener for this in loleaflet.html, so ignore it here + return; } - else if (msg.MessageId === 'Hide_Menubar') { - this._map.hideMenubar(); + + if (msg.MessageId === 'Grab_Focus') { + this._map.makeActive(); + return; } - else if (msg.MessageId === 'Show_Ruler') { - this._map.showRuler(); + + // allow closing documents before they are completely loaded + if (msg.MessageId === 'Close_Session') { + this._map._socket.sendMessage('closedocument'); + return; } - else if (msg.MessageId === 'Hide_Ruler') { - this._map.hideRuler(); + + // For all other messages, warn if trying to interact before we are completely loaded + if (!this._appLoaded) { + console.error('LibreOffice Online not loaded yet. Listen for App_LoadingStatus (Document_Loaded) event before using PostMessage API. Ignoring post message \'' + msg.MessageId + '\'.'); + return; } - else if (msg.MessageId === 'Set_Settings') { + + if (msg.MessageId === 'Set_Settings') { if (msg.Values) { var alwaysActive = msg.Values.AlwaysActive; this._map.options.alwaysActive = !!alwaysActive; commit 7b86174eb85a9cda82247895d026a39c3013e8cd Author: Szymon Kłos <szymon.k...@collabora.com> AuthorDate: Thu Jun 6 17:51:48 2019 +0200 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 Add API to remove menu items Reviewed-on: https://gerrit.libreoffice.org/74128 Reviewed-by: Andras Timar <andras.ti...@collabora.com> Tested-by: Andras Timar <andras.ti...@collabora.com> (cherry picked from commit 16ba97e7ae4a06932bdd63dbf32dd9e09b6b227e) Reviewed-on: https://gerrit.libreoffice.org/75228 (cherry picked from commit 5105f3b95117c88d91a882fb4fef5356b5e45e68) Change-Id: I59f2e3e1ed467f58bcd56db945e0d4807c1cff6e diff --git a/loleaflet/reference.html b/loleaflet/reference.html index 4b3b9a53a..686c2854b 100644 --- a/loleaflet/reference.html +++ b/loleaflet/reference.html @@ -3241,12 +3241,34 @@ Editor to WOPI host <code><nobr>id: <string></nobr></code> </td> <td> - Hides a button from the toolbar.<br/> + Shows a button from the toolbar.<br/> <code>id</code> is the button ID as defined in the <a href="https://opengrok.libreoffice.org/search?project=online&q=&defs=createToolbar">createToolbar</a> function in <a href="https://opengrok.libreoffice.org/xref/online/loleaflet/js/toolbar.js">loleaflet/js/toolbar.js</a>. </td> </tr> + <tr> + <td><code><b>Hide_Menu_Item</b></code></td> + <td> + <code><nobr>id: <string></nobr></code> + </td> + <td> + Hides an item from the menu.<br/> + <code>id</code> is the item ID as defined in the + <a href="https://opengrok.libreoffice.org/xref/online/loleaflet/src/control/Control.Menubar.js">loleaflet/src/control/Control.Menubar.js</a>. + </td> + </tr> + <tr> + <td><code><b>Show_Menu_Item</b></code></td> + <td> + <code><nobr>id: <string></nobr></code> + </td> + <td> + Shows an item from the menu.<br/> + <code>id</code> is the item ID as defined in the + <a href="https://opengrok.libreoffice.org/xref/online/loleaflet/src/control/Control.Menubar.js">loleaflet/src/control/Control.Menubar.js</a>. + </td> + </tr> </table> <h5><a name="toolbar-button-ids">Finding toolbar button IDs</a></h5> diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js index 3057f5d95..f711e5aec 100644 --- a/loleaflet/src/control/Control.Menubar.js +++ b/loleaflet/src/control/Control.Menubar.js @@ -1062,6 +1062,39 @@ L.Control.Menubar = L.Control.extend({ return itemList; }, + _getItems: function() { + return $(this._menubarCont).children().children('ul').children('li').add($(this._menubarCont).children('li')); + }, + + _getItem: function(targetId) { + var items = this._getItems(); + var found = $(items).filter(function() { + var item = this; + var id = $(item).attr('id'); + if (id && id == 'menu-' + targetId) { + return true; + } + return false + }); + return found.length ? found : null; + }, + + hasItem: function(targetId) { + return this._getItem(targetId) != null; + }, + + hideItem: function(targetId) { + var item = this._getItem(targetId); + if (item) + $(item).css('display', 'none'); + }, + + showItem: function(targetId) { + var item = this._getItem(targetId); + if (item) + $(item).css('display', ''); + }, + _initializeMenu: function(menu) { var menuHtml = this._createMenu(menu); for (var i in menuHtml) { diff --git a/loleaflet/src/main.js b/loleaflet/src/main.js index 7e59effb5..1b847bb5e 100644 --- a/loleaflet/src/main.js +++ b/loleaflet/src/main.js @@ -72,7 +72,9 @@ var map = L.map('map', { }); ////// Controls ///// -map.addControl(L.control.menubar()); +var menubar = L.control.menubar(); +map.menubar = menubar; +map.addControl(menubar); setupToolbar(map); map.addControl(L.control.scroll()); map.addControl(L.control.alertDialog()); commit 9783d70520d4ee9e83b402771c9caacf4d9cd96c Author: Jan Holesovsky <ke...@collabora.com> AuthorDate: Mon Jun 3 14:25:30 2019 +0200 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 Show the state of the Delete Slide. When there is only one slide, it cannot be deleted. Use the information from the core to enable or disable the state of the "Delete Slide" button in the slide sorter and the menu entry. Reviewed-on: https://gerrit.libreoffice.org/73383 Reviewed-by: Szymon Kłos <szymon.k...@collabora.com> Tested-by: Szymon Kłos <szymon.k...@collabora.com> (cherry picked from commit 3a1f68dc84dddf252cdd222ab14b2a4635f39251) Reviewed-on: https://gerrit.libreoffice.org/73863 Reviewed-by: Andras Timar <andras.ti...@collabora.com> Tested-by: Andras Timar <andras.ti...@collabora.com> Change-Id: I549d4c09b6fd999b14e281976320d1b6f63d64b7 diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js index 2e0f2e348..3057f5d95 100644 --- a/loleaflet/src/control/Control.Menubar.js +++ b/loleaflet/src/control/Control.Menubar.js @@ -725,6 +725,20 @@ L.Control.Menubar = L.Control.extend({ } else { $(aItem).removeClass(constChecked); } + + } else if (self._map.getDocType() === 'presentation' && (id === 'deletepage' || id === 'insertpage' || id === 'duplicatepage')) { + if (id === 'deletepage') { + itemState = self._map['stateChangeHandler'].getItemValue('.uno:DeletePage'); + } else if (id === 'insertpage') { + itemState = self._map['stateChangeHandler'].getItemValue('.uno:InsertPage'); + } else { + itemState = self._map['stateChangeHandler'].getItemValue('.uno:DuplicatePage'); + } + if (itemState === 'disabled') { + $(aItem).addClass('disabled'); + } else { + $(aItem).removeClass('disabled'); + } } else { $(aItem).removeClass('disabled'); } diff --git a/loleaflet/src/control/Control.Toolbar.js b/loleaflet/src/control/Control.Toolbar.js index 948b85b0d..de4b5fcb1 100644 --- a/loleaflet/src/control/Control.Toolbar.js +++ b/loleaflet/src/control/Control.Toolbar.js @@ -1732,6 +1732,9 @@ function onCommandStateChanged(e) { if (_inMobileMode()) { toolbarUp = statusbar; } + if (map.getDocType() === 'presentation' && (id === 'deletepage' || id === 'insertpage' || id === 'duplicatepage')) { + toolbarUp = w2ui['presentation-toolbar']; + } if (state === 'enabled') { toolbarUp.enable(id); } else { @@ -1998,6 +2001,24 @@ function onUpdatePermission(e) { }); } + presentationButtons.forEach(function(id) { + if (id === 'deletepage') { + var itemState = map['stateChangeHandler'].getItemValue('.uno:DeletePage'); + } else if (id === 'insertpage') { + itemState = map['stateChangeHandler'].getItemValue('.uno:InsertPage'); + } else if (id === 'duplicatepage') { + itemState = map['stateChangeHandler'].getItemValue('.uno:DuplicatePage'); + } else { + itemState = 'enabled'; + } + + if (itemState === 'enabled') { + toolbar.enable(id); + } else { + toolbar.disable(id); + } + }); + toolbar = w2ui['actionbar']; if (toolbar) { toolbarDownButtons.forEach(function(id) { commit 11f5154432eef8e067efb140e329dba0a47afd3d Author: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> AuthorDate: Thu Nov 29 09:32:56 2018 +0100 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 Add postMessage methods to show/hide toolbar buttons (cherry picked from commit c0d0ad736839260667c98aa0cf08feb5630e0b87) Change-Id: Ib5ecde5a53aa0aae2346e360423e72025edade3a diff --git a/loleaflet/reference.html b/loleaflet/reference.html index 1d8b8ba83..4b3b9a53a 100644 --- a/loleaflet/reference.html +++ b/loleaflet/reference.html @@ -3223,6 +3223,30 @@ Editor to WOPI host Shows the horizontal document ruler (Writer only) </td> </tr> + <tr> + <td><code><b>Hide_Button</b></code></td> + <td> + <code><nobr>id: <string></nobr></code> + </td> + <td> + Hides a button from the toolbar.<br/> + <code>id</code> is the button ID as defined in the + <a href="https://opengrok.libreoffice.org/search?project=online&q=&defs=createToolbar">createToolbar</a> + function in <a href="https://opengrok.libreoffice.org/xref/online/loleaflet/js/toolbar.js">loleaflet/js/toolbar.js</a>. + </td> + </tr> + <tr> + <td><code><b>Show_Button</b></code></td> + <td> + <code><nobr>id: <string></nobr></code> + </td> + <td> + Hides a button from the toolbar.<br/> + <code>id</code> is the button ID as defined in the + <a href="https://opengrok.libreoffice.org/search?project=online&q=&defs=createToolbar">createToolbar</a> + function in <a href="https://opengrok.libreoffice.org/xref/online/loleaflet/js/toolbar.js">loleaflet/js/toolbar.js</a>. + </td> + </tr> </table> <h5><a name="toolbar-button-ids">Finding toolbar button IDs</a></h5> commit 30cc128690119114e4b2b92c83f69d6e133623b7 Author: Florin Ciornei <florin.cior...@collabora.com> AuthorDate: Tue May 14 16:13:08 2019 +0200 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 Open/close sidebar on swipe Change-Id: I91e3889375b833c656cf81f2dc4094b1d3f13ea5 Reviewed-on: https://gerrit.libreoffice.org/72354 Reviewed-by: Jan Holesovsky <ke...@collabora.com> Tested-by: Jan Holesovsky <ke...@collabora.com> (cherry picked from commit 0fb53bb1a8487171acba1b08c720c5cdb75855c3) diff --git a/loleaflet/src/control/Control.LokDialog.js b/loleaflet/src/control/Control.LokDialog.js index 4e363f2fc..0dd42476b 100644 --- a/loleaflet/src/control/Control.LokDialog.js +++ b/loleaflet/src/control/Control.LokDialog.js @@ -127,6 +127,25 @@ L.Control.LokDialog = L.Control.extend({ map.on('closesidebar', this._closeSidebar, this); map.on('editorgotfocus', this._onEditorGotFocus, this); L.DomEvent.on(document, 'mouseup', this.onCloseCurrentPopUp, this); + + this.slideAnimationDuration = 250;//sidebar open animation duration + + //open sidebar on left swipe on document view + var documentContainerHammer = new Hammer(document.getElementById('document-container')); + documentContainerHammer.on('swipeleft', function (e) { + var startX = e.changedPointers[0].clientX - e.deltaX; + if (startX < window.screen.width * 0.7)//detect open swipes only near screen edge + return; + map._socket.sendMessage('uno .uno:Sidebar'); + }) + + //close sidebar on right swipe on sidebar panel, also on document view(for tablets) + var sidebarPanelHammer = new Hammer(document.getElementById('sidebar-panel')); + [sidebarPanelHammer, documentContainerHammer].forEach(function (hammerElement) { + hammerElement.on('swiperight', function () { + map._socket.sendMessage('uno .uno:Sidebar'); + }) + }) }, _dialogs: {}, @@ -602,6 +621,19 @@ L.Control.LokDialog = L.Control.extend({ // Render window. this._sendPaintWindowRect(id); + + //play slide from right animation on mobile and tablets + if (L.Browser.mobile) { + var sidebar = $('#sidebar-dock-wrapper'); + var bottomBar = $('#toolbar-down'); + sidebar.css('bottom', '0px');//to take the space occupied by the bottom menu + sidebar.css('position', 'fixed');//fixed position in order to prevent scrollbars to appear while opening/closing + bottomBar.animate({ 'opacity': 0 }, this.slideAnimationDuration); + sidebar.css('margin-right', -width * ratio + 'px').animate({ 'margin-right': '0px' }, this.slideAnimationDuration, function () { + $('#toolbar-down').hide(); + sidebar.css('position', ''); + }); + } }, _setupWindowEvents: function(id, canvas, dlgInput) { @@ -776,6 +808,22 @@ L.Control.LokDialog = L.Control.extend({ this._map.focus(); delete this._dialogs[dialogId]; this._currentDeck = null; + + //play slide animation to right if this is a mobile or tablet + if (L.Browser.mobile) { + var sidebar = $('#sidebar-dock-wrapper'); + var bottomBar = $('#toolbar-down'); + var sidebarWidth = $('#sidebar-dock-wrapper').width(); + bottomBar.animate({ 'opacity': 1 }, this.slideAnimationDuration); + sidebar.css('position', 'fixed');//fixed position in order to prevent scrollbars to appear while opening/closing + sidebar.animate({ 'margin-right': -sidebarWidth + 'px' }, this.slideAnimationDuration, function () { + //remove artifacts from the animation + sidebar.css('margin-right', ''); + sidebar.css('display', ''); + sidebar.css('position', ''); + $('#toolbar-down').show(); + }); + } }, _onDialogClose: function(dialogId, notifyBackend) { commit 4df0548d264f09c440c30bfae75785045e51cca7 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Mon May 13 06:50:32 2019 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 leaflet: update the cursor when the editor gets focus back After closing dialog that had its own cursor, the editor loses the cursor until the user types, which forces a cursor invalidation from Core. This is to make sure that the editor always updates the visibility of its cursor when the editor get focus back. Change-Id: Icba5e6c2c94da7488131269749fc96e185dec6a2 (cherry picked from commit 72025d21cb127aadeb092e564da8acc884188032) diff --git a/loleaflet/src/map/Map.js b/loleaflet/src/map/Map.js index b1607a7f8..e176e0d10 100644 --- a/loleaflet/src/map/Map.js +++ b/loleaflet/src/map/Map.js @@ -862,6 +862,7 @@ L.Map = L.Evented.extend({ focus: function () { this._clipboardContainer.focus(); + this._onEditorGotFocus(); }, hasFocus: function () { commit 6a99e313ec3f348e5af8b5a19ac191d791b3483f Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Sun May 12 16:52:35 2019 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 leaflet: initialize the sidebar only once Calc tends to issue document size change very frequently (after certain operations), and this results in the status: message to be generated. Unfortunately, this message signals finishing document loading, which means it also triggers post-loading events. This fix is to hold a new flag in map to track the true first laod event, to avoid triggering post-load handlers. Ideally, we will get a different and unambiguous message for document loading, vs. generic status updates. Change-Id: Ib8b59c04a770cbfcaf443608c418557671ed207b (cherry picked from commit c97defd5f65a1bbc69247f74a943b224111f2ca2) diff --git a/loleaflet/src/map/Map.js b/loleaflet/src/map/Map.js index ece3a6b37..b1607a7f8 100644 --- a/loleaflet/src/map/Map.js +++ b/loleaflet/src/map/Map.js @@ -230,9 +230,13 @@ L.Map = L.Evented.extend({ // This becomes true if document was ever modified by the user this._everModified = false; - // Document is completely loaded or not + // Document is completely loaded or not. this._docLoaded = false; + // Unlike _docLoaded, this is flagged only once, + // after we receive status for the first time. + this._docLoadedOnce = false; + this.on('commandstatechanged', function(e) { if (e.commandName === '.uno:ModifiedStatus') this._everModified = this._everModified || (e.state === 'true'); @@ -256,7 +260,7 @@ L.Map = L.Evented.extend({ this.initializeModificationIndicator(); // Show sidebar. - if (this._docLayer && !window.mode.isMobile() && !window.mode.isTablet() && + if (this._docLayer && !this._docLoadedOnce && !window.mode.isMobile() && !window.mode.isTablet() && (this._docLayer._docType === 'spreadsheet' || this._docLayer._docType === 'text')) { // Let the first page finish loading then load the sidebar. var map = this; @@ -268,6 +272,11 @@ L.Map = L.Evented.extend({ map._socket.sendMessage('uno .uno:Sidebar'); }, 200); } + + // We have loaded. + if (!this._docLoadedOnce) { + this._docLoadedOnce = this._docLoaded; + } }, this); }, commit 5e84467f62fdc35a6a7c72db9fcc75dd63684fbd Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Thu May 9 08:15:14 2019 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 leaflet: Keep active even in windows and child windows Change-Id: I7e72b21d9276e96e94852916f9e6a8e04d73c222 (cherry picked from commit 977858b8720516d50a4e0365dce5d486939427b1) diff --git a/loleaflet/src/control/Control.LokDialog.js b/loleaflet/src/control/Control.LokDialog.js index 96af0de39..4e363f2fc 100644 --- a/loleaflet/src/control/Control.LokDialog.js +++ b/loleaflet/src/control/Control.LokDialog.js @@ -607,7 +607,6 @@ L.Control.LokDialog = L.Control.extend({ _setupWindowEvents: function(id, canvas, dlgInput) { L.DomEvent.on(canvas, 'contextmenu', L.DomEvent.preventDefault); L.DomEvent.on(canvas, 'mousemove', function(e) { - this._map.lastActiveTime = Date.now(); this._postWindowMouseEvent('move', id, e.offsetX, e.offsetY, 1, 0, 0); // Keep map active while user is playing with sidebar/dialog. this._map.lastActiveTime = Date.now(); @@ -744,23 +743,31 @@ L.Control.LokDialog = L.Control.extend({ _postWindowCompositionEvent: function(winid, type, text) { this._map._docLayer._postCompositionEvent(winid, type, text); + // Keep map active while user is playing with sidebar/dialog. + this._map.lastActiveTime = Date.now(); }, _postWindowMouseEvent: function(type, winid, x, y, count, buttons, modifier) { this._map._socket.sendMessage('windowmouse id=' + winid + ' type=' + type + ' x=' + x + ' y=' + y + ' count=' + count + ' buttons=' + buttons + ' modifier=' + modifier); + // Keep map active while user is playing with sidebar/dialog. + this._map.lastActiveTime = Date.now(); }, _postWindowGestureEvent: function(winid, type, x, y, offset) { console.log('x ' + x + ' y ' + y + ' o ' + offset); this._map._socket.sendMessage('windowgesture id=' + winid + ' type=' + type + ' x=' + x + ' y=' + y + ' offset=' + offset); + // Keep map active while user is playing with sidebar/dialog. + this._map.lastActiveTime = Date.now(); }, _postWindowKeyboardEvent: function(winid, type, charcode, keycode) { this._map._socket.sendMessage('windowkey id=' + winid + ' type=' + type + ' char=' + charcode + ' key=' + keycode); + // Keep map active while user is playing with sidebar/dialog. + this._map.lastActiveTime = Date.now(); }, _onSidebarClose: function(dialogId) { @@ -992,7 +999,6 @@ L.Control.LokDialog = L.Control.extend({ } firstTouchPositionX = null; firstTouchPositionY = null; - } else if (e.type === 'touchmove') { commit 076bbc80fa4bc65559937fc03421ac7f4c6537c3 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Tue May 7 20:59:13 2019 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 leaflet: show message box dialogs centered Change-Id: Ic55f48067c918aac2bdcfe998c8d4b5cbbcc008d (cherry picked from commit 2f0e39b39cc16e4bc3c6157de3ba4b32dba7abf4) diff --git a/loleaflet/src/control/Control.LokDialog.js b/loleaflet/src/control/Control.LokDialog.js index 3552d4f0b..96af0de39 100644 --- a/loleaflet/src/control/Control.LokDialog.js +++ b/loleaflet/src/control/Control.LokDialog.js @@ -248,8 +248,8 @@ L.Control.LokDialog = L.Control.extend({ height = parseInt(e.size.split(',')[1]); } - var left = 0; - var top = 0; + var left; + var top; if (e.position) { left = parseInt(e.position.split(',')[0]); top = parseInt(e.position.split(',')[1]); @@ -257,14 +257,19 @@ L.Control.LokDialog = L.Control.extend({ if (e.action === 'created') { if (e.winType === 'dialog') { + // When left/top are invalid, the dialog shows in the center. this._launchDialog(e.id, left, top, width, height, e.title); } else if (e.winType === 'deck') { - this._launchSidebar(e.id, left, top, width, height); + this._launchSidebar(e.id, width, height); } else if (e.winType === 'child') { var parentId = parseInt(e.parentId); if (!this._isOpen(parentId)) return; + if (!left) + left = 0; + if (!top) + top = 0; this._removeDialogChild(parentId); this._dialogs[parentId].childid = e.id; this._dialogs[parentId].childwidth = width; @@ -501,12 +506,7 @@ L.Control.LokDialog = L.Control.extend({ this._sendPaintWindow(id, this._createRectStr(id)); }, - _launchSidebar: function(id, left, top, width, height) { - - if (!left) - left = 0; - if (!top) - top = 0; + _launchSidebar: function(id, width, height) { if ((window.mode.isMobile() || window.mode.isTablet()) && this._map._permission != 'edit') @@ -571,8 +571,8 @@ L.Control.LokDialog = L.Control.extend({ id: id, strId: strId, isSidebar: true, - left: left, - top: top, + left: 0, + top: 0, width: width, height: height, cursor: null, commit 5fcd8f38beddf0f3c4f13169cf67e9c77e4fa173 Author: Jan Holesovsky <ke...@collabora.com> AuthorDate: Tue May 14 14:02:12 2019 +0200 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 Fix build. Change-Id: Ibfe0d09ca156540f5ec535c6a5da5e9cd339b16d (cherry picked from commit b52dd6b14e63ff160524a0f6fe2d3d4e2361d547) diff --git a/kit/ChildSession.hpp b/kit/ChildSession.hpp index cbaaba54b..3e32f311d 100644 --- a/kit/ChildSession.hpp +++ b/kit/ChildSession.hpp @@ -36,6 +36,8 @@ enum class LokEventTargetEnum class DocumentManagerInterface { public: + virtual ~DocumentManagerInterface() {} + /// Reqest loading a document, or a new view, if one exists. virtual bool onLoad(const std::string& sessionId, const std::string& uriAnonym, commit 7edfa725c19d80e7a54d2aed7b8d694dcbfada7d Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Sat May 4 15:30:11 2019 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 leaflet: Add sidebar commands in toolbar and menu Reviewed-on: https://gerrit.libreoffice.org/71840 Reviewed-by: Jan Holesovsky <ke...@collabora.com> Tested-by: Jan Holesovsky <ke...@collabora.com> (cherry picked from commit 212290a35dc4e87439e5d4d41b16224281c8d27d) Change-Id: Icac459849196a70b62ac0e2a558882d8cc199e6c diff --git a/loleaflet/css/toolbar.css b/loleaflet/css/toolbar.css index 3ae37ad54..5e63e4140 100644 --- a/loleaflet/css/toolbar.css +++ b/loleaflet/css/toolbar.css @@ -617,6 +617,7 @@ button.leaflet-control-search-next .w2ui-icon.fullscreen{ background: url('images/lc_fullscreen.svg') no-repeat center !important; } .w2ui-icon.closemobile{ background: url('images/lc_closedocmobile.svg') no-repeat center !important; } .w2ui-icon.closetoolbar{ background: url('images/close_toolbar.svg') no-repeat center !important; } +.w2ui-icon.sidebar_modify_page{ background: url('images/lc_formproperties.svg') no-repeat center !important; } .w2ui-icon.vereign{ background: url('images/vereign.png') no-repeat center !important; } diff --git a/loleaflet/images/lc_formproperties.svg b/loleaflet/images/lc_formproperties.svg new file mode 100644 index 000000000..75c2b7b52 --- /dev/null +++ b/loleaflet/images/lc_formproperties.svg @@ -0,0 +1 @@ +<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m3 6h18v15h-18z" fill="#fff"/><path d="m3 2c-.554 0-1 .446-1 1v18c0 .554.446 1 1 1h18c.554 0 1-.446 1-1v-18c0-.554-.446-1-1-1zm0 4h18v15h-18z" fill="#808080"/><rect fill="#808080" height="1" ry=".5" width="12" x="6" y="11"/><rect fill="#4d82b8" height="1" ry=".5" width="4" x="6" y="15"/><path d="m10.5 14a1.5 1.5 0 0 0 -1.5 1.5 1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5-1.5 1.5 1.5 0 0 0 -1.5-1.5zm0 1a.5.5 0 0 1 .5.5.5.5 0 0 1 -.5.5.5.5 0 0 1 -.5-.5.5.5 0 0 1 .5-.5z" fill="#4d82b8"/><path d="m13.5 10c-.828427 0-1.5.671573-1.5 1.5s.671573 1.5 1.5 1.5 1.5-.671573 1.5-1.5-.671573-1.5-1.5-1.5z" fill="#808080"/><rect fill="#4d82b8" height="1" ry=".491011" width="7" x="11" y="15"/><g fill="#808080"><rect height="1" ry=".5" width="4" x="6" y="15"/><path d="m10.5 14a1.5 1.5 0 0 0 -1.5 1.5 1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5-1.5 1.5 1.5 0 0 0 -1.5-1.5zm0 1a.5.5 0 0 1 .5.5.5.5 0 0 1 -.5.5.5.5 0 0 1 -.5-.5.5.5 0 0 1 .5-.5z"/> <rect height="1" ry=".491011" width="7" x="11" y="15"/></g></svg> \ No newline at end of file diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js index 6d9fcb33b..2e0f2e348 100644 --- a/loleaflet/src/control/Control.Menubar.js +++ b/loleaflet/src/control/Control.Menubar.js @@ -66,7 +66,9 @@ L.Control.Menubar = L.Control.extend({ {type: 'separator'}, {uno: '.uno:ControlCodes'}, {type: 'separator'}, - {name: _UNO('.uno:ShowResolvedAnnotations', 'text'), id: 'showresolved', type: 'action'} + {name: _UNO('.uno:ShowResolvedAnnotations', 'text'), id: 'showresolved', type: 'action'}, + {type: 'separator'}, + {uno: '.uno:Sidebar'} ] }, {name: _UNO('.uno:InsertMenu', 'text'), type: 'menu', menu: [ @@ -357,7 +359,9 @@ L.Control.Menubar = L.Control.extend({ {uno: '.uno:SearchDialog'} ]}, {name: _UNO('.uno:ViewMenu', 'spreadsheet'), id: 'view', type: 'menu', mobileapp: false, menu: [ - {name: _UNO('.uno:FullScreen', 'spreadsheet'), id: 'fullscreen', type: 'action'} + {name: _UNO('.uno:FullScreen', 'spreadsheet'), id: 'fullscreen', type: 'action'}, + {type: 'separator'}, + {uno: '.uno:Sidebar'} ]}, {name: _UNO('.uno:InsertMenu', 'spreadsheet'), type: 'menu', menu: [ {name: _('Local Image...'), id: 'insertgraphic', type: 'action'}, diff --git a/loleaflet/src/control/Control.Toolbar.js b/loleaflet/src/control/Control.Toolbar.js index 29e5c2590..948b85b0d 100644 --- a/loleaflet/src/control/Control.Toolbar.js +++ b/loleaflet/src/control/Control.Toolbar.js @@ -824,6 +824,8 @@ function initNormalToolbar() { {type: 'button', id: 'insertsymbol', img: 'insertsymbol', hint: _UNO('.uno:InsertSymbol', '', true), uno: 'InsertSymbol'}, {type: 'spacer'}, {type: 'button', id: 'edit', img: 'edit'}, + {type: 'button', id: 'sidebar', img: 'sidebar_modify_page', hint: _UNO('.uno:Sidebar', '', true), uno: '.uno:Sidebar', hidden: true}, + {type: 'break', id: 'breaksidebar', hidden: true}, {type: 'button', id: 'fold', img: 'fold', desktop: true, mobile: false, hidden: true}, {type: 'button', id: 'hamburger-tablet', img: 'hamburger', desktop: false, mobile: false, tablet: true, iosapptablet: false, hidden: true} ]; @@ -1350,7 +1352,7 @@ function onDocLayerInit() { toolbarUp.show('textalign', 'wraptext', 'breakspacing', 'insertannotation', 'conditionalformaticonset', 'numberformatcurrency', 'numberformatpercent', 'numberformatincdecimals', 'numberformatdecdecimals', 'break-number', 'togglemergecells', 'breakmergecells', - 'setborderstyle', 'sortascending', 'sortdescending', 'breaksorting', 'backgroundcolor'); + 'setborderstyle', 'sortascending', 'sortdescending', 'breaksorting', 'backgroundcolor', 'breaksidebar', 'sidebar'); toolbarUp.remove('styles'); statusbar.remove('prev', 'next', 'prevnextbreak'); @@ -1416,7 +1418,7 @@ function onDocLayerInit() { case 'text': toolbarUp.show('leftpara', 'centerpara', 'rightpara', 'justifypara', 'breakpara', 'linespacing', 'breakspacing', 'defaultbullet', 'defaultnumbering', 'breakbullet', 'incrementindent', 'decrementindent', - 'breakindent', 'inserttable', 'insertannotation', 'backcolor'); + 'breakindent', 'inserttable', 'insertannotation', 'backcolor', 'breaksidebar', 'sidebar'); if (!_inMobileMode()) { statusbar.insert('left', [ diff --git a/loleaflet/src/map/Map.js b/loleaflet/src/map/Map.js index 6513f40ac..ece3a6b37 100644 --- a/loleaflet/src/map/Map.js +++ b/loleaflet/src/map/Map.js @@ -264,7 +264,7 @@ L.Map = L.Evented.extend({ // This triggers all sidebar decks, so they would // be loaded and show rather quickly on first use. // Also, triggers sidebar window creation in the client. - map._socket.sendMessage('uno .uno:ViewSidebarStyles'); + map._socket.sendMessage('uno .uno:Sidebar'); map._socket.sendMessage('uno .uno:Sidebar'); }, 200); } commit 3d4f148a56324ceafb1a1688bb4dee8ef7591d61 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Thu May 2 23:28:04 2019 -0400 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 leaflet: Enable sidebar in writer and calc Does not actually show the sidebar yet... Change-Id: Iadddba04bbdb96159e84ffd1498a0845b32e1590 (cherry picked from commit b999c6fe6d080131f96dec34b11075164ae1d9e1) diff --git a/loleaflet/src/map/Map.js b/loleaflet/src/map/Map.js index 1828fabb7..6513f40ac 100644 --- a/loleaflet/src/map/Map.js +++ b/loleaflet/src/map/Map.js @@ -257,17 +257,15 @@ L.Map = L.Evented.extend({ // Show sidebar. if (this._docLayer && !window.mode.isMobile() && !window.mode.isTablet() && - (this._docLayer._docType === 'spreadsheet' || this._docType === 'text')) { + (this._docLayer._docType === 'spreadsheet' || this._docLayer._docType === 'text')) { // Let the first page finish loading then load the sidebar. var map = this; setTimeout(function () { // This triggers all sidebar decks, so they would // be loaded and show rather quickly on first use. // Also, triggers sidebar window creation in the client. - map._socket.sendMessage('uno .uno:MasterSlidesPanel'); - map._socket.sendMessage('uno .uno:CustomAnimation'); - map._socket.sendMessage('uno .uno:SlideChangeWindow'); - map._socket.sendMessage('uno .uno:ModifyPage'); + map._socket.sendMessage('uno .uno:ViewSidebarStyles'); + map._socket.sendMessage('uno .uno:Sidebar'); }, 200); } }, this); commit 652ae5c68f7d494293bc486ecae56c30f2f971c8 Author: Szymon Kłos <szymon.k...@collabora.com> AuthorDate: Mon Mar 25 20:19:09 2019 +0100 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 Sidebar: don't show border and placeholder if not visible Change-Id: I689fa47b0dcb034688ec73c0d338c99423b10a38 (cherry picked from commit 9b31ab7d44894dda87276eae6bb852bbbc692e1e) diff --git a/loleaflet/css/loleaflet.css b/loleaflet/css/loleaflet.css index 0cf5e2b0c..1941b78d5 100644 --- a/loleaflet/css/loleaflet.css +++ b/loleaflet/css/loleaflet.css @@ -117,6 +117,7 @@ body { } #sidebar-dock-wrapper { + display: none; background: #fff; position: absolute; top: 77px; diff --git a/loleaflet/src/control/Control.LokDialog.js b/loleaflet/src/control/Control.LokDialog.js index 9d3721f78..3552d4f0b 100644 --- a/loleaflet/src/control/Control.LokDialog.js +++ b/loleaflet/src/control/Control.LokDialog.js @@ -512,6 +512,8 @@ L.Control.LokDialog = L.Control.extend({ && this._map._permission != 'edit') return; + $('#sidebar-dock-wrapper').css('display', 'block'); + var ratio = 1.0; if (width > window.screen.width) { ratio = window.screen.width / width; @@ -890,7 +892,10 @@ L.Control.LokDialog = L.Control.extend({ _resizeSidebar: function(strId, width) { this._currentDeck.width = width; - width = width + 15; + if (width > 1) { + // Add extra space for scrollbar only when visible + width = width + 15; + } var sidebar = L.DomUtil.get(strId); if (sidebar) { sidebar.width = width; commit d5b906f3d5294414227669d586baed5c8a6159f2 Author: Szymon Kłos <szymon.k...@collabora.com> AuthorDate: Thu Feb 7 15:17:21 2019 +0100 Commit: Ashod Nakashian <ashod.nakash...@collabora.co.uk> CommitDate: Tue Sep 3 01:53:12 2019 -0400 Z-index doc, sidebar under menu Change-Id: Ic9c0dbb326d45c205746e50018906030f7a6fd27 (cherry picked from commit 0d7b28daf8a8bf6f2adc33bbe3d7d5f7f72d6659) diff --git a/loleaflet/README b/loleaflet/README index ad67073bd..5e93024f9 100644 --- a/loleaflet/README +++ b/loleaflet/README @@ -377,3 +377,26 @@ are independent of the map's div, thus enabling us to link them to the map as ne When the user scrolls, the map is panned by the same amount as it would've been scrolled. Also, some custom jquery scrollbars are used, to trigger the same scroll events across browsers. + +Z-index values: +------------------------------------------- + leaflet +------------------------------------------- +10 map +11 ruler +------------------------------------------- + under menu +------------------------------------------- +990 sidebar +999 toolbar-up +------------------------------------------- + menu items +------------------------------------------- +1000 menu, toolbar-down +1050 closebuttonwrapper +------------------------------------------- + on the top +------------------------------------------- +1105 dialogs +2000 mobile-edit-button +------------------------------------------- diff --git a/loleaflet/css/loleaflet.css b/loleaflet/css/loleaflet.css ... etc. - the rest is truncated _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits