diff --git a/.gitignore b/.gitignore index 6d13e746a9..9153574011 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,9 @@ apps/**/main/resources/**/iconsbig*.svg apps/**/main/resources/**/iconsbig*.less apps/**/main/resources/**/iconshuge*.png apps/**/main/resources/**/iconshuge*.less +apps/**/mobile/dist/*.* +apps/**/mobile/hot/*.* +apps/**/mobile/css/*.* # test documents diff --git a/apps/api/documents/api.js b/apps/api/documents/api.js index 8292eaae91..b9f069c743 100644 --- a/apps/api/documents/api.js +++ b/apps/api/documents/api.js @@ -206,9 +206,9 @@ } / false / true // if false/true - use as init value in de/pe. use instead of customization.spellcheck parameter roles: false/true // hide/show Roles manager, roles settings in right panel and roles in View form button in de tabStyle: { - mode: 'tab'/'line' // init value, 'tab' by default, + mode: 'fill'/'line' // init value, 'fill' by default, change: true/false // show/hide feature - } / 'tab'/'line' // if string - use as init value + } / 'fill'/'line' // if string - use as init value tabBackground: { mode: 'header'/'toolbar' // init value, 'header' by default change: true/false // show/hide feature @@ -542,6 +542,8 @@ var target = document.getElementById(placeholderId), iframe; + getShardkey(_config); + if (target && _checkConfigParams()) { iframe = createIframe(_config); if (_config.editorConfig.customization && _config.editorConfig.customization.integrationMode==='embed') @@ -959,6 +961,17 @@ } }; + function getShardkey(config) { + var scripts = document.getElementsByTagName('script'); + for (var i = scripts.length - 1; i >= 0; i--) { + if (scripts[i].src.match(/(.*)api\/documents\/api.js/i)) { + var shardkey = /[\?\&]shardkey=([^&]+)&?/.exec(scripts[i].src); + shardkey && shardkey.length && (config.editorConfig.shardkey = shardkey[1]); + break; + } + } + } + function getBasePath() { var scripts = document.getElementsByTagName('script'), match; @@ -1039,6 +1052,8 @@ if (type && typeof type[4] === 'string') appType = 'slide'; } } + if (!(config.editorConfig && config.editorConfig.shardkey && config.document && config.editorConfig.shardkey!==config.document.key)) + path = extendAppPath(config, path); path += appMap[appType]; const path_type = config.type === "mobile" ? "mobile" : @@ -1136,6 +1151,9 @@ if (config.document && config.document.fileType) params += "&fileType=" + config.document.fileType; + if (config.editorConfig && config.editorConfig.shardkey && config.document && config.editorConfig.shardkey!==config.document.key) + params += "&shardkey=" + config.document.key; + if (config.editorConfig) { var customization = config.editorConfig.customization; if ( customization && typeof(customization) == 'object' && ( customization.toolbarNoTabs || (config.editorConfig.targetApp!=='desktop') && (customization.loaderName || customization.loaderLogo))) { @@ -1191,5 +1209,17 @@ return dest; } + function extendAppPath(config, path) { + if ( !config.isLocalFile ) { + const ver = '/{{PRODUCT_VERSION}}-{{HASH_POSTFIX}}'; + if ( ver.lastIndexOf('{{') < 0 && path.indexOf(ver) < 0 ) { + const pos = path.indexOf('/web-apps/app'); + if ( pos > 0 ) + return [path.slice(0, pos), ver, path.slice(pos)].join(''); + } + } + return path; + } + })(window.DocsAPI = window.DocsAPI || {}, window, document); diff --git a/apps/api/wopi/editor-wopi.ejs b/apps/api/wopi/editor-wopi.ejs index 2cf4230458..915613a93d 100644 --- a/apps/api/wopi/editor-wopi.ejs +++ b/apps/api/wopi/editor-wopi.ejs @@ -91,7 +91,7 @@ div {
- + diff --git a/apps/common/index.html.deploy b/apps/common/index.html.deploy index 686a141426..c594a6b933 100644 --- a/apps/common/index.html.deploy +++ b/apps/common/index.html.deploy @@ -42,6 +42,7 @@ var params = getUrlParams(), postfix = params["indexPostfix"] || '', embed = params["type"]==='embedded'; + params.skipScaling = true; window.frameEditorId = params["frameEditorId"]; window.parentOrigin = params["parentOrigin"]; diff --git a/apps/common/locale.js b/apps/common/locale.js index a854d568bf..f8d01da102 100644 --- a/apps/common/locale.js +++ b/apps/common/locale.js @@ -172,7 +172,7 @@ Common.Locale = new(function() { } else _requireLang(); const _isCurrentRtl = function () { - return currentLang && (/^(ar)$/i.test(currentLang)); + return currentLang && (/^(ar|he)$/i.test(currentLang)); }; return { diff --git a/apps/common/main/lib/component/Button.js b/apps/common/main/lib/component/Button.js index 9eba22679e..421ee7b3d2 100644 --- a/apps/common/main/lib/component/Button.js +++ b/apps/common/main/lib/component/Button.js @@ -847,7 +847,8 @@ define([ html: !!isHtml, title : (typeof me.options.hint == 'string') ? me.options.hint : me.options.hint[0], placement : me.options.hintAnchor||'cursor', - zIndex : tipZIndex + zIndex : tipZIndex, + container : me.options.hintContainer }); !Common.Utils.isGecko && (me.btnEl.data('bs.tooltip').enabled = !me.disabled); me.btnEl.mouseenter(); @@ -857,7 +858,8 @@ define([ html: !!isHtml, title : me.options.hint[1], placement : me.options.hintAnchor||'cursor', - zIndex : tipZIndex + zIndex : tipZIndex, + container : me.options.hintContainer }); !Common.Utils.isGecko && (me.btnMenuEl.data('bs.tooltip').enabled = !me.disabled); me.btnMenuEl.mouseenter(); @@ -867,13 +869,15 @@ define([ html: !!isHtml, title : (typeof this.options.hint == 'string') ? this.options.hint : this.options.hint[0], placement : this.options.hintAnchor||'cursor', - zIndex : tipZIndex + zIndex : tipZIndex, + container : this.options.hintContainer }); this.btnMenuEl && this.btnMenuEl.tooltip({ html: !!isHtml, title : this.options.hint[1], placement : this.options.hintAnchor||'cursor', - zIndex : tipZIndex + zIndex : tipZIndex, + container : this.options.hintContainer }); } if (modalParents.length > 0) { diff --git a/apps/common/main/lib/component/Calendar.js b/apps/common/main/lib/component/Calendar.js index a504ee1dc8..ee991e2e44 100644 --- a/apps/common/main/lib/component/Calendar.js +++ b/apps/common/main/lib/component/Calendar.js @@ -91,6 +91,7 @@ define([ me.btnPrev = new Common.UI.Button({ parentEl: me.cmpEl.find('#prev-arrow'), cls: '', + scaling: false, iconCls: 'arrow-prev img-commonctrl' }); me.btnPrev.on('click', _.bind(me.onClickPrev, me)); @@ -98,6 +99,7 @@ define([ me.btnNext = new Common.UI.Button({ parentEl: me.cmpEl.find('#next-arrow'), cls: '', + scaling: false, iconCls: 'arrow-next img-commonctrl' }); me.btnNext.on('click', _.bind(me.onClickNext, me)); diff --git a/apps/common/main/lib/component/ComboBox.js b/apps/common/main/lib/component/ComboBox.js index 1d92563a7f..19b0df4d4a 100644 --- a/apps/common/main/lib/component/ComboBox.js +++ b/apps/common/main/lib/component/ComboBox.js @@ -86,6 +86,7 @@ define([ displayField: 'displayValue', valueField : 'value', search : false, + searchFields: ['displayValue'], // Property name from the item to be searched by placeHolder : '', scrollAlwaysVisible: false, takeFocusOnClose: false, @@ -128,6 +129,7 @@ define([ this.valueField = me.options.valueField; this.placeHolder = me.options.placeHolder; this.search = me.options.search; + this.searchFields = me.options.searchFields; this.scrollAlwaysVisible = me.options.scrollAlwaysVisible; this.focusWhenNoSelection = (me.options.focusWhenNoSelection!==false); this.restoreMenuHeight = me.options.restoreMenuHeight; @@ -326,8 +328,8 @@ define([ var $list = this.cmpEl.find('ul'), isMenuAbsolute = $list.hasClass('menu-absolute'); if (this.options.restoreMenuHeightAndTop || isMenuAbsolute) { - var offset = this.cmpEl.offset(), - parentTop = this.options.menuAlignEl ? this.options.menuAlignEl.offset().top : 0, + var offset = Common.Utils.getOffset(this.cmpEl), + parentTop = this.options.menuAlignEl ? Common.Utils.getOffset(this.options.menuAlignEl).top : 0, marginTop = parseInt($list.css('margin-top')), menuTop = offset.top - parentTop + this.cmpEl.outerHeight() + marginTop, menuLeft = offset.left; @@ -357,7 +359,7 @@ define([ $selected = $list.find('> li.selected'); if ($selected.length) { - var itemTop = $selected.position().top, + var itemTop = Common.Utils.getPosition($selected).top, itemHeight = $selected.outerHeight(), listHeight = $list.outerHeight(); @@ -393,16 +395,16 @@ define([ } } var cg = Common.Utils.croppedGeometry(), - parentTop = this.options.menuAlignEl ? this.options.menuAlignEl.offset().top : cg.top, + parentTop = this.options.menuAlignEl ? Common.Utils.getOffset(this.options.menuAlignEl).top : cg.top, parentHeight = this.options.menuAlignEl ? this.options.menuAlignEl.outerHeight() : cg.height - 10, menuH = $list.outerHeight(), - menuTop = $list.get(0).getBoundingClientRect().top, + menuTop = Common.Utils.getBoundingClientRect($list.get(0)).top, newH = menuH; if (menuH < this.restoreMenuHeight) newH = this.restoreMenuHeight; - var offset = this.cmpEl.offset(); + var offset = Common.Utils.getOffset(this.cmpEl); if (menuTopindex) { - itemCandidate = item; - idxCandidate = i; - break; + var item = this.store.at(i), + isBreak = false; + this.searchFields.forEach(function(fieldName) { + if (item.get(fieldName) && re.test(item.get(fieldName))) { + if (!itemCandidate) { + itemCandidate = item; + idxCandidate = i; + if(!isFirstCharsEqual) { + isBreak = true; + return; + } + } + if (me._search.full && i==index || i>index) { + itemCandidate = item; + idxCandidate = i; + isBreak = true; + return; + } } - } + }); + if(isBreak) break; } if (itemCandidate) { @@ -514,7 +526,7 @@ define([ if (this.scroller) { this.scroller.update({alwaysVisibleY: this.scrollAlwaysVisible}); var $list = $(this.el).find('ul'); - var itemTop = item.position().top, + var itemTop = Common.Utils.getPosition(item).top, itemHeight = item.outerHeight(), listHeight = $list.outerHeight(); if (itemTop < 0 || itemTop + itemHeight > listHeight) { @@ -843,4 +855,4 @@ define([ this.cmpEl && this.cmpEl.find('.form-control').focus(); } }, Common.UI.ComboBoxCustom || {})); -}); \ No newline at end of file +}); diff --git a/apps/common/main/lib/component/ComboBoxFonts.js b/apps/common/main/lib/component/ComboBoxFonts.js index a17c4bb951..7ce9f0b5be 100644 --- a/apps/common/main/lib/component/ComboBoxFonts.js +++ b/apps/common/main/lib/component/ComboBoxFonts.js @@ -745,7 +745,7 @@ define([ itemNode.addClass('selected'); itemNode.find('a').attr('aria-checked', true); - var itemTop = itemNode.position().top, + var itemTop = Common.Utils.getPosition(itemNode).top, menuTop = menuEl.scrollTop(); if (itemTop != 0) diff --git a/apps/common/main/lib/component/DataView.js b/apps/common/main/lib/component/DataView.js index 97c6b8e288..8a8e059067 100644 --- a/apps/common/main/lib/component/DataView.js +++ b/apps/common/main/lib/component/DataView.js @@ -811,12 +811,12 @@ define([ scrollToRecord: function (record, force, offsetTop) { if (!record) return; var innerEl = $(this.el).find('.inner'), - inner_top = innerEl.offset().top + (offsetTop ? offsetTop : 0), + inner_top = Common.Utils.getOffset(innerEl).top + (offsetTop ? offsetTop : 0), idx = _.indexOf(this.store.models, record), div = (idx>=0 && this.dataViewItems.length>idx) ? $(this.dataViewItems[idx].el) : innerEl.find('#' + record.get('id')); if (div.length<=0) return; - var div_top = div.offset().top, + var div_top = Common.Utils.getOffset(div).top, div_first = $(this.dataViewItems[0].el), div_first_top = (div_first.length>0) ? div_first[0].clientTop : 0; if (force || div_top < inner_top + div_first_top || div_top+div.outerHeight()*0.9 > inner_top + div_first_top + innerEl.height()) { @@ -1065,13 +1065,13 @@ define([ var el = $(this.dataViewItems[0].el), itemW = el.outerWidth() + parseFloat(el.css('margin-left')) + parseFloat(el.css('margin-right')), - offsetLeft = this.$el.offset().left, - offsetTop = el.offset().top, + offsetLeft = Common.Utils.getOffset(this.$el).left, + offsetTop = Common.Utils.getOffset(el).top, prevtop = -1, topIdx = 0, leftIdx = 0; for (var i=0; iprevtop) { prevtop = top; this._layoutParams.itemsIndexes.push([]); @@ -1376,12 +1376,12 @@ define([ scrollToRecord: function (record) { if (!record) return; var innerEl = $(this.el).find('.inner'), - inner_top = innerEl.offset().top, + inner_top = Common.Utils.getOffset(innerEl).top, idx = _.indexOf(this.store.models, record), div = (idx>=0 && this.dataViewItems.length>idx) ? this.dataViewItems[idx].el : innerEl.find('#' + record.get('id')); if (div.length<=0) return; - var div_top = div.offset().top, + var div_top = Common.Utils.getOffset(div).top, div_first = this.dataViewItems[0].el, div_first_top = (div_first.length>0) ? div_first[0].offsetTop : 0; if (div_top < inner_top + div_first_top || div_top+div.outerHeight() > inner_top + innerEl.height()) { @@ -1569,14 +1569,14 @@ define([ var el = this.dataViewItems[0].el, itemW = el.outerWidth() + parseFloat(el.css('margin-left')) + parseFloat(el.css('margin-right')), - offsetLeft = this.$el.offset().left, - offsetTop = el.offset().top, + offsetLeft = Common.Utils.getOffset(this.$el).left, + offsetTop = Common.Utils.getOffset(el).top, prevtop = -1, topIdx = 0, leftIdx = 0; for (var i=0; iprevtop) { prevtop = top; this._layoutParams.itemsIndexes.push([]); @@ -1626,7 +1626,7 @@ define([ '
', '<% _.each(group.groupStore.toJSON(), function(item, index) { %>', '<% if (!item.id) item.id = Common.UI.getId(); %>', - '
tabindex="<%= itemTabindex %>" <% } %> data-index="<%= index %>"<% if(!!item.tip) { %> data-toggle="tooltip" <% } %> ><%= itemTemplate(item) %>
', + '
tabindex="<%= itemTabindex %>" <% } %> data-index="<%= index %>"<% if(!!item.tip) { %> data-toggle="tooltip" <% } %> ><%= itemTemplate(item) %>
', '<% }); %>', '
', '', @@ -1927,7 +1927,7 @@ define([ var template = _.template([ '<% _.each(items, function(item, index) { %>', '<% if (!item.id) item.id = Common.UI.getId(); %>', - '
tabindex="<%= itemTabindex %>" <% } %> data-index="<%= index %>"<% if(!!item.tip) { %> data-toggle="tooltip" <% } %> ><%= itemTemplate(item) %>
', + '
tabindex="<%= itemTabindex %>" <% } %> data-index="<%= index %>"<% if(!!item.tip) { %> data-toggle="tooltip" <% } %> ><%= itemTemplate(item) %>
', '<% }) %>' ].join('')); me.cmpEl && me.cmpEl.find('.recent-items').html(template({ @@ -1958,15 +1958,15 @@ define([ } var itemW = el.outerWidth() + parseInt(el.css('margin-left')) + parseInt(el.css('margin-right')), - offsetLeft = this.$el.offset().left, - offsetTop = el.offset().top, + offsetLeft = Common.Utils.getOffset(this.$el).left, + offsetTop = Common.Utils.getOffset(el).top, prevtop = -1, topIdx = 0, leftIdx = first; for (var i=0; i prevtop) { prevtop = top; this._layoutParams.itemsIndexes.push([]); diff --git a/apps/common/main/lib/component/HSBColorPicker.js b/apps/common/main/lib/component/HSBColorPicker.js index 3f567c1ca0..19a5769355 100644 --- a/apps/common/main/lib/component/HSBColorPicker.js +++ b/apps/common/main/lib/component/HSBColorPicker.js @@ -132,8 +132,8 @@ define([], function () { var onSBAreaMouseMove = function(event, element, eOpts){ if (arrowSatBrightness.length>0 && areaSatBrightness.length>0) { var pos = [ - Math.max(0, Math.min(100, (parseInt((event.pageX*Common.Utils.zoom() - areaSatBrightness.offset().left) / areaSatBrightness.width() * 100)))), - Math.max(0, Math.min(100, (parseInt((event.pageY*Common.Utils.zoom() - areaSatBrightness.offset().top) / areaSatBrightness.height() * 100)))) + Math.max(0, Math.min(100, (parseInt((event.pageX*Common.Utils.zoom() - Common.Utils.getOffset(areaSatBrightness).left) / areaSatBrightness.width() * 100)))), + Math.max(0, Math.min(100, (parseInt((event.pageY*Common.Utils.zoom() - Common.Utils.getOffset(areaSatBrightness).top) / areaSatBrightness.height() * 100)))) ]; arrowSatBrightness.css('left', pos[0] + '%'); @@ -152,7 +152,7 @@ define([], function () { var onHueAreaMouseMove = function(event, element, eOpts){ if (arrowHue&& areaHue) { - var pos = Math.max(0, Math.min(100, (parseInt((event.pageY*Common.Utils.zoom() - areaHue.offset().top) / areaHue.height() * 100)))); + var pos = Math.max(0, Math.min(100, (parseInt((event.pageY*Common.Utils.zoom() - Common.Utils.getOffset(areaHue).top) / areaHue.height() * 100)))); arrowHue.css('top', pos + '%'); hueVal = parseInt(360 * pos / 100.0); diff --git a/apps/common/main/lib/component/InputField.js b/apps/common/main/lib/component/InputField.js index a46b2345f4..fecc5c2922 100644 --- a/apps/common/main/lib/component/InputField.js +++ b/apps/common/main/lib/component/InputField.js @@ -73,7 +73,8 @@ define([ validateOnChange: false, validateOnBlur: true, disabled: false, - editable: true + editable: true, + hideErrorOnInput: false }, template: _.template([ @@ -114,6 +115,7 @@ define([ this.validateOnChange = me.options.validateOnChange; this.validateOnBlur = me.options.validateOnBlur; this.maxLength = me.options.maxLength; + this.hideErrorOnInput = me.options.hideErrorOnInput; me.rendered = me.options.rendered || false; @@ -361,7 +363,12 @@ define([ if (modalParents.length > 0) { errorBadge.data('bs.tooltip').tip().css('z-index', parseInt(modalParents.css('z-index')) + 10); } - + if (me.hideErrorOnInput) { + var onInputChanging = function() { + me.showError(); + }; + me._input.one('input', onInputChanging); + } return errors; } } else { @@ -391,6 +398,12 @@ define([ if (modalParents.length > 0) { errorBadge.data('bs.tooltip').tip().css('z-index', parseInt(modalParents.css('z-index')) + 10); } + if (me.hideErrorOnInput) { + var onInputChanging = function() { + me.showError(); + }; + me._input.one('input', onInputChanging); + } } else { me.cmpEl.removeClass('error'); me.cmpEl.removeClass('warning'); @@ -701,6 +714,8 @@ define([ options.btnHint = options.btnHint || this.textDate; Common.UI.InputFieldBtn.prototype.initialize.call(this, options); + + this.dateValue = undefined; }, render: function (parentEl) { @@ -725,18 +740,29 @@ define([ firstday: 1 }); me.cmpCalendar.on('date:click', function (cmp, date) { + me.dateValue = date; me.trigger('date:click', me, date); menu.hide(); }); + me.dateValue && me.cmpCalendar.setDate(me.dateValue); menu.alignPosition(); } me.cmpCalendar.focus(); - }) + }); + this._input.on('input', function() { + me.dateValue = undefined; + }); }, setDate: function(date) { - if (this.cmpCalendar && date && date instanceof Date && !isNaN(date)) + if (date && date instanceof Date && !isNaN(date)) { this.cmpCalendar && this.cmpCalendar.setDate(date); + this.dateValue = date; + } + }, + + getDate: function() { + return this.dateValue; }, textDate: 'Select date' @@ -751,6 +777,8 @@ define([ style : '', value : '', fixedValue : '', + fixedWidth : '', + fixedCls : '', type : 'text', name : '', validation : null, @@ -786,6 +814,8 @@ define([ initialize : function(options) { this.fixedValue = options.fixedValue; + this.fixedWidth = options.fixedWidth || 'calc(50% + 4px)'; + this.fixedCls = options.fixedCls || ''; Common.UI.InputField.prototype.initialize.call(this, options); }, @@ -793,6 +823,12 @@ define([ render : function(parentEl) { Common.UI.InputField.prototype.render.call(this, parentEl); + this._input.css({ + 'padding-left': Common.UI.isRTL() ? this.fixedWidth : 0, + 'padding-right': Common.UI.isRTL() ? 0: this.fixedWidth, + }); + this.cmpEl.find('input.fixed-text').css({'width': this.fixedWidth}).addClass(this.fixedCls); + if (this.fixedValue) this.setFixedValue(this.fixedValue); diff --git a/apps/common/main/lib/component/Layout.js b/apps/common/main/lib/component/Layout.js index bb266c2b13..2ed7aa1814 100644 --- a/apps/common/main/lib/component/Layout.js +++ b/apps/common/main/lib/component/Layout.js @@ -369,7 +369,7 @@ define([ } if (this.resize.type == 'vertical') - value -= panel.position().top; + value -= Common.Utils.getPosition(panel).top; // if (this.resize.type == 'horizontal') // value -= panel.position().left; @@ -427,7 +427,7 @@ define([ } // if (resize.type == 'vertical') - value -= panel.position().top; + value -= Common.Utils.getPosition(panel).top; // if (resize.type == 'horizontal') // value -= panel.position().left; diff --git a/apps/common/main/lib/component/ListView.js b/apps/common/main/lib/component/ListView.js index b08365eddf..2d6840e4c4 100644 --- a/apps/common/main/lib/component/ListView.js +++ b/apps/common/main/lib/component/ListView.js @@ -262,6 +262,7 @@ define([ this.listenTo(view, 'click', this.onClickItem); this.listenTo(view, 'dblclick',this.onDblClickItem); this.listenTo(view, 'select', this.onSelectItem); + this.listenTo(view, 'tipchange', this.onChangeTip); if (record.get('tip')) { var view_el = $(view.el); @@ -295,7 +296,7 @@ define([ div = (idx>=0 && this.dataViewItems.length>idx) ? $(this.dataViewItems[idx].el) : innerEl.find('#' + record.get('id')); if (div.length<=0) return; - var div_top = div.position().top, + var div_top = Common.Utils.getPosition(div).top, div_height = div.outerHeight(), div_first = this.dataViewItems[0].el, div_first_top = div_first ? div_first.offsetTop : 0, @@ -313,6 +314,22 @@ define([ innerEl.scrollTop(newpos); } } + }, + + onChangeTip: function(item) { + var el = item.$el || $(item.el), + tip = el.data('bs.tooltip'), + record = item.model; + if (tip) + tip.updateTitle(record.get('tip') || ''); + else if (record.get('tip')) { + el.attr('data-toggle', 'tooltip'); + el.tooltip({ + title : record.get('tip'), + placement : 'cursor', + zIndex : this.tipZIndex + }); + } } } })()); diff --git a/apps/common/main/lib/component/Menu.js b/apps/common/main/lib/component/Menu.js index c7cc45f9bd..27a5f94afb 100644 --- a/apps/common/main/lib/component/Menu.js +++ b/apps/common/main/lib/component/Menu.js @@ -410,7 +410,7 @@ define([ var $selected = menuRoot.find('> li .checked'); if ($selected.length) { - var itemTop = $selected.position().top, + var itemTop = Common.Utils.getPosition($selected).top, itemHeight = $selected.outerHeight(), listHeight = menuRoot.outerHeight(); if (!!this.options.scrollToCheckedItem && (itemTop < 0 || itemTop + itemHeight > listHeight)) { @@ -516,7 +516,7 @@ define([ var item = itemCandidate.cmpEl.find('a'); if (this.scroller) { this.scroller.update({alwaysVisibleY: this.scrollAlwaysVisible, wheelSpeed: this.wheelSpeed}); - var itemTop = item.position().top, + var itemTop = Common.Utils.getPosition(item).top, itemHeight = item.outerHeight(), listHeight = this.menuRoot.outerHeight(); if (itemTop < 0 || itemTop + itemHeight > listHeight) { @@ -639,7 +639,7 @@ define([ var menuRoot = this.menuRoot, menuParent = this.menuAlignEl || menuRoot.parent(), m = this.menuAlign.match(/^([a-z]+)-([a-z]+)/), - offset = menuParent.offset(), + offset = Common.Utils.getOffset(menuParent), docW = Common.Utils.innerWidth() - 10, docH = Common.Utils.innerHeight() - 10, // Yep, it's magic number menuW = menuRoot.outerWidth(), @@ -773,6 +773,7 @@ define([ offset : [0, 0], cyclic : true, search : false, + searchFields: ['caption'], // Property name from the item to be searched by scrollAlwaysVisible: true, scrollToCheckedItem: true, // if true - scroll menu to checked item on menu show focusToCheckedItem: false // if true - move focus to checked item on menu show @@ -1034,7 +1035,7 @@ define([ var menuRoot = this.menuRoot, $selected = menuRoot.find('> li .checked'); if ($selected.length) { - var itemTop = $selected.position().top, + var itemTop = Common.Utils.getPosition($selected).top, itemHeight = $selected.outerHeight(), listHeight = menuRoot.outerHeight(); if (!!this.options.scrollToCheckedItem && (itemTop < 0 || itemTop + itemHeight > listHeight)) { @@ -1100,26 +1101,36 @@ define([ }, selectCandidate: function() { - var index = (this._search.index && this._search.index != -1) ? this._search.index : 0, + var me = this, + index = (this._search.index && this._search.index != -1) ? this._search.index : 0, re = new RegExp('^' + ((this._search.full) ? this._search.text : this._search.char), 'i'), - isFirstCharsEqual = re.test(this.items[index].caption), + isFirstCharsEqual = this.options.searchFields.some(function(field) { + return re.test(me.items[index][field]); + }), itemCandidate, idxCandidate; for (var i=0; iindex) { - itemCandidate = item; - idxCandidate = i; - break; + var item = this.items[i], + isBreak = false; + this.options.searchFields.forEach(function(fieldName) { + if (item[fieldName] && re.test(item[fieldName])) { + if (!itemCandidate) { + itemCandidate = item; + idxCandidate = i; + if(!isFirstCharsEqual) { + isBreak = true; + return; + } + } + if (me._search.full && i==index || i>index) { + itemCandidate = item; + idxCandidate = i; + isBreak = true; + return; + } } - } + }); + if(isBreak) break; } if (itemCandidate) { @@ -1127,7 +1138,7 @@ define([ var item = itemCandidate.el; if (this.scroller) { this.scroller.update({alwaysVisibleY: this.scrollAlwaysVisible}); - var itemTop = item.position().top, + var itemTop = Common.Utils.getPosition(item).top, itemHeight = item.outerHeight(), listHeight = this.menuRoot.outerHeight(); if (itemTop < 0 || itemTop + itemHeight > listHeight) { @@ -1154,7 +1165,7 @@ define([ var menuRoot = this.menuRoot, menuParent = this.menuAlignEl || menuRoot.parent(), m = this.menuAlign.match(/^([a-z]+)-([a-z]+)/), - offset = menuParent.offset(), + offset = Common.Utils.getOffset(menuParent), docW = Common.Utils.innerWidth(), docH = Common.Utils.innerHeight() - 10, // Yep, it's magic number menuW = menuRoot.outerWidth(), diff --git a/apps/common/main/lib/component/MenuItem.js b/apps/common/main/lib/component/MenuItem.js index 9dac9ef957..b8a18cbdb7 100644 --- a/apps/common/main/lib/component/MenuItem.js +++ b/apps/common/main/lib/component/MenuItem.js @@ -204,7 +204,7 @@ define([ el.tooltip({ title : me.options.hint, placement : me.options.hintAnchor||function(tip, element) { - var pos = this.getPosition(), + var pos = Common.Utils.getBoundingClientRect(element), actualWidth = tip.offsetWidth, actualHeight = tip.offsetHeight, innerWidth = Common.Utils.innerWidth(), @@ -217,7 +217,7 @@ define([ if (left + actualWidth > innerWidth) { left = pos.left - actualWidth - 2; } - $(tip).offset({top: top,left: left}).addClass('in'); + Common.Utils.setOffset($(tip),{top: top,left: left}).addClass('in'); } }); } @@ -320,7 +320,7 @@ define([ }, onItemMouseDown: function(e) { - Common.UI.HintManager && Common.UI.HintManager.clearHints(); + Common.UI.HintManager && Common.UI.HintManager.isHintVisible() && Common.UI.HintManager.clearHints(false, true); if (e.which != 1) { e.preventDefault(); e.stopPropagation(); diff --git a/apps/common/main/lib/component/Mixtbar.js b/apps/common/main/lib/component/Mixtbar.js index 3a459998ed..3a5b785c6e 100644 --- a/apps/common/main/lib/component/Mixtbar.js +++ b/apps/common/main/lib/component/Mixtbar.js @@ -306,6 +306,7 @@ define([ me._timerSetTab = false; }, 500); me.setTab(tab); + me.fireEvent('tab:click', [tab]); // me.processPanelVisible(); if ( !me.isFolded ) { if ( me.dblclick_timer ) clearTimeout(me.dblclick_timer); @@ -428,17 +429,17 @@ define([ hasTabInvisible: function() { if ($boxTabs.length<1) return false; - var _left_bound_ = Math.round($boxTabs.offset().left), + var _left_bound_ = Math.round(Common.Utils.getOffset($boxTabs).left), _right_bound_ = Math.round(_left_bound_ + $boxTabs.width()); var tab = this.$tabs.filter(Common.UI.isRTL() ? ':visible:last' : ':visible:first').get(0); if ( !tab ) return false; - var rect = tab.getBoundingClientRect(); + var rect = Common.Utils.getBoundingClientRect(tab); if ( !(Math.round(rect.left) < _left_bound_) ) { tab = this.$tabs.filter(Common.UI.isRTL() ? ':visible:first' : ':visible:last').get(0); - rect = tab.getBoundingClientRect(); + rect = Common.Utils.getBoundingClientRect(tab); if (!(Math.round(rect.right) > _right_bound_)) return false; @@ -540,7 +541,7 @@ define([ me.$boxpanels.width() - $active.outerWidth() + item.el.width()); } item.el.css('width', checkedwidth ? (checkedwidth + parseFloat(item.el.css('padding-left')) + parseFloat(item.el.css('padding-right'))) + 'px' : item.width); - data.rightedge = $active.get(0).getBoundingClientRect().right; + data.rightedge = Common.Utils.getBoundingClientRect($active.get(0)).right; } } } @@ -588,7 +589,7 @@ define([ setMoreButton: function(tab, panel) { var me = this; if (!btnsMore[tab]) { - var top = panel.position().top; + var top = Common.Utils.getPosition(panel).top; var box = $('
' + '
' + '
' + @@ -764,7 +765,7 @@ define([ if (_rightedge <= _maxright) // stop moving items break; - var rect = item.get(0).getBoundingClientRect(), + var rect = Common.Utils.getBoundingClientRect(item.get(0)), item_width = item.outerWidth(), children = item.children(); if (!item.attr('inner-width') && item.attr('group-state') !== 'open') { @@ -795,7 +796,7 @@ define([ hideAllMenus = true; break; } else { - var child_rect = child.get(0).getBoundingClientRect(), + var child_rect = Common.Utils.getBoundingClientRect(child.get(0)), child_width = child.outerWidth(); if ((Common.UI.isRTL() ? box_controls_width - child_rect.right : child_rect.left)+child_width>_maxright) { if (!last_group) { @@ -974,9 +975,9 @@ define([ onMoreShow: function(btn, e) { var moreContainer = btn.panel.parent(), - parentxy = moreContainer.parent().offset(), + parentxy = Common.Utils.getOffset(moreContainer.parent()), target = btn.$el, - showxy = target.offset(), + showxy = Common.Utils.getOffset(target), right = Common.Utils.innerWidth() - (showxy.left - parentxy.left + target.width()), top = showxy.top - parentxy.top + target.height() + 10; diff --git a/apps/common/main/lib/component/SideMenu.js b/apps/common/main/lib/component/SideMenu.js index a3bfcddf5a..a965cdc53e 100644 --- a/apps/common/main/lib/component/SideMenu.js +++ b/apps/common/main/lib/component/SideMenu.js @@ -213,6 +213,10 @@ define([ }); }, + isButtonInMoreMenu: function (btn) { + return _.indexOf(this.buttons, btn)>-1; + }, + getPluginButton: function (guid) { var btn; for (var i=0; i maxValue, pos = Math.max(0, Math.min(100, position)), value = pos/me.delta + me.minValue; @@ -420,7 +420,7 @@ define([ lastValue = me.thumbs[index].value, minValue = (index-1<0) ? 0 : me.thumbs[index-1].position, maxValue = (index+1 maxValue, pos = Math.max(0, Math.min(100, position)), value = pos/me.delta + me.minValue; @@ -431,7 +431,7 @@ define([ if (need_sort) me.sortThumbs(); - var positionY = e.pageY*Common.Utils.zoom() - me.cmpEl.offset().top; + var positionY = e.pageY*Common.Utils.zoom() - Common.Utils.getOffset(me.cmpEl).top; me.isRemoveThumb = positionY > me.cmpEl.height() || positionY < 0; me.setRemoveThumb(index, me.isRemoveThumb); @@ -445,7 +445,7 @@ define([ var index = e.data.index, thumb = me.thumbs[index].thumb; - me._dragstart = e.pageX*Common.Utils.zoom() - thumb.offset().left - 6.5; + me._dragstart = e.pageX*Common.Utils.zoom() - Common.Utils.getOffset(thumb).left - 6.5; setCenters(index); me.setActiveThumb(index); @@ -461,7 +461,7 @@ define([ var onTrackMouseUp = function (e) { if ( me.disabled || !_.isUndefined(me._dragstart) || me.thumbs.length > 9) return; - var pos = Math.max(0, Math.min(100, (Math.round((e.pageX*Common.Utils.zoom() - me.cmpEl.offset().left) / me.width * 100)))), + var pos = Math.max(0, Math.min(100, (Math.round((e.pageX*Common.Utils.zoom() - Common.Utils.getOffset(me.cmpEl).left) / me.width * 100)))), nearIndex = findThumb(pos), thumbColor = me.thumbs[nearIndex].colorValue, thumbValue = me.thumbs[nearIndex].value, @@ -479,7 +479,7 @@ define([ /*var onTrackMouseDown = function (e) { if ( me.disabled ) return; - var pos = Math.max(0, Math.min(100, (Math.round((e.pageX*Common.Utils.zoom() - me.cmpEl.offset().left) / me.width * 100)))), + var pos = Math.max(0, Math.min(100, (Math.round((e.pageX*Common.Utils.zoom() - Common.Utils.getOffset(me.cmpEl).left) / me.width * 100)))), index = findThumb(pos), lastValue = me.thumbs[index].value, value = pos/me.delta + me.minValue; diff --git a/apps/common/main/lib/component/SynchronizeTip.js b/apps/common/main/lib/component/SynchronizeTip.js index 7cf3fe615b..7ec05832d6 100644 --- a/apps/common/main/lib/component/SynchronizeTip.js +++ b/apps/common/main/lib/component/SynchronizeTip.js @@ -132,7 +132,7 @@ define([ applyPlacement: function () { var target = this.target && this.target.length>0 ? this.target : $(document.body); - var showxy = target.offset(); + var showxy = Common.Utils.getOffset(target); if (this.placement=='target' && !this.position) { this.cmpEl.css({top : showxy.top + 5 + 'px', left: showxy.left + 5 + 'px'}); return; diff --git a/apps/common/main/lib/component/TabBar.js b/apps/common/main/lib/component/TabBar.js index 209adac046..c9c92dbdba 100644 --- a/apps/common/main/lib/component/TabBar.js +++ b/apps/common/main/lib/component/TabBar.js @@ -100,7 +100,7 @@ define([ calculateBounds: function () { var me = this, length = me.bar.tabs.length, - barBounds = me.bar.$bar.get(0).getBoundingClientRect(); + barBounds = Common.Utils.getBoundingClientRect(me.bar.$bar.get(0)); me.leftBorder = barBounds.left; me.rightBorder = barBounds.right; @@ -110,7 +110,7 @@ define([ me.bar.scrollX = this.scrollLeft; for (var i = 0; i < length; ++i) { - this.bounds.push(me.bar.tabs[i].$el.get(0).getBoundingClientRect()); + this.bounds.push(Common.Utils.getBoundingClientRect(me.bar.tabs[i].$el.get(0))); } me.lastTabRight = me.bounds[length - 1].right; @@ -519,7 +519,7 @@ define([ if (this.$bar.find('.separator-item').length === 0) { this.$bar.append('
  • '); } - this.$bar.scrollLeft(this.$bar.scrollLeft() + (tab.position().left + parseInt(tab.css('width')) - this.$bar.width()) + (this.$bar.width() > 400 ? 20 : 5)); + this.$bar.scrollLeft(this.$bar.scrollLeft() + (Common.Utils.getPosition(tab).left + parseInt(tab.css('width')) - this.$bar.width()) + (this.$bar.width() > 400 ? 20 : 5)); this.checkInvisible(suppress); } else { if (!this.isTabVisible(this.tabs.length - 1) && this.$bar.find('.separator-item').length === 0) { @@ -530,7 +530,7 @@ define([ if (index == 'forward') { for (var i = 0; i < this.tabs.length; i++) { tab = this.tabs[i].$el; - right = tab.position().left + parseInt(tab.css('width')); + right = Common.Utils.getPosition(tab).left + parseInt(tab.css('width')); if (right > rightbound) { this.$bar.scrollLeft(this.$bar.scrollLeft() + (right - rightbound) + (this.$bar.width() > 400 ? 20 : 5)); @@ -541,7 +541,7 @@ define([ } else if (index == 'backward') { for (i = this.tabs.length; i-- > 0; ) { tab = this.tabs[i].$el; - left = tab.position().left; + left = Common.Utils.getPosition(tab).left; if (left < 0) { this.$bar.scrollLeft(this.$bar.scrollLeft() + left - 26); @@ -551,7 +551,7 @@ define([ } } else if (typeof index == 'number') { tab = this.tabs[index].$el; - left = tab.position().left; + left = Common.Utils.getPosition(tab).left; right = left + parseInt(tab.css('width')); if (left < 0) { @@ -576,7 +576,7 @@ define([ }, hasInvisible: function() { - var _left_bound_ = this.$bar.offset().left, + var _left_bound_ = Common.Utils.getOffset(this.$bar).left, _right_bound_ = _left_bound_ + this.$bar.width(); for (var i = this.tabs.length; i-- > 0; ) { @@ -589,13 +589,13 @@ define([ }, isTabVisible: function(index) { - var leftbound = arguments[1] || this.$bar.offset().left, + var leftbound = arguments[1] || Common.Utils.getOffset(this.$bar).left, rightbound = arguments[2] || (leftbound + this.$bar.width()), left, right, tab, rect; if (index < this.tabs.length && index >= 0) { tab = this.tabs[index].$el; - rect = tab.get(0).getBoundingClientRect(); + rect = Common.Utils.getBoundingClientRect(tab.get(0)); left = rect.left; right = rect.right; diff --git a/apps/common/main/lib/component/ThemeColorPalette.js b/apps/common/main/lib/component/ThemeColorPalette.js index e97395bcdc..d4f6dd7328 100644 --- a/apps/common/main/lib/component/ThemeColorPalette.js +++ b/apps/common/main/lib/component/ThemeColorPalette.js @@ -674,13 +674,13 @@ define([ var el = $(this.colorItems[0].el), itemW = el.outerWidth() + parseInt(el.css('margin-left')) + parseInt(el.css('margin-right')), - offsetLeft = this.$el.offset().left, - offsetTop = el.offset().top, + offsetLeft = Common.Utils.getOffset(this.$el).left, + offsetTop = Common.Utils.getOffset(el).top, prevtop = -1, topIdx = 0, leftIdx = 0; for (var i=0; iprevtop) { prevtop = top; this._layoutParams.itemsIndexes.push([]); diff --git a/apps/common/main/lib/component/Window.js b/apps/common/main/lib/component/Window.js index 983143607b..d00a57c200 100644 --- a/apps/common/main/lib/component/Window.js +++ b/apps/common/main/lib/component/Window.js @@ -515,7 +515,7 @@ define([ if (!options.dontshow) body.css('padding-bottom', '10px'); if (options.maxwidth && options.width=='auto') { - var width = !Common.UI.isRTL() ? (text.position().left + text.width() + parseInt(text_cnt.css('padding-right'))) : + var width = !Common.UI.isRTL() ? (Common.Utils.getPosition(text).left + text.width() + parseInt(text_cnt.css('padding-right'))) : (parseInt(text_cnt.css('padding-right')) + icon_width + text.width() + parseInt(text_cnt.css('padding-left'))); if (width > options.maxwidth) options.width = options.maxwidth; @@ -525,7 +525,7 @@ define([ body.height(parseInt(text_cnt.css('height')) + parseInt(footer.css('height'))); var span_el = check.find('span'); var width = !Common.UI.isRTL() ? - (Math.max(text.width(), span_el.length>0 ? span_el.position().left + span_el.width() : 0) + text.position().left + parseInt(text_cnt.css('padding-right'))) : + (Math.max(text.width(), span_el.length>0 ? Common.Utils.getPosition(span_el).left + span_el.width() : 0) + Common.Utils.getPosition(text).left + parseInt(text_cnt.css('padding-right'))) : (parseInt(text_cnt.css('padding-right')) + icon_width + parseInt(text_cnt.css('padding-left')) + (Math.max(text.width(), check.length>0 ? $(check).find('.checkbox-indeterminate').outerWidth(true) : 0))); window.setSize(width, parseInt(body.css('height')) + parseInt(header.css('height'))); diff --git a/apps/common/main/lib/controller/Comments.js b/apps/common/main/lib/controller/Comments.js index 35d51f7e1e..2b0471ee10 100644 --- a/apps/common/main/lib/controller/Comments.js +++ b/apps/common/main/lib/controller/Comments.js @@ -1211,7 +1211,7 @@ define([ var users = this.userCollection, hasGroup = false, updateCommentData = function(comment, user, isNotReply) { - var color = (user) ? user.get('color') : Common.UI.ExternalUsers.getColor(comment.get('userid')), + var color = (user) ? user.get('color') : Common.UI.ExternalUsers.getColor(comment.get('userid') || comment.get('username')), needrender = false; if (color !== comment.get('usercolor')) { needrender = true; diff --git a/apps/common/main/lib/controller/Desktop.js b/apps/common/main/lib/controller/Desktop.js index 097d7a136f..13d5456720 100644 --- a/apps/common/main/lib/controller/Desktop.js +++ b/apps/common/main/lib/controller/Desktop.js @@ -191,7 +191,7 @@ define([ } else if (/althints:show/.test(cmd)) { if ( /false|hide/.test(param) ) - Common.NotificationCenter.trigger('hints:clear'); + Common.NotificationCenter && Common.NotificationCenter.trigger('hints:clear'); } else if (/file:print/.test(cmd)) { webapp.getController('Main').onPrint(); @@ -283,7 +283,7 @@ define([ if ( e.keyCode == 78 /* N */ ) { if (config.canCreateNew && !e.shiftKey && ((Common.Utils.isWindows && e.ctrlKey && !e.metaKey) || - (Common.Utils.isMac && e.metaKey && e.ctrlKey))) + (Common.Utils.isMac && e.metaKey && !e.ctrlKey))) { this.process('create:new'); } diff --git a/apps/common/main/lib/controller/HintManager.js b/apps/common/main/lib/controller/HintManager.js index a59afeb724..debf8083de 100644 --- a/apps/common/main/lib/controller/HintManager.js +++ b/apps/common/main/lib/controller/HintManager.js @@ -149,7 +149,7 @@ Common.UI.HintManager = new(function() { }; var _lockedKeyEvents = function (isLocked) { - if (_api) { + if (_api && (isLocked || !Common.Utils.ModalWindow.isVisible())) { _isLockedKeyEvents = isLocked; _api.asc_enableKeyEvents(!isLocked); } @@ -346,7 +346,7 @@ Common.UI.HintManager = new(function() { var docH = _isEditDiagram ? (window.parent.innerHeight * Common.Utils.zoom()) : (Common.Utils.innerHeight() - 20), docW = _isEditDiagram ? (window.parent.innerWidth * Common.Utils.zoom()) : (Common.Utils.innerWidth()), section = _isEditDiagram ? _currentSection[0] : _currentSection, - topSection = _currentLevel !== 0 && $(section).length > 0 && !_isEditDiagram ? $(section).offset().top : 0, + topSection = _currentLevel !== 0 && $(section).length > 0 && !_isEditDiagram ? Common.Utils.getOffset($(section)).top : 0, bottomSection = _currentLevel !== 0 && $(section).length > 0 && !_isEditDiagram ? topSection + $(section).height() : docH; if ($(section).prop('id') === 'toolbar' && $(section).outerHeight() < $(section).find('.box-controls').outerHeight()) { bottomSection += $(section).find('.box-controls').outerHeight(); @@ -364,13 +364,13 @@ Common.UI.HintManager = new(function() { } if (window.SSE && item.parent().prop('id') === 'statusbar_bottom') { var $statusbar = item.parent(); - if (item.offset().left > $statusbar.offset().left + $statusbar.width()) { + if (Common.Utils.getOffset(item).left > Common.Utils.getOffset($statusbar).left + $statusbar.width()) { return; } } if (_currentLevel === 0 && item.closest('.tabs.short').length > 0) { var blockTabs = item.closest('.tabs.short'); - leftBorder = blockTabs.offset().left; + leftBorder = Common.Utils.getOffset(blockTabs).left; rightBorder = leftBorder + blockTabs.width(); if (!item.hasClass('scroll')) { leftBorder += 20; @@ -424,7 +424,7 @@ Common.UI.HintManager = new(function() { offsets = offsets ? item.attr('data-hint-offset').split(',').map(function (item) { return parseInt(item); }) : [0, 0]; Common.UI.isRTL() && (offsets[1] = -offsets[1]); } - var offset = item.offset(); + var offset = Common.Utils.getOffset(item); var top, left; if (direction === 'left-top') { top = offset.top - 10 + offsets[0]; @@ -569,6 +569,7 @@ Common.UI.HintManager = new(function() { } } if (curr) { + Common.UI.ScreenReaderFocusManager && Common.UI.ScreenReaderFocusManager.exitFocusMode(); var tag = curr.prop("tagName").toLowerCase(); if (window.SSE && curr.parent().prop('id') === 'statusbar_bottom') { _hideHints(); diff --git a/apps/common/main/lib/controller/History.js b/apps/common/main/lib/controller/History.js index adf32a750d..0ffd247ff1 100644 --- a/apps/common/main/lib/controller/History.js +++ b/apps/common/main/lib/controller/History.js @@ -199,10 +199,10 @@ define([ this.timerId = 0; } - if (opts.data.error) { + if (!opts.data || opts.data.error) { var config = { title: this.notcriticalErrorTitle, - msg: opts.data.error, + msg: opts.data && opts.data.error ? opts.data.error : this.txtErrorLoadHistory, iconCls: 'warn', buttons: ['ok'] }; @@ -335,9 +335,7 @@ define([ this.onSelectRevision(null, null, rec); } console.log('Received changes that are incompatible with the file version'); - }, - - notcriticalErrorTitle: 'Warning' + } }, Common.Controllers.History || {})); }); diff --git a/apps/common/main/lib/controller/LaunchController.js b/apps/common/main/lib/controller/LaunchController.js index 05dc22e00f..d39ea65da8 100644 --- a/apps/common/main/lib/controller/LaunchController.js +++ b/apps/common/main/lib/controller/LaunchController.js @@ -40,6 +40,7 @@ define([ this.api = api; Common.NotificationCenter.on('app:ready', on_app_ready.bind(this)); Common.NotificationCenter.on('app:face', on_hide_loader.bind(this)); + Common.NotificationCenter.on('app-pack:loaded', on_app_pack_loaded.bind(this)); } const load_scripts = function () { @@ -53,14 +54,19 @@ define([ if (!!Common.UI.ScreenReaderFocusManager) { Common.UI.ScreenReaderFocusManager.init(me.api); } - _all_scripts_loaded = true; if ( !!window.less ) { // detect development mode + _all_scripts_loaded = true; Common.NotificationCenter.trigger('script:loaded'); } }); } + const on_app_pack_loaded = function (config) { + _all_scripts_loaded = true; + Common.NotificationCenter.trigger('script:loaded'); + } + const on_app_ready = function (config) { load_scripts.call(this); } diff --git a/apps/common/main/lib/controller/LayoutManager.js b/apps/common/main/lib/controller/LayoutManager.js index 368df43608..a0cd041f4d 100644 --- a/apps/common/main/lib/controller/LayoutManager.js +++ b/apps/common/main/lib/controller/LayoutManager.js @@ -48,7 +48,9 @@ Common.UI.LayoutManager = new(function() { var _config, _licensed, _api, - _lastInternalTabIdx = 10; + _lastInternalTabIdx = 10, + _toolbar, + _arrPlugins = []; // all plugins that add controls to toolbar or menu items to toolbar buttons var _init = function(config, licensed, api) { _config = config; _licensed = licensed; @@ -172,6 +174,8 @@ Common.UI.LayoutManager = new(function() { var _addCustomItems = function (toolbar, data) { if (!data) return; + _toolbar = toolbar; + var lang = Common.Locale.getCurrentLanguage(), btns = []; data.forEach(function(plugin) { @@ -217,6 +221,13 @@ Common.UI.LayoutManager = new(function() { if (tab) { var added = [], removed = _findRemovedButtons(toolbar, tab.id, plugin.guid, tab.items); + + if (!_arrPlugins[plugin.guid]) + _arrPlugins[plugin.guid] = {actions: [], tabs: []}; + + if (_.indexOf(_arrPlugins[plugin.guid].tabs, tab)<0) + _arrPlugins[plugin.guid].tabs.push(tab.id); + tab.items && tab.items.forEach(function(item, index) { var btn = _findCustomButton(toolbar, tab.id, plugin.guid, item.id), _set = Common.enumLock; @@ -292,13 +303,24 @@ Common.UI.LayoutManager = new(function() { return btns; }; + var _clearCustomItems = function(guid) { + if (!_toolbar) return; + if (_arrPlugins[guid] && _arrPlugins[guid].tabs) { + _arrPlugins[guid].tabs.forEach(function(tab) { + _toolbar.addCustomItems({action: tab}, undefined, _findRemovedButtons(_toolbar, tab, guid)); + }); + _arrPlugins[guid].tabs = []; + } + }; + return { init: _init, applyCustomization: _applyCustomization, isElementVisible: _isElementVisible, getInitValue: _getInitValue, lastTabIdx: _lastInternalTabIdx, - addCustomItems: _addCustomItems + addCustomItems: _addCustomItems, + clearCustomItems: _clearCustomItems, // remove controls added by plugin from toolbar } })(); diff --git a/apps/common/main/lib/controller/Plugins.js b/apps/common/main/lib/controller/Plugins.js index f87195fecd..d07bd2a9c6 100644 --- a/apps/common/main/lib/controller/Plugins.js +++ b/apps/common/main/lib/controller/Plugins.js @@ -114,6 +114,7 @@ define([ this.customPluginsDlg = []; this.newInstalledBackgroundPlugins = []; + this.customButtonsArr = []; Common.Gateway.on('init', this.loadConfig.bind(this)); Common.NotificationCenter.on('app:face', this.onAppShowed.bind(this)); @@ -223,7 +224,7 @@ define([ Common.NotificationCenter.on({ 'layout:resizestart': function(e) { if (panel) { - var offset = panel.currentPluginFrame.offset(); + var offset = Common.Utils.getOffset(panel.currentPluginFrame); me._moveOffset = {x: offset.left + parseInt(panel.currentPluginFrame.css('padding-left')), y: offset.top + parseInt(panel.currentPluginFrame.css('padding-top'))}; me.api.asc_pluginEnableMouseEvents(true); @@ -409,6 +410,11 @@ define([ onResetPlugins: function (collection) { var me = this; + me.customButtonsArr.forEach(function(item) { + me.toolbar && me.toolbar.addCustomItems({action: item.tab}, undefined, [item.btn]) + }); + me.customButtonsArr = []; + me.appOptions.canPlugins = !collection.isEmpty(); if ( me.$toolbarPanelPlugins ) { me.backgroundPlugins = []; @@ -427,7 +433,13 @@ define([ return; } if (model.get('tab')) { - me.toolbar && me.toolbar.addCustomItems(model.get('tab'), [me.viewPlugins.createPluginButton(model)]); + let tab = model.get('tab'), + btn = me.viewPlugins.createPluginButton(model); + if (btn) { + btn.options.separator = tab.separator; + me.toolbar && me.toolbar.addCustomItems(tab, [btn]); + me.customButtonsArr.push({tab: tab.action, btn: btn}); + } return; } @@ -470,11 +482,7 @@ define([ }; me.viewPlugins.backgroundBtn.menu.on('show:before', onShowBefore); me.viewPlugins.backgroundBtn.on('click', function () { - if (me.backgroundPluginsTip) { - me.backgroundPluginsTip.close(); - me.backgroundPluginsTip = undefined; - me.newInstalledBackgroundPlugins && (me.newInstalledBackgroundPlugins.length = 0); - } + me.closeBackPluginsTip(); }); } @@ -755,6 +763,8 @@ define([ !this.turnOffBackgroundPlugin(guid) && this.viewPlugins.closedPluginMode(guid, isIframePlugin); this.runAutoStartPlugins(); + + Common.UI.LayoutManager.clearCustomItems(guid); // remove custom toolbar buttons }, onPluginResize: function(size, minSize, maxSize, callback ) { @@ -781,7 +791,7 @@ define([ onPluginMouseMove: function(x, y) { if (this.pluginDlg) { - var offset = this.pluginContainer.offset(); + var offset = Common.Utils.getOffset(this.pluginContainer); if (this.pluginDlg.binding.drag) this.pluginDlg.binding.drag({ pageX: x*Common.Utils.zoom()+offset.left, pageY: y*Common.Utils.zoom()+offset.top }); if (this.pluginDlg.binding.resize) this.pluginDlg.binding.resize({ pageX: x*Common.Utils.zoom()+offset.left, pageY: y*Common.Utils.zoom()+offset.top }); } else @@ -829,7 +839,7 @@ define([ }, parsePlugins: function(pluginsdata, uiCustomize, forceUpdate, fromManager) { - this.newInstalledBackgroundPlugins.length = 0; + this.closeBackPluginsTip(); var me = this; var pluginStore = this.getApplication().getCollection('Common.Collections.Plugins'), isEdit = me.appOptions.isEdit && !me.isPDFEditor, @@ -912,6 +922,13 @@ define([ if (pluginVisible) pluginVisible = me.checkPluginVersion(apiVersion, item.minVersion); + if (item.guid === "asc.{E6978D28-0441-4BD7-8346-82FAD68BCA3B}") { + item.tab = { + "id": "view", + "separator": true + } + } + var props = { name : name, guid: item.guid, @@ -926,7 +943,7 @@ define([ isDisplayedInViewer: isDisplayedInViewer, isBackgroundPlugin: pluginVisible && isBackgroundPlugin, isSystem: isSystem, - tab: item.tab ? {action: item.tab.id, caption: ((typeof item.tab.text == 'object') ? item.tab.text[lang] || item.tab.text['en'] : item.tab.text) || ''} : undefined + tab: item.tab ? {action: item.tab.id, caption: ((typeof item.tab.text == 'object') ? item.tab.text[lang] || item.tab.text['en'] : item.tab.text) || '', separator: item.tab.separator} : undefined }; updatedItem ? updatedItem.set(props) : arr.push(new Common.Models.Plugin(props)); if (fromManager && !updatedItem && props.isBackgroundPlugin) { @@ -1215,7 +1232,7 @@ define([ onPluginWindowMouseMove: function(frameId, x, y) { if (this.customPluginsDlg[frameId]) { - var offset = this.customPluginsDlg[frameId].options.pluginContainer.offset(); + var offset = Common.Utils.getOffset(this.customPluginsDlg[frameId].options.pluginContainer); if (this.customPluginsDlg[frameId].binding.drag) this.customPluginsDlg[frameId].binding.drag({ pageX: x*Common.Utils.zoom()+offset.left, pageY: y*Common.Utils.zoom()+offset.top }); if (this.customPluginsDlg[frameId].binding.resize) this.customPluginsDlg[frameId].binding.resize({ pageX: x*Common.Utils.zoom()+offset.left, pageY: y*Common.Utils.zoom()+offset.top }); } else @@ -1285,6 +1302,9 @@ define([ if (plugins && plugins.length > 0) { var text = plugins.length > 1 ? this.textPluginsSuccessfullyInstalled : Common.Utils.String.format(this.textPluginSuccessfullyInstalled, plugins[0].name); + if (this.backgroundPluginsTip && this.backgroundPluginsTip.isVisible()) { + this.backgroundPluginsTip.close(); + } this.backgroundPluginsTip = new Common.UI.SynchronizeTip({ extCls: 'colored', placement: 'bottom', @@ -1302,19 +1322,21 @@ define([ this.newInstalledBackgroundPlugins.length = 0; }, this); this.backgroundPluginsTip.on('closeclick', function () { - this.backgroundPluginsTip.close(); - this.backgroundPluginsTip = undefined; - this.newInstalledBackgroundPlugins.length = 0; + this.closeBackPluginsTip(); }, this); this.backgroundPluginsTip.show(); } }, onActiveTab: function (tab) { - if (tab !== 'plugins' && this.backgroundPluginsTip) { + (tab !== 'plugins') && this.closeBackPluginsTip(); + }, + + closeBackPluginsTip: function() { + if (this.backgroundPluginsTip) { this.backgroundPluginsTip.close(); this.backgroundPluginsTip = undefined; - this.newInstalledBackgroundPlugins.length = 0; + this.newInstalledBackgroundPlugins && (this.newInstalledBackgroundPlugins.length = 0); } }, diff --git a/apps/common/main/lib/controller/ReviewChanges.js b/apps/common/main/lib/controller/ReviewChanges.js index 753f61b5ea..ae88549146 100644 --- a/apps/common/main/lib/controller/ReviewChanges.js +++ b/apps/common/main/lib/controller/ReviewChanges.js @@ -813,13 +813,14 @@ define([ }, insertDocumentFromStorage: function(data) { - if (data && data.url && (data.c==='compare' || data.c==='combine')) { + if (data && data.url && (data.c==='compare' || data.c==='combine' || data.c==='insert-text')) { if (!this._state.compareSettings) { this._state.compareSettings = new AscCommonWord.ComparisonOptions(); this._state.compareSettings.putWords(!Common.localStorage.getBool("de-compare-char")); } (data.c==='compare') && this.api.asc_CompareDocumentUrl(data.url, this._state.compareSettings, data.token); (data.c==='combine') && this.api.asc_MergeDocumentUrl(data.url, this._state.compareSettings, data.token); + (data.c==='insert-text') && this.api.asc_insertTextFromUrl(data.url, data.token); } }, @@ -970,7 +971,7 @@ define([ docProtection : me._state.docProtection })); var sdk = $('#editor_sdk'), - offset = sdk.offset(); + offset = Common.Utils.getOffset(sdk); me.dlgChanges.show(Math.max(10, offset.left + sdk.width() - 300), Math.max(10, offset.top + sdk.height() - 150)); } } else if (config.canViewReview) { @@ -1093,7 +1094,7 @@ define([ var users = this.userCollection; this.popoverChanges && this.popoverChanges.each(function (model) { var user = users.findOriginalUser(model.get('userid')); - model.set('usercolor', (user) ? user.get('color') : Common.UI.ExternalUsers.getColor(model.get('userid'))); + model.set('usercolor', (user) ? user.get('color') : Common.UI.ExternalUsers.getColor(model.get('userid') || model.get('username'))); user && user.get('avatar') && model.set('avatar', user.get('avatar')); }); }, diff --git a/apps/common/main/lib/controller/ScreenReaderFocus.js b/apps/common/main/lib/controller/ScreenReaderFocus.js index bb011253ec..84e5c0f426 100644 --- a/apps/common/main/lib/controller/ScreenReaderFocus.js +++ b/apps/common/main/lib/controller/ScreenReaderFocus.js @@ -84,14 +84,14 @@ Common.UI.ScreenReaderFocusManager = new(function() { }; var _lockedKeyEvents = function (isLocked) { - if (_api) { + if (_api && (isLocked || !Common.Utils.ModalWindow.isVisible())) { _isLockedKeyEvents = isLocked; _api.asc_enableKeyEvents(!isLocked); } }; var _showFocus = function () { - if (_currentControls.length === 0 || ($('#file-menu-panel').is(':visible' || _isEditDiagram) && _currentLevel === 1)) { + if (_currentControls.length === 0 || (($('#file-menu-panel').is(':visible') || _isEditDiagram) && _currentLevel === 1)) { _getControls(); // console.log(_currentControls); } @@ -416,6 +416,7 @@ Common.UI.ScreenReaderFocusManager = new(function() { return { init: _init, - isFocusMode: _isFocusMode + isFocusMode: _isFocusMode, + exitFocusMode: _exitFocusMode } })(); \ No newline at end of file diff --git a/apps/common/main/lib/controller/TabStyler.js b/apps/common/main/lib/controller/TabStyler.js new file mode 100644 index 0000000000..552658ce80 --- /dev/null +++ b/apps/common/main/lib/controller/TabStyler.js @@ -0,0 +1,121 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2024 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +/** + * Created on 28/08/2024. + */ + +define([ + 'core' +], function () { + 'use strict'; + + !Common.UI && (Common.UI = {}); + + Common.UI.TabStyler = new(function() { + var _customization, + _canChangeStyle = true, + _canChangeBackground = true; + + var _init = function (customization) { + _customization = customization; + _canChangeStyle = Common.UI.FeaturesManager.canChange('tabStyle', true); + _canChangeBackground = !Common.Utils.isIE && Common.UI.FeaturesManager.canChange('tabBackground', true); + + var value = Common.UI.FeaturesManager.getInitValue('tabStyle', true); + if ( _canChangeStyle && Common.localStorage.itemExists("settings-tab-style")) { // get from local storage + value = Common.localStorage.getItem("settings-tab-style"); + } else if (value === undefined && _customization && (typeof _customization === 'object') && _customization.toolbarNoTabs) { + value = 'line'; + } + Common.Utils.InternalSettings.set("settings-tab-style", value || 'fill'); + + value = Common.UI.FeaturesManager.getInitValue('tabBackground', true); + if (_canChangeBackground && Common.localStorage.itemExists("settings-tab-background")) { // get from local storage + value = Common.localStorage.getItem("settings-tab-background"); + } else if (value === undefined && _customization && (typeof _customization === 'object') && _customization.toolbarNoTabs) { + value = 'toolbar'; + } + Common.Utils.InternalSettings.set("settings-tab-background", value || 'header'); + _customization && (typeof _customization === 'object') && _customization.toolbarNoTabs && + console.log("Obsolete: The 'toolbarNoTabs' parameter of the 'customization' section is deprecated. Please use 'tabStyle' and 'tabBackground' parameters in the 'customization.features' section instead."); + + $(window).on('storage', function (e) { + if ( e.key === 'settings-tab-style' && _canChangeStyle) { + _refreshStyle(e.originalEvent.newValue); + } else if ( e.key === 'settings-tab-background' && _canChangeBackground) { + _refreshBackground(e.originalEvent.newValue); + } + }) + }; + + var _refreshStyle = function() { + if ( Common.localStorage.getItem('settings-tab-style') !== Common.Utils.InternalSettings.get("settings-tab-style") ) { + const value = Common.localStorage.getItem('settings-tab-style'); + if ( value ) { + Common.Utils.InternalSettings.set('settings-tab-style', value); + Common.NotificationCenter.trigger('tabstyle:changed', value); + } + } + }; + + var _refreshBackground = function() { + if ( Common.localStorage.getItem('settings-tab-background') !== Common.Utils.InternalSettings.get("settings-tab-background") ) { + const value = Common.localStorage.getItem('settings-tab-background'); + if ( value ) { + Common.Utils.InternalSettings.set('settings-tab-background', value); + Common.NotificationCenter.trigger('tabbackground:changed', value); + } + } + }; + + var _setStyle = function(style) { + Common.localStorage.setItem('settings-tab-style', style); + Common.Utils.InternalSettings.set('settings-tab-style', style); + Common.NotificationCenter.trigger('tabstyle:changed', style); + }; + + var _setBackground = function(background) { + Common.localStorage.setItem('settings-tab-background', background); + Common.Utils.InternalSettings.set('settings-tab-background', background); + Common.NotificationCenter.trigger('tabbackground:changed', background); + }; + + return { + init: _init, + setStyle: _setStyle, + setBackground: _setBackground, + refreshStyle: _refreshStyle, + refreshBackground: _refreshBackground + } + })(); +}); diff --git a/apps/common/main/lib/controller/Themes.js b/apps/common/main/lib/controller/Themes.js index 9596127f21..adfeca6ffc 100644 --- a/apps/common/main/lib/controller/Themes.js +++ b/apps/common/main/lib/controller/Themes.js @@ -443,6 +443,12 @@ define([ return { init: function (api) { + ['toolbar-header-document', 'toolbar-header-spreadsheet', 'toolbar-header-presentation', 'toolbar-header-pdf'] + .forEach(function (i) { + document.documentElement.style.removeProperty('--' + i); + }); + + Common.Gateway.on('opendocument', on_document_open.bind(this)); $(window).on('storage', function (e) { if ( e.key == 'ui-theme-id' && !Common.Controllers.Desktop.isActive() ) { diff --git a/apps/common/main/lib/extend/Bootstrap.js b/apps/common/main/lib/extend/Bootstrap.js index 629b44b8d0..6e86f36c6a 100755 --- a/apps/common/main/lib/extend/Bootstrap.js +++ b/apps/common/main/lib/extend/Bootstrap.js @@ -72,7 +72,7 @@ function onDropDownKeyDown(e) { function checkFocusedItem(cmp, item) { var innerHeight = cmp.innerHeight(), padding = (innerHeight - cmp.height())/2, - pos = item.position().top, + pos = Common.Utils.getPosition(item).top, itemHeight = item.outerHeight(); if (pos<0) cmp.scrollTop(cmp.scrollTop() + pos - padding); diff --git a/apps/common/main/lib/mods/perfect-scrollbar.js b/apps/common/main/lib/mods/perfect-scrollbar.js index e81b30fdc6..417a91dde4 100644 --- a/apps/common/main/lib/mods/perfect-scrollbar.js +++ b/apps/common/main/lib/mods/perfect-scrollbar.js @@ -84,8 +84,8 @@ var $scrollbarXRail = $("
    ").appendTo($this), $scrollbarYRail = $("
    ").appendTo($this), - $scrollbarX = $("
    ").appendTo($scrollbarXRail), - $scrollbarY = $("
    ").appendTo($scrollbarYRail), + $scrollbarX = $("
    ").appendTo($scrollbarXRail), + $scrollbarY = $("
    ").appendTo($scrollbarYRail), scrollbarXActive, scrollbarYActive, containerWidth, @@ -100,7 +100,8 @@ scrollbarYTop, scrollbarYRight = parseInt($scrollbarYRail.css('right'), 10), scrollbarYRailHeight, - eventClassName = getEventClassName(); + eventClassName = getEventClassName(), + canScrollX = false; var updateContentScrollTop = function (currentTop, deltaY) { var newTop = currentTop + deltaY, @@ -122,9 +123,14 @@ }; var updateContentScrollLeft = function (currentLeft, deltaX) { - var newLeft = currentLeft + deltaX, - maxLeft = scrollbarXRailWidth - scrollbarXWidth; + var maxLeft = scrollbarXRailWidth - scrollbarXWidth; + if (Common.UI.isRTL()) { + currentLeft = maxLeft - currentLeft; + deltaX *= -1; + } + + var newLeft = currentLeft + deltaX; if (newLeft < 0) { scrollbarXLeft = 0; } @@ -136,8 +142,9 @@ } var scrollLeft = parseInt(scrollbarXLeft * (contentWidth - containerWidth) / (scrollbarXRailWidth - scrollbarXWidth), 10); - $this.scrollLeft(scrollLeft); + $this.scrollLeft(scrollLeft * (Common.UI.isRTL() ? -1 : 1)); $scrollbarYRail.css({right: scrollbarYRight - scrollLeft}); + Common.UI.isRTL() && canScrollX && $scrollbarYRail.css({left: $this.scrollLeft() + 1}); }; var getSettingsAdjustedThumbSize = function (thumbSize) { @@ -148,14 +155,16 @@ }; var updateScrollbarCss = function () { - $scrollbarXRail.css({left: $this.scrollLeft(), bottom: scrollbarXBottom - $this.scrollTop(), width: scrollbarXRailWidth, display: scrollbarXActive ? "inherit": "none"}); + $scrollbarXRail.css({left: Common.UI.isRTL() ? 'auto' : $this.scrollLeft(), right: !Common.UI.isRTL() ? 'auto' : -$this.scrollLeft(), bottom: scrollbarXBottom - $this.scrollTop(), width: scrollbarXRailWidth, display: scrollbarXActive ? "inherit": "none"}); if ($scrollbarYRail.hasClass('in-scrolling')) $scrollbarYRail.css({/*top: $this.scrollTop(),*/ right: scrollbarYRight - $this.scrollLeft(), height: scrollbarYRailHeight, display: scrollbarYActive ? "inherit": "none"}); - else - $scrollbarYRail.css({top: $this.scrollTop(), right: scrollbarYRight - $this.scrollLeft(), height: scrollbarYRailHeight, display: scrollbarYActive ? "inherit": "none"}); + else { + $scrollbarYRail.css({top: $this.scrollTop(), right: scrollbarYRight - $this.scrollLeft(), height: scrollbarYRailHeight, display: scrollbarYActive ? "inherit": "none"}); + Common.UI.isRTL() && canScrollX && $scrollbarYRail.css({left: $this.scrollLeft() + 1}); + } - $scrollbarX && $scrollbarX.css({left: scrollbarXLeft, width: scrollbarXWidth}); + $scrollbarX && $scrollbarX.css({left: Common.UI.isRTL() ? 'auto' : scrollbarXLeft, right: !Common.UI.isRTL() ? 'auto' : scrollbarXLeft, width: scrollbarXWidth}); $scrollbarY && $scrollbarY.css({top: scrollbarYTop, height: scrollbarYHeight}); }; @@ -170,7 +179,7 @@ if (!settings.suppressScrollX && containerWidth + settings.scrollXMarginOffset < contentWidth) { scrollbarXActive = true; scrollbarXWidth = getSettingsAdjustedThumbSize(parseInt(scrollbarXRailWidth * containerWidth / contentWidth, 10)); - scrollbarXLeft = parseInt($this.scrollLeft() * (scrollbarXRailWidth - scrollbarXWidth) / (contentWidth - containerWidth), 10); + scrollbarXLeft = parseInt($this.scrollLeft() * (Common.UI.isRTL() ? -1 : 1) * (scrollbarXRailWidth - scrollbarXWidth) / (contentWidth - containerWidth), 10); } else { scrollbarXActive = false; @@ -210,9 +219,10 @@ currentPageX; $scrollbarX.bind('mousedown' + eventClassName, function (e) { + canScrollX = true; Common.NotificationCenter.trigger('hints:clear'); - currentPageX = e.pageX; - currentLeft = $scrollbarX.position().left; + currentPageX = e.pageX*Common.Utils.zoom(); + currentLeft = Common.Utils.getPosition($scrollbarX).left; $scrollbarXRail.addClass('in-scrolling'); e.stopPropagation(); e.preventDefault(); @@ -220,7 +230,7 @@ $(document).bind('mousemove' + eventClassName, function (e) { if ($scrollbarXRail.hasClass('in-scrolling')) { - updateContentScrollLeft(currentLeft, e.pageX - currentPageX); + updateContentScrollLeft(currentLeft, e.pageX*Common.Utils.zoom() - currentPageX); e.stopPropagation(); e.preventDefault(); } @@ -242,12 +252,12 @@ $scrollbarY.bind('mousedown' + eventClassName, function (e) { Common.NotificationCenter.trigger('hints:clear'); - currentPageY = e.pageY; - currentTop = $scrollbarY.position().top; + currentPageY = e.pageY*Common.Utils.zoom(); + currentTop = Common.Utils.getPosition($scrollbarY).top; $scrollbarYRail.addClass('in-scrolling'); var margin = parseInt($scrollbarYRail.css('margin-top')); - var rect = $scrollbarYRail[0].getBoundingClientRect(); + var rect = Common.Utils.getBoundingClientRect($scrollbarYRail[0]); $scrollbarYRail.css({ position: 'fixed', left: rect.left, @@ -260,7 +270,7 @@ $(document).bind('mousemove' + eventClassName, function (e) { if ($scrollbarYRail.hasClass('in-scrolling')) { - updateContentScrollTop(currentTop, e.pageY - currentPageY); + updateContentScrollTop(currentTop, e.pageY*Common.Utils.zoom() - currentPageY); e.stopPropagation(); e.preventDefault(); } @@ -360,6 +370,7 @@ // useBothWheelAxes and only horizontal bar is active, so use both // wheel axes for horizontal bar if (deltaX) { + canScrollX = true; $this.scrollLeft($this.scrollLeft() + (deltaX * settings.wheelSpeed)); } else { $this.scrollLeft($this.scrollLeft() - (deltaY * settings.wheelSpeed)); @@ -449,7 +460,7 @@ $scrollbarY.bind('click' + eventClassName, stopPropagation); $scrollbarYRail.bind('click' + eventClassName, function (e) { var halfOfScrollbarLength = parseInt(scrollbarYHeight / 2, 10), - positionTop = e.pageY - $scrollbarYRail.offset().top - halfOfScrollbarLength, + positionTop = e.pageY*Common.Utils.zoom() - Common.Utils.getOffset($scrollbarYRail).top - halfOfScrollbarLength, maxPositionTop = scrollbarYRailHeight - scrollbarYHeight, positionRatio = positionTop / maxPositionTop; @@ -465,17 +476,16 @@ $scrollbarX.bind('click' + eventClassName, stopPropagation); $scrollbarXRail.bind('click' + eventClassName, function (e) { var halfOfScrollbarLength = parseInt(scrollbarXWidth / 2, 10), - positionLeft = e.pageX - $scrollbarXRail.offset().left - halfOfScrollbarLength, maxPositionLeft = scrollbarXRailWidth - scrollbarXWidth, - positionRatio = positionLeft / maxPositionLeft; - + positionLeft = Common.UI.isRTL() ? maxPositionLeft - (e.pageX*Common.Utils.zoom() - Common.Utils.getOffset($scrollbarXRail).left) + halfOfScrollbarLength : e.pageX*Common.Utils.zoom() - Common.Utils.getOffset($scrollbarXRail).left - halfOfScrollbarLength, + positionRatio = (positionLeft / maxPositionLeft); + canScrollX = true; if (positionRatio < 0) { positionRatio = 0; } else if (positionRatio > 1) { positionRatio = 1; } - - $this.scrollLeft((contentWidth - containerWidth) * positionRatio); + $this.scrollLeft((contentWidth - containerWidth) * positionRatio * (Common.UI.isRTL() ? -1 : 1)); }); }; @@ -589,6 +599,8 @@ scrollbarYHeight = scrollbarYTop = scrollbarYRight = null; + + canScrollX = false; }; var ieSupport = function (version) { diff --git a/apps/common/main/lib/mods/tooltip.js b/apps/common/main/lib/mods/tooltip.js index c8c1c8c2ee..3836be55a3 100644 --- a/apps/common/main/lib/mods/tooltip.js +++ b/apps/common/main/lib/mods/tooltip.js @@ -405,18 +405,9 @@ if (isNaN(marginLeft)) marginLeft = 0 offset.top += marginTop - offset.left += marginLeft - - // $.fn.offset doesn't round pixel values - // so we use setOffset directly with our own function B-0 - $.offset.setOffset($tip[0], $.extend({ - using: function (props) { - $tip.css({ - top: Math.round(props.top), - left: Math.round(props.left) - }) - } - }, offset), 0) + offset.left += marginLeft; + + (Common.Utils || common.utils).setOffset($tip, offset); $tip.addClass('in') @@ -435,9 +426,9 @@ var isVertical = /top|bottom/.test(placement) var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight - var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' + var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'; - $tip.offset(offset) + (Common.Utils || common.utils).setOffset($tip, offset); this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) } @@ -513,7 +504,7 @@ var el = $element[0] var isBody = el.tagName == 'BODY' - var elRect = el.getBoundingClientRect() + var elRect = (Common.Utils || common.utils).getBoundingClientRect(el) if (elRect.width == null) { // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) @@ -521,7 +512,7 @@ var isSvg = window.SVGElement && el instanceof window.SVGElement // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3. // See https://github.com/twbs/bootstrap/issues/20280 - var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset()) + var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : (Common.Utils || common.utils).getOffset($element)) var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null diff --git a/apps/common/main/lib/template/Comments.template b/apps/common/main/lib/template/Comments.template index 771ac2190c..c7d8170265 100644 --- a/apps/common/main/lib/template/Comments.template +++ b/apps/common/main/lib/template/Comments.template @@ -101,9 +101,9 @@ <% } %> <% } %> <% if (editable && !scope.viewmode) { %> -
    +
    <% } else if ((!editable || scope.viewmode) && resolved) { %> -
    +
    <% } %>
    <% } %> diff --git a/apps/common/main/lib/template/CommentsPopover.template b/apps/common/main/lib/template/CommentsPopover.template index d43b79abf7..e09499a79f 100644 --- a/apps/common/main/lib/template/CommentsPopover.template +++ b/apps/common/main/lib/template/CommentsPopover.template @@ -100,9 +100,9 @@ <% } %> <% } %> <% if (editable && (fullInfoInHint || !hint) && !scope.viewmode) { %> -
    +
    <% } else if ((fullInfoInHint || !hint) && (!editable || scope.viewmode) && resolved) { %> -
    +
    <% } %> <% } %> diff --git a/apps/common/main/lib/template/Header.template b/apps/common/main/lib/template/Header.template deleted file mode 100644 index a23dc0dddc..0000000000 --- a/apps/common/main/lib/template/Header.template +++ /dev/null @@ -1,6 +0,0 @@ -
    - -
    <%= headerCaption %>
    -
    <%= documentCaption %>
    -
    <%= textBack %>
    -
    \ No newline at end of file diff --git a/apps/common/main/lib/util/LanguageInfo.js b/apps/common/main/lib/util/LanguageInfo.js index 0c28fea6a8..aa4925e96d 100644 --- a/apps/common/main/lib/util/LanguageInfo.js +++ b/apps/common/main/lib/util/LanguageInfo.js @@ -90,9 +90,9 @@ Common.util.LanguageInfo = new(function() { 0x0445 : ["bn-IN", "বাংলা (ভারত)", "Bengali (India)"], 0x781A : ["bs", "bosanski"], 0x641A : ["bs-Cyrl", "Босански (Ћирилица)"], - 0x201A : ["bs-Cyrl-BA", "Босански (Босна и Херцеговина)", "Bosnian (Cyrillic) (Bosnia and Herzegovina)"], + 0x201A : ["bs-Cyrl-BA", "Босански (Босна и Херцеговина)", "Bosnian (Cyrillic, Bosnia and Herzegovina)"], 0x681A : ["bs-Latn", "Bosanski (Latinica)"], - 0x141A : ["bs-Latn-BA", "Bosanski (Bosna i Hercegovina)", "Bosnian (Latin) (Bosnia and Herzegovina)"], + 0x141A : ["bs-Latn-BA", "Bosanski (Bosna i Hercegovina)", "Bosnian (Latin, Bosnia and Herzegovina)"], 0x007E : ["br", "Brezhoneg"], 0x047E : ["br-FR", "Brezhoneg (Frañs)", "Breton (France)"], 0x0002 : ["bg", "Български"], @@ -187,7 +187,7 @@ Common.util.LanguageInfo = new(function() { 0x0447 : ["gu-IN", "ગુજરાતી (ભારત)", "Gujarati (India)"], 0x0068 : ["ha", "Hausa"], 0x7C68 : ["ha-Latn", "Hausa (Latin)"], - 0x0468 : ["ha-Latn-NG", "Hausa (Nigeria)", "Hausa (Latin) (Nigeria)"], + 0x0468 : ["ha-Latn-NG", "Hausa (Nigeria)", "Hausa (Latin, Nigeria)"], 0x000D : ["he", "עברית‏"], 0x040D : ["he-IL", "עברית (ישראל)‏", "Hebrew (Israel)"], 0x0039 : ["hi", "हिंदी"], @@ -202,7 +202,7 @@ Common.util.LanguageInfo = new(function() { 0x0421 : ["id-ID", "Bahasa Indonesia (Indonesia)", "Indonesian (Indonesia)"], 0x005D : ["iu", "Inuktitut"], 0x7C5D : ["iu-Latn", "Inuktitut (Qaliujaaqpait)"], - 0x085D : ["iu-Latn-CA", "Inuktitut (Kanatami) (kanata)", "Inuktitut (Latin) (Canada)"], + 0x085D : ["iu-Latn-CA", "Inuktitut (Kanatami, kanata)", "Inuktitut (Latin, Canada)"], 0x785D : ["iu-Cans", "ᐃᓄᒃᑎᑐᑦ (ᖃᓂᐅᔮᖅᐸᐃᑦ)"], 0x045D : ["iu-Cans-CA", "ᐃᓄᒃᑎᑐᑦ (ᑲᓇᑕᒥ)", "Inuktitut (Canada)"], 0x003C : ["ga", "Gaeilge"], @@ -244,7 +244,7 @@ Common.util.LanguageInfo = new(function() { 0x082E : ["dsb-DE", "Dolnoserbšćina (Nimska)", "Lower Sorbian (Germany)"], 0x006E : ["lb", "Lëtzebuergesch"], 0x046E : ["lb-LU", "Lëtzebuergesch (Luxembourg)", "Luxembourgish (Luxembourg)"], - 0x042F : ["mk-MK", "Македонски јазик (Македонија)", "Macedonian (Former Yugoslav Republic of Macedonia)"], + 0x042F : ["mk-MK", "Македонски јазик (Македонија)", "Macedonian (Macedonia)"], 0x002F : ["mk", "Македонски јазик"], 0x003E : ["ms", "Bahasa Melayu"], 0x083E : ["ms-BN", "Bahasa Melayu (Brunei Darussalam)", "Malay (Brunei Darussalam)"], @@ -265,7 +265,7 @@ Common.util.LanguageInfo = new(function() { 0x7850 : ["mn-Cyrl", "Монгол хэл"], 0x0450 : ["mn-MN", "Монгол хэл (Монгол улс)", "Mongolian (Cyrillic, Mongolia)"], 0x7C50 : ["mn-Mong", "ᠮᠤᠨᠭᠭᠤᠯ ᠬᠡᠯᠡ"], - 0x0850 : ["mn-Mong-CN", "ᠮᠤᠨᠭᠭᠤᠯ ᠬᠡᠯᠡ (ᠪᠦᠭᠦᠳᠡ ᠨᠠᠢᠷᠠᠮᠳᠠᠬᠤ ᠳᠤᠮᠳᠠᠳᠤ ᠠᠷᠠᠳ ᠣᠯᠣᠰ)", "Mongolian (Traditional Mongolian) (People's Republic of China)"], + 0x0850 : ["mn-Mong-CN", "ᠮᠤᠨᠭᠭᠤᠯ ᠬᠡᠯᠡ (ᠪᠦᠭᠦᠳᠡ ᠨᠠᠢᠷᠠᠮᠳᠠᠬᠤ ᠳᠤᠮᠳᠠᠳᠤ ᠠᠷᠠᠳ ᠣᠯᠣᠰ)", "Mongolian (People's Republic of China)"], 0x0061 : ["ne", "नेपाली"], 0x0461 : ["ne-NP", "नेपाली (नेपाल)", "Nepali (Nepal)"], 0x0861 : ["ne-IN", "नेपाली (भारत)", "Nepali (India)"], @@ -302,26 +302,26 @@ Common.util.LanguageInfo = new(function() { 0x0419 : ["ru-RU", "Русский (Россия)", "Russian (Russia)"], 0x0819 : ["ru-MD", "Русский (Молдавия)", "Russian (Republic of Moldova)"], 0x703B : ["smn", "Sämikielâ"], - 0x243B : ["smn-FI", "Sämikielâ (Suomâ)", "Sami (Inari) (Finland)"], + 0x243B : ["smn-FI", "Sämikielâ (Suomâ)", "Sami (Inari, Finland)"], 0x7C3B : ["smj", "Julevusámegiella"], - 0x103B : ["smj-NO", "Julevusámegiella (Vuodna)", "Sami (Lule) (Norway)"], - 0x143B : ["smj-SE", "Julevusámegiella (Svierik)", "Sami (Lule) (Sweden)"], + 0x103B : ["smj-NO", "Julevusámegiella (Vuodna)", "Sami (Lule, Norway)"], + 0x143B : ["smj-SE", "Julevusámegiella (Svierik)", "Sami (Lule, Sweden)"], 0x003B : ["se", "Davvisámegiella"], - 0x0C3B : ["se-FI", "Davvisámegiella (Suopma)", "Sami (Northern) (Finland)"], - 0x043B : ["se-NO", "Davvisámegiella (Norga)", "Sami (Northern) (Norway)"], - 0x083B : ["se-SE", "Davvisámegiella (Ruoŧŧa)", "Sami (Northern) (Sweden)"], + 0x0C3B : ["se-FI", "Davvisámegiella (Suopma)", "Sami (Northern, Finland)"], + 0x043B : ["se-NO", "Davvisámegiella (Norga)", "Sami (Northern, Norway)"], + 0x083B : ["se-SE", "Davvisámegiella (Ruoŧŧa)", "Sami (Northern, Sweden)"], 0x743B : ["sms", "Sääm´ǩiõll"], - 0x203B : ["sms-FI", "Sääm´ǩiõll (Lää´ddjânnam)", "Sami (Skolt) (Finland)"], + 0x203B : ["sms-FI", "Sääm´ǩiõll (Lää´ddjânnam)", "Sami (Skolt, Finland)"], 0x783B : ["sma", "åarjelsaemiengiele"], - 0x183B : ["sma-NO", "åarjelsaemiengiele (Nöörje)", "Sami (Southern) (Norway)"], - 0x1C3B : ["sma-SE", "åarjelsaemiengiele (Sveerje)", "Sami (Southern) (Sweden)"], + 0x183B : ["sma-NO", "åarjelsaemiengiele (Nöörje)", "Sami (Southern, Norway)"], + 0x1C3B : ["sma-SE", "åarjelsaemiengiele (Sveerje)", "Sami (Southern, Sweden)"], 0x004F : ["sa", "संस्कृत"], 0x044F : ["sa-IN", "संस्कृत (भारतम्)", "Sanskrit (India)"], 0x0091 : ["gd", "Gàidhlig"], 0x0491 : ["gd-GB", "Gàidhlig (An Rìoghachd Aonaichte)", "Scottish Gaelic (United Kingdom)"], 0x7C1A : ["sr", "Srpski"], 0x6C1A : ["sr-Cyrl", "Српски (Ћирилица)"], - 0x1C1A : ["sr-Cyrl-BA", "Српски (Босна и Херцеговина)", "Serbian (Cyrillic) (Bosnia and Herzegovina)"], + 0x1C1A : ["sr-Cyrl-BA", "Српски (Босна и Херцеговина)", "Serbian (Cyrillic, Bosnia and Herzegovina)"], 0x301A : ["sr-Cyrl-ME", "Српски (Црна Гора)", "Serbian (Cyrillic, Montenegro)"], 0x0C1A : ["sr-Cyrl-CS", "Српски (Србија и Црна Гора (Претходно))", "Serbian (Cyrillic, Serbia and Montenegro (Former))"], 0x281A : ["sr-Cyrl-RS", "Српски (Србија)", "Serbian (Cyrillic, Serbia)"], @@ -371,10 +371,10 @@ Common.util.LanguageInfo = new(function() { 0x045A : ["syr-SY", "ܣܘܪܝܝܐ (سوريا)‏", "Syriac (Syria)"], 0x0028 : ["tg", "Тоҷикӣ"], 0x7C28 : ["tg-Cyrl", "Тоҷикӣ"], - 0x0428 : ["tg-Cyrl-TJ", "Тоҷикӣ (Тоҷикистон)", "Tajik (Cyrillic) (Tajikistan)"], + 0x0428 : ["tg-Cyrl-TJ", "Тоҷикӣ (Тоҷикистон)", "Tajik (Cyrillic, Tajikistan)"], 0x005F : ["tzm", "Tamazight"], 0x7C5F : ["tzm-Latn", "Tamazight (Latin)"], - 0x085F : ["tzm-Latn-DZ", "Tamazight (Djazaïr)", "Tamazight (Latin) (Algeria)"], + 0x085F : ["tzm-Latn-DZ", "Tamazight (Djazaïr)", "Tamazight (Latin, Algeria)"], 0x0049 : ["ta", "தமிழ்"], 0x0449 : ["ta-IN", "தமிழ் (இந்தியா)", "Tamil (India)"], 0x0044 : ["tt", "Татар"], @@ -398,7 +398,7 @@ Common.util.LanguageInfo = new(function() { 0x0420 : ["ur-PK", "اُردو (پاکستان)‏", "Urdu (Islamic Republic of Pakistan)"], 0x0820 : ["ur-IN", "اُردو (بھارت)‏", "Urdu (India)"], 0x0080 : ["ug", "ئۇيغۇر يېزىقى‏"], - 0x0480 : ["ug-CN", "(ئۇيغۇر يېزىقى (جۇڭخۇا خەلق جۇمھۇرىيىتى‏", "Uighur (People's Republic of China)"], + 0x0480 : ["ug-CN", "ئۇيغۇر يېزىقى (جۇڭخۇا خەلق جۇمھۇرىيىتى)‏", "Uighur (People's Republic of China)"], 0x7843 : ["uz-Cyrl", "Ўзбек"], 0x0843 : ["uz-Cyrl-UZ", "Ўзбек (Ўзбекистон)", "Uzbek (Cyrillic, Uzbekistan)"], 0x0043 : ["uz", "U'zbek"], @@ -456,8 +456,42 @@ Common.util.LanguageInfo = new(function() { return null; }, + /** + * @typedef {Object} LangDisplayName + * @property {string} native - Native name + * @property {string} english - English name + */ + /** + * @param {string} code - Language code (example - 1025, 1026, ...). + * @returns {LangDisplayName|null} Object with a native language name (native) and an English name (english). + * If the English name is missing, returns an object with an empty string for English. + * Returns `null` if no language code is found. + */ + getLocalLanguageDisplayName: function(code) { + var lang = localLanguageName[code]; + if(lang) { + var nativeName = lang[1]; + var englishName = lang[2]; + function replaceBrackets(text) { + let newText = text.replace('(', '– '); + let lastCloseBracketIndex = newText.lastIndexOf(')'); + if (lastCloseBracketIndex !== -1) { + newText = newText.slice(0, lastCloseBracketIndex) + newText.slice(lastCloseBracketIndex + 1); + } + return newText; + } + + if(englishName) { + return { native: replaceBrackets(nativeName), english: replaceBrackets(englishName) }; + } else { + return { native: nativeName, english: ''}; + } + } + return null; + }, + getLanguages: function() { return localLanguageName; } } -})(); \ No newline at end of file +})(); diff --git a/apps/common/main/lib/util/Tip.js b/apps/common/main/lib/util/Tip.js index ebe8a87915..2191da53d2 100644 --- a/apps/common/main/lib/util/Tip.js +++ b/apps/common/main/lib/util/Tip.js @@ -171,7 +171,7 @@ const tip = function ($) { tp.top = innerHeight - $tip.height() - 30; } - $tip.offset(tp).addClass('in'); + Common.Utils.setOffset($tip, tp).addClass('in'); } else { var pos = this.getPosition(); diff --git a/apps/common/main/lib/util/define.js b/apps/common/main/lib/util/define.js index f2f38e1f62..2eb4a27df6 100644 --- a/apps/common/main/lib/util/define.js +++ b/apps/common/main/lib/util/define.js @@ -510,12 +510,12 @@ define(function(){ 'use strict'; { group: 'menu-chart-group-area', type: Asc.c_oAscChartTypeSettings.areaNormal, iconCls: 'area-normal', tip: this.textArea}, { group: 'menu-chart-group-area', type: Asc.c_oAscChartTypeSettings.areaStacked, iconCls: 'area-stack', tip: this.textAreaStacked}, { group: 'menu-chart-group-area', type: Asc.c_oAscChartTypeSettings.areaStackedPer, iconCls: 'area-pstack', tip: this.textAreaStackedPer}, + { group: 'menu-chart-group-stock', type: Asc.c_oAscChartTypeSettings.stock, iconCls: 'stock-normal', tip: this.textStock}, { group: 'menu-chart-group-scatter', type: Asc.c_oAscChartTypeSettings.scatter, iconCls: 'point-normal', tip: this.textScatter}, { group: 'menu-chart-group-scatter', type: Asc.c_oAscChartTypeSettings.scatterSmoothMarker,iconCls: 'point-smooth-marker', tip: this.textScatterSmoothMarker}, { group: 'menu-chart-group-scatter', type: Asc.c_oAscChartTypeSettings.scatterSmooth, iconCls: 'point-smooth', tip: this.textScatterSmooth}, { group: 'menu-chart-group-scatter', type: Asc.c_oAscChartTypeSettings.scatterLineMarker, iconCls: 'point-line-marker', tip: this.textScatterLineMarker}, { group: 'menu-chart-group-scatter', type: Asc.c_oAscChartTypeSettings.scatterLine, iconCls: 'point-line', tip: this.textScatterLine}, - { group: 'menu-chart-group-stock', type: Asc.c_oAscChartTypeSettings.stock, iconCls: 'stock-normal', tip: this.textStock}, { group: 'menu-chart-group-radar', type: Asc.c_oAscChartTypeSettings.radar, iconCls: 'radar', tip: this.textRadar}, { group: 'menu-chart-group-radar', type: Asc.c_oAscChartTypeSettings.radarMarker, iconCls: 'radar-with-markers', tip: this.textRadarMarker}, { group: 'menu-chart-group-radar', type: Asc.c_oAscChartTypeSettings.radarFilled, iconCls: 'filled-radar', tip: this.textRadarFilled}, diff --git a/apps/common/main/lib/util/htmlutils.js b/apps/common/main/lib/util/htmlutils.js index 874a53bf15..8e8173542d 100644 --- a/apps/common/main/lib/util/htmlutils.js +++ b/apps/common/main/lib/util/htmlutils.js @@ -48,7 +48,7 @@ if (!window.lang) { window.lang && (window.lang = window.lang.split(/[\-\_]/)[0].toLowerCase()); var isLangRtl = function (lang) { - return lang.lastIndexOf('ar', 0) === 0; + return lang.lastIndexOf('ar', 0) === 0 || lang.lastIndexOf('he', 0) === 0; } var ui_rtl = false; @@ -68,6 +68,7 @@ if ( ui_rtl && !isIE ) { if ( isLangRtl(lang) ) { document.body.classList.add('rtl-font'); } +document.body.setAttribute('applang', lang); function checkScaling() { var matches = { @@ -138,7 +139,7 @@ window.Common = { } } -checkScaling(); +!params.skipScaling && checkScaling(); if ( !!params.uitheme ) { if ( params.uitheme == 'default-dark' ) { diff --git a/apps/common/main/lib/util/themeinit.js b/apps/common/main/lib/util/themeinit.js index 96c47083cc..e2ba2f5fd8 100644 --- a/apps/common/main/lib/util/themeinit.js +++ b/apps/common/main/lib/util/themeinit.js @@ -75,7 +75,22 @@ !window.uitheme.id && window.uitheme.set_id(localstorage.getItem("ui-theme-id")); window.uitheme.iscontentdark = localstorage.getItem("content-theme") == 'dark'; + function inject_style_tag(content) { + const style = document.createElement('style'); + style.type = 'text/css'; + style.innerHTML = content; + document.getElementsByTagName('head')[0].appendChild(style); + } + + inject_style_tag(':root .theme-dark {' + + '--toolbar-header-document: #2a2a2a; --toolbar-header-spreadsheet: #2a2a2a;' + + '--toolbar-header-presentation: #2a2a2a; --toolbar-header-pdf: #2a2a2a;}' + + ':root .theme-contrast-dark {' + + '--toolbar-header-document: #1e1e1e; --toolbar-header-spreadsheet: #1e1e1e;' + + '--toolbar-header-presentation: #1e1e1e; --toolbar-header-pdf: #1e1e1e;}'); + let objtheme = window.uitheme.colors ? window.uitheme : localstorage.getItem("ui-theme"); + const header_tokens = ['toolbar-header-document', 'toolbar-header-spreadsheet', 'toolbar-header-presentation', 'toolbar-header-pdf']; if ( !!objtheme ) { if ( typeof(objtheme) == 'string' && objtheme.lastIndexOf("{", 0) === 0 && objtheme.indexOf("}", objtheme.length - 1) !== -1 ) @@ -94,8 +109,7 @@ } if ( objtheme.colors ) { - ['toolbar-header-document', 'toolbar-header-spreadsheet', 'toolbar-header-presentation', 'toolbar-header-pdf'] - .forEach(function (i) { + header_tokens.forEach(function (i) { !!objtheme.colors[i] && document.documentElement.style.setProperty('--' + i, objtheme.colors[i]); }); @@ -104,12 +118,15 @@ colors.push('--' + c + ':' + objtheme.colors[c]); } - var style = document.createElement('style'); - style.type = 'text/css'; - style.innerHTML = '.' + objtheme.id + '{' + colors.join(';') + ';}'; - document.getElementsByTagName('head')[0].appendChild(style); + inject_style_tag('.' + objtheme.id + '{' + colors.join(';') + ';}'); } } } + } else { + if ( window.uitheme.id.lastIndexOf("theme-gray", 0) === 0 ) { + header_tokens.forEach(function (i) { + !!document.documentElement.style.setProperty('--' + i, "#f7f7f7"); + }); + } } }(); diff --git a/apps/common/main/lib/util/utils.js b/apps/common/main/lib/util/utils.js index cab53e4db5..f1e8ed82ee 100644 --- a/apps/common/main/lib/util/utils.js +++ b/apps/common/main/lib/util/utils.js @@ -100,7 +100,7 @@ define([], function () { ipRe = /^(((https?)|(ftps?)):\/\/)?([\-\wа-яё]*:?[\-\wа-яё]*@)?(((1[0-9]{2}|2[0-4][0-9]|25[0-5]|[1-9][0-9]|[0-9])\.){3}(1[0-9]{2}|2[0-4][0-9]|25[0-5]|[1-9][0-9]|[0-9]))(:\d+)?(\/[%\-\wа-яё]*(\.[\wа-яё]{2,})?(([\wа-яё\-\.\?\\\/+@&#;:`~=%!,\(\)]*)(\.[\wа-яё]{2,})?)*)*\/?/i, hostnameRe = /^(((https?)|(ftps?)):\/\/)?([\-\wа-яё]*:?[\-\wа-яё]*@)?(([\-\wа-яё]+\.)+[\wа-яё\-]{2,}(:\d+)?(\/[%\-\wа-яё]*(\.[\wа-яё]{2,})?(([\wа-яё\-\.\?\\\/\+@&#;:`'~=%!,\(\)]*)(\.[\wа-яё]{2,})?)*)*\/?)/i, localRe = /^(((https?)|(ftps?)):\/\/)([\-\wа-яё]*:?[\-\wа-яё]*@)?(([\-\wа-яё]+)(:\d+)?(\/[%\-\wа-яё]*(\.[\wа-яё]{2,})?(([\wа-яё\-\.\?\\\/\+@&#;:`'~=%!,\(\)]*)(\.[\wа-яё]{2,})?)*)*\/?)/i, - emailStrongRe = /(mailto:)?([a-z0-9'\._-]+@[a-z0-9\.-]+\.[a-z0-9]{2,4})([a-яё0-9\._%+-=\?:&]*)/ig, + emailStrongRe = /(mailto:)?([a-z0-9'\.\+_-]+@[a-z0-9\.-]+\.[a-z0-9]{2,4})([a-яё0-9\._%+-=\?:&]*)/ig, emailAddStrongRe = /(mailto:|\s[@]|\s[+])?([a-z0-9'\._-]+@[a-z0-9\.-]+\.[a-z0-9]{2,4})([a-яё0-9\._%\+-=\?:&]*)/ig, ipStrongRe = /(((https?)|(ftps?)):\/\/([\-\wа-яё]*:?[\-\wа-яё]*@)?)(((1[0-9]{2}|2[0-4][0-9]|25[0-5]|[1-9][0-9]|[0-9])\.){3}(1[0-9]{2}|2[0-4][0-9]|25[0-5]|[1-9][0-9]|[0-9]))(:\d+)?(\/[%\-\wа-яё]*(\.[\wа-яё]{2,})?(([\wа-яё\-\.\?\\\/\+@&#;:`~=%!,\(\)]*)(\.[\wа-яё]{2,})?)*)*\/?/ig, hostnameStrongRe = /((((https?)|(ftps?)):\/\/([\-\wа-яё]*:?[\-\wа-яё]*@)?)|(([\-\wа-яё]*:?[\-\wа-яё]*@)?www\.))((([\-\wа-яё]+\.)+[\wа-яё\-]{2,}|([\-\wа-яё]+))(:\d+)?(\/[%\-\wа-яё]*(\.[\wа-яё]{2,})?(([\wа-яё\-\.\?\\\/\+@&#;:`~=%!,\(\)]*)(\.[\wа-яё]{2,})?)*)*\/?)/ig, @@ -196,11 +196,80 @@ define([], function () { me.innerWidth = window.innerWidth * me.zoom; me.innerHeight = window.innerHeight * me.zoom; me.applicationPixelRatio = scale.applicationPixelRatio || scale.devicePixelRatio; + }, + checkSizeIE = function () { + me.innerWidth = window.innerWidth; + me.innerHeight = window.innerHeight; + }, + isOffsetUsedZoom = function() { + if (isChrome && 128 <= chromeVersion) + return (me.zoom === 1) ? false : true; + return false; + }, + getBoundingClientRect = function(element) { + let rect = element.getBoundingClientRect(); + if (!isOffsetUsedZoom()) + return rect; + + let koef = me.zoom; + let newRect = {} + if (rect.x!==undefined) newRect.x = rect.x * koef; + if (rect.y!==undefined) newRect.y = rect.y * koef; + if (rect.width!==undefined) newRect.width = rect.width * koef; + if (rect.height!==undefined) newRect.height = rect.height * koef; + + if (rect.left!==undefined) newRect.left = rect.left * koef; + if (rect.top!==undefined) newRect.top = rect.top * koef; + if (rect.right!==undefined) newRect.right = rect.right * koef; + if (rect.bottom!==undefined) newRect.bottom = rect.bottom * koef; + return newRect; + }, + getOffset = function($element) { + let pos = $element.offset(); + if (!isOffsetUsedZoom()) + return pos; + return {left: pos.left * me.zoom, top: pos.top * me.zoom}; + }, + getPosition = function($element) { + let pos = $element.position(); + if (!isOffsetUsedZoom()) + return pos; + return {left: pos.left * me.zoom, top: pos.top * me.zoom}; + }, + setOffset = function($element, options) { + var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, + position = $element.css("position"), + props = {}; + + if ( position === "static" ) { + $element[0].style.position = "relative"; + } + + curOffset = getOffset($element); + curCSSTop = $element.css("top"); + curCSSLeft = $element.css("left"); + calculatePosition = ( position === "absolute" || position === "fixed" ) && + ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1; + + if ( calculatePosition ) { + curPosition = getPosition($element); + curTop = curPosition.top; + curLeft = curPosition.left; + } else { + curTop = parseFloat( curCSSTop ) || 0; + curLeft = parseFloat( curCSSLeft ) || 0; + } + + if ( options.top != null ) { + props.top = ( options.top - curOffset.top ) + curTop; + } + if ( options.left != null ) { + props.left = ( options.left - curOffset.left ) + curLeft; + } + $element.css( props ); + return $element; }; - checkSizeIE = function () { - me.innerWidth = window.innerWidth; - me.innerHeight = window.innerHeight; - }; + me.zoom = 1; me.applicationPixelRatio = 1; me.innerWidth = window.innerWidth; @@ -297,7 +366,11 @@ define([], function () { width: me.innerWidth, height: me.innerHeight - Common.Utils.InternalSettings.get('window-inactive-area-top') } - } + }, + getBoundingClientRect: getBoundingClientRect, + getOffset: getOffset, + setOffset: setOffset, + getPosition: getPosition } })(); @@ -1116,6 +1189,7 @@ define([], function () { } Common.Utils.cancelFullscreen = function () { + if (!(document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement )) return; if (document.cancelFullScreen) { document.cancelFullScreen(); } else if (document.webkitCancelFullScreen) { @@ -1295,7 +1369,7 @@ define([], function () { if (window.isrtl === undefined) { if (window.nativeprocvars && window.nativeprocvars.rtl !== undefined) window.isrtl = window.nativeprocvars.rtl; - else window.isrtl = !Common.Utils.isIE && Common.localStorage.getBool("ui-rtl", Common.Locale.isCurrentLanguageRtl()); + else window.isrtl = Common.Locale.isCurrentLanguageRtl() ? !Common.Utils.isIE && Common.localStorage.getBool("ui-rtl", Common.Locale.isCurrentLanguageRtl()) : false; } return window.isrtl; diff --git a/apps/common/main/lib/view/AutoCorrectDialog.js b/apps/common/main/lib/view/AutoCorrectDialog.js index fe9dc6c71b..d3a2801812 100644 --- a/apps/common/main/lib/view/AutoCorrectDialog.js +++ b/apps/common/main/lib/view/AutoCorrectDialog.js @@ -447,7 +447,7 @@ define([ var checked = (field.getValue()==='checked'); Common.localStorage.setBool(me.appPrefix + "settings-letter-exception-cells", checked); Common.Utils.InternalSettings.set(me.appPrefix + "settings-letter-exception-cells", checked); - me.api.asc_SetAutoCorrectFirstLetterOfSentences && me.api.asc_SetAutoCorrectFirstLetterOfSentences(checked); + me.api.asc_SetAutoCorrectFirstLetterOfCells && me.api.asc_SetAutoCorrectFirstLetterOfCells(checked); }); this.btnsCategory[3].on('click', _.bind(this.onAutocorrectCategoryClick, this, false)); diff --git a/apps/common/main/lib/view/Chat.js b/apps/common/main/lib/view/Chat.js index 16101840e7..b0240c1283 100644 --- a/apps/common/main/lib/view/Chat.js +++ b/apps/common/main/lib/view/Chat.js @@ -196,7 +196,7 @@ define([ // scroll to end this.panelMessages.scroller.update({minScrollbarLength : 40, alwaysVisibleY: true}); - this.panelMessages.scroller.scrollTop(content.get(0).getBoundingClientRect().height); + this.panelMessages.scroller.scrollTop(Common.Utils.getBoundingClientRect(content.get(0)).height); } } }, diff --git a/apps/common/main/lib/view/Comments.js b/apps/common/main/lib/view/Comments.js index 131e4184c0..dcf34a1dad 100644 --- a/apps/common/main/lib/view/Comments.js +++ b/apps/common/main/lib/view/Comments.js @@ -163,12 +163,12 @@ define([ autoScrollToEditButtons: function () { var button = $('#id-comments-change'), // TODO: add to cache btnBounds = null, - contentBounds = this.el.getBoundingClientRect(), + contentBounds = Common.Utils.getBoundingClientRect(this.el), moveY = 0, padding = 7; if (button.length) { - btnBounds = button.get(0).getBoundingClientRect(); + btnBounds = Common.Utils.getBoundingClientRect(button.get(0)); if (btnBounds && contentBounds) { moveY = contentBounds.bottom - (btnBounds.bottom + padding); if (moveY < 0) { diff --git a/apps/common/main/lib/view/DocumentPropertyDialog.js b/apps/common/main/lib/view/DocumentPropertyDialog.js new file mode 100644 index 0000000000..9768508def --- /dev/null +++ b/apps/common/main/lib/view/DocumentPropertyDialog.js @@ -0,0 +1,324 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2024 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +define([], function () { 'use strict'; + + Common.Views.DocumentPropertyDialog = Common.UI.Window.extend(_.extend({ + options: { + width: 320, + cls: 'modal-dlg', + buttons: ['ok', 'cancel'] + }, + + initialize : function(options) { + _.extend(this.options, { + title: this.txtTitle, + defaultValue: {} + }, options); + + this.template = [ + '
    ', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ' + ].join(''); + + this.options.tpl = _.template(this.template)(this.options); + + this.asc2type = function(ascType) { + if (ascType === AscCommon.c_oVariantTypes.vtLpwstr) { + return 'text'; + } else if (ascType === AscCommon.c_oVariantTypes.vtI4 || ascType === AscCommon.c_oVariantTypes.vtR8) { + return 'number'; + } else if (ascType === AscCommon.c_oVariantTypes.vtBool) { + return 'boolean'; + } else if (ascType === AscCommon.c_oVariantTypes.vtFiletime) { + return 'date'; + } + } + + Common.UI.Window.prototype.initialize.call(this, this.options); + }, + + render: function() { + Common.UI.Window.prototype.render.call(this); + + var me = this; + this.inputTitle = new Common.UI.InputField({ + el: $('#id-dlg-title'), + allowBlank: false, + blankError: this.txtPropertyTitleBlankError, + validateOnBlur: false, + hideErrorOnInput: true, + validation: function(value) { + if (me.options.nameValidator !== undefined) { + return me.options.nameValidator(value); + } + } + }); + if (this.options.defaultValue.name) { + this.inputTitle.setValue(this.options.defaultValue.name); + } + + this.comboboxType = new Common.UI.ComboBox({ + el: $('#id-dlg-type'), + cls: 'input-group-nr', + menuStyle: 'min-width: 85px; width: 100%;', + editable: false, + data: [ + { displayValue: this.txtPropertyTypeText, value: 'text' }, + { displayValue: this.txtPropertyTypeNumber, value: 'number' }, + { displayValue: this.txtPropertyTypeDate, value: 'date' }, + { displayValue: this.txtPropertyTypeBoolean, value: 'boolean' } + ], + dataHint: '1', + dataHintDirection: 'bottom', + dataHintOffset: 'big', + ariaLabel: this.strLineHeight, + takeFocusOnClose: true + }); + var currentType = this.options.defaultValue.type ? this.asc2type(this.options.defaultValue.type) : 'text' + this.comboboxType.setValue(currentType); + this.comboboxType.on('selected', _.bind(function (cmb, record) { + this.inputTextOrNumber.setVisible(record.value === 'text' || record.value === 'number'); + this.comboboxBoolean.setVisible(record.value === 'boolean'); + this.datepicker.setVisible(record.value === 'date'); + }, this)) + + this.inputTextOrNumber = new Common.UI.InputField({ + el: $('#id-dlg-value-input'), + style: 'width: 100%;', + validateOnBlur: false, + hideErrorOnInput: true, + allowBlank: false, + blankError: this.txtPropertyValueBlankError, + validation: function(value) { + if (this.comboboxType.getValue() === 'number' && (typeof value !== 'number' && isNaN(value.replace(',', '.')))) { + return this.txtPropertyTypeNumberInvalid; + } + + return true; + }.bind(this) + }); + if (this.options.defaultValue.value && (currentType === 'text' || currentType === 'number')) { + this.inputTextOrNumber.setValue(this.options.defaultValue.value); + } + this.inputTextOrNumber.setVisible( + this.options.defaultValue.type + ? (this.options.defaultValue.type !== AscCommon.c_oVariantTypes.vtFiletime && this.options.defaultValue.type !== AscCommon.c_oVariantTypes.vtBool) + : (currentType === 'text' || currentType === 'number') + ); + + this.comboboxBoolean = new Common.UI.ComboBox({ + el: $('#id-dlg-value-boolean'), + cls: 'input-group-nr', + menuStyle: 'min-width: 85px; width: 100%;', + editable: false, + data: [ + { displayValue: this.txtPropertyBooleanTrue, value: 1 }, + { displayValue: this.txtPropertyBooleanFalse, value: 0 } + ], + dataHint: '1', + dataHintDirection: 'bottom', + dataHintOffset: 'big', + ariaLabel: this.strLineHeight, + takeFocusOnClose: true + }); + this.comboboxBoolean.setValue(this.options.defaultValue.value !== undefined && currentType === 'boolean' ? (this.options.defaultValue.value ? 1 : 0) : 1); + this.comboboxBoolean.setVisible(this.options.defaultValue.type ? this.options.defaultValue.type === AscCommon.c_oVariantTypes.vtBool : currentType === 'boolean'); + + this.datepicker = new Common.UI.InputFieldBtnCalendar({ + el: $('#id-dlg-value-date'), + allowBlank : false, + blankError : this.txtPropertyValueBlankError, + validateOnBlur: false, + value : '', + hideErrorOnInput: true, + dataHint : '1', + dataHintDirection: 'left', + dataHintOffset: 'small' + }); + if (this.options.defaultValue.value && currentType === 'date') { + this.datepicker.setDate(this.options.defaultValue.value); + this.datepicker.setValue(this.dateToString(this.options.defaultValue.value)); + } + this.datepicker.setVisible(this.options.defaultValue.type ? this.options.defaultValue.type === AscCommon.c_oVariantTypes.vtFiletime : currentType === 'date'); + this.datepicker.on('date:click', function (cmp, date) { + cmp.setValue(this.dateToString(date)); + }.bind(this)); + + var $window = this.getChild(); + $window.find('.dlg-btn').on('click', _.bind(this.onBtnClick, this)); + }, + + getFocusedComponents: function() { + return [this.inputTitle, this.comboboxType, this.inputTextOrNumber, this.comboboxBoolean, this.datepicker].concat(this.getFooterButtons()); + }, + + getDefaultFocusableComponent: function () { + return this.inputTitle; + }, + + show: function() { + Common.UI.Window.prototype.show.apply(this, arguments); + + var me = this; + _.delay(function(){ + me.inputTitle.focus(); + },100); + }, + + onPrimary: function(event) { + this._handleInput('ok'); + return false; + }, + + onBtnClick: function(event) { + this._handleInput(event.currentTarget.attributes['result'].value); + }, + + _handleInput: function(state) { + if (this.options.handler) { + if (state === 'ok') { + if (this.inputTitle.checkValidate() !== true) { + this.inputTitle.focus(); + return; + } + + var title = this.inputTitle.getValue(), type = this.comboboxType.getValue(), ascValue, ascType; + if (type === 'boolean') { + ascValue = this.comboboxBoolean.getValue() === 1; + ascType = AscCommon.c_oVariantTypes.vtBool; + } else if (type === 'date') { + if (this.datepicker.checkValidate() !== true) { + this.datepicker.focus(); + return; + } + ascValue = this.datepicker.getDate(); + if (!ascValue) { + ascValue = new Date(this.datepicker.getValue()); + if (!ascValue || !(ascValue instanceof Date) || isNaN(ascValue)) + ascValue = undefined; + } + if (!ascValue) { + var me = this; + Common.UI.warning({ + msg: me.errorDate, + buttons: ['ok', 'cancel'], + callback: function(btn) { + if (btn==='ok') { + me.options.handler.call(this, state, title, AscCommon.c_oVariantTypes.vtLpwstr, me.datepicker.getValue()); + me.close(); + } else + me.datepicker.focus(); + } + }); + return; + } + ascType = AscCommon.c_oVariantTypes.vtFiletime; + } else { + if (this.inputTextOrNumber.checkValidate() !== true) { + this.inputTextOrNumber.focus(); + return; + } + + var value = this.inputTextOrNumber.getValue(); + if (type === 'text') { + ascType = AscCommon.c_oVariantTypes.vtLpwstr; + ascValue = value; + } else { + // note: precisely a numeric value because we validated it + if (typeof value !== 'number') { + value = value.replace(',', '.'); + } + + if (value % 1 === 0) { + ascType = AscCommon.c_oVariantTypes.vtI4; + ascValue = parseInt(value); + } else { + ascType = AscCommon.c_oVariantTypes.vtR8; + ascValue = parseFloat(value); + } + } + } + + this.options.handler.call(this, state, title, ascType, ascValue); + } + } + + this.close(); + }, + + dateToString: function (value) { + var text = ''; + if (value) { + value = new Date(value) + var lang = (this.options.lang || 'en').replace('_', '-').toLowerCase(); + try { + if ( lang == 'ar-SA'.toLowerCase() ) lang = lang + '-u-nu-latn-ca-gregory'; + text = value.toLocaleString(lang, {year: 'numeric', month: '2-digit', day: '2-digit'}); + } catch (e) { + lang = 'en'; + text = value.toLocaleString(lang, {year: 'numeric', month: '2-digit', day: '2-digit'}); + } + } + return text; + }, + + txtTitle: "New Document Property", + txtPropertyTitleLabel: "Title", + txtPropertyTitleBlankError: 'Property should have a title', + txtPropertyTypeLabel: "Type", + txtPropertyValueLabel: "Value", + txtPropertyValueBlankError: 'Property should have a value', + txtPropertyTypeText: "Text", + txtPropertyTypeNumber: "Number", + txtPropertyTypeNumberInvalid: 'Provide a valid number', + txtPropertyTypeDate: "Date", + txtPropertyTypeBoolean: '"Yes" or "no"', + txtPropertyBooleanTrue: 'Yes', + txtPropertyBooleanFalse: 'No', + errorDate: 'You can choose a value from the calendar to store the value as Date.
    If you enter a value manually, it will be stored as Text.' + }, Common.Views.DocumentPropertyDialog || {})); +}); \ No newline at end of file diff --git a/apps/common/main/lib/view/Header.js b/apps/common/main/lib/view/Header.js index c44c4ba91a..8fed536d11 100644 --- a/apps/common/main/lib/view/Header.js +++ b/apps/common/main/lib/view/Header.js @@ -43,15 +43,14 @@ Common.Views = Common.Views || {}; define([ 'backbone', - 'text!common/main/lib/template/Header.template', 'core' -], function (Backbone, headerTemplate) { 'use strict'; +], function (Backbone) { 'use strict'; Common.Views.Header = Backbone.View.extend(_.extend(function(){ var storeUsers, appConfig; var $userList, $panelUsers, $btnUsers, $btnUserName, $labelDocName; var _readonlyRights = false; - var _tabStyle = 'tab', _logoImage = ''; + var _tabStyle = 'fill', _logoImage = ''; var isPDFEditor = !!window.PDFE, isDocEditor = !!window.DE, isSSEEditor = !!window.SSE; @@ -232,12 +231,12 @@ define([ if ( $labelDocName && config) { var $parent = $labelDocName.parent(); if (!config.twoLevelHeader) { - var _left_width = $parent.position().left, + var _left_width = Common.Utils.getPosition($parent).left, _right_width = $parent.next().outerWidth(); $parent.css('padding-left', _left_width < _right_width ? Math.max(2, _right_width - _left_width) : 2); $parent.css('padding-right', _left_width < _right_width ? 2 : Math.max(2, _left_width - _right_width)); } else if (!config.compactHeader) { - var _left_width = $parent.position().left, + var _left_width = Common.Utils.getPosition($parent).left, _right_width = $parent.next().outerWidth(), outerWidth = $labelDocName.outerWidth(), cssWidth = $labelDocName[0].style.width; @@ -265,9 +264,9 @@ define([ var me = this; config = config || appConfig; if (!me.btnPDFMode || !config) return; - var type = config.isPDFEdit ? 'edit' : (config.isPDFAnnotate && config.canCoEditing ? 'comment' : 'view'), + var type = config.isPDFEdit ? 'edit' : (config.isPDFAnnotate ? 'comment' : 'view'), isEdit = config.isPDFEdit, - isComment = !isEdit && config.isPDFAnnotate && config.canCoEditing; + isComment = !isEdit && config.isPDFAnnotate; me.btnPDFMode.setIconCls('toolbar__icon icon--inverse ' + (isEdit ? 'btn-edit' : (isComment ? 'btn-menu-comments' : 'btn-sheet-view'))); me.btnPDFMode.setCaption(isEdit ? me.textEdit : (isComment ? me.textComment : me.textView)); me.btnPDFMode.updateHint(isEdit ? me.tipEdit : (isComment ? me.tipComment : me.tipView)); @@ -593,34 +592,35 @@ define([ if (me.btnPDFMode) { var arr = [], type = me.btnPDFMode.options.value; - appConfig.canPDFEdit && arr.push({ - caption: me.textEdit, - iconCls : 'menu__icon btn-edit', - template: menuTemplate, - description: appConfig.canCoEditing ? me.textEditDesc : me.textEditDescNoCoedit, - value: 'edit', - checkable: true, - toggleGroup: 'docmode' - }); - arr.push({ - caption: appConfig.canCoEditing ? me.textComment : me.textView, - iconCls : 'menu__icon ' + (appConfig.canCoEditing ? 'btn-menu-comments' : 'btn-sheet-view'), - template: menuTemplate, - description: appConfig.canCoEditing ? me.textCommentDesc : me.textViewDescNoCoedit, - value: appConfig.canCoEditing ? 'comment' : 'view', - disabled: !appConfig.canPDFAnnotate, - checkable: true, - toggleGroup: 'docmode' - }); - appConfig.canCoEditing && arr.push({ - caption: me.textView, - iconCls : 'menu__icon btn-sheet-view', - template: menuTemplate, - description: me.textViewDesc, - value: 'view', - checkable: true, - toggleGroup: 'docmode' - }); + // arr.push({ + // caption: me.textView, + // iconCls : 'menu__icon btn-sheet-view', + // template: menuTemplate, + // description: me.textViewDesc, + // value: 'view', + // checkable: true, + // toggleGroup: 'docmode' + // }); + if (appConfig.canPDFEdit) { + arr.push({ + caption: me.textComment, + iconCls : 'menu__icon btn-menu-comments', + template: menuTemplate, + description: me.textAnnotateDesc, + value: 'comment', + checkable: true, + toggleGroup: 'docmode' + }); + arr.push({ + caption: me.textEdit, + iconCls : 'menu__icon btn-edit', + template: menuTemplate, + description: me.textEditDescNoCoedit, + value: 'edit', + checkable: true, + toggleGroup: 'docmode' + }); + } me.btnPDFMode.setMenu(new Common.UI.Menu({ cls: 'ppm-toolbar select-checked-items', style: 'width: 220px;', @@ -757,9 +757,6 @@ define([ el: '#header', - // Compile our stats template - template: _.template(headerTemplate), - // Delegated events for creating new items, and clearing completed ones. events: { // 'click #header-logo': function (e) {} @@ -818,6 +815,9 @@ define([ }); Common.NotificationCenter.on('uitheme:changed', this.changeLogo.bind(this)); Common.NotificationCenter.on('mentions:setusers', this.avatarsUpdate.bind(this)); + Common.NotificationCenter.on('tabstyle:changed', this.changeLogo.bind(this)); + Common.NotificationCenter.on('tabbackground:changed', this.changeLogo.bind(this)); + }, render: function (el, role) { @@ -827,6 +827,8 @@ define([ }, getPanel: function (role, config) { + !appConfig && (appConfig = config); + var me = this; function createTitleButton(iconid, slot, disabled, hintDirection, hintOffset, hintTitle, lock) { @@ -901,7 +903,8 @@ define([ if ( config.canQuickPrint ) this.btnPrintQuick = createTitleButton('toolbar__icon icon--inverse btn-quick-print', $html.findById('#slot-hbtn-print-quick'), undefined, 'bottom', 'big', 'Q'); } - if ( config.canRequestEditRights && (!config.twoLevelHeader && config.canEdit && !isPDFEditor || config.isPDFForm && config.canFillForms && config.isRestrictedEdit)) + if ( config.canRequestEditRights && (!config.twoLevelHeader && config.canEdit && !isPDFEditor || config.isPDFForm && config.canFillForms && config.isRestrictedEdit || + isPDFEditor && (config.canPDFEdit && !config.isPDFEdit && !config.isPDFAnnotate || config.isPDFFill))) this.btnEdit = createTitleButton('toolbar__icon icon--inverse btn-edit', $html.findById('#slot-hbtn-edit'), undefined, 'bottom', 'big'); me.btnSearch.render($html.find('#slot-btn-search')); @@ -942,13 +945,14 @@ define([ $html.find('#slot-btn-share').hide(); } - if (isPDFEditor && config.isEdit && config.canSwitchMode) { + if (isPDFEditor && config.isEdit && config.canSwitchMode) { // hide in pdf editor me.btnPDFMode = new Common.UI.Button({ cls: 'btn-header btn-header-pdf-mode', - iconCls: 'toolbar__icon icon--inverse btn-sheet-view', - caption: me.textView, + iconCls: 'toolbar__icon icon--inverse btn-menu-comments', + caption: me.textComment, menu: true, - value: 'view', + value: 'comment', + lock: [Common.enumLock.lostConnect, Common.enumLock.fileMenuOpened, Common.enumLock.changeModeLock], dataHint: '0', dataHintDirection: 'bottom', dataHintOffset: 'big' @@ -1091,7 +1095,7 @@ define([ branding = branding || {}; var image = branding.logo ? branding.logo.image || branding.logo.imageDark || branding.logo.imageLight : null, isDark = true; - tabStyle = tabStyle || Common.Utils.InternalSettings.get("settings-tab-style") || 'tab'; + tabStyle = tabStyle || Common.Utils.InternalSettings.get("settings-tab-style") || 'fill'; tabBackground = tabBackground || Common.Utils.InternalSettings.get("settings-tab-background") || 'header'; if (!Common.Utils.isIE) { var header_color = Common.UI.Themes.currentThemeColor(isDocEditor && config.isPDFForm || isPDFEditor ? '--toolbar-header-pdf' : @@ -1106,6 +1110,8 @@ define([ }, changeLogo: function () { + if (!appConfig) return; + var value = this.branding; var logo = this.getSuitableLogo(value, appConfig, Common.Utils.InternalSettings.get("settings-tab-style"), Common.Utils.InternalSettings.get("settings-tab-background")); $('#header-logo').toggleClass('logo-light', logo.isLight); @@ -1325,7 +1331,7 @@ define([ switch ( alias ) { case 'undo': _lockButton(me.btnUndo); break; case 'redo': _lockButton(me.btnRedo); break; - case 'mode': _lockButton(me.btnDocMode); break; + case 'mode': _lockButton(me.btnDocMode ? me.btnDocMode : me.btnPDFMode); break; default: break; } } @@ -1391,7 +1397,8 @@ define([ helpDocModeHeader: 'Switch between modes', helpQuickAccess: 'Hide or show the functional buttons of your choice.', helpQuickAccessHeader: 'Customize Quick Access', - ariaQuickAccessToolbar: 'Quick access toolbar' + ariaQuickAccessToolbar: 'Quick access toolbar', + textAnnotateDesc: 'Fill forms or annotate' } }(), Common.Views.Header || {})) }); diff --git a/apps/common/main/lib/view/LanguageDialog.js b/apps/common/main/lib/view/LanguageDialog.js index d4bba6fc0d..147ac305d6 100644 --- a/apps/common/main/lib/view/LanguageDialog.js +++ b/apps/common/main/lib/view/LanguageDialog.js @@ -90,8 +90,11 @@ define([], function () { 'use strict'; '<% _.each(items, function(item) { %>', '
  • ', '', - '', - '<%= scope.getDisplayValue(item) %>', + '
    ', + '', + '<%= item.displayValue %>', + '
    ', + '', '
    ', '
  • ', '<% }); %>', @@ -101,6 +104,7 @@ define([], function () { 'use strict'; data: this.options.languages, takeFocusOnClose: true, search: true, + searchFields: ['displayValue', 'displayValueEn'], scrollAlwaysVisible: true }); @@ -155,4 +159,4 @@ define([], function () { 'use strict'; labelSelect : 'Select document language' }, Common.Views.LanguageDialog || {})) -}); \ No newline at end of file +}); diff --git a/apps/common/main/lib/view/OpenDialog.js b/apps/common/main/lib/view/OpenDialog.js index a79320b4ee..dec32ddbaa 100644 --- a/apps/common/main/lib/view/OpenDialog.js +++ b/apps/common/main/lib/view/OpenDialog.js @@ -258,13 +258,16 @@ define([ delimiter = this.cmbDelimiter ? this.cmbDelimiter.getValue() : null, delimiterChar = (delimiter == -1) ? this.inputDelimiter.getValue() : null; (delimiter == -1) && (delimiter = null); - if (!this.closable && this.type == Common.Utils.importTextType.TXT) { //save last encoding only for opening txt files - Common.localStorage.setItem("de-settings-open-encoding", encoding); - } - if (this.type === Common.Utils.importTextType.CSV) { // only for csv files - Common.localStorage.setItem("sse-settings-csv-delimiter", delimiter === null ? -1 : delimiter); - Common.localStorage.setItem("sse-settings-csv-delimiter-char", delimiterChar || ''); - Common.localStorage.setItem("sse-settings-csv-encoding", encoding); + if (this.type === Common.Utils.importTextType.TXT) { //save last encoding only for txt files + this._isEncodingChanged && Common.localStorage.setItem("de-settings-open-encoding", encoding); + } else if (this.type === Common.Utils.importTextType.CSV) { // only for csv files + this._isDelimChanged && Common.localStorage.setItem("sse-settings-csv-delimiter", delimiter === null ? -1 : delimiter); + this._isDelimCharChanged && Common.localStorage.setItem("sse-settings-csv-delimiter-char", delimiterChar || ''); + this._isEncodingChanged && Common.localStorage.setItem("sse-settings-csv-encoding", encoding); + } else if (this.type === Common.Utils.importTextType.Paste || this.type === Common.Utils.importTextType.Columns || this.type === Common.Utils.importTextType.Data) { + this._isDelimChanged && Common.localStorage.setItem("sse-settings-data-delimiter", delimiter === null ? -1 : delimiter); + this._isDelimCharChanged && Common.localStorage.setItem("sse-settings-data-delimiter-char", delimiterChar || ''); + this._isEncodingChanged && Common.localStorage.setItem("sse-settings-data-encoding", encoding); } var decimal = this.separatorOptions ? this.separatorOptions.decimal : undefined, @@ -286,7 +289,7 @@ define([ }, initCodePages: function () { - var i, c, codepage, encodedata = [], listItems = [], length = 0, lcid_width = 0; + var i, c, codepage, encodedata = [], listItems = [], length = 0, lcid_width = 0, utf8 = 0; if (this.codepages) { encodedata = []; @@ -296,6 +299,7 @@ define([ c[0] = codepage.asc_getCodePage(); c[1] = codepage.asc_getCodePageName(); c[2] = codepage.asc_getLcid(); + (c[2]===65001) && (utf8 = i); encodedata.push(c); } @@ -337,17 +341,22 @@ define([ }); this.cmbEncoding.setDisabled(false); - var encoding = (this.settings && this.settings.asc_getCodePage()) ? this.settings.asc_getCodePage() : encodedata[0][0]; - if (!this.closable && this.type == Common.Utils.importTextType.TXT) { // only for opening txt files - var value = Common.localStorage.getItem("de-settings-open-encoding"); - value && (encoding = parseInt(value)); - } else if (this.type === Common.Utils.importTextType.CSV) { // only for csv files - var value = Common.localStorage.getItem("sse-settings-csv-encoding"); - value && (encoding = parseInt(value)); + var encoding = (this.settings && this.settings.asc_getCodePage()) ? this.settings.asc_getCodePage() : encodedata[utf8][0]; + if (encoding===-1) { + if (this.type == Common.Utils.importTextType.TXT) { // only for opening txt files + var value = Common.localStorage.getItem("de-settings-open-encoding"); + value && (encoding = parseInt(value)); + } else if (this.type === Common.Utils.importTextType.CSV) { // only for csv files + var value = Common.localStorage.getItem("sse-settings-csv-encoding"); + value && (encoding = parseInt(value)); + } else if (this.type === Common.Utils.importTextType.Data) { + var value = Common.localStorage.getItem("sse-settings-data-encoding"); + value && (encoding = parseInt(value)); + } + (encoding===-1) && (encoding = encodedata[utf8][0]); } this.cmbEncoding.setValue(encoding); - if (this.preview) - this.cmbEncoding.on('selected', _.bind(this.onCmbEncodingSelect, this)); + this.cmbEncoding.on('selected', _.bind(this.onCmbEncodingSelect, this)); var ul = this.cmbEncoding.cmpEl.find('ul'), a = ul.find('li:nth(0) a'), @@ -358,14 +367,12 @@ define([ if (this.type == Common.Utils.importTextType.CSV || this.type == Common.Utils.importTextType.Paste || this.type == Common.Utils.importTextType.Columns || this.type == Common.Utils.importTextType.Data) { var delimiter = this.settings && this.settings.asc_getDelimiter() ? this.settings.asc_getDelimiter() : 4, delimiterChar = this.settings && this.settings.asc_getDelimiterChar() ? this.settings.asc_getDelimiterChar() : ''; - if (this.type == Common.Utils.importTextType.CSV) { // only for csv files - var value = Common.localStorage.getItem("sse-settings-csv-delimiter"); - if (value) { - value = parseInt(value); - if (!isNaN(value)) { - delimiter = value; - (delimiter===-1) && (delimiterChar = Common.localStorage.getItem("sse-settings-csv-delimiter-char") || ''); - } + var value = Common.localStorage.getItem(this.type == Common.Utils.importTextType.CSV ? "sse-settings-csv-delimiter" : "sse-settings-data-delimiter"); + if (value) { + value = parseInt(value); + if (!isNaN(value)) { + delimiter = value; + (delimiter===-1) && (delimiterChar = Common.localStorage.getItem(this.type == Common.Utils.importTextType.CSV ? "sse-settings-csv-delimiter-char" : "sse-settings-data-delimiter-char") || ''); } } @@ -396,8 +403,7 @@ define([ value: delimiterChar }); this.inputDelimiter.setVisible(delimiter===-1); - if (this.preview) - this.inputDelimiter.on ('changing', _.bind(this.updatePreview, this)); + this.inputDelimiter.on ('changing', _.bind(this.onInputCharChanging, this)); if (this.type == Common.Utils.importTextType.Paste || this.type == Common.Utils.importTextType.Columns || this.type == Common.Utils.importTextType.Data) { this.btnAdvanced = new Common.UI.Button({ @@ -538,10 +544,17 @@ define([ setTimeout(function(){me.inputDelimiter.focus();}, 10); if (this.preview) this.updatePreview(); + this._isDelimChanged = true; + }, + + onInputCharChanging: function(){ + this.preview && this.updatePreview(); + this._isDelimCharChanged = true; }, onCmbEncodingSelect: function(combo, record){ - this.updatePreview(); + this.preview && this.updatePreview(); + this._isEncodingChanged = true; }, onAdvancedClick: function() { @@ -595,9 +608,9 @@ define([ },1); }); - var xy = me.$window.offset(); + var xy = Common.Utils.getOffset(me.$window); me.hide(); - win.show(xy.left + 160, xy.top + 125); + win.show(me.$window, xy); win.setSettings({ api : me.api, range : (!_.isEmpty(txtRange.getValue()) && (txtRange.checkValidate()==true)) ? txtRange.getValue() : (me.dataDestValid), diff --git a/apps/common/main/lib/view/ReviewPopover.js b/apps/common/main/lib/view/ReviewPopover.js index f2405242e3..3c12292251 100644 --- a/apps/common/main/lib/view/ReviewPopover.js +++ b/apps/common/main/lib/view/ReviewPopover.js @@ -765,7 +765,7 @@ define([ sdkBoundsTopPos = 0; if (commentsView && arrowView && editorView && editorView.get(0)) { - editorBounds = editorView.get(0).getBoundingClientRect(); + editorBounds = Common.Utils.getBoundingClientRect(editorView.get(0)); if (editorBounds) { sdkBoundsHeight = editorBounds.height - this.sdkBounds.padding * 2; @@ -887,11 +887,11 @@ define([ commentsView.css({height: '100%'}); - contentBounds = commentsView.get(0).getBoundingClientRect(); + contentBounds = Common.Utils.getBoundingClientRect(commentsView.get(0)); if (contentBounds) { editorView = $('#editor_sdk'); if (editorView && editorView.get(0)) { - editorBounds = editorView.get(0).getBoundingClientRect(); + editorBounds = Common.Utils.getBoundingClientRect(editorView.get(0)); if (editorBounds) { sdkBoundsHeight = editorBounds.height - this.sdkBounds.padding * 2; sdkBoundsTopPos = sdkBoundsTop; @@ -951,7 +951,7 @@ define([ arrowView.toggleClass('top', isMoveDown); arrowView.toggleClass('bottom', !isMoveDown); arrowView.removeClass('left right'); - } else if (sdkBoundsHeight <= outerHeight) { + } else if (Math.ceil(sdkBoundsHeight) <= Math.ceil(outerHeight)) { this.$window.css({ maxHeight: sdkBoundsHeight - sdkPanelHeight + 'px', top: sdkBoundsTop + sdkPanelHeight + 'px' @@ -1177,12 +1177,12 @@ define([ autoScrollToEditButtons: function () { var button = $('#id-comments-change-popover'), // TODO: add to cache btnBounds = null, - contentBounds = this.$window[0].getBoundingClientRect(), + contentBounds = Common.Utils.getBoundingClientRect(this.$window[0]), moveY = 0, padding = 7; if (button.length) { - btnBounds = button.get(0).getBoundingClientRect(); + btnBounds = Common.Utils.getBoundingClientRect(button.get(0)); if (btnBounds && contentBounds) { moveY = contentBounds.bottom - (btnBounds.bottom + padding); if (moveY < 0) { diff --git a/apps/common/main/lib/view/TextInputDialog.js b/apps/common/main/lib/view/TextInputDialog.js index ed0e0c4e6d..2698e41809 100644 --- a/apps/common/main/lib/view/TextInputDialog.js +++ b/apps/common/main/lib/view/TextInputDialog.js @@ -68,6 +68,8 @@ define([], function () { 'use strict'; allowBlank: true }, options.inputConfig || {}); + this.inputFixedConfig = options.inputFixedConfig; + _options.tpl = _.template(this.template)(_options); Common.UI.Window.prototype.initialize.call(this, _options); }, @@ -76,13 +78,29 @@ define([], function () { 'use strict'; Common.UI.Window.prototype.render.call(this); var me = this; - me.inputLabel = new Common.UI.InputField({ + me.inputLabel = !this.inputFixedConfig ? new Common.UI.InputField({ el : $('#id-dlg-label-custom-input'), allowBlank : me.inputConfig.allowBlank, blankError : me.inputConfig.blankError, + maxLength : me.inputConfig.maxLength, style : 'width: 100%;', validateOnBlur: false, validation : me.inputConfig.validation + }) : new Common.UI.InputFieldFixed({ + el : $('#id-dlg-label-custom-input'), + allowBlank : me.inputConfig.allowBlank, + blankError : me.inputConfig.blankError, + maxLength : me.inputFixedConfig.fixedValue && me.inputConfig.maxLength ? me.inputConfig.maxLength - me.inputFixedConfig.fixedValue.length : me.inputConfig.maxLength, + style : 'width: 100%;', + validateOnBlur: false, + validation : me.inputConfig.validation, + cls : 'text-align-left', + fixedValue : me.inputFixedConfig.fixedValue, + fixedCls : 'light', + fixedWidth : me.inputFixedConfig.fixedWidth + }); + me.inputLabel.cmpEl.on('focus', 'input.fixed-text', function() { + setTimeout(function(){me.inputLabel._input && me.inputLabel._input.focus();}, 1); }); me.inputLabel.setValue(me.options.value || ''); var $window = this.getChild(); @@ -90,7 +108,7 @@ define([], function () { 'use strict'; }, getFocusedComponents: function() { - return [this.inputLabel].concat(this.getFooterButtons()); + return [{cmp: this.inputLabel, selector: 'input:not(.fixed-text)'}].concat(this.getFooterButtons()); }, getDefaultFocusableComponent: function () { diff --git a/apps/common/main/resources/img/controls/Scroll_center.svg b/apps/common/main/resources/img/controls/Scroll_center.svg new file mode 100644 index 0000000000..76e0ade4d3 --- /dev/null +++ b/apps/common/main/resources/img/controls/Scroll_center.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/common/main/resources/img/controls/common-controls.png b/apps/common/main/resources/img/controls/common-controls.png old mode 100755 new mode 100644 index 9fd5188870..a570d9b8b4 Binary files a/apps/common/main/resources/img/controls/common-controls.png and b/apps/common/main/resources/img/controls/common-controls.png differ diff --git a/apps/common/main/resources/img/controls/common-controls@1.25x.png b/apps/common/main/resources/img/controls/common-controls@1.25x.png index 81f7530e99..a114ff3fee 100644 Binary files a/apps/common/main/resources/img/controls/common-controls@1.25x.png and b/apps/common/main/resources/img/controls/common-controls@1.25x.png differ diff --git a/apps/common/main/resources/img/controls/common-controls@1.5x.png b/apps/common/main/resources/img/controls/common-controls@1.5x.png index 3d2b77002f..55f01fab8c 100644 Binary files a/apps/common/main/resources/img/controls/common-controls@1.5x.png and b/apps/common/main/resources/img/controls/common-controls@1.5x.png differ diff --git a/apps/common/main/resources/img/controls/common-controls@1.75x.png b/apps/common/main/resources/img/controls/common-controls@1.75x.png index 40e326cb97..316f479eea 100644 Binary files a/apps/common/main/resources/img/controls/common-controls@1.75x.png and b/apps/common/main/resources/img/controls/common-controls@1.75x.png differ diff --git a/apps/common/main/resources/img/controls/common-controls@2x.png b/apps/common/main/resources/img/controls/common-controls@2x.png old mode 100755 new mode 100644 index 0d16712bac..4ea52d0fe0 Binary files a/apps/common/main/resources/img/controls/common-controls@2x.png and b/apps/common/main/resources/img/controls/common-controls@2x.png differ diff --git a/apps/common/main/resources/less/colors-table-gray.less b/apps/common/main/resources/less/colors-table-gray.less index e9d3b22bc9..98f9c1db66 100644 --- a/apps/common/main/resources/less/colors-table-gray.less +++ b/apps/common/main/resources/less/colors-table-gray.less @@ -7,10 +7,10 @@ --toolbar-header-presentation: #f7f7f7; --toolbar-header-pdf: #f7f7f7; - --text-toolbar-header-on-background-document: #38567A; - --text-toolbar-header-on-background-spreadsheet: #336B49; - --text-toolbar-header-on-background-presentation: #854535; - --text-toolbar-header-on-background-pdf: #8D4444; + --text-toolbar-header-on-background-document: #FFFFFF; + --text-toolbar-header-on-background-spreadsheet: #FFFFFF; + --text-toolbar-header-on-background-presentation: #FFFFFF; + --text-toolbar-header-on-background-pdf: #FFFFFF; --background-normal: #fff; --background-toolbar: #f7f7f7; diff --git a/apps/common/main/resources/less/colors-table.less b/apps/common/main/resources/less/colors-table.less index 66ec962b6e..fd281616ed 100644 --- a/apps/common/main/resources/less/colors-table.less +++ b/apps/common/main/resources/less/colors-table.less @@ -314,6 +314,8 @@ @canvas-background: var(--canvas-background); @canvas-content-background: var(--canvas-content-background); @canvas-page-border: var(--canvas-page-border); +@canvas-scroll-arrow: var(--canvas-scroll-arrow); +@canvas-scroll-arrow-hover: var(--canvas-scroll-arrow-hover); @canvas-scroll-thumb-hover: var(--canvas-scroll-thumb-hover); @canvas-scroll-thumb-border-hover: var(--canvas-scroll-thumb-border-hover); diff --git a/apps/common/main/resources/less/combo-dataview.less b/apps/common/main/resources/less/combo-dataview.less index 575fa5f3f1..7e2c91b08e 100644 --- a/apps/common/main/resources/less/combo-dataview.less +++ b/apps/common/main/resources/less/combo-dataview.less @@ -512,6 +512,7 @@ width: @x-huge-btn-icon-size; height: @x-huge-btn-icon-size; min-width: 0; + flex-shrink: 0; } .caption{ diff --git a/apps/common/main/resources/less/comments.less b/apps/common/main/resources/less/comments.less index 7a888208f7..2ed9fae2ce 100644 --- a/apps/common/main/resources/less/comments.less +++ b/apps/common/main/resources/less/comments.less @@ -352,11 +352,11 @@ .btn-edit,.btn-delete, .btn-resolve, .icon-resolve, .btn-resolve-check, .btn-accept, .btn-reject, .btn-goto { width: 16px; height: 16px; - margin: 0 0 0 5px; + margin: 1px 0 0 5px; background-color: transparent; .rtl & { - margin: 0 5px 0 0; + margin: 1px 5px 0 0; } } @@ -431,7 +431,18 @@ } } - .btn-resolve, .btn-accept, .icon-resolve { + .btn-resolve.comment-resolved, .icon-resolve.i-comment-resolved { + background-position: 0px -63px; + width: 17px; + height: 18px; + margin: 0 0 0 4px; + + .rtl & { + margin: 0px 4px 0 0; + } + } + + .btn-resolve:not(.comment-resolved), .btn-accept{ position: relative; &:after { @@ -440,19 +451,12 @@ border: solid @text-normal-ie; border: solid @text-normal; border-width: 0 2px 2px 0; - transform: rotate(40deg); + transform: rotate(45deg); width: 7px; height: 12px; left: 6px; top: 0px; } - - &.comment-resolved, &.i-comment-resolved { - &:after { - border-color: @icon-success-ie; - border-color: @icon-success; - } - } } .btn-resolve-check { diff --git a/apps/common/main/resources/less/common.less b/apps/common/main/resources/less/common.less index 01b60dbd76..ffaf170f34 100644 --- a/apps/common/main/resources/less/common.less +++ b/apps/common/main/resources/less/common.less @@ -317,7 +317,7 @@ label { } &:not(:has(.menu-item-icon)) { - padding-left: 28px; + .padding-left-28(); } } } diff --git a/apps/common/main/resources/less/input.less b/apps/common/main/resources/less/input.less index ad89f1459f..eeda789017 100644 --- a/apps/common/main/resources/less/input.less +++ b/apps/common/main/resources/less/input.less @@ -186,22 +186,10 @@ textarea.form-control:focus { .input-field-fixed { position: relative; - input:not(.fixed-text) { - .text-align-right(); - padding-right: 50%; - padding-right: calc(50% + 4px); - .rtl & { - padding-left: 50%; - padding-right: 0; - } - } - .fixed-text { position: absolute; right: 0; top: 0; - width: 50%; - width: calc(50% + 4px); border-color: transparent; background: transparent; .text-align-left(); @@ -215,6 +203,9 @@ textarea.form-control:focus { left: 0; } } + .fixed-text.light { + opacity: 0.8; + } &.disabled .fixed-text { opacity: @component-disabled-opacity-ie; opacity: @component-disabled-opacity; diff --git a/apps/common/main/resources/less/language-dialog.less b/apps/common/main/resources/less/language-dialog.less index ecc545978e..06c382e723 100644 --- a/apps/common/main/resources/less/language-dialog.less +++ b/apps/common/main/resources/less/language-dialog.less @@ -7,9 +7,9 @@ li { .icon.spellcheck-lang { - margin: -3px 4px 0 -24px; + margin: -1px 4px 0 -24px; .rtl & { - margin: -3px -24px 0 4px; + margin: -1px -24px 0 4px; } } diff --git a/apps/common/main/resources/less/scroller.less b/apps/common/main/resources/less/scroller.less index 4e764a1ea8..c864e7a354 100644 --- a/apps/common/main/resources/less/scroller.less +++ b/apps/common/main/resources/less/scroller.less @@ -20,18 +20,47 @@ background-color: @background-toolbar-ie; background-color: @background-toolbar; - background-image: data-uri('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAuSURBVChTY6AfOH/+/H9SaSYQg1RAlqZhCT5+/AgOSlJoOgY50DqSNZJhEwMDACkvNZLpune5AAAAAElFTkSuQmCC'); - background-repeat: no-repeat; - - @media - only screen and (-webkit-min-device-pixel-ratio: 2), - only screen and (min-resolution: 2dppx), - only screen and (min-resolution: 192dpi) { - background-image: data-uri('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAcCAMAAABIzV/hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAAAEBAQICAgMDAwQEBAUFBQYGBgcHBwgICAkJCQoKCgsLCwwMDA0NDQ4ODg8PDxAQEBERERISEhMTExQUFBUVFRYWFhcXFxgYGBkZGRoaGhsbGxwcHB0dHR4eHh8fHyAgICEhISIiIiMjIyQkJCUlJSYmJicnJygoKCkpKSoqKisrKywsLC0tLS4uLi8vLzAwMDExMTIyMjMzMzQ0NDU1NTY2Njc3Nzg4ODk5OTo6Ojs7Ozw8PD09PT4+Pj8/P0BAQEFBQUJCQkNDQ0REREVFRUZGRkdHR0hISElJSUpKSktLS0xMTE1NTU5OTk9PT1BQUFFRUVJSUlNTU1RUVFVVVVZWVldXV1hYWFlZWVpaWltbW1xcXF1dXV5eXl9fX2BgYGFhYWJiYmNjY2RkZGVlZWZmZmdnZ2hoaGlpaWpqamtra2xsbG1tbW5ubm9vb3BwcHFxcXJycnNzc3R0dHV1dXZ2dnd3d3h4eHl5eXp6ent7e3x8fH19fX5+fn9/f4CAgIGBgYKCgoODg4SEhIWFhYaGhoeHh4iIiImJiYqKiouLi4yMjI2NjY6Ojo+Pj5CQkJGRkZKSkpOTk5SUlJWVlZaWlpeXl5iYmJmZmZqampubm5ycnJ2dnZ6enp+fn6CgoKGhoaKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq6ysrK2tra6urq+vr7CwsLGxsbKysrOzs7S0tLW1tba2tre3t7i4uLm5ubq6uru7u7y8vL29vb6+vr+/v8DAwMHBwcLCwsPDw8TExMXFxcbGxsfHx8jIyMnJycrKysvLy8zMzM3Nzc7Ozs/Pz9DQ0NHR0dLS0tPT09TU1NXV1dbW1tfX19jY2NnZ2dra2tvb29zc3N3d3d7e3t/f3+Dg4OHh4eLi4uPj4+Tk5OXl5ebm5ufn5+jo6Onp6erq6uvr6+zs7O3t7e7u7u/v7/Dw8PHx8fLy8vPz8/T09PX19fb29vf39/j4+Pn5+fr6+vv7+/z8/P39/f7+/v///+KwXX0AAAABdFJOUwBA5thmAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAANklEQVQoU93IoREAQAjEwOu/OWqhg1dBBYv4zKxJLqtayYIsyIIsyBqf1r2SBVmQBVmQNa5KHuCckwGi77ddAAAAAElFTkSuQmCC'); - background-size: auto 14px; + + div { + display: block; + height: 100%; + + background-image: data-uri('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAuSURBVChTY6AfOH/+/H9SaSYQg1RAlqZhCT5+/AgOSlJoOgY50DqSNZJhEwMDACkvNZLpune5AAAAAElFTkSuQmCC'); + background-repeat: no-repeat; + background-position: center 0; + + .pixel-ratio__1_25 & { + background-image: data-uri('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAARCAYAAADUryzEAAAAOklEQVR4nGJioBBQbsD58+f/wzjksAeBFyg1gGIw8F4YBAZ8/PgRnjDIYQ8CL1BqAMWAYhcAAgAA///oxiuTlVHD9AAAAABJRU5ErkJggg=='); + background-size: auto 14px; + background-position: center @scaled-one-px-value; + } + + .pixel-ratio__1_5 & { + background-image: data-uri('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAAXCAYAAADpwXTaAAAAPElEQVR4nGJioCIYxIadP3/+P4xDKXsQe3NkGEZVMHi9OYgN+/jxIzxLUMoexN4cGYZRFQxebwICAAD//4jOMt1BEBZ2AAAAAElFTkSuQmCC'); + background-size: auto 15px; + } + + .pixel-ratio__1_75 & { + background-image: data-uri('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAZCAYAAAA14t7uAAAAT0lEQVR4nGJioBEYNRgOWM6fP/8fxDA0NGQE0dTiD72gGHoG0wwMvaAYNZj2BrN8/PgRnLf5+fnBeZ1a/KEXFEPPYJqBoRcUNDMYEAAA//+u9y9xdUo+pAAAAABJRU5ErkJggg=='); + background-size: auto 14px; + } + + .pixel-ratio__2 & { + background-image: data-uri('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAcCAYAAAB/E6/TAAAAUElEQVR4nGJioBMYtYhswHL+/Pn/IIahoSEjiKYVf/gF3ahFgx8Mv6AbtWjUIjhg+fjxI7h05efnB5e2tOIPv6AbtWjwg+EXdHSzCBAAAP//nKY3dwCCOM8AAAAASUVORK5CYII='); + background-size: auto 14px; + } + + .pixel-ratio__2_5 & { + mask-image: data-uri('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMyIgaGVpZ2h0PSI3IiB2aWV3Qm94PSIwIDAgMTMgNyI+DQogICAgPHBhdGggZD0iTTAsNWwwLTNoMXYzSDB6IE0yLDVWMmgxdjNIMnogTTQsNVYyaDF2M0g0eiBNNiw1VjJoMXYzSDZ6IE04LDVWMmgxdjNIOHogTTEwLDVWMmgxdjNIMTB6IE0xMiw1VjJoMXYzSDEyeiIvPg0KPC9zdmc+DQo='); + background-color: @canvas-scroll-arrow; + + background-image: none; + mask-size: 13px 7px; + mask-position: center; + mask-repeat: no-repeat; + } } - background-position: center 0; .border-radius(2px); border: @scaled-one-px-value-ie solid @border-regular-control-ie; border: @scaled-one-px-value solid @border-regular-control; @@ -42,25 +71,50 @@ } } - &:hover, - .hover { + &:hover, .hover { + background-color: @background-toolbar-additional-ie; + background-color: @background-toolbar-additional; + .ps-scrollbar-x { &.always-visible-x { background-color: @canvas-scroll-thumb-hover-ie; background-color: @canvas-scroll-thumb-hover; - background-position: center -7px; + + div { + background-position: center -7px; + .pixel-ratio__1_75 & { + background-position: center -6px; + } + + .pixel-ratio__2_5 & { + background-color: @canvas-scroll-arrow-hover; + } + } } } } &.in-scrolling { + background-color: @background-toolbar-additional-ie; + background-color: @background-toolbar-additional; + .ps-scrollbar-x { &.always-visible-x { background-color: @canvas-scroll-thumb-hover-ie; background-color: @canvas-scroll-thumb-hover; border-color: @canvas-scroll-thumb-border-hover-ie; border-color: @canvas-scroll-thumb-border-hover; - background-position: center -7px; + + div { + background-position: center -7px; + .pixel-ratio__1_75 & { + background-position: center -6px; + } + + .pixel-ratio__2_5 & { + background-color: @canvas-scroll-arrow-hover; + } + } } } } @@ -87,27 +141,48 @@ background-color: @background-toolbar-ie; background-color: @background-toolbar; - .background-ximage('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAANCAQAAAAz1Zf0AAAAIUlEQVR42mNgAILz/0GQAQo+/gdBBqLAqE5ydH5k+sgEANHgUH2JtDRHAAAAAElFTkSuQmCC', - 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAaAgMAAADZOtQaAAAACVBMVEUAAADPz8/x8fFVrc9qAAAAAXRSTlMAQObYZgAAABZJREFUeNpjYAgNYOBaxcDEgAsMLXkA/sUJfm1m4l8AAAAASUVORK5CYII=', 14px); - .pixel-ratio__1_5 & { - //background-image: ~"url(@{common-image-const-path}/controls/Scroll_center@1.5x.png)"; - background-image: data-uri('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAATAgMAAAAG1X4lAAAACVBMVEUAAADPz8/x8fFVrc9qAAAAAXRSTlMAQObYZgAAABNJREFUeNpjYAx14FrFgAboLAgAVgQJB86JyMQAAAAASUVORK5CYII='); - background-size: 15px auto; - } - .pixel-ratio__1_25 & { - background-image: data-uri('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAQCAYAAADwMZRfAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAA7SURBVHgB7c87FQAgDEPRVkG11L+IaIkCWPgzc1hy5wx5bg2AYovMdDuQ3DYRcW3+GneUo5zXlDP1nApvZzAH1eXFfwAAAABJRU5ErkJggg=='); - background-size: 14px auto; - background-position: @scaled-one-px-value center; - } - .pixel-ratio__1_75 & { - background-image: data-uri('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAWCAYAAAA1vze2AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAABFSURBVHgB7dGxDQAgCERRcAFmYf8hmIUJtBZiYeXF3CvJVXyVIiJmvbm7ykFmtr2ZbfshdKH9mk2eYxM8bIKHTfD802QBUw8wE4bLVDsAAAAASUVORK5CYII='); - background-size: 14px auto; - background-position: @scaled-one-px-value center; + div { + display: block; + height: 100%; + + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAANCAQAAAAz1Zf0AAAAIUlEQVR42mNgAILz/0GQAQo+/gdBBqLAqE5ydH5k+sgEANHgUH2JtDRHAAAAAElFTkSuQmCC'); + background-repeat: no-repeat; + background-position: 0 center; + + .pixel-ratio__1_25 & { + background-image: data-uri('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAQCAYAAADwMZRfAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAA7SURBVHgB7c87FQAgDEPRVkG11L+IaIkCWPgzc1hy5wx5bg2AYovMdDuQ3DYRcW3+GneUo5zXlDP1nApvZzAH1eXFfwAAAABJRU5ErkJggg=='); + background-size: 14px auto; + background-position: @scaled-one-px-value center; + } + + .pixel-ratio__1_5 & { + background-image: data-uri('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAATAgMAAAAG1X4lAAAACVBMVEUAAADPz8/x8fFVrc9qAAAAAXRSTlMAQObYZgAAABNJREFUeNpjYAx14FrFgAboLAgAVgQJB86JyMQAAAAASUVORK5CYII='); + background-size: 15px auto; + } + + .pixel-ratio__1_75 & { + background-image: data-uri('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAWCAYAAAA1vze2AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAABFSURBVHgB7dGxDQAgCERRcAFmYf8hmIUJtBZiYeXF3CvJVXyVIiJmvbm7ykFmtr2ZbfshdKH9mk2eYxM8bIKHTfD802QBUw8wE4bLVDsAAAAASUVORK5CYII='); + background-size: 14px auto; + background-position: @scaled-one-px-value center; + } + + .pixel-ratio__2 & { + background-image: data-uri('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAaCAAAAACBP2NVAAAAAnRSTlMAAHaTzTgAAAAfSURBVHgBYwCB82DAAAUfwQDEwi1JERg4O0ftHLUTADyCkwGAuWTrAAAAAElFTkSuQmCC'); + background-size: 14px auto; + } + + .pixel-ratio__2_5 & { + mask-image: data-uri('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNyIgaGVpZ2h0PSIxMyIgdmlld0JveD0iMCAwIDcgMTMiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgICA8cGF0aCBkPSJNMiAwaDN2MUgyem0wIDJoM3YxSDJ6bTAgMmgzdjFIMnptMCAyaDN2MUgyem0wIDJoM3YxSDJ6bTAgMmgzdjFIMnptMCAyaDN2MUgyeiIgZmlsbD0iY3VycmVudENvbG9yIi8+Cjwvc3ZnPgo='); + background-color: @canvas-scroll-arrow; + + background-image: none; + mask-size: 7px 13px; + mask-position: center; + mask-repeat: no-repeat; + } } - background-repeat: no-repeat; - background-position: 0 center; .border-radius(2px); border: @scaled-one-px-value-ie solid @border-regular-control-ie; border: @scaled-one-px-value solid @border-regular-control; @@ -118,8 +193,7 @@ } } - &:hover, - .hover { + &:hover, .hover { background-color: @background-toolbar-additional-ie; background-color: @background-toolbar-additional; @@ -127,9 +201,16 @@ &.always-visible-y { background-color: @canvas-scroll-thumb-hover-ie; background-color: @canvas-scroll-thumb-hover; - background-position: -7px center; - .pixel-ratio__1_75 &{ - background-position: -6px center; + + div { + background-position: -7px center; + .pixel-ratio__1_75 & { + background-position: -6px center; + } + + .pixel-ratio__2_5 & { + background-color: @canvas-scroll-arrow-hover; + } } } } @@ -145,9 +226,12 @@ background-color: @canvas-scroll-thumb-hover; border-color: @canvas-scroll-thumb-border-hover-ie; border-color: @canvas-scroll-thumb-border-hover; - background-position: -7px center; - .pixel-ratio__1_75 &{ - background-position: -6px center; + + div { + background-position: -7px center; + .pixel-ratio__2_5 & { + background-color: @canvas-scroll-arrow-hover; + } } } } diff --git a/apps/common/main/resources/less/toolbar.less b/apps/common/main/resources/less/toolbar.less index 3b802ad862..acb7444a26 100644 --- a/apps/common/main/resources/less/toolbar.less +++ b/apps/common/main/resources/less/toolbar.less @@ -113,6 +113,9 @@ text-align: center; color: @text-toolbar-header-ie; color: @text-toolbar-header; + &:focus { + outline: none; + } } &.active { @@ -608,8 +611,8 @@ } svg.icon { - fill: @icon-toolbar-header-ie; - fill: @icon-toolbar-header; + fill: @icon-normal-ie; + fill: @icon-normal; } .caption { @@ -640,8 +643,8 @@ background-color: @highlight-button-pressed; svg.icon { - fill: @icon-toolbar-header-ie; - fill: @icon-toolbar-header; + fill: @icon-normal-pressed-ie; + fill: @icon-normal-pressed; } .caption { @@ -710,7 +713,7 @@ border-top-width: @underscore_height; content: ''; position: absolute; - margin-left: 6px; + .margin-left-6(); width: calc(100% - 12px); bottom: -@underscore_height; opacity: 0; diff --git a/apps/common/main/resources/less/variables.less b/apps/common/main/resources/less/variables.less index 16fa219303..5becb249a3 100644 --- a/apps/common/main/resources/less/variables.less +++ b/apps/common/main/resources/less/variables.less @@ -66,7 +66,9 @@ // ------------------------- .rtl-font { - --font-family-base-custom: system-ui, -apple-system, "Geeza Pro", "Segoe UI", "Traditional Arabic", "Noto Sans"; + &[applang=ar] { + --font-family-base-custom: system-ui, -apple-system, "Geeza Pro", "Segoe UI", "Traditional Arabic", "Noto Sans"; + } } @font-family-sans-serif: Arial, Helvetica, "Helvetica Neue", sans-serif; diff --git a/apps/common/mobile/utils/htmlutils.js b/apps/common/mobile/utils/htmlutils.js index f9dd4a5ea1..8872b105c7 100644 --- a/apps/common/mobile/utils/htmlutils.js +++ b/apps/common/mobile/utils/htmlutils.js @@ -28,7 +28,7 @@ function isLocalStorageAvailable() { let lang = (/(?:&|^)lang=([^&]+)&?/i).exec(window.location.search.substring(1)); lang = ((lang && lang[1]) || window.Common.Locale.defaultLang).split(/[\-\_]/)[0]; Common.Locale.currentLang = lang; - Common.Locale.isCurrentLangRtl = lang.lastIndexOf('ar', 0) === 0; + Common.Locale.isCurrentLangRtl = lang.lastIndexOf('ar', 0) === 0 || lang.lastIndexOf('he', 0) === 0; } { diff --git a/apps/documenteditor/embed/index.html b/apps/documenteditor/embed/index.html index ce1e731614..de0861cd36 100644 --- a/apps/documenteditor/embed/index.html +++ b/apps/documenteditor/embed/index.html @@ -80,7 +80,6 @@ background: #e2e2e2; overflow: hidden; position: relative; - -webkit-animation: startFlickerAnimation 2s infinite ease-in-out; -moz-animation: startFlickerAnimation 2s infinite ease-in-out; -o-animation: startFlickerAnimation 2s infinite ease-in-out; diff --git a/apps/documenteditor/embed/index.html.deploy b/apps/documenteditor/embed/index.html.deploy index 72a718eed6..84bbdb6a93 100644 --- a/apps/documenteditor/embed/index.html.deploy +++ b/apps/documenteditor/embed/index.html.deploy @@ -7,8 +7,6 @@ - -