From 2f868c978034ab3e5625220c790356bf5d517e44 Mon Sep 17 00:00:00 2001 From: Julia Radzhabova Date: Fri, 17 Sep 2021 18:16:00 +0300 Subject: [PATCH] Refactoring focus in color buttons --- apps/common/main/lib/component/ColorButton.js | 51 +++--------- apps/common/main/lib/component/Menu.js | 78 +++++++++++++++++++ .../main/lib/component/ThemeColorPalette.js | 17 ++-- 3 files changed, 99 insertions(+), 47 deletions(-) diff --git a/apps/common/main/lib/component/ColorButton.js b/apps/common/main/lib/component/ColorButton.js index 1b5d93b34..e33631d3b 100644 --- a/apps/common/main/lib/component/ColorButton.js +++ b/apps/common/main/lib/component/ColorButton.js @@ -59,8 +59,7 @@ define([ el: this.cmpEl.find('#' + this.menu.id + '-color-menu'), transparent: this.options.transparent, value: color, - colors: colors, - parentButton: this + colors: colors }); this.colorPicker.on('select', _.bind(this.onColorSelect, this)); this.cmpEl.find('#' + this.menu.id + '-color-new').on('click', _.bind(this.addNewColor, this)); @@ -69,6 +68,7 @@ define([ this.colorAuto = this.cmpEl.find('#' + this.menu.id + '-color-auto > a'); (color == 'auto') && this.setAutoColor(true); } + this.initInnerMenu(); } return this.colorPicker; }, @@ -105,7 +105,7 @@ define([ } ]) }); - this.colorPicker && (this.colorPicker.parentButton = menu); + this.initInnerMenu(); var me = this; menu.on('keydown:before', _.bind(this.onBeforeKeyDown, this)); menu.on('show:after', function(menu) { @@ -123,6 +123,14 @@ define([ return this.menu; }, + initInnerMenu: function() { + if (!this.colorPicker || typeof this.menu !== 'object') return; + + var index = (this.options.additionalItems || []).length + (this.options.auto ? 2 : 0); + this.colorPicker.outerMenu = {menu: this.menu, index: index}; + this.menu.setInnerMenu([{menu: this.colorPicker, index: index}]); + }, + setMenu: function (m) { m = m || this.getMenu(); Common.UI.Button.prototype.setMenu.call(this, m); @@ -174,49 +182,12 @@ define([ $('button', this.cmpEl).click(); return false; } - if (e.keyCode == Common.UI.Keys.RETURN) { - var li = $(e.target).closest('li'); - if (li.length>0) { - e.preventDefault(); - e.stopPropagation(); - li.click(); - } - Common.UI.Menu.Manager.hideAll(); - } else if (e.namespace!=="after.bs.dropdown" && (e.keyCode == Common.UI.Keys.DOWN || e.keyCode == Common.UI.Keys.UP)) { - var $items = $('> [role=menu] > li:not(.divider):not(.disabled):visible', menu.$el).find('> a'); - if (!$items.length) return; - var index = $items.index($items.filter(':focus')), - me = this, - pickerIndex = $items.length-1 ; - if (e.keyCode == Common.UI.Keys.DOWN && (index==pickerIndex-1 || pickerIndex==0) || e.keyCode == Common.UI.Keys.UP && index==pickerIndex) { - e.preventDefault(); - e.stopPropagation(); - _.delay(function() { - me.focusInner(e); - }, 10); - } - } }, isMenuOpen: function() { return this.cmpEl.hasClass('open'); }, - focusInner: function(e) { - if (!this.colorPicker) return; - - this.colorPicker.focus(e.keyCode == Common.UI.Keys.DOWN ? 'first' : 'last'); - }, - - focusOuter: function(e) { - if (!this.menu) return; - - var $items = $('> [role=menu] > li:not(.divider):not(.disabled):visible', this.menu.$el).find('> a'); - if (!$items.length) return; - - $items.eq(e.keyCode == Common.UI.Keys.UP ? $items.length-2 : $items.length-1).focus(); - }, - textNewColor: 'Add New Custom Color', textAutoColor: 'Automatic' diff --git a/apps/common/main/lib/component/Menu.js b/apps/common/main/lib/component/Menu.js index 398f0490c..043276199 100644 --- a/apps/common/main/lib/component/Menu.js +++ b/apps/common/main/lib/component/Menu.js @@ -267,6 +267,7 @@ define([ this.parentEl.on('hide.bs.dropdown', _.bind(me.onBeforeHideMenu, me)); this.parentEl.on('hidden.bs.dropdown', _.bind(me.onAfterHideMenu, me)); this.parentEl.on('keydown.after.bs.dropdown', _.bind(me.onAfterKeydownMenu, me)); + this.options.innerMenus && this.on('keydown:before', _.bind(me.onBeforeKeyDown, me)); menuRoot.hover( function(e) { me.isOver = true;}, @@ -491,6 +492,83 @@ define([ } }, + onBeforeKeyDown: function(menu, e) { + if (e.keyCode == Common.UI.Keys.RETURN) { + var li = $(e.target).closest('li'); + if (li.length>0) { + e.preventDefault(); + e.stopPropagation(); + li.click(); + } + Common.UI.Menu.Manager.hideAll(); + } else if (e.namespace!=="after.bs.dropdown" && (e.keyCode == Common.UI.Keys.DOWN || e.keyCode == Common.UI.Keys.UP)) { + var innerMenu = this.findInnerMenu(e.keyCode); + if (innerMenu && innerMenu.focusInner) { + e.preventDefault(); + e.stopPropagation(); + _.delay(function() { + innerMenu.focusInner(e); + }, 10); + } + } + }, + + setInnerMenu: function(menus) { + if (this.options.innerMenus || !menus) return; + + this.options.innerMenus = menus; + this.options.innerMenus && this.on('keydown:before', _.bind(this.onBeforeKeyDown, this)); + }, + + findInnerMenu: function(direction, index, findOuter) { + if (!this.options.innerMenus) return; + + var $allItems = $('> li', this.menuRoot), + $liItems = $('> li:not(.divider):not(.disabled):visible', this.menuRoot), + length = $liItems.length; + if (!length) return; + + var step = 0; + while (step a').filter(':focus').parent()); + var checkedIndex = (direction == Common.UI.Keys.DOWN) ? (focusedIndex0 ? focusedIndex-1 : length-1), + checkedItem = $liItems.eq(checkedIndex); + index = $allItems.index(checkedItem); + + for (var i=0; i a').length>0) + return findOuter ? checkedItem : undefined; + step++; + } + }, + + focusInner: function(e) { + if (e.keyCode == Common.UI.Keys.UP) + this.items[this.items.length-1].cmpEl.find('> a').focus(); + else + this.items[0].cmpEl.find('> a').focus(); + }, + + focusOuter: function(e, index) { + var innerMenu = this.findInnerMenu(e.keyCode, index, true); + if (innerMenu && innerMenu.focusInner) { + _.delay(function() { + innerMenu.focusInner(e); + }, 10); + } else if (innerMenu) { + innerMenu.find('> a').focus(); + } else { + var $items = $('> li:not(.divider):not(.disabled):visible', this.menuRoot).find('> a'), + length = $items.length; + length && $items.eq(e.keyCode == Common.UI.Keys.UP ? (index<0 ? length-1 : index) : (index>=length-1 ? 0 : index+1)).focus(); + } + }, + onItemClick: function(item, e) { if (!item.menu) this.isOver = false; if (item.options.stopPropagation) { diff --git a/apps/common/main/lib/component/ThemeColorPalette.js b/apps/common/main/lib/component/ThemeColorPalette.js index 79b937503..dfefb3980 100644 --- a/apps/common/main/lib/component/ThemeColorPalette.js +++ b/apps/common/main/lib/component/ThemeColorPalette.js @@ -105,7 +105,6 @@ define([ this.colors = me.options.colors || this.generateColorData(me.options.themecolors, me.options.effects, me.options.standardcolors, me.options.transparent); this.enableKeyEvents= me.options.enableKeyEvents; this.tabindex = me.options.tabindex || 0; - this.parentButton = me.options.parentButton; this.lastSelectedIdx = -1; me.colorItems = []; @@ -516,8 +515,8 @@ define([ var rec = this.getSelectedColor(); if (data.keyCode==Common.UI.Keys.RETURN) { rec && this.selectByIndex(rec.index); - if (this.parentButton && this.parentButton.menu) - this.parentButton.menu.hide(); + if (this.outerMenu && this.outerMenu.menu) + this.outerMenu.menu.hide(); } else { var idx = rec ? rec.index : -1; if (idx<0) { @@ -544,9 +543,9 @@ define([ idx = this._layoutParams.itemsIndexes[topIdx][leftIdx]; } } else if (data.keyCode==Common.UI.Keys.UP) { - if (topIdx==0 && this.parentButton) { + if (topIdx==0 && this.outerMenu && this.outerMenu.menu) { this.clearSelection(true); - this.parentButton.focusOuter(data); + this.outerMenu.menu.focusOuter(data, this.outerMenu.index); } else while (idx===undefined) { topIdx--; @@ -554,9 +553,9 @@ define([ idx = this._layoutParams.itemsIndexes[topIdx][leftIdx]; } } else { - if (topIdx==this._layoutParams.rows-1 && this.parentButton) { + if (topIdx==this._layoutParams.rows-1 && this.outerMenu && this.outerMenu.menu) { this.clearSelection(true); - this.parentButton.focusOuter(data); + this.outerMenu.menu.focusOuter(data, this.outerMenu.index); } else while (idx===undefined) { topIdx++; @@ -635,6 +634,10 @@ define([ this.selectByIndex(index, true); }, + focusInner: function(e) { + this.focus(e.keyCode == Common.UI.Keys.DOWN ? 'first' : 'last'); + }, + textThemeColors : 'Theme Colors', textStandartColors : 'Standart Colors' }, Common.UI.ThemeColorPalette || {}));