diff options
Diffstat (limited to 'ext/js/dom')
-rw-r--r-- | ext/js/dom/popup-menu.js | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/ext/js/dom/popup-menu.js b/ext/js/dom/popup-menu.js index 9ad4e260..af076baa 100644 --- a/ext/js/dom/popup-menu.js +++ b/ext/js/dom/popup-menu.js @@ -24,6 +24,7 @@ class PopupMenu extends EventDispatcher { this._bodyNode = containerNode.querySelector('.popup-menu-body'); this._isClosed = false; this._eventListeners = new EventListenerCollection(); + this._itemEventListeners = new EventListenerCollection(); } get sourceElement() { @@ -47,17 +48,13 @@ class PopupMenu extends EventDispatcher { } prepare() { - const items = this._bodyNode.querySelectorAll('.popup-menu-item'); this._setPosition(); this._containerNode.focus(); this._eventListeners.addEventListener(window, 'resize', this._onWindowResize.bind(this), false); this._eventListeners.addEventListener(this._containerNode, 'click', this._onMenuContainerClick.bind(this), false); - const onMenuItemClick = this._onMenuItemClick.bind(this); - for (const item of items) { - this._eventListeners.addEventListener(item, 'click', onMenuItemClick, false); - } + this.updateMenuItems(); PopupMenu.openMenus.add(this); @@ -69,7 +66,20 @@ class PopupMenu extends EventDispatcher { } close(cancelable=true) { - return this._close(null, 'close', cancelable); + return this._close(null, 'close', cancelable, {}); + } + + updateMenuItems() { + this._itemEventListeners.removeAllEventListeners(); + const items = this._bodyNode.querySelectorAll('.popup-menu-item'); + const onMenuItemClick = this._onMenuItemClick.bind(this); + for (const item of items) { + this._itemEventListeners.addEventListener(item, 'click', onMenuItemClick, false); + } + } + + updatePosition() { + this._setPosition(); } // Private @@ -78,7 +88,7 @@ class PopupMenu extends EventDispatcher { if (e.currentTarget !== e.target) { return; } e.stopPropagation(); e.preventDefault(); - this._close(null, 'outside', true); + this._close(null, 'outside', true, e); } _onMenuItemClick(e) { @@ -86,11 +96,11 @@ class PopupMenu extends EventDispatcher { if (item.disabled) { return; } e.stopPropagation(); e.preventDefault(); - this._close(item, 'item', true); + this._close(item, 'item', true, e); } _onWindowResize() { - this._close(null, 'resize', true); + this._close(null, 'resize', true, {}); } _setPosition() { @@ -172,15 +182,20 @@ class PopupMenu extends EventDispatcher { menu.style.top = `${y}px`; } - _close(item, cause, cancelable) { + _close(item, cause, cancelable, originalEvent) { if (this._isClosed) { return true; } const action = (item !== null ? item.dataset.menuAction : null); + const {altKey=false, ctrlKey=false, metaKey=false, shiftKey=false} = originalEvent; const detail = { menu: this, item, action, - cause + cause, + altKey, + ctrlKey, + metaKey, + shiftKey }; const result = this._sourceElement.dispatchEvent(new CustomEvent('menuClose', {bubbles: false, cancelable, detail})); if (cancelable && !result) { return false; } @@ -189,6 +204,7 @@ class PopupMenu extends EventDispatcher { this._isClosed = true; this._eventListeners.removeAllEventListeners(); + this._itemEventListeners.removeAllEventListeners(); if (this._containerNode.parentNode !== null) { this._containerNode.parentNode.removeChild(this._containerNode); } |