diff --git a/Readme.md b/Readme.md index 56395225d..747cb8437 100644 --- a/Readme.md +++ b/Readme.md @@ -1,25 +1,29 @@ -[![License](https://img.shields.io/badge/License-GNU%20AGPL%20V3-green.svg?style=flat)](https://www.gnu.org/licenses/agpl-3.0.en.html) - -## web-apps - -The frontend for [ONLYOFFICE Document Server][2]. Builds the program interface and allows the user create, edit, save and export text, spreadsheet and presentation documents using the common interface of a document editor. - -## Project Information - -Official website: [http://www.onlyoffice.org](http://onlyoffice.org "http://www.onlyoffice.org") - -Code repository: [https://github.com/ONLYOFFICE/web-apps](https://github.com/ONLYOFFICE/web-apps "https://github.com/ONLYOFFICE/web-apps") - -SaaS version: [http://www.onlyoffice.com](http://www.onlyoffice.com "http://www.onlyoffice.com") - -## User Feedback and Support - -If you have any problems with or questions about [ONLYOFFICE Document Server][2], please visit our official forum to find answers to your questions: [dev.onlyoffice.org][1] or you can ask and answer ONLYOFFICE development questions on [Stack Overflow][3]. - - [1]: http://dev.onlyoffice.org - [2]: https://github.com/ONLYOFFICE/DocumentServer - [3]: http://stackoverflow.com/questions/tagged/onlyoffice - -## License - -web-apps is released under an GNU AGPL v3.0 license. See the LICENSE file for more information. +[![License](https://img.shields.io/badge/License-GNU%20AGPL%20V3-green.svg?style=flat)](https://www.gnu.org/licenses/agpl-3.0.en.html) + +## web-apps + +The frontend for [ONLYOFFICE Document Server][2]. Builds the program interface and allows the user create, edit, save and export text, spreadsheet and presentation documents using the common interface of a document editor. + +## Previos versions + +Until 2019-10-23 the repository was called web-apps-pro + +## Project Information + +Official website: [http://www.onlyoffice.org](http://onlyoffice.org "http://www.onlyoffice.org") + +Code repository: [https://github.com/ONLYOFFICE/web-apps](https://github.com/ONLYOFFICE/web-apps "https://github.com/ONLYOFFICE/web-apps") + +SaaS version: [http://www.onlyoffice.com](http://www.onlyoffice.com "http://www.onlyoffice.com") + +## User Feedback and Support + +If you have any problems with or questions about [ONLYOFFICE Document Server][2], please visit our official forum to find answers to your questions: [dev.onlyoffice.org][1] or you can ask and answer ONLYOFFICE development questions on [Stack Overflow][3]. + + [1]: http://dev.onlyoffice.org + [2]: https://github.com/ONLYOFFICE/DocumentServer + [3]: http://stackoverflow.com/questions/tagged/onlyoffice + +## License + +web-apps is released under an GNU AGPL v3.0 license. See the LICENSE file for more information. diff --git a/apps/api/documents/api.js b/apps/api/documents/api.js index 66f179591..8b9efb748 100644 --- a/apps/api/documents/api.js +++ b/apps/api/documents/api.js @@ -129,7 +129,8 @@ toolbarNoTabs: false, toolbarHideFileName: false, reviewDisplay: 'original', - spellcheck: true + spellcheck: true, + compatibleFeatures: false }, plugins: { autostart: ['asc.{FFE1F462-1EA2-4391-990D-4CC84940B754}'], diff --git a/apps/common/main/lib/component/TabBar.js b/apps/common/main/lib/component/TabBar.js index 27d120875..baae6631d 100644 --- a/apps/common/main/lib/component/TabBar.js +++ b/apps/common/main/lib/component/TabBar.js @@ -113,6 +113,8 @@ define([ this.bounds.push(me.bar.tabs[i].$el.get(0).getBoundingClientRect()); } + me.lastTabRight = me.bounds[length - 1].right; + me.tabBarLeft = me.bounds[0].left; me.tabBarRight = me.bounds[length - 1].right; me.tabBarRight = Math.min(me.tabBarRight, barBounds.right - 1); @@ -322,17 +324,18 @@ define([ function dragMove (event) { if (!_.isUndefined(me.drag)) { me.drag.moveX = event.clientX*Common.Utils.zoom(); - if (me.drag.moveX > me.tabBarRight) { + if (me.drag.moveX < me.tabBarRight && me.drag.moveX > me.tabBarLeft) { + var name = $(event.target).parent().data('label'), + currentTab = _.findIndex(bar.tabs, {label: name}); + if (currentTab !== -1 && (me.bounds[currentTab].left - me.scrollLeft >= me.tabBarLeft)) { + me.drag.place = currentTab; + $(event.target).parent().parent().find('li.mousemove').removeClass('mousemove right'); + $(event.target).parent().addClass('mousemove'); + } + } else if ((me.drag.moveX > me.lastTabRight - me.scrollLeft) && (me.tabBarRight >= me.lastTabRight - me.scrollLeft)) { //move to end of list, right border of the right tab is visible + bar.$el.find('li.mousemove').removeClass('mousemove right'); bar.tabs[bar.tabs.length - 1].$el.addClass('mousemove right'); me.drag.place = bar.tabs.length; - } else { - $(event.target).parent().parent().find('li.mousemove').removeClass('mousemove right'); - $(event.target).parent().addClass('mousemove'); - var name = event.target.parentElement.dataset.label, - currentTab = _.findWhere(bar.tabs, {label: name}); - if (!_.isUndefined(currentTab)) { - me.drag.place = currentTab.sheetindex; - } } } } @@ -357,7 +360,9 @@ define([ click: $.proxy(function (event) { if (!tab.disabled) { if (event.ctrlKey || event.metaKey) { - tab.changeState(true); + if (!tab.isActive()) { + tab.changeState(true); + } } else if (event.shiftKey) { this.bar.$el.find('ul > li.selected').removeClass('selected'); this.bar.selectTabs.length = 0; diff --git a/apps/common/main/lib/view/Comments.js b/apps/common/main/lib/view/Comments.js index bdb95b10a..679ea505c 100644 --- a/apps/common/main/lib/view/Comments.js +++ b/apps/common/main/lib/view/Comments.js @@ -559,9 +559,13 @@ define([ add = $('.new-comment-ct', this.el), to = $('.add-link-ct', this.el), msgs = $('.messages-ct', this.el); - msgs.toggleClass('stretch', !mode.canComments); - if (!mode.canComments) { - add.hide(); to.hide(); + msgs.toggleClass('stretch', !mode.canComments || mode.compatibleFeatures); + if (!mode.canComments || mode.compatibleFeatures) { + if (mode.compatibleFeatures) { + add.remove(); to.remove(); + } else { + add.hide(); to.hide(); + } this.layout.changeLayout([{el: msgs[0], rely: false, stretch: true}]); } else { var container = $('#comments-box', this.el), diff --git a/apps/common/main/lib/view/Header.js b/apps/common/main/lib/view/Header.js index 6f3333034..7933acdee 100644 --- a/apps/common/main/lib/view/Header.js +++ b/apps/common/main/lib/view/Header.js @@ -183,7 +183,7 @@ define([ function onLostEditRights() { _readonlyRights = true; - $panelUsers.find('#tlb-change-rights').hide(); + $panelUsers && $panelUsers.find('#tlb-change-rights').hide(); $btnUsers && !$btnUsers.menu && $panelUsers.hide(); } diff --git a/apps/common/main/lib/view/ImageFromUrlDialog.js b/apps/common/main/lib/view/ImageFromUrlDialog.js index 172859ce7..beffb0fc8 100644 --- a/apps/common/main/lib/view/ImageFromUrlDialog.js +++ b/apps/common/main/lib/view/ImageFromUrlDialog.js @@ -47,8 +47,7 @@ define([ width: 330, header: false, cls: 'modal-dlg', - buttons: ['ok', 'cancel'], - footerCls: 'right' + buttons: ['ok', 'cancel'] }, initialize : function(options) { diff --git a/apps/common/main/lib/view/LanguageDialog.js b/apps/common/main/lib/view/LanguageDialog.js index ad4216a15..cee215f17 100644 --- a/apps/common/main/lib/view/LanguageDialog.js +++ b/apps/common/main/lib/view/LanguageDialog.js @@ -52,8 +52,7 @@ define([ header: false, width: 350, cls: 'modal-dlg', - buttons: ['ok', 'cancel'], - footerCls: 'right' + buttons: ['ok', 'cancel'] }, template: '
' + diff --git a/apps/common/main/lib/view/RenameDialog.js b/apps/common/main/lib/view/RenameDialog.js index 023cff6ba..7b89225f5 100644 --- a/apps/common/main/lib/view/RenameDialog.js +++ b/apps/common/main/lib/view/RenameDialog.js @@ -48,8 +48,7 @@ define([ header: false, cls: 'modal-dlg', filename: '', - buttons: ['ok', 'cancel'], - footerCls: 'right' + buttons: ['ok', 'cancel'] }, initialize : function(options) { diff --git a/apps/common/main/resources/img/controls/toolbarbig.png b/apps/common/main/resources/img/controls/toolbarbig.png index d1f6b29d3..29c5eb05a 100644 Binary files a/apps/common/main/resources/img/controls/toolbarbig.png and b/apps/common/main/resources/img/controls/toolbarbig.png differ diff --git a/apps/common/main/resources/img/controls/toolbarbig@2x.png b/apps/common/main/resources/img/controls/toolbarbig@2x.png index 828c6941c..f5127cb0f 100644 Binary files a/apps/common/main/resources/img/controls/toolbarbig@2x.png and b/apps/common/main/resources/img/controls/toolbarbig@2x.png differ diff --git a/apps/common/main/resources/less/buttons.less b/apps/common/main/resources/less/buttons.less index e85961ac6..3642c73af 100644 --- a/apps/common/main/resources/less/buttons.less +++ b/apps/common/main/resources/less/buttons.less @@ -399,6 +399,11 @@ } } } + .dropdown-menu { + li.disabled { + opacity: 0.65; + } + } } @color-gray: @secondary; diff --git a/apps/documenteditor/embed/locale/fr.json b/apps/documenteditor/embed/locale/fr.json index 1145973e3..f06efef7c 100644 --- a/apps/documenteditor/embed/locale/fr.json +++ b/apps/documenteditor/embed/locale/fr.json @@ -12,6 +12,7 @@ "DE.ApplicationController.errorAccessDeny": "Vous tentez d'exéсuter une action pour laquelle vous ne disposez pas des droits.
Veuillez contacter l'administrateur de Document Server.", "DE.ApplicationController.errorDefaultMessage": "Code d'erreur: %1", "DE.ApplicationController.errorFilePassProtect": "Le fichier est protégé par le mot de passe et ne peut pas être ouvert.", + "DE.ApplicationController.errorFileSizeExceed": "La taille du fichier dépasse les limites établies sur votre serveur.
Veuillez contacter votre administrateur de Document Server pour obtenir plus d'information. ", "DE.ApplicationController.errorUserDrop": "Impossible d'accéder au fichier.", "DE.ApplicationController.notcriticalErrorTitle": "Avertissement", "DE.ApplicationController.scriptLoadError": "La connexion est trop lente, certains éléments ne peuvent pas être chargés. Veuillez recharger la page.", diff --git a/apps/documenteditor/embed/locale/it.json b/apps/documenteditor/embed/locale/it.json index 327a968e2..f35b88f9b 100644 --- a/apps/documenteditor/embed/locale/it.json +++ b/apps/documenteditor/embed/locale/it.json @@ -12,6 +12,7 @@ "DE.ApplicationController.errorAccessDeny": "Stai tentando di eseguire un'azione per la quale non disponi di permessi sufficienti.
Si prega di contattare l'amministratore del Server dei Documenti.", "DE.ApplicationController.errorDefaultMessage": "Codice errore: %1", "DE.ApplicationController.errorFilePassProtect": "Il file è protetto da una password. Impossibile aprirlo.", + "DE.ApplicationController.errorFileSizeExceed": "La dimensione del file supera la limitazione impostata per il tuo server.
Per i dettagli, contatta l'amministratore del Document server.", "DE.ApplicationController.errorUserDrop": "Impossibile accedere al file subito.", "DE.ApplicationController.notcriticalErrorTitle": "Avviso", "DE.ApplicationController.scriptLoadError": "La connessione è troppo lenta, alcuni componenti non possono essere caricati. Si prega di ricaricare la pagina.", diff --git a/apps/documenteditor/embed/locale/ru.json b/apps/documenteditor/embed/locale/ru.json index ea575e0d1..6fc73f817 100644 --- a/apps/documenteditor/embed/locale/ru.json +++ b/apps/documenteditor/embed/locale/ru.json @@ -12,6 +12,7 @@ "DE.ApplicationController.errorAccessDeny": "Вы пытаетесь выполнить действие, на которое у вас нет прав.
Пожалуйста, обратитесь к администратору Сервера документов.", "DE.ApplicationController.errorDefaultMessage": "Код ошибки: %1", "DE.ApplicationController.errorFilePassProtect": "Файл защищен паролем и не может быть открыт.", + "DE.ApplicationController.errorFileSizeExceed": "Размер файла превышает ограничение, установленное для вашего сервера.
Обратитесь к администратору Сервера документов для получения дополнительной информации.", "DE.ApplicationController.errorUserDrop": "В настоящий момент файл недоступен.", "DE.ApplicationController.notcriticalErrorTitle": "Внимание", "DE.ApplicationController.scriptLoadError": "Слишком медленное подключение, некоторые компоненты не удалось загрузить. Пожалуйста, обновите страницу.", diff --git a/apps/documenteditor/main/app/controller/Main.js b/apps/documenteditor/main/app/controller/Main.js index c17bb472a..7fc8b9c74 100644 --- a/apps/documenteditor/main/app/controller/Main.js +++ b/apps/documenteditor/main/app/controller/Main.js @@ -352,6 +352,7 @@ define([ this.appOptions.canRequestSaveAs = this.editorConfig.canRequestSaveAs; this.appOptions.canRequestInsertImage = this.editorConfig.canRequestInsertImage; this.appOptions.canRequestMailMergeRecipients = this.editorConfig.canRequestMailMergeRecipients; + this.appOptions.compatibleFeatures = (typeof (this.appOptions.customization) == 'object') && !!this.appOptions.customization.compatibleFeatures; appHeader = this.getApplication().getController('Viewport').getView('Common.Views.Header'); appHeader.setCanBack(this.appOptions.canBackToFolder === true, (this.appOptions.canBackToFolder) ? this.editorConfig.customization.goback.text : '') @@ -365,7 +366,7 @@ define([ if (!( this.editorConfig.customization && ( this.editorConfig.customization.toolbarNoTabs || (this.editorConfig.targetApp!=='desktop') && (this.editorConfig.customization.loaderName || this.editorConfig.customization.loaderLogo)))) { - $('#editor_sdk').append('
' + '
'.repeat(20) + '
'); + $('#editor-container').append('
' + '
'.repeat(20) + '
'); } Common.Controllers.Desktop.init(this.appOptions); @@ -1447,7 +1448,7 @@ define([ break; case Asc.c_oAscError.ID.Warning: - config.msg = this.errorConnectToServer.replace('%1', '{{API_URL_EDITING_CALLBACK}}'); + config.msg = this.errorConnectToServer; config.closable = false; break; @@ -2217,15 +2218,14 @@ define([ sendMergeTitle: 'Sending Merge', sendMergeText: 'Sending Merge...', txtArt: 'Your text here', - errorConnectToServer: 'The document could not be saved. Please check connection settings or contact your administrator.
When you click the \'OK\' button, you will be prompted to download the document.

' + - 'Find more information about connecting Document Server here', + errorConnectToServer: 'The document could not be saved. Please check connection settings or contact your administrator.
When you click the \'OK\' button, you will be prompted to download the document.', textTryUndoRedo: 'The Undo/Redo functions are disabled for the Fast co-editing mode.
Click the \'Strict mode\' button to switch to the Strict co-editing mode to edit the file without other users interference and send your changes only after you save them. You can switch between the co-editing modes using the editor Advanced settings.', textStrict: 'Strict mode', txtErrorLoadHistory: 'Loading history failed', textBuyNow: 'Visit website', textNoLicenseTitle: '%1 connection limitation', textContactUs: 'Contact sales', - errorViewerDisconnect: 'Connection is lost. You can still view the document,
but will not be able to download or print until the connection is restored.', + errorViewerDisconnect: 'Connection is lost. You can still view the document,
but will not be able to download or print until the connection is restored and page is reloaded.', warnLicenseExp: 'Your license has expired.
Please update your license and refresh the page.', titleLicenseExp: 'License expired', openErrorText: 'An error has occurred while opening the file', diff --git a/apps/documenteditor/main/app/controller/Toolbar.js b/apps/documenteditor/main/app/controller/Toolbar.js index 704255430..71c5041ce 100644 --- a/apps/documenteditor/main/app/controller/Toolbar.js +++ b/apps/documenteditor/main/app/controller/Toolbar.js @@ -653,7 +653,8 @@ define([ var i = -1, type, paragraph_locked = false, header_locked = false, - image_locked = false; + image_locked = false, + in_image = false; while (++i < selectedObjects.length) { type = selectedObjects[i].get_ObjectType(); @@ -663,11 +664,15 @@ define([ } else if (type === Asc.c_oAscTypeSelectElement.Header) { header_locked = selectedObjects[i].get_ObjectValue().get_Locked(); } else if (type === Asc.c_oAscTypeSelectElement.Image) { + in_image = true; image_locked = selectedObjects[i].get_ObjectValue().get_Locked(); } } var need_disable = !this.api.can_AddQuotedComment() || paragraph_locked || header_locked || image_locked; + if (this.mode.compatibleFeatures) { + need_disable = need_disable || in_image; + } if ( this.btnsComment && this.btnsComment.length > 0 ) this.btnsComment.setDisabled(need_disable); }, @@ -829,6 +834,9 @@ define([ toolbar.listStylesAdditionalMenuItem.setDisabled(frame_pr===undefined); need_disable = !this.api.can_AddQuotedComment() || paragraph_locked || header_locked || image_locked; + if (this.mode.compatibleFeatures) { + need_disable = need_disable || in_image; + } if ( this.btnsComment && this.btnsComment.length > 0 ) this.btnsComment.setDisabled(need_disable); @@ -2827,45 +2835,43 @@ define([ compactview = true; } - setTimeout(function () { - me.toolbar.render(_.extend({isCompactView: compactview}, config)); + me.toolbar.render(_.extend({isCompactView: compactview}, config)); - var tab = {action: 'review', caption: me.toolbar.textTabCollaboration}; - var $panel = me.application.getController('Common.Controllers.ReviewChanges').createToolbarPanel(); - if ( $panel ) - me.toolbar.addTab(tab, $panel, 4); + var tab = {action: 'review', caption: me.toolbar.textTabCollaboration}; + var $panel = me.application.getController('Common.Controllers.ReviewChanges').createToolbarPanel(); + if ( $panel ) + me.toolbar.addTab(tab, $panel, 4); - if ( config.isEdit ) { - me.toolbar.setMode(config); + if ( config.isEdit ) { + me.toolbar.setMode(config); - me.toolbar.btnSave.on('disabled', _.bind(me.onBtnChangeState, me, 'save:disabled')); + me.toolbar.btnSave.on('disabled', _.bind(me.onBtnChangeState, me, 'save:disabled')); - if (!(config.customization && config.customization.compactHeader)) { - // hide 'print' and 'save' buttons group and next separator - me.toolbar.btnPrint.$el.parents('.group').hide().next().hide(); + if (!(config.customization && config.customization.compactHeader)) { + // hide 'print' and 'save' buttons group and next separator + me.toolbar.btnPrint.$el.parents('.group').hide().next().hide(); - // hide 'undo' and 'redo' buttons and retrieve parent container - var $box = me.toolbar.btnUndo.$el.hide().next().hide().parent(); + // hide 'undo' and 'redo' buttons and retrieve parent container + var $box = me.toolbar.btnUndo.$el.hide().next().hide().parent(); - // move 'paste' button to the container instead of 'undo' and 'redo' - me.toolbar.btnPaste.$el.detach().appendTo($box); - me.toolbar.btnCopy.$el.removeClass('split'); - } - - if ( config.isDesktopApp ) { - if ( config.canProtect ) { - tab = {action: 'protect', caption: me.toolbar.textTabProtect}; - $panel = me.getApplication().getController('Common.Controllers.Protection').createToolbarPanel(); - - if ($panel) me.toolbar.addTab(tab, $panel, 5); - } - } - - var links = me.getApplication().getController('Links'); - links.setApi(me.api).setConfig({toolbar: me}); - Array.prototype.push.apply(me.toolbar.toolbarControls, links.getView('Links').getButtons()); + // move 'paste' button to the container instead of 'undo' and 'redo' + me.toolbar.btnPaste.$el.detach().appendTo($box); + me.toolbar.btnCopy.$el.removeClass('split'); } - }, 0); + + if ( config.isDesktopApp ) { + if ( config.canProtect ) { + tab = {action: 'protect', caption: me.toolbar.textTabProtect}; + $panel = me.getApplication().getController('Common.Controllers.Protection').createToolbarPanel(); + + if ($panel) me.toolbar.addTab(tab, $panel, 5); + } + } + + var links = me.getApplication().getController('Links'); + links.setApi(me.api).setConfig({toolbar: me}); + Array.prototype.push.apply(me.toolbar.toolbarControls, links.getView('Links').getButtons()); + } }, onAppReady: function (config) { diff --git a/apps/documenteditor/main/app/template/Viewport.template b/apps/documenteditor/main/app/template/Viewport.template index 40c1ea100..8d56d214c 100644 --- a/apps/documenteditor/main/app/template/Viewport.template +++ b/apps/documenteditor/main/app/template/Viewport.template @@ -9,7 +9,7 @@
-
+
diff --git a/apps/documenteditor/main/app/view/AddNewCaptionLabelDialog.js b/apps/documenteditor/main/app/view/AddNewCaptionLabelDialog.js index c1ed6c6c9..4ca86915e 100644 --- a/apps/documenteditor/main/app/view/AddNewCaptionLabelDialog.js +++ b/apps/documenteditor/main/app/view/AddNewCaptionLabelDialog.js @@ -48,8 +48,7 @@ define([ width: 330, header: false, cls: 'modal-dlg', - buttons: ['ok', 'cancel'], - footerCls: 'center' + buttons: ['ok', 'cancel'] }, initialize : function(options) { diff --git a/apps/documenteditor/main/app/view/BookmarksDialog.js b/apps/documenteditor/main/app/view/BookmarksDialog.js index 60dea4536..9210e9648 100644 --- a/apps/documenteditor/main/app/view/BookmarksDialog.js +++ b/apps/documenteditor/main/app/view/BookmarksDialog.js @@ -110,7 +110,7 @@ define([ '
', '', '', - '