CellEditor
This commit is contained in:
parent
c4002b57e3
commit
acbc4f5fd0
|
@ -8,6 +8,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- debug begin -->
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="../../../../sdkjs/cell/css/main.css"/>
|
||||
<link rel="stylesheet/less" type="text/css" href="resources/less/application.less" />
|
||||
<link rel="stylesheet/less" type="text/css" href="resources/less/celleditor.less" />
|
||||
|
@ -205,16 +206,18 @@
|
|||
</script>
|
||||
|
||||
<div class="viewer">
|
||||
<div class="ce-group-name">
|
||||
<input id="ce-cell-name" class="aslabel form-control" type="text">
|
||||
<div id="ce-cell-name-menu"></div>
|
||||
<button id="ce-func-label" type="button" class="btn small btn-toolbar"><i class="icon toolbar__icon btn-function"></i></button>
|
||||
</div>
|
||||
<div class="ce-group-expand">
|
||||
<button id="ce-btn-expand" type="button" class="btn"><span class="caret"> </span></button>
|
||||
</div>
|
||||
<div class="ce-group-content">
|
||||
<textarea id="ce-cell-content" class="form-control" spellcheck="false" rows="1" cols="20"></textarea>
|
||||
<div id="cell-editing-box">
|
||||
<div class="ce-group-name">
|
||||
<input id="ce-cell-name" class="aslabel form-control" type="text">
|
||||
<div id="ce-cell-name-menu" class="layout-item" style="height: 20px; top: 0px; border-left: none;"></div>
|
||||
<!-- <button id="ce-func-label" type="button" class="btn small btn-toolbar"><i class="icon toolbar__icon btn-function"></i></button>
|
||||
--></div>
|
||||
<div class="ce-group-expand">
|
||||
<button id="ce-btn-expand" type="button" class="btn"><span class="caret"> </span></button>
|
||||
</div>
|
||||
<div class="ce-group-content">
|
||||
<textarea id="ce-cell-content" class="form-control" spellcheck="false" rows="1" cols="20"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div id="editor_sdk" class="sdk-view" style="overflow: hidden;" tabindex="-1"></div>
|
||||
<ul id="worksheets" class="worksheet-list"></ul>
|
||||
|
@ -263,12 +266,16 @@
|
|||
<script type="text/javascript" src="../../../vendor/jquery/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="../../../vendor/jquery.browser/dist/jquery.browser.min.js"></script>
|
||||
<script type="text/javascript" src="../../../vendor/bootstrap/dist/js/bootstrap.js"></script>
|
||||
<script type="text/javascript" src="../../../vendor/underscore/underscore.js"></script>
|
||||
|
||||
|
||||
<script type="text/javascript" src="../../../vendor/sockjs/sockjs.min.js"></script>
|
||||
<script type="text/javascript" src="../../../vendor/underscore/underscore-min.js"></script>
|
||||
<script type="text/javascript" src="../../../vendor/xregexp/xregexp-all-min.js"></script>
|
||||
<script type="text/javascript" src="../../../vendor/jszip/jszip.min.js"></script>
|
||||
<script type="text/javascript" src="../../../vendor/jszip-utils/jszip-utils.min.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../../../vendor/backbone/backbone.js"></script>
|
||||
|
||||
<script src="../../../vendor/requirejs/require.js"></script>
|
||||
<script>
|
||||
|
@ -299,6 +306,9 @@
|
|||
<script type="text/javascript" src="js/CellEditorView.js"></script>
|
||||
<script type="text/javascript" src="js/CellEditorController.js"></script>-->
|
||||
|
||||
|
||||
<script type="text/javascript" src="../../unit-tests/common/main/lib/view/CellEditor.js"></script>
|
||||
<script type="text/javascript" src="../../unit-tests/common/main/lib/controller/CellEditor.js"></script>
|
||||
<script type="text/javascript" src="js/ApplicationView.js"></script>
|
||||
<script type="text/javascript" src="js/ApplicationController.js"></script>
|
||||
<script type="text/javascript" src="js/application.js"></script>
|
||||
|
|
|
@ -243,6 +243,11 @@ SSE.ApplicationController = new(function(){
|
|||
Common.Gateway.on('requestclose', onRequestClose);
|
||||
|
||||
|
||||
if(common.controller.CellEditor ) {
|
||||
common.controller.CellEditor.create();
|
||||
common.controller.CellEditor.setApi(api)
|
||||
common.controller.CellEditor.setMode(config);
|
||||
}
|
||||
|
||||
SSE.ApplicationView.tools.get('#idt-fullscreen')
|
||||
.on('click', function(){
|
||||
|
|
|
@ -30,45 +30,19 @@
|
|||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
*
|
||||
*/
|
||||
|
||||
if (SSE === undefined) {
|
||||
var SSE = {};
|
||||
}
|
||||
|
||||
SSE.ApplicationView = new(function(){
|
||||
|
||||
var $btnTools
|
||||
,$cellname
|
||||
,$btnexpand
|
||||
,$btnfunc
|
||||
,btnNamedRanges;
|
||||
|
||||
|
||||
|
||||
var $btnTools;
|
||||
// Initialize view
|
||||
|
||||
function createView(){
|
||||
|
||||
$cellname = $('#ce-cell-name');
|
||||
$btnexpand = $('#ce-btn-expand');
|
||||
$btnfunc = $('#ce-func-label');
|
||||
$btnfunc.addClass('disabled');
|
||||
/*btnNamedRanges = new Common.UI.Button({
|
||||
parentEl: $('#ce-cell-name-menu'),
|
||||
menu : new Common.UI.Menu({
|
||||
style : 'min-width: 70px;max-width:400px;',
|
||||
maxHeight: 250,
|
||||
items: [
|
||||
{ caption: this.textManager, value: 'manager' },
|
||||
{ caption: '--' }
|
||||
]
|
||||
})
|
||||
});
|
||||
this.btnNamedRanges.setVisible(false);
|
||||
this.btnNamedRanges.menu.setOffset(-81);*/
|
||||
|
||||
$btnTools = $('#box-tools button');
|
||||
|
||||
|
||||
$btnTools.addClass('dropdown-toggle').attr('data-toggle', 'dropdown').attr('aria-expanded', 'true');
|
||||
$btnTools.parent().append(
|
||||
'<ul class="dropdown-menu pull-right">' +
|
||||
|
@ -85,25 +59,13 @@ SSE.ApplicationView = new(function(){
|
|||
function getTools(name) {
|
||||
return $btnTools.parent().find(name);
|
||||
}
|
||||
function updateCellInfo(info) {
|
||||
if (info) {
|
||||
this.$cellname.val(typeof(info)=='string' ? info : info.asc_getName());
|
||||
}
|
||||
}
|
||||
function cellNameDisabled(disabled){
|
||||
(disabled) ? this.$cellname.attr('disabled', 'disabled') : this.$cellname.removeAttr('disabled');
|
||||
this.btnNamedRanges.setDisabled(disabled);
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
create: createView
|
||||
, tools: {
|
||||
get: getTools
|
||||
},
|
||||
cell: {
|
||||
updateInfo: updateCellInfo,
|
||||
nameDisabled: cellNameDisabled
|
||||
},
|
||||
|
||||
txtDownload: 'Download',
|
||||
txtPrint: 'Print',
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
@import "../../../../unit-tests/common/main/resources/less/colors-table-ie-fix.less";
|
||||
@import "../../../../unit-tests/common/main/resources/less/variables.less";
|
||||
@import "../../../../unit-tests/common/main/resources/less/colors-table.less";
|
||||
@import "../../../../unit-tests/common/main/resources/less/asc-mixins.less";
|
||||
@import "../../../../unit-tests/common/main/resources/less/buttons.less";
|
||||
#cell-editing-box {
|
||||
--pixel-ratio-factor: 1;
|
||||
border-bottom: solid @scaled-one-px-value-ie @border-toolbar-ie;
|
||||
border-bottom: solid @scaled-one-px-value @border-toolbar;
|
||||
border-left: solid @scaled-one-px-value-ie @border-toolbar-ie;
|
||||
|
@ -23,7 +24,7 @@
|
|||
#ce-cell-name {
|
||||
width: 100px;
|
||||
height: 19px;
|
||||
height: calc(19px + (1px - 1px/var(--pixel-ratio-factor,1)));
|
||||
//height: calc(19px + (1px - 1px/var(--pixel-ratio-factor,1)));
|
||||
padding: 0px 19px 0 4px;
|
||||
vertical-align: top;
|
||||
display: inline-block;
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
<div class="ce-group-name">
|
||||
<input id="ce-cell-name" class="aslabel form-control" type="text">
|
||||
<div id="ce-cell-name-menu"></div>
|
||||
<button id="ce-func-label" type="button" class="btn small btn-toolbar"><i class="icon toolbar__icon btn-function"></i></button>
|
||||
</div>
|
||||
<div class="ce-group-expand">
|
||||
<button id="ce-btn-expand" type="button" class="btn"><span class="caret"> </span></button>
|
||||
</div>
|
||||
<div class="ce-group-content">
|
||||
<textarea id="ce-cell-content" class="form-control" spellcheck="false" rows="1" cols="20"></textarea>
|
||||
</div>
|
1058
test/unit-tests/common/main/lib/component/Menu.js
Normal file
1058
test/unit-tests/common/main/lib/component/Menu.js
Normal file
File diff suppressed because it is too large
Load diff
394
test/unit-tests/common/main/lib/component/MenuItem.js
Normal file
394
test/unit-tests/common/main/lib/component/MenuItem.js
Normal file
|
@ -0,0 +1,394 @@
|
|||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2010-2019
|
||||
*
|
||||
* 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-12 Ernesta Birznieka-Upisha
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* MenuItem.js
|
||||
*
|
||||
* A base class for all menu items that require menu-related functionality such as click handling,
|
||||
* sub-menus, icons, etc.
|
||||
*
|
||||
* Created by Alexander Yuzhin on 1/27/14
|
||||
* Copyright (c) 2018 Ascensio System SIA. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Default template
|
||||
*
|
||||
* Simple menu item:
|
||||
* <li><a href="#">Caption</a></li>
|
||||
*
|
||||
* Separator:
|
||||
* <li class="divider"></li>
|
||||
*
|
||||
* Menu item with sub-menu:
|
||||
* <li class="dropdown-submenu">
|
||||
* <a href="#">Sub-menu item</a>
|
||||
* <ul class="dropdown-menu"></ul>
|
||||
* </li>
|
||||
*
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* new Common.UI.MenuItem({
|
||||
* caption: 'View Compact Toolbar',
|
||||
* checkable: true,
|
||||
* menu: {
|
||||
* items: [
|
||||
* { caption: 'Menu item 1', value: 'value-1' },
|
||||
* { caption: 'Menu item 2', value: 'value-2' },
|
||||
* new Common.UI.MenuItem({ caption: 'Menu item 3', value: 'value-3' })
|
||||
* ]
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* @property {Object} value
|
||||
*
|
||||
* @property {Common.UI.Menu} menu
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
if (Common === undefined)
|
||||
var Common = {};
|
||||
|
||||
define([
|
||||
'common/main/lib/component/BaseView',
|
||||
'common/main/lib/component/ToggleManager'
|
||||
], function () {
|
||||
'use strict';
|
||||
|
||||
Common.UI.MenuItem = Common.UI.BaseView.extend({
|
||||
options : {
|
||||
id : null,
|
||||
cls : '',
|
||||
style : '',
|
||||
hint : false,
|
||||
checkable : false,
|
||||
checked : false,
|
||||
allowDepress: false,
|
||||
disabled : false,
|
||||
value : null,
|
||||
toggleGroup : null,
|
||||
iconCls : '',
|
||||
menu : null,
|
||||
canFocused : true,
|
||||
dataHint : '',
|
||||
dataHintDirection: '',
|
||||
dataHintOffset: ''
|
||||
},
|
||||
|
||||
tagName : 'li',
|
||||
|
||||
template: _.template([
|
||||
'<a id="<%= id %>" style="<%= style %>" <% if(options.canFocused) { %> tabindex="-1" type="menuitem" <% }; if(!_.isUndefined(options.stopPropagation)) { %> data-stopPropagation="true" <% }; if(!_.isUndefined(options.dataHint)) { %> data-hint="<%= options.dataHint %>" <% }; if(!_.isUndefined(options.dataHintDirection)) { %> data-hint-direction="<%= options.dataHintDirection %>" <% }; if(!_.isUndefined(options.dataHintOffset)) { %> data-hint-offset="<%= options.dataHintOffset %>" <% }; %> >',
|
||||
'<% if (!_.isEmpty(iconCls)) { %>',
|
||||
'<span class="menu-item-icon <%= iconCls %>"></span>',
|
||||
'<% } %>',
|
||||
'<%= caption %>',
|
||||
'</a>'
|
||||
].join('')),
|
||||
|
||||
initialize : function(options) {
|
||||
Common.UI.BaseView.prototype.initialize.call(this, options);
|
||||
|
||||
var me = this;
|
||||
|
||||
this.id = me.options.id || Common.UI.getId();
|
||||
this.cls = me.options.cls;
|
||||
this.style = me.options.style;
|
||||
this.caption = me.options.caption;
|
||||
this.menu = me.options.menu || null;
|
||||
this.checkable = me.options.checkable;
|
||||
this.checked = me.options.checked;
|
||||
me.allowDepress = me.options.allowDepress;
|
||||
this.disabled = me.options.disabled;
|
||||
this.value = me.options.value;
|
||||
this.toggleGroup = me.options.toggleGroup;
|
||||
this.template = me.options.template || this.template;
|
||||
this.iconCls = me.options.iconCls;
|
||||
this.hint = me.options.hint;
|
||||
this.rendered = false;
|
||||
|
||||
if (this.menu !== null && !(this.menu instanceof Common.UI.Menu) && !(this.menu instanceof Common.UI.MenuSimple)) {
|
||||
this.menu = new Common.UI.Menu(_.extend({}, me.options.menu));
|
||||
}
|
||||
|
||||
if (me.options.el)
|
||||
this.render();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var me = this,
|
||||
el = me.$el || $(this.el);
|
||||
|
||||
me.trigger('render:before', me);
|
||||
|
||||
if (me.caption === '--') {
|
||||
el.addClass('divider');
|
||||
} else {
|
||||
if (!this.rendered) {
|
||||
el.off('click');
|
||||
Common.UI.ToggleManager.unregister(me);
|
||||
|
||||
el.html(this.template({
|
||||
id : me.id,
|
||||
caption : me.caption,
|
||||
iconCls : me.iconCls,
|
||||
style : me.style,
|
||||
options : me.options
|
||||
}));
|
||||
|
||||
if (me.menu) {
|
||||
el.addClass('dropdown-submenu');
|
||||
|
||||
me.menu.render(el);
|
||||
el.mouseenter(_.bind(me.menu.alignPosition, me.menu));
|
||||
// el.focusin(_.bind(me.onFocusItem, me));
|
||||
el.focusout(_.bind(me.onBlurItem, me));
|
||||
el.hover(
|
||||
_.bind(me.onHoverItem, me),
|
||||
_.bind(me.onUnHoverItem, me)
|
||||
);
|
||||
}
|
||||
|
||||
var firstChild = el.children(':first');
|
||||
|
||||
if (this.checkable && firstChild) {
|
||||
firstChild.toggleClass('checkable', this.checkable);
|
||||
firstChild.toggleClass('no-checkmark', this.options.checkmark===false);
|
||||
firstChild.toggleClass('checked', this.checked);
|
||||
if (!_.isEmpty(this.iconCls)) {
|
||||
firstChild.css('background-image', 'none');
|
||||
}
|
||||
}
|
||||
|
||||
if (me.options.hint) {
|
||||
el.attr('data-toggle', 'tooltip');
|
||||
el.tooltip({
|
||||
title : me.options.hint,
|
||||
placement : me.options.hintAnchor||function(tip, element) {
|
||||
var pos = this.getPosition(),
|
||||
actualWidth = tip.offsetWidth,
|
||||
actualHeight = tip.offsetHeight,
|
||||
innerWidth = Common.Utils.innerWidth(),
|
||||
innerHeight = Common.Utils.innerHeight();
|
||||
var top = pos.top,
|
||||
left = pos.left + pos.width + 2;
|
||||
if (top + actualHeight > innerHeight) {
|
||||
top = innerHeight - actualHeight - 2;
|
||||
}
|
||||
if (left + actualWidth > innerWidth) {
|
||||
left = pos.left - actualWidth - 2;
|
||||
}
|
||||
$(tip).offset({top: top,left: left}).addClass('in');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (this.disabled)
|
||||
el.toggleClass('disabled', this.disabled);
|
||||
|
||||
el.on('click', _.bind(this.onItemClick, this));
|
||||
el.on('mousedown', _.bind(this.onItemMouseDown, this));
|
||||
|
||||
Common.UI.ToggleManager.register(me);
|
||||
}
|
||||
}
|
||||
|
||||
me.cmpEl = el;
|
||||
me.rendered = true;
|
||||
|
||||
me.trigger('render:after', me);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
setCaption: function(caption, noencoding) {
|
||||
this.caption = caption;
|
||||
|
||||
if (this.rendered)
|
||||
this.cmpEl.find('a').contents().last()[0].textContent = (noencoding) ? caption : Common.Utils.String.htmlEncode(caption);
|
||||
},
|
||||
|
||||
setIconCls: function(iconCls) {
|
||||
if (this.rendered && !_.isEmpty(this.iconCls)) {
|
||||
var firstChild = this.cmpEl.children(':first');
|
||||
if (firstChild) {
|
||||
firstChild.find('.menu-item-icon').removeClass(this.iconCls).addClass(iconCls);
|
||||
}
|
||||
}
|
||||
this.iconCls = iconCls;
|
||||
},
|
||||
|
||||
setChecked: function(check, suppressEvent) {
|
||||
this.toggle(check, suppressEvent);
|
||||
},
|
||||
|
||||
isChecked: function() {
|
||||
return this.checked;
|
||||
},
|
||||
|
||||
setDisabled: function(disabled) {
|
||||
this.disabled = !!disabled;
|
||||
|
||||
if (this.rendered)
|
||||
this.cmpEl.toggleClass('disabled', this.disabled);
|
||||
},
|
||||
|
||||
isDisabled: function() {
|
||||
return this.disabled;
|
||||
},
|
||||
|
||||
toggle: function(toggle, suppressEvent) {
|
||||
var state = toggle === undefined ? !this.checked : !!toggle;
|
||||
|
||||
if (this.checkable) {
|
||||
this.checked = state;
|
||||
|
||||
if (this.rendered) {
|
||||
var firstChild = this.cmpEl.children(':first');
|
||||
|
||||
if (firstChild) {
|
||||
firstChild.toggleClass('checked', this.checked);
|
||||
if (!_.isEmpty(this.iconCls)) {
|
||||
firstChild.css('background-image', 'none');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!suppressEvent)
|
||||
this.trigger('toggle', this, state);
|
||||
}
|
||||
},
|
||||
|
||||
onItemMouseDown: function(e) {
|
||||
if (e.which != 1) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
return false;
|
||||
}
|
||||
e.stopPropagation();
|
||||
},
|
||||
|
||||
onItemClick: function(e) {
|
||||
if (e.which != 1 && (e.which !== undefined || this.menu))
|
||||
return false;
|
||||
|
||||
if (!this.disabled && (this.allowDepress || !(this.checked && this.toggleGroup)) && !this.menu)
|
||||
this.setChecked(!this.checked);
|
||||
|
||||
if (this.menu) {
|
||||
if (e.target.id == this.id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.menu.isOver)
|
||||
this.cmpEl.removeClass('over');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.disabled) {
|
||||
this.trigger('click', this, e);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
onHoverItem: function(e) {
|
||||
this._doHover(e);
|
||||
// $('a', this.cmpEl).focus();
|
||||
},
|
||||
|
||||
onUnHoverItem: function(e) {
|
||||
this._doUnHover(e);
|
||||
// $('a', this.cmpEl).blur();
|
||||
},
|
||||
|
||||
// onFocusItem: function(e) {
|
||||
// this._doHover(e);
|
||||
// },
|
||||
|
||||
onBlurItem: function(e) {
|
||||
this._doUnHover(e);
|
||||
},
|
||||
|
||||
_doHover: function(e) {
|
||||
var me = this;
|
||||
|
||||
if (me.menu && !me.disabled) {
|
||||
clearTimeout(me.hideMenuTimer);
|
||||
|
||||
me.cmpEl.trigger('show.bs.dropdown');
|
||||
me.expandMenuTimer = _.delay(function(){
|
||||
me.cmpEl.addClass('over');
|
||||
me.cmpEl.trigger('shown.bs.dropdown');
|
||||
}, 200);
|
||||
}
|
||||
},
|
||||
|
||||
_doUnHover: function(e) {
|
||||
var me = this;
|
||||
if (me.cmpEl.hasClass('dropdown-submenu') && me.cmpEl.hasClass('over') &&
|
||||
(e && e.relatedTarget && me.cmpEl.find(e.relatedTarget).length>0 || me.cmpEl.hasClass('focused-submenu'))) {
|
||||
// When focus go from menuItem to it's submenu don't hide this submenu
|
||||
me.cmpEl.removeClass('focused-submenu');
|
||||
return;
|
||||
}
|
||||
if (me.menu && !me.disabled) {
|
||||
clearTimeout(me.expandMenuTimer);
|
||||
|
||||
me.hideMenuTimer = _.delay(function(){
|
||||
if (!me.menu.isOver)
|
||||
me.cmpEl.removeClass('over');
|
||||
}, 200);
|
||||
|
||||
if (e && e.type !== 'focusout') { // when mouseleave from clicked menu item with submenu
|
||||
var focused = me.cmpEl.children(':focus');
|
||||
if (focused.length>0) {
|
||||
focused.blur();
|
||||
me.cmpEl.closest('ul').focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Common.UI.MenuItemSeparator = function(options) {
|
||||
options = options || {};
|
||||
options.caption = '--';
|
||||
return new Common.UI.MenuItem(options);
|
||||
};
|
||||
});
|
180
test/unit-tests/common/main/lib/component/Scroller.js
Normal file
180
test/unit-tests/common/main/lib/component/Scroller.js
Normal file
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2010-2019
|
||||
*
|
||||
* 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-12 Ernesta Birznieka-Upisha
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* Scroller.js
|
||||
*
|
||||
* Created by Alexander Yuzhin on 3/14/14
|
||||
* Copyright (c) 2018 Ascensio System SIA. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
if (Common === undefined)
|
||||
var Common = {};
|
||||
|
||||
define([
|
||||
'vendor/perfect-scrollbar/src/jquery.mousewheel',
|
||||
'test/unit-tests/common/main/lib/mods/perfectscrollbar',
|
||||
'test/unit-tests/common/main/lib/component/BaseView'
|
||||
], function () { 'use strict';
|
||||
|
||||
Common.UI.Scroller = (function(){
|
||||
var mouseCapture;
|
||||
|
||||
return _.extend(Common.UI.BaseView.extend({
|
||||
options: {
|
||||
wheelSpeed : 20,
|
||||
wheelPropagation : false,
|
||||
minScrollbarLength : null,
|
||||
useBothWheelAxes : false,
|
||||
useKeyboard : true,
|
||||
suppressScrollX : false,
|
||||
suppressScrollY : false,
|
||||
scrollXMarginOffset : 5,
|
||||
scrollYMarginOffset : 5,
|
||||
includePadding : true,
|
||||
includeMargin : true,
|
||||
alwaysVisibleX : false,
|
||||
alwaysVisibleY : false
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
Common.UI.BaseView.prototype.initialize.call(this, options);
|
||||
|
||||
if (this.options.el) {
|
||||
this.render();
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var me = this;
|
||||
|
||||
me.cmpEl = me.$el || $(this.el);
|
||||
|
||||
if (!me.rendered) {
|
||||
me.cmpEl.perfectScrollbar(_.extend({}, me.options));
|
||||
me.rendered = true;
|
||||
|
||||
this.setAlwaysVisibleX(me.options.alwaysVisibleX);
|
||||
this.setAlwaysVisibleY(me.options.alwaysVisibleY);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
remove: function() {
|
||||
this.destroy();
|
||||
Backbone.View.prototype.remove.call(this);
|
||||
},
|
||||
|
||||
update: function(config) {
|
||||
var options = this.options;
|
||||
if (config) {
|
||||
this.destroy();
|
||||
options = _.extend(this.options, config);
|
||||
this.cmpEl.perfectScrollbar(options);
|
||||
} else {
|
||||
this.cmpEl.perfectScrollbar('update');
|
||||
}
|
||||
|
||||
this.setAlwaysVisibleX(options.alwaysVisibleX);
|
||||
this.setAlwaysVisibleY(options.alwaysVisibleY);
|
||||
|
||||
// Emulate capture scroller
|
||||
var mouseDownHandler = function(e) {
|
||||
mouseCapture = true;
|
||||
|
||||
var upHandler = function(e) {
|
||||
$(document).unbind('mouseup', upHandler);
|
||||
_.delay(function() {
|
||||
mouseCapture = false;
|
||||
}, 10);
|
||||
};
|
||||
|
||||
$(document).mouseup(upHandler);
|
||||
};
|
||||
|
||||
$('.ps-scrollbar-x-rail, .ps-scrollbar-y-rail, .ps-scrollbar-x, .ps-scrollbar-y', this.cmpEl)
|
||||
.off('mousedown', mouseDownHandler).on('mousedown', mouseDownHandler);
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.cmpEl.perfectScrollbar('destroy');
|
||||
},
|
||||
|
||||
scrollLeft: function(pos) {
|
||||
this.cmpEl.scrollLeft(pos);
|
||||
this.update();
|
||||
},
|
||||
|
||||
scrollTop: function(pos) {
|
||||
this.cmpEl.scrollTop(pos);
|
||||
this.update();
|
||||
},
|
||||
|
||||
getScrollTop: function () {
|
||||
return this.cmpEl.scrollTop();
|
||||
},
|
||||
|
||||
getScrollLeft: function () {
|
||||
return this.cmpEl.scrollLeft();
|
||||
},
|
||||
setAlwaysVisibleX: function(flag) {
|
||||
if (flag) {
|
||||
$(this.el).find('.ps-scrollbar-x-rail').addClass('always-visible-x');
|
||||
$(this.el).find('.ps-scrollbar-x').addClass('always-visible-x');
|
||||
} else {
|
||||
$(this.el).find('.ps-scrollbar-x-rail').removeClass('always-visible-x');
|
||||
$(this.el).find('.ps-scrollbar-x').addClass('always-visible-x');
|
||||
}
|
||||
},
|
||||
setAlwaysVisibleY: function(flag) {
|
||||
if (flag) {
|
||||
$(this.el).find('.ps-scrollbar-y-rail').addClass('always-visible-y');
|
||||
$(this.el).find('.ps-scrollbar-y').addClass('always-visible-y');
|
||||
} else {
|
||||
$(this.el).find('.ps-scrollbar-y-rail').removeClass('always-visible-y');
|
||||
$(this.el).find('.ps-scrollbar-y').addClass('always-visible-y');
|
||||
}
|
||||
},
|
||||
|
||||
isVisible: function() {
|
||||
return $(this.el).find('.ps-scrollbar-y-rail').is(':visible');
|
||||
}
|
||||
|
||||
}), {
|
||||
isMouseCapture: function() {
|
||||
return mouseCapture
|
||||
}
|
||||
})
|
||||
})();
|
||||
});
|
236
test/unit-tests/common/main/lib/controller/CellEditor.js
Normal file
236
test/unit-tests/common/main/lib/controller/CellEditor.js
Normal file
|
@ -0,0 +1,236 @@
|
|||
!window.common && (window.common = {});
|
||||
!common.controller && (common.controller = {});
|
||||
Common.UI = _.extend(Common.UI || {}, {
|
||||
Keys : {
|
||||
BACKSPACE: 8,
|
||||
TAB: 9,
|
||||
RETURN: 13,
|
||||
SHIFT: 16,
|
||||
CTRL: 17,
|
||||
ALT: 18,
|
||||
ESC: 27,
|
||||
LEFT: 37,
|
||||
UP: 38,
|
||||
RIGHT: 39,
|
||||
DOWN: 40,
|
||||
DELETE: 46,
|
||||
HOME: 36,
|
||||
END: 35,
|
||||
SPACE: 32,
|
||||
PAGEUP: 33,
|
||||
PAGEDOWN: 34,
|
||||
INSERT: 45,
|
||||
EQUALITY_FF:61,
|
||||
NUM_PLUS: 107,
|
||||
NUM_MINUS: 109,
|
||||
F1: 112,
|
||||
F2: 113,
|
||||
F3: 114,
|
||||
F4: 115,
|
||||
F5: 116,
|
||||
F6: 117,
|
||||
F7: 118,
|
||||
F8: 119,
|
||||
F9: 120,
|
||||
F10: 121,
|
||||
F11: 122,
|
||||
F12: 123,
|
||||
MINUS_FF: 173,
|
||||
EQUALITY: 187,
|
||||
MINUS: 189
|
||||
}});
|
||||
common.controller.CellEditor = new(function(){
|
||||
var me,
|
||||
api,
|
||||
editor,
|
||||
mode,
|
||||
created=false;
|
||||
|
||||
function onCellName(e){
|
||||
if (e.keyCode == Common.UI.Keys.RETURN){
|
||||
var name = editor.$cellname.val();
|
||||
if (name && name.length) {
|
||||
api.asc_findCell(name);
|
||||
}
|
||||
//Common.NotificationCenter.trigger('edit:complete', editor);
|
||||
}
|
||||
}
|
||||
function onKeyupCellEditor(e) {
|
||||
if(e.keyCode == Common.UI.Keys.RETURN && !e.altKey){
|
||||
api.isCEditorFocused = 'clear';
|
||||
}
|
||||
}
|
||||
function onBlurCellEditor() {
|
||||
if (api.isCEditorFocused == 'clear')
|
||||
api.isCEditorFocused = undefined;
|
||||
else if (api.isCellEdited)
|
||||
api.isCEditorFocused = true;
|
||||
}
|
||||
function expandEditorField() {
|
||||
if ( Math.floor(editor.$el.height()) > 19) {
|
||||
editor.keep_height = editor.$el.height();
|
||||
editor.$el.height(19);
|
||||
editor.$el.removeClass('expanded');
|
||||
editor.$btnexpand['removeClass']('btn-collapse');
|
||||
common.localStorage.setBool('sse-celleditor-expand', false);
|
||||
} else {
|
||||
editor.$el.height(editor.keep_height);
|
||||
editor.$el.addClass('expanded');
|
||||
editor.$btnexpand['addClass']('btn-collapse');
|
||||
common.localStorage.setBool('sse-celleditor-expand', true);
|
||||
}
|
||||
|
||||
//Common.NotificationCenter.trigger('layout:changed', 'celleditor');
|
||||
//Common.NotificationCenter.trigger('edit:complete', editor, {restorefocus:true});
|
||||
}
|
||||
function events() {
|
||||
editor.$el.find('#ce-cell-name').on( 'keyup', onCellName);
|
||||
editor.$el.find('textarea#ce-cell-content').on( 'keyup', onKeyupCellEditor);
|
||||
editor.$el.find('textarea#ce-cell-content').on('blur', onBlurCellEditor);
|
||||
editor.$el.find('button#ce-btn-expand').on('click', expandEditorField);/*,
|
||||
/*'click button#ce-func-label': onInsertFunction*/
|
||||
}
|
||||
function createController() {
|
||||
me = this;
|
||||
if (created)
|
||||
return me;
|
||||
|
||||
|
||||
created = true;
|
||||
onLaunch();
|
||||
return me;
|
||||
}
|
||||
function onLayoutResize(o, r) {
|
||||
if (r == 'cell:edit') {
|
||||
if (Math.floor(editor.$el.height()) > 19) {
|
||||
if (!editor.$btnexpand.hasClass('btn-collapse')) {
|
||||
editor.$el.addClass('expanded');
|
||||
editor.$btnexpand['addClass']('btn-collapse');
|
||||
}
|
||||
|
||||
o && common.localStorage.setItem('sse-celleditor-height', editor.$el.height());
|
||||
o && common.localStorage.setBool('sse-celleditor-expand', true);
|
||||
} else {
|
||||
editor.$el.removeClass('expanded');
|
||||
editor.$btnexpand['removeClass']('btn-collapse');
|
||||
o && common.localStorage.setBool('sse-celleditor-expand', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
function onLaunch(){
|
||||
common.view.CellEditor.create();
|
||||
editor = common.view.CellEditor;
|
||||
//me.bindViewEvents(editor, events);
|
||||
events();
|
||||
|
||||
editor.$el.parent().find('.after').css({zIndex: '4'}); // for spreadsheets - bug 23127
|
||||
|
||||
var val = common.localStorage.getItem('sse-celleditor-height');
|
||||
editor.keep_height = (val!==null && parseInt(val)>0) ? parseInt(val) : 74;
|
||||
if (common.localStorage.getBool('sse-celleditor-expand')) {
|
||||
editor.$el.height(editor.keep_height);
|
||||
onLayoutResize(undefined, 'cell:edit');
|
||||
}
|
||||
|
||||
/* editor.btnNamedRanges.menu.on('item:click', _.bind(this.onNamedRangesMenu, this))
|
||||
.on('show:before', _.bind(this.onNameBeforeShow, this));*/
|
||||
this.namedrange_locked = false;
|
||||
}
|
||||
|
||||
function onApiCellSelection(info){
|
||||
editor.cell.updateInfo(info);
|
||||
}
|
||||
function onApiEditCell(state) {
|
||||
if (this.viewmode) return; // signed file
|
||||
|
||||
if (state == Asc.c_oAscCellEditorState.editStart){
|
||||
api.isCellEdited = true;
|
||||
editor.cell.nameDisabled(true);
|
||||
} else if (state == Asc.c_oAscCellEditorState.editInCell) {
|
||||
api.isCEditorFocused = 'clear';
|
||||
} else if (state == Asc.c_oAscCellEditorState.editEnd) {
|
||||
api.isCellEdited = false;
|
||||
api.isCEditorFocused = false;
|
||||
editor.cell.nameDisabled(false);
|
||||
}
|
||||
editor.$btnfunc.toggleClass('disabled', state == Asc.c_oAscCellEditorState.editText);
|
||||
}
|
||||
function onLockDefNameManager(state) {
|
||||
this.namedrange_locked = (state == Asc.c_oAscDefinedNameReason.LockDefNameManager);
|
||||
}
|
||||
function onInputKeyDown(e) {
|
||||
if (Common.UI.Keys.UP === e.keyCode || Common.UI.Keys.DOWN === e.keyCode ||
|
||||
Common.UI.Keys.TAB === e.keyCode || Common.UI.Keys.RETURN === e.keyCode || Common.UI.Keys.ESC === e.keyCode ||
|
||||
Common.UI.Keys.LEFT === e.keyCode || Common.UI.Keys.RIGHT === e.keyCode) {
|
||||
var menu = $('#menu-formula-selection'); // for formula menu
|
||||
if (menu.hasClass('open'))
|
||||
menu.find('.dropdown-menu').trigger('keydown', e);
|
||||
}
|
||||
}
|
||||
function onApiDisconnect() {
|
||||
mode.isEdit = false;
|
||||
|
||||
var controller = this.getApplication().getController('FormulaDialog');
|
||||
if (controller) {
|
||||
controller.hideDialog();
|
||||
}
|
||||
|
||||
if (!mode.isEdit) {
|
||||
$('#ce-func-label', editor.$el).addClass('disabled');
|
||||
editor.btnNamedRanges.setVisible(false);
|
||||
}
|
||||
}
|
||||
function onCellsRange(status) {
|
||||
editor.cell.nameDisabled(status != Asc.c_oAscSelectionDialogType.None);
|
||||
editor.$btnfunc.toggleClass('disabled', status != Asc.c_oAscSelectionDialogType.None);
|
||||
}
|
||||
function setApi(apiF){
|
||||
api=apiF;
|
||||
|
||||
api.isCEditorFocused = false;
|
||||
api.asc_registerCallback('asc_onSelectionNameChanged', onApiCellSelection);
|
||||
api.asc_registerCallback('asc_onEditCell', onApiEditCell);
|
||||
api.asc_registerCallback('asc_onCoAuthoringDisconnect', onApiDisconnect);
|
||||
//Common.NotificationCenter.on('api:disconnect', onApiDisconnect);
|
||||
//Common.NotificationCenter.on('cells:range', onCellsRange);
|
||||
api.asc_registerCallback('asc_onLockDefNameManager', onLockDefNameManager);
|
||||
api.asc_registerCallback('asc_onInputKeyDown', onInputKeyDown);
|
||||
}
|
||||
function onApiSelectionChanged(info) {
|
||||
if (this.viewmode) return; // signed file
|
||||
|
||||
var seltype = info.asc_getSelectionType(),
|
||||
coauth_disable = (!mode.isEditMailMerge && !mode.isEditDiagram) ? (info.asc_getLocked() === true || info.asc_getLockedTable() === true || info.asc_getLockedPivotTable()===true) : false;
|
||||
|
||||
var is_chart_text = seltype == Asc.c_oAscSelectionType.RangeChartText,
|
||||
is_chart = seltype == Asc.c_oAscSelectionType.RangeChart,
|
||||
is_shape_text = seltype == Asc.c_oAscSelectionType.RangeShapeText,
|
||||
is_shape = seltype == Asc.c_oAscSelectionType.RangeShape,
|
||||
is_image = seltype == Asc.c_oAscSelectionType.RangeImage || seltype == Asc.c_oAscSelectionType.RangeSlicer,
|
||||
is_mode_2 = is_shape_text || is_shape || is_chart_text || is_chart;
|
||||
|
||||
editor.$btnfunc.toggleClass('disabled', is_image || is_mode_2 || coauth_disable);
|
||||
}
|
||||
function setMode(modeF) {
|
||||
mode = modeF;
|
||||
|
||||
editor.$btnfunc[mode.isEdit?'removeClass':'addClass']('disabled');
|
||||
//editor.btnNamedRanges.setVisible(mode.isEdit && !mode.isEditDiagram && !mode.isEditMailMerge);
|
||||
|
||||
if ( mode.isEdit ) {
|
||||
api.asc_registerCallback('asc_onSelectionChanged', onApiSelectionChanged);
|
||||
}
|
||||
}
|
||||
function setPreviewMode(mode) {
|
||||
if (this.viewmode === mode) return;
|
||||
this.viewmode = mode;
|
||||
editor.$btnfunc[!mode && mode.isEdit?'removeClass':'addClass']('disabled');
|
||||
editor.cell.nameDisabled(mode && !(mode.isEdit && !mode.isEditDiagram && !mode.isEditMailMerge));
|
||||
}
|
||||
return {
|
||||
create: createController,
|
||||
setApi: setApi,
|
||||
setMode: setMode
|
||||
}
|
||||
|
||||
})();
|
|
@ -55,10 +55,9 @@
|
|||
|
||||
if (Common === undefined)
|
||||
var Common = {};
|
||||
|
||||
define([
|
||||
'backbone'
|
||||
], function (Backbone) {
|
||||
/*if (Backbone === undefined)
|
||||
var Backbone = ;*/
|
||||
Common.NotificationCenter=new( function (Backbone) {
|
||||
'use strict';
|
||||
|
||||
var NotificationCenter = function(){};
|
||||
|
@ -75,4 +74,4 @@ define([
|
|||
else {
|
||||
throw ('Native Common.NotificationCenter instance already defined.')
|
||||
}
|
||||
});
|
||||
})();
|
|
@ -1,4 +1,4 @@
|
|||
(function(){
|
||||
Backbone=new(function(){
|
||||
var resolveNamespace = function(className, root) {
|
||||
var parts = className.split('.'),
|
||||
current = root || window;
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
# HG changeset patch
|
||||
# User Alexey Musinov
|
||||
# Date 1415710176 -10800
|
||||
# Tue Nov 11 15:49:36 2014 +0300
|
||||
# Node ID 784fe548cf4cbfc0a6c96b295ae83c551ce22166
|
||||
# Parent 07b43d47bcf8afe8a2dabc8a0bce8c7dab3bd498
|
||||
[Common] â perfect-scrollbar - ñêðîëèíã íàä 'textarea' è 'input' ïåðåäàåòñÿ â ýòè ýëåìåíòû.
|
||||
|
||||
diff -r 07b43d47bcf8 -r 784fe548cf4c apps/common/main/lib/mods/perfect-scrollbar.js
|
||||
--- a/apps/common/main/lib/mods/perfect-scrollbar.js Mon Nov 10 19:37:33 2014 +0300
|
||||
+++ b/apps/common/main/lib/mods/perfect-scrollbar.js Tue Nov 11 15:49:36 2014 +0300
|
||||
@@ -313,6 +313,22 @@
|
||||
var deltaX = e.deltaX * e.deltaFactor || deprecatedDeltaX,
|
||||
deltaY = e.deltaY * e.deltaFactor || deprecatedDeltaY;
|
||||
|
||||
+ if (e && e.target && (e.target.type === 'textarea' || e.target.type === 'input')) {
|
||||
+ e.stopImmediatePropagation();
|
||||
+ e.preventDefault();
|
||||
+
|
||||
+ var scroll = $(e.target).scrollTop(), wheelDeltaY = 0;
|
||||
+ if (e.originalEvent) {
|
||||
+ if (e.originalEvent.wheelDelta) wheelDeltaY = e.originalEvent.wheelDelta / -40;
|
||||
+ if (e.originalEvent.deltaY) wheelDeltaY = e.originalEvent.deltaY;
|
||||
+ if (e.originalEvent.detail) wheelDeltaY = e.originalEvent.detail;
|
||||
+ }
|
||||
+
|
||||
+ $(e.target).scrollTop(scroll - wheelDeltaY);
|
||||
+
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
shouldPrevent = false;
|
||||
if (!settings.useBothWheelAxes) {
|
||||
// deltaX will only be used for horizontal scrolling and deltaY will
|
|
@ -0,0 +1,48 @@
|
|||
diff -r 5047272bb302 apps/common/main/lib/mods/perfect-scrollbar.js
|
||||
--- a/apps/common/main/lib/mods/perfect-scrollbar.js Fri Sep 12 18:17:33 2014 +0400
|
||||
+++ b/apps/common/main/lib/mods/perfect-scrollbar.js Fri Sep 12 18:18:56 2014 +0400
|
||||
@@ -146,7 +146,12 @@
|
||||
|
||||
var updateScrollbarCss = function () {
|
||||
$scrollbarXRail.css({left: $this.scrollLeft(), bottom: scrollbarXBottom - $this.scrollTop(), width: containerWidth, display: scrollbarXActive ? "inherit": "none"});
|
||||
- $scrollbarYRail.css({top: $this.scrollTop(), right: scrollbarYRight - $this.scrollLeft(), height: containerHeight, display: scrollbarYActive ? "inherit": "none"});
|
||||
+
|
||||
+ if ($scrollbarYRail.hasClass('in-scrolling'))
|
||||
+ $scrollbarYRail.css({/*top: $this.scrollTop(),*/ right: scrollbarYRight - $this.scrollLeft(), height: containerHeight, display: scrollbarYActive ? "inherit": "none"});
|
||||
+ else
|
||||
+ $scrollbarYRail.css({top: $this.scrollTop(), right: scrollbarYRight - $this.scrollLeft(), height: containerHeight, display: scrollbarYActive ? "inherit": "none"});
|
||||
+
|
||||
$scrollbarX.css({left: scrollbarXLeft, width: scrollbarXWidth});
|
||||
$scrollbarY.css({top: scrollbarYTop, height: scrollbarYHeight});
|
||||
};
|
||||
@@ -229,6 +234,15 @@
|
||||
currentPageY = e.pageY;
|
||||
currentTop = $scrollbarY.position().top;
|
||||
$scrollbarYRail.addClass('in-scrolling');
|
||||
+
|
||||
+ var padding = parseInt($scrollbarYRail.offsetParent().css('padding-top'));
|
||||
+ var rect = $scrollbarYRail[0].getBoundingClientRect();
|
||||
+ $scrollbarYRail.css({
|
||||
+ position: 'fixed',
|
||||
+ left: rect.left,
|
||||
+ top: rect.top - padding
|
||||
+ });
|
||||
+
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
@@ -244,6 +258,14 @@
|
||||
$(document).bind('mouseup' + eventClassName, function (e) {
|
||||
if ($scrollbarYRail.hasClass('in-scrolling')) {
|
||||
$scrollbarYRail.removeClass('in-scrolling');
|
||||
+
|
||||
+ $scrollbarYRail.css({
|
||||
+ position: '',
|
||||
+ left: '',
|
||||
+ top: ''
|
||||
+ });
|
||||
+
|
||||
+ updateScrollbarCss();
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
diff -r daaf445d707b apps/common/main/lib/mods/perfect-scrollbar.js
|
||||
--- a/apps/common/main/lib/mods/perfect-scrollbar.js Mon Jun 15 15:25:53 2015 +0300
|
||||
+++ b/apps/common/main/lib/mods/perfect-scrollbar.js Thu Jun 18 13:29:36 2015 +0300
|
||||
// change thumb event
|
||||
@@ -197,6 +197,10 @@
|
||||
}
|
||||
|
||||
updateScrollbarCss();
|
||||
+
|
||||
+ if (settings.onChange) {
|
||||
+ settings.onChange(this);
|
||||
+ }
|
||||
};
|
||||
|
||||
var bindMouseScrollXHandler = function () {
|
|
@ -0,0 +1,103 @@
|
|||
diff -r c7981f4f7e09 apps/common/main/lib/mods/perfect-scrollbar.js
|
||||
--- a/apps/common/main/lib/mods/perfect-scrollbar.js Tue Oct 07 11:32:00 2014 +0400
|
||||
+++ b/apps/common/main/lib/mods/perfect-scrollbar.js Wed Oct 08 11:37:27 2014 +0400
|
||||
// Use margins of scrollbarYRail when calculate scrollbarYRail height (scrollbarYRailHeight) and top position
|
||||
@@ -28,7 +28,8 @@
|
||||
suppressScrollY: false,
|
||||
scrollXMarginOffset: 0,
|
||||
scrollYMarginOffset: 0,
|
||||
- includePadding: false
|
||||
+ includePadding: false,
|
||||
+ includeMargin: true
|
||||
};
|
||||
|
||||
var getEventClassName = (function () {
|
||||
@@ -97,11 +98,12 @@
|
||||
scrollbarYHeight,
|
||||
scrollbarYTop,
|
||||
scrollbarYRight = parseInt($scrollbarYRail.css('right'), 10),
|
||||
+ scrollbarYRailHeight,
|
||||
eventClassName = getEventClassName();
|
||||
|
||||
var updateContentScrollTop = function (currentTop, deltaY) {
|
||||
var newTop = currentTop + deltaY,
|
||||
- maxTop = containerHeight - scrollbarYHeight;
|
||||
+ maxTop = scrollbarYRailHeight - scrollbarYHeight;
|
||||
|
||||
if (newTop < 0) {
|
||||
scrollbarYTop = 0;
|
||||
@@ -113,7 +115,7 @@
|
||||
scrollbarYTop = newTop;
|
||||
}
|
||||
|
||||
- var scrollTop = parseInt(scrollbarYTop * (contentHeight - containerHeight) / (containerHeight - scrollbarYHeight), 10);
|
||||
+ var scrollTop = parseInt(scrollbarYTop * (contentHeight - containerHeight) / (scrollbarYRailHeight - scrollbarYHeight), 10);
|
||||
$this.scrollTop(scrollTop);
|
||||
$scrollbarXRail.css({bottom: scrollbarXBottom - scrollTop});
|
||||
};
|
||||
@@ -148,9 +150,9 @@
|
||||
$scrollbarXRail.css({left: $this.scrollLeft(), bottom: scrollbarXBottom - $this.scrollTop(), width: containerWidth, display: scrollbarXActive ? "inherit": "none"});
|
||||
|
||||
if ($scrollbarYRail.hasClass('in-scrolling'))
|
||||
- $scrollbarYRail.css({/*top: $this.scrollTop(),*/ right: scrollbarYRight - $this.scrollLeft(), height: containerHeight, display: scrollbarYActive ? "inherit": "none"});
|
||||
+ $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: containerHeight, display: scrollbarYActive ? "inherit": "none"});
|
||||
+ $scrollbarYRail.css({top: $this.scrollTop(), right: scrollbarYRight - $this.scrollLeft(), height: scrollbarYRailHeight, display: scrollbarYActive ? "inherit": "none"});
|
||||
|
||||
$scrollbarX.css({left: scrollbarXLeft, width: scrollbarXWidth});
|
||||
$scrollbarY.css({top: scrollbarYTop, height: scrollbarYHeight});
|
||||
@@ -159,6 +161,7 @@
|
||||
var updateBarSizeAndPosition = function () {
|
||||
containerWidth = settings.includePadding ? $this.innerWidth() : $this.width();
|
||||
containerHeight = settings.includePadding ? $this.innerHeight() : $this.height();
|
||||
+ scrollbarYRailHeight = containerHeight - (settings.includeMargin ? (parseInt($scrollbarYRail.css('margin-top')) + parseInt($scrollbarYRail.css('margin-bottom'))): 0);
|
||||
contentWidth = $this.prop('scrollWidth');
|
||||
contentHeight = $this.prop('scrollHeight');
|
||||
|
||||
@@ -176,8 +179,8 @@
|
||||
|
||||
if (!settings.suppressScrollY && containerHeight + settings.scrollYMarginOffset < contentHeight) {
|
||||
scrollbarYActive = true;
|
||||
- scrollbarYHeight = getSettingsAdjustedThumbSize(parseInt(containerHeight * containerHeight / contentHeight, 10));
|
||||
- scrollbarYTop = parseInt($this.scrollTop() * (containerHeight - scrollbarYHeight) / (contentHeight - containerHeight), 10);
|
||||
+ scrollbarYHeight = getSettingsAdjustedThumbSize(parseInt(scrollbarYRailHeight * containerHeight / contentHeight, 10));
|
||||
+ scrollbarYTop = parseInt($this.scrollTop() * (scrollbarYRailHeight - scrollbarYHeight) / (contentHeight - containerHeight), 10);
|
||||
}
|
||||
else {
|
||||
scrollbarYActive = false;
|
||||
@@ -186,8 +189,8 @@
|
||||
$this.scrollTop(0);
|
||||
}
|
||||
|
||||
- if (scrollbarYTop >= containerHeight - scrollbarYHeight) {
|
||||
- scrollbarYTop = containerHeight - scrollbarYHeight;
|
||||
+ if (scrollbarYTop >= scrollbarYRailHeight - scrollbarYHeight) {
|
||||
+ scrollbarYTop = scrollbarYRailHeight - scrollbarYHeight;
|
||||
}
|
||||
if (scrollbarXLeft >= containerWidth - scrollbarXWidth) {
|
||||
scrollbarXLeft = containerWidth - scrollbarXWidth;
|
||||
@@ -235,12 +238,12 @@
|
||||
currentTop = $scrollbarY.position().top;
|
||||
$scrollbarYRail.addClass('in-scrolling');
|
||||
|
||||
- var padding = parseInt($scrollbarYRail.offsetParent().css('padding-top'));
|
||||
+ var margin = parseInt($scrollbarYRail.css('margin-top'));
|
||||
var rect = $scrollbarYRail[0].getBoundingClientRect();
|
||||
$scrollbarYRail.css({
|
||||
position: 'fixed',
|
||||
left: rect.left,
|
||||
- top: rect.top - padding
|
||||
+ top: rect.top - margin
|
||||
});
|
||||
|
||||
e.stopPropagation();
|
||||
@@ -419,7 +422,7 @@
|
||||
$scrollbarYRail.bind('click' + eventClassName, function (e) {
|
||||
var halfOfScrollbarLength = parseInt(scrollbarYHeight / 2, 10),
|
||||
positionTop = e.pageY - $scrollbarYRail.offset().top - halfOfScrollbarLength,
|
||||
- maxPositionTop = containerHeight - scrollbarYHeight,
|
||||
+ maxPositionTop = scrollbarYRailHeight - scrollbarYHeight,
|
||||
positionRatio = positionTop / maxPositionTop;
|
||||
|
||||
if (positionRatio < 0) {
|
|
@ -0,0 +1,89 @@
|
|||
From d16a11fb136ef9ff06d20810e56e4a944173c977 Mon Sep 17 00:00:00 2001
|
||||
From: Julia Radzhabova
|
||||
Date: Fri, 19 Apr 2019 17:54:45 +0300
|
||||
Subject: [PATCH] [Common] perfect-scrollbar: set width and position for
|
||||
scrollbarXRail based on margins.
|
||||
|
||||
---
|
||||
apps/common/main/lib/mods/perfect-scrollbar.js | 18 ++++++++++--------
|
||||
1 file changed, 10 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/apps/common/main/lib/mods/perfect-scrollbar.js b/apps/common/main/lib/mods/perfect-scrollbar.js
|
||||
index 9b6f650..778009d 100644
|
||||
--- a/apps/common/main/lib/mods/perfect-scrollbar.js
|
||||
+++ b/apps/common/main/lib/mods/perfect-scrollbar.js
|
||||
@@ -95,6 +95,7 @@
|
||||
scrollbarXWidth,
|
||||
scrollbarXLeft,
|
||||
scrollbarXBottom = parseInt($scrollbarXRail.css('bottom'), 10),
|
||||
+ scrollbarXRailWidth,
|
||||
scrollbarYHeight,
|
||||
scrollbarYTop,
|
||||
scrollbarYRight = parseInt($scrollbarYRail.css('right'), 10),
|
||||
@@ -122,7 +123,7 @@
|
||||
|
||||
var updateContentScrollLeft = function (currentLeft, deltaX) {
|
||||
var newLeft = currentLeft + deltaX,
|
||||
- maxLeft = containerWidth - scrollbarXWidth;
|
||||
+ maxLeft = scrollbarXRailWidth - scrollbarXWidth;
|
||||
|
||||
if (newLeft < 0) {
|
||||
scrollbarXLeft = 0;
|
||||
@@ -134,7 +135,7 @@
|
||||
scrollbarXLeft = newLeft;
|
||||
}
|
||||
|
||||
- var scrollLeft = parseInt(scrollbarXLeft * (contentWidth - containerWidth) / (containerWidth - scrollbarXWidth), 10);
|
||||
+ var scrollLeft = parseInt(scrollbarXLeft * (contentWidth - containerWidth) / (scrollbarXRailWidth - scrollbarXWidth), 10);
|
||||
$this.scrollLeft(scrollLeft);
|
||||
$scrollbarYRail.css({right: scrollbarYRight - scrollLeft});
|
||||
};
|
||||
@@ -147,7 +148,7 @@
|
||||
};
|
||||
|
||||
var updateScrollbarCss = function () {
|
||||
- $scrollbarXRail.css({left: $this.scrollLeft(), bottom: scrollbarXBottom - $this.scrollTop(), width: containerWidth, display: scrollbarXActive ? "inherit": "none"});
|
||||
+ $scrollbarXRail.css({left: $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"});
|
||||
@@ -162,13 +163,14 @@
|
||||
containerWidth = settings.includePadding ? $this.innerWidth() : $this.width();
|
||||
containerHeight = settings.includePadding ? $this.innerHeight() : $this.height();
|
||||
scrollbarYRailHeight = containerHeight - (settings.includeMargin ? (parseInt($scrollbarYRail.css('margin-top')) + parseInt($scrollbarYRail.css('margin-bottom'))): 0);
|
||||
+ scrollbarXRailWidth = containerWidth - (settings.includeMargin ? (parseInt($scrollbarXRail.css('margin-left')) + parseInt($scrollbarXRail.css('margin-right'))): 0);
|
||||
contentWidth = $this.prop('scrollWidth');
|
||||
contentHeight = $this.prop('scrollHeight');
|
||||
|
||||
if (!settings.suppressScrollX && containerWidth + settings.scrollXMarginOffset < contentWidth) {
|
||||
scrollbarXActive = true;
|
||||
- scrollbarXWidth = getSettingsAdjustedThumbSize(parseInt(containerWidth * containerWidth / contentWidth, 10));
|
||||
- scrollbarXLeft = parseInt($this.scrollLeft() * (containerWidth - scrollbarXWidth) / (contentWidth - containerWidth), 10);
|
||||
+ scrollbarXWidth = getSettingsAdjustedThumbSize(parseInt(scrollbarXRailWidth * containerWidth / contentWidth, 10));
|
||||
+ scrollbarXLeft = parseInt($this.scrollLeft() * (scrollbarXRailWidth - scrollbarXWidth) / (contentWidth - containerWidth), 10);
|
||||
}
|
||||
else {
|
||||
scrollbarXActive = false;
|
||||
@@ -192,8 +194,8 @@
|
||||
if (scrollbarYTop >= scrollbarYRailHeight - scrollbarYHeight) {
|
||||
scrollbarYTop = scrollbarYRailHeight - scrollbarYHeight;
|
||||
}
|
||||
- if (scrollbarXLeft >= containerWidth - scrollbarXWidth) {
|
||||
- scrollbarXLeft = containerWidth - scrollbarXWidth;
|
||||
+ if (scrollbarXLeft >= scrollbarXRailWidth - scrollbarXWidth) {
|
||||
+ scrollbarXLeft = scrollbarXRailWidth - scrollbarXWidth;
|
||||
}
|
||||
|
||||
updateScrollbarCss();
|
||||
@@ -461,7 +463,7 @@
|
||||
$scrollbarXRail.bind('click' + eventClassName, function (e) {
|
||||
var halfOfScrollbarLength = parseInt(scrollbarXWidth / 2, 10),
|
||||
positionLeft = e.pageX - $scrollbarXRail.offset().left - halfOfScrollbarLength,
|
||||
- maxPositionLeft = containerWidth - scrollbarXWidth,
|
||||
+ maxPositionLeft = scrollbarXRailWidth - scrollbarXWidth,
|
||||
positionRatio = positionLeft / maxPositionLeft;
|
||||
|
||||
if (positionRatio < 0) {
|
||||
--
|
||||
2.6.1.windows.1
|
||||
|
658
test/unit-tests/common/main/lib/mods/perfect-scrollbar.js
Normal file
658
test/unit-tests/common/main/lib/mods/perfect-scrollbar.js
Normal file
|
@ -0,0 +1,658 @@
|
|||
/* Copyright (c) 2012, 2014 Hyeonje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS
|
||||
factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals
|
||||
factory(jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
'use strict';
|
||||
|
||||
// The default settings for the plugin
|
||||
var defaultSettings = {
|
||||
wheelSpeed: 10,
|
||||
wheelPropagation: false,
|
||||
minScrollbarLength: null,
|
||||
useBothWheelAxes: false,
|
||||
useKeyboard: true,
|
||||
suppressScrollX: false,
|
||||
suppressScrollY: false,
|
||||
scrollXMarginOffset: 0,
|
||||
scrollYMarginOffset: 0,
|
||||
includePadding: false,
|
||||
includeMargin: true
|
||||
};
|
||||
|
||||
var getEventClassName = (function () {
|
||||
var incrementingId = 0;
|
||||
return function () {
|
||||
var id = incrementingId;
|
||||
incrementingId += 1;
|
||||
return '.perfect-scrollbar-' + id;
|
||||
};
|
||||
}());
|
||||
|
||||
$.fn.perfectScrollbar = function (suppliedSettings, option) {
|
||||
|
||||
return this.each(function () {
|
||||
// Use the default settings
|
||||
var settings = $.extend(true, {}, defaultSettings),
|
||||
$this = $(this);
|
||||
|
||||
if (typeof suppliedSettings === "object") {
|
||||
// But over-ride any supplied
|
||||
$.extend(true, settings, suppliedSettings);
|
||||
} else {
|
||||
// If no settings were supplied, then the first param must be the option
|
||||
option = suppliedSettings;
|
||||
}
|
||||
|
||||
// Catch options
|
||||
|
||||
if (option === 'update') {
|
||||
if ($this.data('perfect-scrollbar-update')) {
|
||||
$this.data('perfect-scrollbar-update')();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
else if (option === 'destroy') {
|
||||
if ($this.data('perfect-scrollbar-destroy')) {
|
||||
$this.data('perfect-scrollbar-destroy')();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($this.data('perfect-scrollbar')) {
|
||||
// if there's already perfect-scrollbar
|
||||
return $this.data('perfect-scrollbar');
|
||||
}
|
||||
|
||||
|
||||
// Or generate new perfectScrollbar
|
||||
|
||||
// Set class to the container
|
||||
$this.addClass('ps-container oo');
|
||||
|
||||
var $scrollbarXRail = $("<div class='ps-scrollbar-x-rail'></div>").appendTo($this),
|
||||
$scrollbarYRail = $("<div class='ps-scrollbar-y-rail'></div>").appendTo($this),
|
||||
$scrollbarX = $("<div class='ps-scrollbar-x'></div>").appendTo($scrollbarXRail),
|
||||
$scrollbarY = $("<div class='ps-scrollbar-y'></div>").appendTo($scrollbarYRail),
|
||||
scrollbarXActive,
|
||||
scrollbarYActive,
|
||||
containerWidth,
|
||||
containerHeight,
|
||||
contentWidth,
|
||||
contentHeight,
|
||||
scrollbarXWidth,
|
||||
scrollbarXLeft,
|
||||
scrollbarXBottom = parseInt($scrollbarXRail.css('bottom'), 10),
|
||||
scrollbarXRailWidth,
|
||||
scrollbarYHeight,
|
||||
scrollbarYTop,
|
||||
scrollbarYRight = parseInt($scrollbarYRail.css('right'), 10),
|
||||
scrollbarYRailHeight,
|
||||
eventClassName = getEventClassName();
|
||||
|
||||
var updateContentScrollTop = function (currentTop, deltaY) {
|
||||
var newTop = currentTop + deltaY,
|
||||
maxTop = scrollbarYRailHeight - scrollbarYHeight;
|
||||
|
||||
if (newTop < 0) {
|
||||
scrollbarYTop = 0;
|
||||
}
|
||||
else if (newTop > maxTop) {
|
||||
scrollbarYTop = maxTop;
|
||||
}
|
||||
else {
|
||||
scrollbarYTop = newTop;
|
||||
}
|
||||
|
||||
var scrollTop = parseInt(scrollbarYTop * (contentHeight - containerHeight) / (scrollbarYRailHeight - scrollbarYHeight), 10);
|
||||
$this.scrollTop(scrollTop);
|
||||
$scrollbarXRail.css({bottom: scrollbarXBottom - scrollTop});
|
||||
};
|
||||
|
||||
var updateContentScrollLeft = function (currentLeft, deltaX) {
|
||||
var newLeft = currentLeft + deltaX,
|
||||
maxLeft = scrollbarXRailWidth - scrollbarXWidth;
|
||||
|
||||
if (newLeft < 0) {
|
||||
scrollbarXLeft = 0;
|
||||
}
|
||||
else if (newLeft > maxLeft) {
|
||||
scrollbarXLeft = maxLeft;
|
||||
}
|
||||
else {
|
||||
scrollbarXLeft = newLeft;
|
||||
}
|
||||
|
||||
var scrollLeft = parseInt(scrollbarXLeft * (contentWidth - containerWidth) / (scrollbarXRailWidth - scrollbarXWidth), 10);
|
||||
$this.scrollLeft(scrollLeft);
|
||||
$scrollbarYRail.css({right: scrollbarYRight - scrollLeft});
|
||||
};
|
||||
|
||||
var getSettingsAdjustedThumbSize = function (thumbSize) {
|
||||
if (settings.minScrollbarLength) {
|
||||
thumbSize = Math.max(thumbSize, settings.minScrollbarLength);
|
||||
}
|
||||
return thumbSize;
|
||||
};
|
||||
|
||||
var updateScrollbarCss = function () {
|
||||
$scrollbarXRail.css({left: $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"});
|
||||
|
||||
$scrollbarX && $scrollbarX.css({left: scrollbarXLeft, width: scrollbarXWidth});
|
||||
$scrollbarY && $scrollbarY.css({top: scrollbarYTop, height: scrollbarYHeight});
|
||||
};
|
||||
|
||||
var updateBarSizeAndPosition = function () {
|
||||
containerWidth = settings.includePadding ? $this.innerWidth() : $this.width();
|
||||
containerHeight = settings.includePadding ? $this.innerHeight() : $this.height();
|
||||
scrollbarYRailHeight = containerHeight - (settings.includeMargin ? (parseInt($scrollbarYRail.css('margin-top')) + parseInt($scrollbarYRail.css('margin-bottom'))): 0);
|
||||
scrollbarXRailWidth = containerWidth - (settings.includeMargin ? (parseInt($scrollbarXRail.css('margin-left')) + parseInt($scrollbarXRail.css('margin-right'))): 0);
|
||||
contentWidth = $this.prop('scrollWidth');
|
||||
contentHeight = $this.prop('scrollHeight');
|
||||
|
||||
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);
|
||||
}
|
||||
else {
|
||||
scrollbarXActive = false;
|
||||
scrollbarXWidth = 0;
|
||||
scrollbarXLeft = 0;
|
||||
$this.scrollLeft(0);
|
||||
}
|
||||
|
||||
if (!settings.suppressScrollY && containerHeight + settings.scrollYMarginOffset < contentHeight) {
|
||||
scrollbarYActive = true;
|
||||
scrollbarYHeight = getSettingsAdjustedThumbSize(parseInt(scrollbarYRailHeight * containerHeight / contentHeight, 10));
|
||||
scrollbarYTop = parseInt($this.scrollTop() * (scrollbarYRailHeight - scrollbarYHeight) / (contentHeight - containerHeight), 10);
|
||||
}
|
||||
else {
|
||||
scrollbarYActive = false;
|
||||
scrollbarYHeight = 0;
|
||||
scrollbarYTop = 0;
|
||||
$this.scrollTop(0);
|
||||
}
|
||||
|
||||
if (scrollbarYTop >= scrollbarYRailHeight - scrollbarYHeight) {
|
||||
scrollbarYTop = scrollbarYRailHeight - scrollbarYHeight;
|
||||
}
|
||||
if (scrollbarXLeft >= scrollbarXRailWidth - scrollbarXWidth) {
|
||||
scrollbarXLeft = scrollbarXRailWidth - scrollbarXWidth;
|
||||
}
|
||||
|
||||
updateScrollbarCss();
|
||||
|
||||
if (settings.onChange) {
|
||||
settings.onChange(this);
|
||||
}
|
||||
};
|
||||
|
||||
var bindMouseScrollXHandler = function () {
|
||||
var currentLeft,
|
||||
currentPageX;
|
||||
|
||||
$scrollbarX.bind('mousedown' + eventClassName, function (e) {
|
||||
currentPageX = e.pageX;
|
||||
currentLeft = $scrollbarX.position().left;
|
||||
$scrollbarXRail.addClass('in-scrolling');
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
$(document).bind('mousemove' + eventClassName, function (e) {
|
||||
if ($scrollbarXRail.hasClass('in-scrolling')) {
|
||||
updateContentScrollLeft(currentLeft, e.pageX - currentPageX);
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
$(document).bind('mouseup' + eventClassName, function (e) {
|
||||
if ($scrollbarXRail.hasClass('in-scrolling')) {
|
||||
$scrollbarXRail.removeClass('in-scrolling');
|
||||
}
|
||||
});
|
||||
|
||||
currentLeft =
|
||||
currentPageX = null;
|
||||
};
|
||||
|
||||
var bindMouseScrollYHandler = function () {
|
||||
var currentTop,
|
||||
currentPageY;
|
||||
|
||||
$scrollbarY.bind('mousedown' + eventClassName, function (e) {
|
||||
currentPageY = e.pageY;
|
||||
currentTop = $scrollbarY.position().top;
|
||||
$scrollbarYRail.addClass('in-scrolling');
|
||||
|
||||
var margin = parseInt($scrollbarYRail.css('margin-top'));
|
||||
var rect = $scrollbarYRail[0].getBoundingClientRect();
|
||||
$scrollbarYRail.css({
|
||||
position: 'fixed',
|
||||
left: rect.left,
|
||||
top: rect.top - margin
|
||||
});
|
||||
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
$(document).bind('mousemove' + eventClassName, function (e) {
|
||||
if ($scrollbarYRail.hasClass('in-scrolling')) {
|
||||
updateContentScrollTop(currentTop, e.pageY - currentPageY);
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
$(document).bind('mouseup' + eventClassName, function (e) {
|
||||
if ($scrollbarYRail.hasClass('in-scrolling')) {
|
||||
$scrollbarYRail.removeClass('in-scrolling');
|
||||
|
||||
$scrollbarYRail.css({
|
||||
position: '',
|
||||
left: '',
|
||||
top: ''
|
||||
});
|
||||
|
||||
updateScrollbarCss();
|
||||
}
|
||||
});
|
||||
|
||||
currentTop =
|
||||
currentPageY = null;
|
||||
};
|
||||
|
||||
// check if the default scrolling should be prevented.
|
||||
var shouldPreventDefault = function (deltaX, deltaY) {
|
||||
var scrollTop = $this.scrollTop();
|
||||
if (deltaX === 0) {
|
||||
if (!scrollbarYActive) {
|
||||
return false;
|
||||
}
|
||||
if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= contentHeight - containerHeight && deltaY < 0)) {
|
||||
return !settings.wheelPropagation;
|
||||
}
|
||||
}
|
||||
|
||||
var scrollLeft = $this.scrollLeft();
|
||||
if (deltaY === 0) {
|
||||
if (!scrollbarXActive) {
|
||||
return false;
|
||||
}
|
||||
if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= contentWidth - containerWidth && deltaX > 0)) {
|
||||
return !settings.wheelPropagation;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// bind handlers
|
||||
var bindMouseWheelHandler = function () {
|
||||
// FIXME: Backward compatibility.
|
||||
// After e.deltaFactor applied, wheelSpeed should have smaller value.
|
||||
// Currently, there's no way to change the settings after the scrollbar initialized.
|
||||
// But if the way is implemented in the future, wheelSpeed should be reset.
|
||||
settings.wheelSpeed /= 10;
|
||||
|
||||
var shouldPrevent = false;
|
||||
$this.bind('mousewheel' + eventClassName, function (e, deprecatedDelta, deprecatedDeltaX, deprecatedDeltaY) {
|
||||
Common.NotificationCenter.trigger('hints:clear');
|
||||
var deltaX = e.deltaX * e.deltaFactor || deprecatedDeltaX,
|
||||
deltaY = e.deltaY * e.deltaFactor || deprecatedDeltaY;
|
||||
|
||||
if (e && e.target && (e.target.type === 'textarea' || e.target.type === 'input')) {
|
||||
e.stopImmediatePropagation();
|
||||
e.preventDefault();
|
||||
|
||||
var scroll = $(e.target).scrollTop(), wheelDeltaY = 0;
|
||||
if (e.originalEvent) {
|
||||
if (e.originalEvent.wheelDelta) wheelDeltaY = e.originalEvent.wheelDelta;
|
||||
else if (e.originalEvent.deltaY) wheelDeltaY = -e.originalEvent.deltaY*40;
|
||||
else if (e.originalEvent.detail) wheelDeltaY = e.originalEvent.detail;
|
||||
} else {
|
||||
wheelDeltaY = (e.wheelDelta !== undefined) ? e.wheelDelta : e.deltaY;
|
||||
}
|
||||
|
||||
|
||||
$(e.target).scrollTop(scroll - wheelDeltaY);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
shouldPrevent = false;
|
||||
if (!settings.useBothWheelAxes) {
|
||||
// deltaX will only be used for horizontal scrolling and deltaY will
|
||||
// only be used for vertical scrolling - this is the default
|
||||
$this.scrollTop($this.scrollTop() - (deltaY * settings.wheelSpeed));
|
||||
$this.scrollLeft($this.scrollLeft() + (deltaX * settings.wheelSpeed));
|
||||
} else if (scrollbarYActive && !scrollbarXActive) {
|
||||
// only vertical scrollbar is active and useBothWheelAxes option is
|
||||
// active, so let's scroll vertical bar using both mouse wheel axes
|
||||
if (deltaY) {
|
||||
$this.scrollTop($this.scrollTop() - (deltaY * settings.wheelSpeed));
|
||||
} else {
|
||||
$this.scrollTop($this.scrollTop() + (deltaX * settings.wheelSpeed));
|
||||
}
|
||||
shouldPrevent = true;
|
||||
} else if (scrollbarXActive && !scrollbarYActive) {
|
||||
// useBothWheelAxes and only horizontal bar is active, so use both
|
||||
// wheel axes for horizontal bar
|
||||
if (deltaX) {
|
||||
$this.scrollLeft($this.scrollLeft() + (deltaX * settings.wheelSpeed));
|
||||
} else {
|
||||
$this.scrollLeft($this.scrollLeft() - (deltaY * settings.wheelSpeed));
|
||||
}
|
||||
shouldPrevent = true;
|
||||
}
|
||||
|
||||
// update bar position
|
||||
updateBarSizeAndPosition();
|
||||
|
||||
shouldPrevent = (shouldPrevent || shouldPreventDefault(deltaX, deltaY));
|
||||
if (shouldPrevent) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
// fix Firefox scroll problem
|
||||
$this.bind('MozMousePixelScroll' + eventClassName, function (e) {
|
||||
if (shouldPrevent) {
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var bindKeyboardHandler = function () {
|
||||
var hovered = false;
|
||||
$this.bind('mouseenter' + eventClassName, function (e) {
|
||||
hovered = true;
|
||||
});
|
||||
$this.bind('mouseleave' + eventClassName, function (e) {
|
||||
hovered = false;
|
||||
});
|
||||
|
||||
var shouldPrevent = false;
|
||||
$(document).bind('keydown' + eventClassName, function (e) {
|
||||
if (!hovered || $(document.activeElement).is(":input,[contenteditable]")) {
|
||||
return;
|
||||
}
|
||||
|
||||
var deltaX = 0,
|
||||
deltaY = 0;
|
||||
|
||||
switch (e.which) {
|
||||
case 37: // left
|
||||
deltaX = -30;
|
||||
break;
|
||||
case 38: // up
|
||||
deltaY = 30;
|
||||
break;
|
||||
case 39: // right
|
||||
deltaX = 30;
|
||||
break;
|
||||
case 40: // down
|
||||
deltaY = -30;
|
||||
break;
|
||||
case 33: // page up
|
||||
deltaY = 90;
|
||||
break;
|
||||
case 32: // space bar
|
||||
case 34: // page down
|
||||
deltaY = -90;
|
||||
break;
|
||||
case 35: // end
|
||||
deltaY = -containerHeight;
|
||||
break;
|
||||
case 36: // home
|
||||
deltaY = containerHeight;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
$this.scrollTop($this.scrollTop() - deltaY);
|
||||
$this.scrollLeft($this.scrollLeft() + deltaX);
|
||||
|
||||
shouldPrevent = shouldPreventDefault(deltaX, deltaY);
|
||||
if (shouldPrevent) {
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var bindRailClickHandler = function () {
|
||||
var stopPropagation = function (e) { e.stopPropagation(); };
|
||||
|
||||
$scrollbarY.bind('click' + eventClassName, stopPropagation);
|
||||
$scrollbarYRail.bind('click' + eventClassName, function (e) {
|
||||
var halfOfScrollbarLength = parseInt(scrollbarYHeight / 2, 10),
|
||||
positionTop = e.pageY - $scrollbarYRail.offset().top - halfOfScrollbarLength,
|
||||
maxPositionTop = scrollbarYRailHeight - scrollbarYHeight,
|
||||
positionRatio = positionTop / maxPositionTop;
|
||||
|
||||
if (positionRatio < 0) {
|
||||
positionRatio = 0;
|
||||
} else if (positionRatio > 1) {
|
||||
positionRatio = 1;
|
||||
}
|
||||
|
||||
$this.scrollTop((contentHeight - containerHeight) * positionRatio);
|
||||
});
|
||||
|
||||
$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;
|
||||
|
||||
if (positionRatio < 0) {
|
||||
positionRatio = 0;
|
||||
} else if (positionRatio > 1) {
|
||||
positionRatio = 1;
|
||||
}
|
||||
|
||||
$this.scrollLeft((contentWidth - containerWidth) * positionRatio);
|
||||
});
|
||||
};
|
||||
|
||||
// bind mobile touch handler
|
||||
var bindMobileTouchHandler = function () {
|
||||
var applyTouchMove = function (differenceX, differenceY) {
|
||||
$this.scrollTop($this.scrollTop() - differenceY);
|
||||
$this.scrollLeft($this.scrollLeft() - differenceX);
|
||||
|
||||
// update bar position
|
||||
updateBarSizeAndPosition();
|
||||
};
|
||||
|
||||
var startCoords = {},
|
||||
startTime = 0,
|
||||
speed = {},
|
||||
breakingProcess = null,
|
||||
inGlobalTouch = false;
|
||||
|
||||
$(window).bind("touchstart" + eventClassName, function (e) {
|
||||
inGlobalTouch = true;
|
||||
});
|
||||
$(window).bind("touchend" + eventClassName, function (e) {
|
||||
inGlobalTouch = false;
|
||||
});
|
||||
|
||||
$this.bind("touchstart" + eventClassName, function (e) {
|
||||
var touch = e.originalEvent.targetTouches[0];
|
||||
|
||||
startCoords.pageX = touch.pageX;
|
||||
startCoords.pageY = touch.pageY;
|
||||
|
||||
startTime = (new Date()).getTime();
|
||||
|
||||
if (breakingProcess !== null) {
|
||||
clearInterval(breakingProcess);
|
||||
}
|
||||
|
||||
e.stopPropagation();
|
||||
});
|
||||
$this.bind("touchmove" + eventClassName, function (e) {
|
||||
if (!inGlobalTouch && e.originalEvent.targetTouches.length === 1) {
|
||||
var touch = e.originalEvent.targetTouches[0];
|
||||
|
||||
var currentCoords = {};
|
||||
currentCoords.pageX = touch.pageX;
|
||||
currentCoords.pageY = touch.pageY;
|
||||
|
||||
var differenceX = currentCoords.pageX - startCoords.pageX,
|
||||
differenceY = currentCoords.pageY - startCoords.pageY;
|
||||
|
||||
applyTouchMove(differenceX, differenceY);
|
||||
startCoords = currentCoords;
|
||||
|
||||
var currentTime = (new Date()).getTime();
|
||||
|
||||
var timeGap = currentTime - startTime;
|
||||
if (timeGap > 0) {
|
||||
speed.x = differenceX / timeGap;
|
||||
speed.y = differenceY / timeGap;
|
||||
startTime = currentTime;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
$this.bind("touchend" + eventClassName, function (e) {
|
||||
clearInterval(breakingProcess);
|
||||
breakingProcess = setInterval(function () {
|
||||
if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) {
|
||||
clearInterval(breakingProcess);
|
||||
return;
|
||||
}
|
||||
|
||||
applyTouchMove(speed.x * 30, speed.y * 30);
|
||||
|
||||
speed.x *= 0.8;
|
||||
speed.y *= 0.8;
|
||||
}, 10);
|
||||
});
|
||||
};
|
||||
|
||||
var bindScrollHandler = function () {
|
||||
$this.bind('scroll' + eventClassName, function (e) {
|
||||
updateBarSizeAndPosition();
|
||||
});
|
||||
};
|
||||
|
||||
var destroy = function () {
|
||||
$this.unbind(eventClassName);
|
||||
$(window).unbind(eventClassName);
|
||||
$(document).unbind(eventClassName);
|
||||
$this.data('perfect-scrollbar', null);
|
||||
$this.data('perfect-scrollbar-update', null);
|
||||
$this.data('perfect-scrollbar-destroy', null);
|
||||
$scrollbarX.remove();
|
||||
$scrollbarY.remove();
|
||||
$scrollbarXRail.remove();
|
||||
$scrollbarYRail.remove();
|
||||
|
||||
// clean all variables
|
||||
$scrollbarX =
|
||||
$scrollbarY =
|
||||
containerWidth =
|
||||
containerHeight =
|
||||
contentWidth =
|
||||
contentHeight =
|
||||
scrollbarXWidth =
|
||||
scrollbarXLeft =
|
||||
scrollbarXBottom =
|
||||
scrollbarYHeight =
|
||||
scrollbarYTop =
|
||||
scrollbarYRight = null;
|
||||
};
|
||||
|
||||
var ieSupport = function (version) {
|
||||
$this.addClass('ie').addClass('ie' + version);
|
||||
|
||||
var bindHoverHandlers = function () {
|
||||
var mouseenter = function () {
|
||||
$(this).addClass('hover');
|
||||
};
|
||||
var mouseleave = function () {
|
||||
$(this).removeClass('hover');
|
||||
};
|
||||
$this.bind('mouseenter' + eventClassName, mouseenter).bind('mouseleave' + eventClassName, mouseleave);
|
||||
$scrollbarXRail.bind('mouseenter' + eventClassName, mouseenter).bind('mouseleave' + eventClassName, mouseleave);
|
||||
$scrollbarYRail.bind('mouseenter' + eventClassName, mouseenter).bind('mouseleave' + eventClassName, mouseleave);
|
||||
$scrollbarX.bind('mouseenter' + eventClassName, mouseenter).bind('mouseleave' + eventClassName, mouseleave);
|
||||
$scrollbarY.bind('mouseenter' + eventClassName, mouseenter).bind('mouseleave' + eventClassName, mouseleave);
|
||||
};
|
||||
|
||||
var fixIe6ScrollbarPosition = function () {
|
||||
updateScrollbarCss = function () {
|
||||
$scrollbarX.css({left: scrollbarXLeft + $this.scrollLeft(), bottom: scrollbarXBottom, width: scrollbarXWidth});
|
||||
$scrollbarY.css({top: scrollbarYTop + $this.scrollTop(), right: scrollbarYRight, height: scrollbarYHeight});
|
||||
$scrollbarX.hide().show();
|
||||
$scrollbarY.hide().show();
|
||||
};
|
||||
};
|
||||
|
||||
if (version === 6) {
|
||||
bindHoverHandlers();
|
||||
fixIe6ScrollbarPosition();
|
||||
}
|
||||
};
|
||||
|
||||
var supportsTouch = (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch);
|
||||
|
||||
var initialize = function () {
|
||||
var ieMatch = navigator.userAgent.toLowerCase().match(/(msie) ([\w.]+)/);
|
||||
if (ieMatch && ieMatch[1] === 'msie') {
|
||||
// must be executed at first, because 'ieSupport' may addClass to the container
|
||||
ieSupport(parseInt(ieMatch[2], 10));
|
||||
}
|
||||
|
||||
updateBarSizeAndPosition();
|
||||
bindScrollHandler();
|
||||
bindMouseScrollXHandler();
|
||||
bindMouseScrollYHandler();
|
||||
bindRailClickHandler();
|
||||
if (supportsTouch) {
|
||||
bindMobileTouchHandler();
|
||||
}
|
||||
if ($this.mousewheel) {
|
||||
bindMouseWheelHandler();
|
||||
}
|
||||
if (settings.useKeyboard) {
|
||||
bindKeyboardHandler();
|
||||
}
|
||||
$this.data('perfect-scrollbar', $this);
|
||||
$this.data('perfect-scrollbar-update', updateBarSizeAndPosition);
|
||||
$this.data('perfect-scrollbar-destroy', destroy);
|
||||
};
|
||||
|
||||
// initialize
|
||||
initialize();
|
||||
|
||||
return $this;
|
||||
});
|
||||
};
|
||||
}));
|
86
test/unit-tests/common/main/lib/view/CellEditor.js
Normal file
86
test/unit-tests/common/main/lib/view/CellEditor.js
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2010-2021
|
||||
*
|
||||
* 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-12 Ernesta Birznieka-Upisha
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* CellEditor.js
|
||||
*
|
||||
* Displays loading mask over selected element(s) or component. Accepts both single and multiple selectors.
|
||||
*
|
||||
* Created by Sharova Olga 07.09.2021
|
||||
* Copyright (c) 2021 Ascensio System SIA. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
!window.common && (window.common = {});
|
||||
!common.view && (common.view = {});
|
||||
|
||||
common.view.CellEditor = new(function (){
|
||||
var me
|
||||
,$cellname
|
||||
,$cellcontent
|
||||
,$btnexpand
|
||||
,$btnfunc;
|
||||
|
||||
function createView()
|
||||
{
|
||||
me=this;
|
||||
me.$el = $('#cell-editing-box');
|
||||
me.$cellcontent=$('#ce-cell-content');
|
||||
me.$cellname = $('#ce-cell-name');
|
||||
me.$btnexpand = $('#ce-btn-expand');
|
||||
me.$btnfunc = $('#ce-func-label');
|
||||
me.$btnfunc.addClass('disabled');
|
||||
|
||||
me.$cellname.on('focus', function(e){
|
||||
var txt = me.$cellname[0];
|
||||
txt.selectionStart = 0;
|
||||
txt.selectionEnd = txt.value.length;
|
||||
txt.scrollLeft = txt.scrollWidth;
|
||||
});
|
||||
}
|
||||
function updateCellInfo(info) {
|
||||
if (info) {
|
||||
me.$cellname.val(typeof(info)=='string' ? info : info.asc_getName());
|
||||
}
|
||||
}
|
||||
function cellNameDisabled(disabled){
|
||||
(disabled) ? me.$cellname.attr('disabled', 'disabled') : me.$cellname.removeAttr('disabled');
|
||||
//this.btnNamedRanges.setDisabled(disabled);
|
||||
}
|
||||
return {
|
||||
create: createView,
|
||||
cell: {
|
||||
updateInfo: updateCellInfo,
|
||||
nameDisabled: cellNameDisabled
|
||||
}
|
||||
}
|
||||
})();
|
397
test/unit-tests/common/main/resources/less/asc-mixins.less
Normal file
397
test/unit-tests/common/main/resources/less/asc-mixins.less
Normal file
|
@ -0,0 +1,397 @@
|
|||
*, *:before, *:after {
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.gradient(@color: #F5F5F5, @start: #EEE, @stop: #FFF) {
|
||||
background: @color;
|
||||
background: -webkit-gradient(linear, left bottom,left top, color-stop(0, @start), color-stop(1, @stop));
|
||||
background: -moz-linear-gradient(center bottom, @start 0%, @stop 100%);
|
||||
background: -o-linear-gradient(@stop, @start);
|
||||
background: linear-gradient(bottom, @start, @stop);
|
||||
// filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",@stop, @start));
|
||||
}
|
||||
|
||||
.box-shadow(@arguments) {
|
||||
-webkit-box-shadow: @arguments;
|
||||
//-moz-box-shadow: @arguments;
|
||||
box-shadow: @arguments;
|
||||
}
|
||||
|
||||
.box-inner-shadow(@arguments) {
|
||||
-webkit-box-shadow: inset @arguments;
|
||||
//-moz-box-shadow: inset @arguments;
|
||||
box-shadow: inset @arguments;
|
||||
}
|
||||
|
||||
.border-radius(@radius: 2px) {
|
||||
border-radius: @radius;
|
||||
}
|
||||
|
||||
.position(@type: absolute, @left: 0, @top: 0, @right: 0, @bottom: 0) {
|
||||
position: @type;
|
||||
left: @left;
|
||||
top: @top;
|
||||
right: @right;
|
||||
bottom: @bottom;
|
||||
}
|
||||
|
||||
.fontsize(@value) {
|
||||
font-size: @value;
|
||||
}
|
||||
|
||||
// User select
|
||||
.user-select(@select: none) {
|
||||
-webkit-user-select: @select;
|
||||
-moz-user-select: @select;
|
||||
-ms-user-select: @select;
|
||||
// -o-user-select: @select;
|
||||
user-select: @select;
|
||||
}
|
||||
|
||||
.toolbar-btn-icon(@icon-class, @index, @icon-size, @offset-x: 0, @offset-y: 0) {
|
||||
.@{icon-class} {background-position: 0 -(@index * @icon-size - @offset-y);}
|
||||
.btn.active > .@{icon-class},
|
||||
.btn:active > .@{icon-class} {background-position: (-1 * @icon-size - @offset-x) -(@index * @icon-size - @offset-y);}
|
||||
.btn.disabled > .@{icon-class} {background-position: (-2 * @icon-size - @offset-x) -(@index * @icon-size - @offset-y);}
|
||||
}
|
||||
|
||||
.toolbar-group-btn-icon(@icon-class, @index, @icon-size, @offset-x: 0, @offset-y: 0) {
|
||||
.@{icon-class} {background-position: 0 -(@index * @icon-size - @offset-y);}
|
||||
.btn-group.open > .@{icon-class},
|
||||
.btn.active > .@{icon-class},
|
||||
.btn:active > .@{icon-class} {background-position: (-1 * @icon-size - @offset-x) -(@index * @icon-size - @offset-y);}
|
||||
.btn.disabled > .@{icon-class} {background-position: (-2 * @icon-size - @offset-x) -(@index * @icon-size - @offset-y);}
|
||||
}
|
||||
|
||||
.menu-btn-icon(@icon-class, @index, @icon-size) {
|
||||
.menu-item-icon.@{icon-class} {background-position: 0 -@index*@icon-size;}
|
||||
li > a.checked > .menu-item-icon.@{icon-class} {background-position: -1*@icon-size -@index*@icon-size;}
|
||||
}
|
||||
|
||||
.options-btn-icon(@icon-class, @index, @icon-size) {
|
||||
.@{icon-class} {background-position: 0 -@index*@icon-size;}
|
||||
button.over > .@{icon-class} {background-position: -1*@icon-size -@index*@icon-size;}
|
||||
// .btn-group.open > .@{icon-class},
|
||||
button.active > .@{icon-class},
|
||||
button:active > .@{icon-class} {background-position: -2*@icon-size -@index*@icon-size;}
|
||||
button.disabled > .@{icon-class} {background-position: -3*@icon-size -@index*@icon-size;}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
:root {
|
||||
--bgX: 0px;
|
||||
|
||||
--pixel-ratio-factor: 1;
|
||||
|
||||
.pixel-ratio__1_5 {
|
||||
@ratio: 1.5;
|
||||
@one-px: 1px / @ratio;
|
||||
@two-px: 2px / @ratio;
|
||||
|
||||
--pixel-ratio-factor: @ratio;
|
||||
--scaled-one-pixel: @one-px;
|
||||
--scaled-two-pixel: @two-px;
|
||||
}
|
||||
|
||||
.pixel-ratio__2 {
|
||||
}
|
||||
|
||||
.pixel-ratio__1_25 {
|
||||
@ratio: 1.25;
|
||||
@one-px: 1px / @ratio;
|
||||
@two-px: 2px / @ratio;
|
||||
|
||||
--pixel-ratio-factor: @ratio;
|
||||
--scaled-one-pixel: @one-px;
|
||||
--scaled-two-pixel: @two-px;
|
||||
}
|
||||
|
||||
.pixel-ratio__1_75 {
|
||||
@ratio: 1.75;
|
||||
@one-px: 1px / @ratio;
|
||||
@two-px: 2px / @ratio;
|
||||
|
||||
--pixel-ratio-factor: @ratio;
|
||||
--scaled-one-pixel: @one-px;
|
||||
--scaled-two-pixel: @two-px;
|
||||
}
|
||||
}
|
||||
|
||||
.button-normal-icon(@icon-class, @index, @icon-size, @normal-h-offset: 0px) {
|
||||
.@{icon-class} {
|
||||
background-position: -0*@icon-size -@index*@icon-size;
|
||||
background-position: @normal-h-offset -@index*@icon-size;
|
||||
}
|
||||
// .@{icon-class} {background-position-y: -@index*@icon-size;}
|
||||
}
|
||||
|
||||
.button-otherstates-icon(@icon-class, @icon-size) {
|
||||
.btn {
|
||||
&:active, &.active {
|
||||
&:not(:disabled):not(.disabled) {
|
||||
> .@{icon-class} {
|
||||
@iconsize: -1*@icon-size;
|
||||
|
||||
background-position-x: @iconsize;
|
||||
--bgX: @iconsize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx-button-otherstates-icon2(@offset) {
|
||||
&.active, &:active{
|
||||
&:not(:disabled):not(.disabled) {
|
||||
.icon {
|
||||
background-position-x: @offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//&.active svg.icon,
|
||||
//&:active svg.icon {fill:#fff;}
|
||||
}
|
||||
|
||||
.button-otherstates-icon2(@icon-class, @icon-size) {
|
||||
button.@{icon-class} {
|
||||
.mx-button-otherstates-icon2(@icon-size);
|
||||
}
|
||||
}
|
||||
|
||||
.menu-icon-normal(@icon-class, @index, @icon-size) {
|
||||
.menu-item-icon.@{icon-class} {
|
||||
background-position: 0 -@index*@icon-size;
|
||||
background-position: var(--bgX) -@index*@icon-size;
|
||||
}
|
||||
// .menu-item-icon.@{icon-class} {background-position-y: -@index*@icon-size;}
|
||||
}
|
||||
|
||||
.menu-otherstates-icon(@menu-class, @icon-size) {
|
||||
.@{menu-class} li > a.checked > .menu-item-icon {background-position-x: -1*@icon-size; --bgX: calc(-1*@icon-size);}
|
||||
.@{menu-class} li.disabled .menu-item-icon {background-position-x: -2*@icon-size; --bgX: calc(-2*@icon-size);}
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
.background-ximage(@image, @image2x, @w: auto, @h: auto, @repeat: no-repeat) {
|
||||
background-image: data-uri(%("%s",@image));
|
||||
background-repeat: @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(%("%s",@image2x));
|
||||
background-size: @w @h;
|
||||
}
|
||||
}
|
||||
|
||||
.choose-image-path(@fromcommon) when (@fromcommon = false) {
|
||||
@path: if(@icon-src-base64, @app-image-path, @app-image-const-path);
|
||||
};
|
||||
|
||||
.choose-image-path(@fromcommon) when (@fromcommon = true) {
|
||||
@path: if(@icon-src-base64, @common-image-path, @common-image-const-path);
|
||||
}
|
||||
|
||||
.background-ximage-v2(@image, @w: auto, @h: auto, @repeat: no-repeat, @commonimage: true) {
|
||||
.choose-image-path(@commonimage);
|
||||
@imagepath: '@{path}/@{image}';
|
||||
|
||||
background-image: if(@icon-src-base64, data-uri(%("%s", '@{imagepath}')), ~"url(@{imagepath})");
|
||||
background-repeat: @repeat;
|
||||
|
||||
@1d5ximage: replace(@imagepath, '\.png$', '@1.5x.png');
|
||||
@1d75ximage: replace(@imagepath, '\.png$', '@1.75x.png');
|
||||
@1d25ximage: replace(@imagepath, '\.png$', '@1.25x.png');
|
||||
@2ximage: replace(@imagepath, '\.png$', '@2x.png');
|
||||
|
||||
@media only screen {
|
||||
@media (-webkit-min-device-pixel-ratio: 1.5) and (-webkit-max-device-pixel-ratio: 1.9),
|
||||
(min-resolution: 1.5dppx) and (max-resolution: 1.9dppx),
|
||||
(min-resolution: 144dpi) and (max-resolution: 191dpi)
|
||||
{
|
||||
background-image: ~"url(@{1d5ximage})";
|
||||
background-size: @w @h;
|
||||
}
|
||||
|
||||
@media (-webkit-min-device-pixel-ratio: 2),
|
||||
(min-resolution: 2dppx),
|
||||
(min-resolution: 192dpi)
|
||||
{
|
||||
background-image: ~"url(@{2ximage})";
|
||||
background-size: @w @h;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.background-ximage-all(@image, @w: auto, @h: auto, @repeat: no-repeat, @commonimage: true) {
|
||||
.choose-image-path(@commonimage);
|
||||
@imagepath: '@{path}/@{image}';
|
||||
|
||||
background-image: if(@icon-src-base64, data-uri(%("%s", '@{imagepath}')), ~"url(@{imagepath})");
|
||||
background-repeat: @repeat;
|
||||
|
||||
@1d5ximage: replace(@imagepath, '\.png$', '@1.5x.png');
|
||||
@1d75ximage: replace(@imagepath, '\.png$', '@1.75x.png');
|
||||
@1d25ximage: replace(@imagepath, '\.png$', '@1.25x.png');
|
||||
@2ximage: replace(@imagepath, '\.png$', '@2x.png');
|
||||
|
||||
@media only screen {
|
||||
@media (-webkit-min-device-pixel-ratio: 1.25) and (-webkit-max-device-pixel-ratio: 1.49),
|
||||
(min-resolution: 1.25dppx) and (max-resolution: 1.49dppx),
|
||||
(min-resolution: 120dpi) and (max-resolution: 143dpi)
|
||||
{
|
||||
background-image: ~"url(@{1d25ximage})";
|
||||
background-size: @w @h;
|
||||
}
|
||||
|
||||
@media (-webkit-min-device-pixel-ratio: 1.5) and (-webkit-max-device-pixel-ratio: 1.74),
|
||||
(min-resolution: 1.5dppx) and (max-resolution: 1.74dppx),
|
||||
(min-resolution: 144dpi) and (max-resolution: 167dpi)
|
||||
{
|
||||
background-image: ~"url(@{1d5ximage})";
|
||||
background-size: @w @h;
|
||||
}
|
||||
|
||||
@media (-webkit-min-device-pixel-ratio: 1.75) and (-webkit-max-device-pixel-ratio: 1.9),
|
||||
(min-resolution: 1.75dppx) and (max-resolution: 1.9dppx),
|
||||
(min-resolution: 168dpi) and (max-resolution: 191dpi)
|
||||
{
|
||||
background-image: ~"url(@{1d75ximage})";
|
||||
background-size: @w @h;
|
||||
}
|
||||
|
||||
@media (-webkit-min-device-pixel-ratio: 2),
|
||||
(min-resolution: 2dppx),
|
||||
(min-resolution: 192dpi)
|
||||
{
|
||||
background-image: ~"url(@{2ximage})";
|
||||
background-size: @w @h;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.img-commonctrl {
|
||||
&.img-colored {
|
||||
filter: none;
|
||||
}
|
||||
}
|
||||
|
||||
@common-controls-width: 100px;
|
||||
.img-commonctrl,
|
||||
.dropdown-menu li .checked:before, .input-error:before, .input-warning:before,
|
||||
.btn-toolbar .icon.img-commonctrl, .list-item div.checked:before
|
||||
{
|
||||
background-image: if(@icon-src-base64, data-uri(%("%s",'@{common-image-path}/@{common-controls}')), ~"url(@{common-image-const-path}/@{common-controls})");
|
||||
background-repeat: no-repeat;
|
||||
filter: @component-normal-icon-filter;
|
||||
|
||||
@1d25ximage: replace(@common-controls, '\.png$', '@1.25x.png');
|
||||
@1d5ximage: replace(@common-controls, '\.png$', '@1.5x.png');
|
||||
@1d75ximage: replace(@common-controls, '\.png$', '@1.75x.png');
|
||||
@2ximage: replace(@common-controls, '\.png$', '@2x.png');
|
||||
|
||||
@media only screen {
|
||||
@media (-webkit-min-device-pixel-ratio: 1.5) and (-webkit-max-device-pixel-ratio: 1.9),
|
||||
(min-resolution: 1.5dppx) and (max-resolution: 1.9dppx),
|
||||
(min-resolution: 144dpi) and (max-resolution: 191dpi)
|
||||
{
|
||||
background-image: ~"url(@{common-image-const-path}/@{1d5ximage})";
|
||||
background-size: @common-controls-width auto;
|
||||
}
|
||||
|
||||
@media (-webkit-min-device-pixel-ratio: 2),
|
||||
(min-resolution: 2dppx),
|
||||
(min-resolution: 192dpi)
|
||||
{
|
||||
background-image: ~"url(@{common-image-const-path}/@{2ximage})";
|
||||
background-size: @common-controls-width auto;
|
||||
}
|
||||
}
|
||||
|
||||
.pixel-ratio__1_25 & {
|
||||
background-image: ~"url(@{common-image-const-path}/@{1d25ximage})";
|
||||
background-size: @common-controls-width auto;
|
||||
}
|
||||
|
||||
.pixel-ratio__1_75 & {
|
||||
background-image: ~"url(@{common-image-const-path}/@{1d75ximage})";
|
||||
background-size: @common-controls-width auto;
|
||||
}
|
||||
}
|
||||
|
||||
@img-colorpicker-width: 205px;
|
||||
.img-colorpicker, .hsb-colorpicker .empty-color:before
|
||||
{
|
||||
background-image: if(@icon-src-base64, data-uri(%("%s",'@{common-image-path}/hsbcolorpicker/hsb-colorpicker.png')), ~"url(@{common-image-const-path}/hsbcolorpicker/hsb-colorpicker.png)");
|
||||
background-repeat: no-repeat;
|
||||
|
||||
@media only screen {
|
||||
@media (-webkit-min-device-pixel-ratio: 1.5) and (-webkit-max-device-pixel-ratio: 1.9),
|
||||
(min-resolution: 1.5dppx) and (max-resolution: 1.9dppx),
|
||||
(min-resolution: 144dpi) and (max-resolution: 191dpi)
|
||||
{
|
||||
background-image: ~"url(@{common-image-const-path}/hsbcolorpicker/hsb-colorpicker@1.5x.png)";
|
||||
background-size: @img-colorpicker-width auto;
|
||||
}
|
||||
|
||||
@media (-webkit-min-device-pixel-ratio: 2),
|
||||
(min-resolution: 2dppx),
|
||||
(min-resolution: 192dpi)
|
||||
{
|
||||
background-image: ~"url(@{common-image-const-path}/hsbcolorpicker/hsb-colorpicker@2x.png)";
|
||||
background-size: @img-colorpicker-width auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon.lang-flag {
|
||||
@img-flags-width: 48px;
|
||||
|
||||
width: 16px;
|
||||
height: 12px;
|
||||
|
||||
background-image: if(@icon-src-base64, data-uri(%("%s",'@{common-image-path}/controls/flags.png')), ~"url(@{common-image-const-path}/controls/flags.png)");
|
||||
background-repeat: no-repeat;
|
||||
|
||||
@media only screen {
|
||||
@media (-webkit-min-device-pixel-ratio: 1.5) and (-webkit-max-device-pixel-ratio: 1.9),
|
||||
(min-resolution: 1.5dppx) and (max-resolution: 1.9dppx),
|
||||
(min-resolution: 144dpi) and (max-resolution: 191dpi)
|
||||
{
|
||||
background-image: ~"url(@{common-image-const-path}/controls/flags@1.5x.png)";
|
||||
background-size: @img-flags-width auto;
|
||||
}
|
||||
|
||||
@media (-webkit-min-device-pixel-ratio: 2),
|
||||
(min-resolution: 2dppx),
|
||||
(min-resolution: 192dpi)
|
||||
{
|
||||
background-image: ~"url(@{common-image-const-path}/controls/flags@2x.png)";
|
||||
background-size: @img-flags-width auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//.adaptive-solid-border(@width, @color, @borderside: all) {
|
||||
// @lb-border: if((@borderside = all), border, e('border-@{borderside}'));
|
||||
// @lb-border-width: if((@borderside = all), border-width, e('border-@{borderside}-width'));
|
||||
//
|
||||
// @{lb-border}: @width solid @color;
|
||||
//
|
||||
// @media only screen {
|
||||
// @media (-webkit-min-device-pixel-ratio: 1.5) and (-webkit-max-device-pixel-ratio: 1.9),
|
||||
// (min-resolution: 1.5dppx) and (max-resolution: 1.9dppx),
|
||||
// (min-resolution: 144dpi) and (max-resolution: 191dpi)
|
||||
// {
|
||||
// @{lb-border-width}: (@width / 1.5);
|
||||
// }
|
||||
// }
|
||||
//}
|
1148
test/unit-tests/common/main/resources/less/buttons.less
Normal file
1148
test/unit-tests/common/main/resources/less/buttons.less
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue