diff --git a/apps/common/main/lib/component/MenuItem.js b/apps/common/main/lib/component/MenuItem.js index ff07ef33ec..39d288b2fb 100644 --- a/apps/common/main/lib/component/MenuItem.js +++ b/apps/common/main/lib/component/MenuItem.js @@ -391,6 +391,28 @@ define([ } } } + }, + + setMenu: function (m) { + if (m && _.isObject(m) && _.isFunction(m.render)){ + if (this.rendered) { + if (this.menu && (this.menu instanceof Common.UI.Menu || this.menu instanceof Common.UI.MenuSimple)) { + Common.UI.Menu.Manager.unregister(this.menu); + this.menu.cmpEl && this.menu.cmpEl.remove(); + } + this.menu = m; + var el = this.cmpEl; + el.addClass('dropdown-submenu'); + this.menu.render(el); + el.mouseenter(_.bind(this.menu.alignPosition, this.menu)); + el.focusout(_.bind(this.onBlurItem, this)); + el.hover( + _.bind(this.onHoverItem, this), + _.bind(this.onUnHoverItem, this) + ); + } else + this.menu = m; + } } }); diff --git a/apps/documenteditor/main/app/controller/DocumentHolder.js b/apps/documenteditor/main/app/controller/DocumentHolder.js index aa24c42a17..cb85c36582 100644 --- a/apps/documenteditor/main/app/controller/DocumentHolder.js +++ b/apps/documenteditor/main/app/controller/DocumentHolder.js @@ -2564,7 +2564,7 @@ define([ onPluginContextMenu: function(data) { if (data && data.length>0 && this.documentHolder && this.documentHolder.currentMenu && this.documentHolder.currentMenu.isVisible()){ - this.documentHolder.addCustomItems(this.documentHolder.currentMenu, data); + this.documentHolder.updateCustomItems(this.documentHolder.currentMenu, data); } }, diff --git a/apps/documenteditor/main/app/view/DocumentHolder.js b/apps/documenteditor/main/app/view/DocumentHolder.js index 88bce780be..51e4dbc298 100644 --- a/apps/documenteditor/main/app/view/DocumentHolder.js +++ b/apps/documenteditor/main/app/view/DocumentHolder.js @@ -2926,68 +2926,96 @@ define([ }); }, - addCustomItems: function(menu, data) { - if (!menu || !data) return; + updateCustomItems: function(menu, data) { + if (!menu || !data || data.length<1) return; var me = this, lang = me.mode && me.mode.lang ? me.mode.lang.split(/[\-_]/)[0] : 'en'; - var getMenu = function(items, guid) { - var arr = []; + var findCustomItem = function(guid, id) { + if (menu && menu.items.length>0) { + for (var i = menu.items.length-1; i >=0 ; i--) { + if (menu.items[i].options.isCustomItem && (guid===undefined && id===undefined || menu.items[i].options.guid === guid && menu.items[i].value === id)) { + return menu.items[i]; + } + } + } + } + + var getMenu = function(items, guid, toMenu) { + if (toMenu) + toMenu.removeAll(); + else { + toMenu = new Common.UI.Menu({ + cls: 'shifted-right', + menuAlign: 'tl-tr', + items: [] + }); + toMenu.on('item:click', function(menu, item, e) { + me.api && me.api.onPluginContextMenuItemClick && me.api.onPluginContextMenuItemClick(item.options.guid, item.value); + }); + } items.forEach(function(item) { - if (item.text) { - var caption = ((typeof item.text == 'object') ? item.text[lang] || item.text['en'] : item.text) || ''; - arr.push({ - caption : caption, - isCustomItem: true, - value: item.id, - guid: guid, - menu: item.items && item.items.length>0 ? getMenu(item.items, guid) : false, - disabled: !!item.disabled - }); - } + item.text && toMenu.addItem({ + caption: ((typeof item.text == 'object') ? item.text[lang] || item.text['en'] : item.text) || '', + isCustomItem: true, + value: item.id, + guid: guid, + menu: item.items ? getMenu(item.items, guid) : false, + disabled: !!item.disabled + }); }); - - var submenu = new Common.UI.Menu({ - cls: 'shifted-right', - menuAlign: 'tl-tr', - items: arr - }); - submenu.on('item:click', function(menu, item, e) { - me.api && me.api.onPluginContextMenuItemClick && me.api.onPluginContextMenuItemClick(item.options.guid, item.value); - }); - return submenu; + return toMenu; } - if (data && data.length>0) { - menu.addItem(new Common.UI.MenuItem({ - caption: '--', - isCustomItem: true - })); - data.forEach(function(plugin) { - if (plugin && plugin.items && plugin.items.length>0) { - plugin.items.forEach(function(item) { - if (item.text) { - var caption = ((typeof item.text == 'object') ? item.text[lang] || item.text['en'] : item.text) || ''; - var mnu = new Common.UI.MenuItem({ - caption : caption, - isCustomItem: true, - value: item.id, - guid: plugin.guid, - menu: item.items && item.items.length>0 ? getMenu(item.items, plugin.guid) : false, - disabled: !!item.disabled - }).on('click', function(item, e) { - me.api && me.api.onPluginContextMenuItemClick && me.api.onPluginContextMenuItemClick(item.options.guid, item.value); - }); - menu.addItem(mnu); + // add separator + !findCustomItem() && menu.addItem(new Common.UI.MenuItem({ + caption: '--', + isCustomItem: true + })); + + var focused; + data.forEach(function(plugin) { + if (plugin && plugin.items && plugin.items.length>0) { + plugin.items.forEach(function(item) { + if (!item.text) return; + var mnu = findCustomItem(plugin.guid, item.id), + caption = ((typeof item.text == 'object') ? item.text[lang] || item.text['en'] : item.text) || ''; + if (mnu) { + mnu.setCaption(caption); + mnu.setDisabled(!!item.disabled); + if (item.items) { + if (mnu.menu) { + if (mnu.menu.isVisible() && mnu.menu.cmpEl.find(' > li:not(.divider):not(.disabled):visible').find('> a').filter(':focus').length>0) { + mnu.menu.isOver = true; + focused = mnu.cmpEl; + } + getMenu(item.items, plugin.guid, mnu.menu); + } else + mnu.setMenu(getMenu(item.items, plugin.guid)); } - }); - } - }); + } else { + var mnu = new Common.UI.MenuItem({ + caption : caption, + isCustomItem: true, + value: item.id, + guid: plugin.guid, + menu: item.items && item.items.length>=0 ? getMenu(item.items, plugin.guid) : false, + disabled: !!item.disabled + }).on('click', function(item, e) { + me.api && me.api.onPluginContextMenuItemClick && me.api.onPluginContextMenuItemClick(item.options.guid, item.value); + }); + menu.addItem(mnu); + } + }); + } + }); + + if (focused) { + var $subitems = $('> [role=menu]', focused).find('> li:not(.divider):not(.disabled):visible > a'); + ($subitems.length>0) && $subitems.eq(0).focus(); } - menu.alignPosition(); - }, clearCustomItems: function(menu) {