From 863d087ae8527a5d8a8d14e8fc136c62680e33c1 Mon Sep 17 00:00:00 2001 From: brahim <92426196+BrhmDev@users.noreply.github.com> Date: Sat, 21 Sep 2024 02:35:02 +0200 Subject: [PATCH 1/2] Add general gZenUIManager.addPopupTracking method to detect open popups on any element. Add popup tracking to navbar container. --- src/browser/base/content/ZenStartup.mjs | 1 + src/browser/base/content/ZenUIManager.mjs | 88 ++++++++++++++--------- 2 files changed, 57 insertions(+), 32 deletions(-) diff --git a/src/browser/base/content/ZenStartup.mjs b/src/browser/base/content/ZenStartup.mjs index b1ad3e4d0..bd4f37b65 100644 --- a/src/browser/base/content/ZenStartup.mjs +++ b/src/browser/base/content/ZenStartup.mjs @@ -41,6 +41,7 @@ gBrowser.tabContainer.arrowScrollbox.smoothScroll = false; ZenWorkspaces.init(); + gZenUIManager.init(); gZenVerticalTabsManager.init(); gZenCompactModeManager.init(); gZenKeyboardShortcuts.init(); diff --git a/src/browser/base/content/ZenUIManager.mjs b/src/browser/base/content/ZenUIManager.mjs index 13b6a34cc..a7b2332f4 100644 --- a/src/browser/base/content/ZenUIManager.mjs +++ b/src/browser/base/content/ZenUIManager.mjs @@ -1,4 +1,13 @@ var gZenUIManager = { + _popupTrackingElements: [], + + init () { + + addEventListener('popupshowing', this.onPopupShowing.bind(this)); + addEventListener('popuphidden', this.onPopupHidden.bind(this)); + addEventListener('click', this.onClick.bind(this)); + }, + openAndChangeToTab(url, options) { if (window.ownerGlobal.parent) { let tab = window.ownerGlobal.parent.gBrowser.addTrustedTab(url, options); @@ -24,6 +33,51 @@ var gZenUIManager = { createValidXULText(text) { return text.replace(/&/g, '&').replace(//g, '>'); }, + + /** + * Adds the 'has-popup-menu' attribute to the element when popup is opened on it. + * @param element element to track + */ + addPopupTracking(element) { + this._popupTrackingElements.push(element); + }, + + onPopupShowing(showEvent) { + for (const el of this._popupTrackingElements) { + if (!el.contains(event.explicitOriginalTarget)) { + continue; + } + removeEventListener('mousemove', this.__removeHasPopupAttribute); + el.setAttribute('has-popup-menu', ''); + + this.__lastElementClicked = null; + this.__currentPopup = showEvent.target; + this.__currentPopupTrackElement = el; + break; + } + }, + + onPopupHidden(hideEvent) { + if (!this.__currentPopup || this.__currentPopup !== hideEvent.target) { + return; + } + const element = this.__currentPopupTrackElement; + /* If item is selected on popup, the :hover effect will not be reapplied until the cursor moves, + to mitigate this: Wait for mousemove when popup item selected + */ + if (this.__lastElementClicked?.tagName === 'menuitem') { + this.__removeHasPopupAttribute = () => element.removeAttribute('has-popup-menu'); + addEventListener('mousemove', this.__removeHasPopupAttribute, {once: true}); + } else { + element.removeAttribute('has-popup-menu'); + } + this.__currentPopup = null; + this.__currentPopupTrackElement = null; + }, + + onClick(event) { + this.__lastElementClicked = event.target; + }, }; var gZenVerticalTabsManager = { @@ -151,7 +205,8 @@ var gZenCompactModeManager = { Services.prefs.addObserver('zen.view.compact', this._updateEvent.bind(this)); Services.prefs.addObserver('zen.view.compact.toolbar-flash-popup.duration', this._updatedSidebarFlashDuration.bind(this)); - addEventListener('popupshowing', this.keepSidebarVisibleOnContextMenu.bind(this)); + gZenUIManager.addPopupTracking(this.sidebar); + gZenUIManager.addPopupTracking(document.getElementById('zen-appcontent-navbar-container')); }, get prefefence() { @@ -210,37 +265,6 @@ var gZenCompactModeManager = { }, this.flashSidebarDuration); }, - keepSidebarVisibleOnContextMenu(event) { - if (!this.sidebar.contains(event.explicitOriginalTarget)) { - return; - } - this.sidebar.setAttribute('has-popup-menu', ''); - /* If the cursor is on the popup when it hides, the :hover effect will not be reapplied to the sidebar until the cursor moves, - to mitigate this: Wait for mousemove when popup item selected - */ - if (!this.__removeHasPopupAttribute) { - this.__removeHasPopupAttribute = () => this.sidebar.removeAttribute('has-popup-menu'); - } - removeEventListener('mousemove', this.__removeHasPopupAttribute); - - const waitForMouseMoveOnPopupSelect = (event) => { - if (event.target.tagName === 'menuitem') { - removeEventListener('click', waitForMouseMoveOnPopupSelect); - removeEventListener('popuphidden', removeHasPopupOnPopupHidden); - addEventListener('mousemove', this.__removeHasPopupAttribute, {once: true}); - } - } - const removeHasPopupOnPopupHidden = (hiddenEvent) => { - if (event.target === hiddenEvent.target) { - removeEventListener('click', waitForMouseMoveOnPopupSelect); - removeEventListener('popuphidden', removeHasPopupOnPopupHidden); - this.__removeHasPopupAttribute(); - } - } - addEventListener('click', waitForMouseMoveOnPopupSelect); - addEventListener('popuphidden', removeHasPopupOnPopupHidden); - }, - toggleToolbar() { let toolbar = document.getElementById('zen-appcontent-navbar-container'); toolbar.toggleAttribute('zen-user-show'); From b06edc0dd9cf4d1a7999c78a6f3e9125934fd748 Mon Sep 17 00:00:00 2001 From: brahim <92426196+BrhmDev@users.noreply.github.com> Date: Sat, 21 Sep 2024 11:50:15 +0200 Subject: [PATCH 2/2] Add removePopupTrackingAttribute method, refactor onPopupHidden. --- src/browser/base/content/ZenUIManager.mjs | 34 ++++++++++------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/src/browser/base/content/ZenUIManager.mjs b/src/browser/base/content/ZenUIManager.mjs index a7b2332f4..59e8bb0bc 100644 --- a/src/browser/base/content/ZenUIManager.mjs +++ b/src/browser/base/content/ZenUIManager.mjs @@ -3,9 +3,8 @@ var gZenUIManager = { init () { - addEventListener('popupshowing', this.onPopupShowing.bind(this)); - addEventListener('popuphidden', this.onPopupHidden.bind(this)); - addEventListener('click', this.onClick.bind(this)); + document.addEventListener('popupshowing', this.onPopupShowing.bind(this)); + document.addEventListener('popuphidden', this.onPopupHidden.bind(this)); }, openAndChangeToTab(url, options) { @@ -38,19 +37,21 @@ var gZenUIManager = { * Adds the 'has-popup-menu' attribute to the element when popup is opened on it. * @param element element to track */ - addPopupTracking(element) { + addPopupTrackingAttribute(element) { this._popupTrackingElements.push(element); }, + removePopupTrackingAttribute(element) { + this._popupTrackingElements.remove(element); + }, + onPopupShowing(showEvent) { for (const el of this._popupTrackingElements) { if (!el.contains(event.explicitOriginalTarget)) { continue; } - removeEventListener('mousemove', this.__removeHasPopupAttribute); + document.removeEventListener('mousemove', this.__removeHasPopupAttribute); el.setAttribute('has-popup-menu', ''); - - this.__lastElementClicked = null; this.__currentPopup = showEvent.target; this.__currentPopupTrackElement = el; break; @@ -62,22 +63,15 @@ var gZenUIManager = { return; } const element = this.__currentPopupTrackElement; - /* If item is selected on popup, the :hover effect will not be reapplied until the cursor moves, - to mitigate this: Wait for mousemove when popup item selected - */ - if (this.__lastElementClicked?.tagName === 'menuitem') { - this.__removeHasPopupAttribute = () => element.removeAttribute('has-popup-menu'); - addEventListener('mousemove', this.__removeHasPopupAttribute, {once: true}); - } else { + if (document.getElementById('main-window').matches(':hover')) { element.removeAttribute('has-popup-menu'); + } else { + this.__removeHasPopupAttribute = () => element.removeAttribute('has-popup-menu'); + document.addEventListener('mousemove', this.__removeHasPopupAttribute, {once: true}); } this.__currentPopup = null; this.__currentPopupTrackElement = null; }, - - onClick(event) { - this.__lastElementClicked = event.target; - }, }; var gZenVerticalTabsManager = { @@ -205,8 +199,8 @@ var gZenCompactModeManager = { Services.prefs.addObserver('zen.view.compact', this._updateEvent.bind(this)); Services.prefs.addObserver('zen.view.compact.toolbar-flash-popup.duration', this._updatedSidebarFlashDuration.bind(this)); - gZenUIManager.addPopupTracking(this.sidebar); - gZenUIManager.addPopupTracking(document.getElementById('zen-appcontent-navbar-container')); + gZenUIManager.addPopupTrackingAttribute(this.sidebar); + gZenUIManager.addPopupTrackingAttribute(document.getElementById('zen-appcontent-navbar-container')); }, get prefefence() {