From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../unifiedtoolbar/content/mail-tab-button.mjs | 153 +++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 comm/mail/components/unifiedtoolbar/content/mail-tab-button.mjs (limited to 'comm/mail/components/unifiedtoolbar/content/mail-tab-button.mjs') diff --git a/comm/mail/components/unifiedtoolbar/content/mail-tab-button.mjs b/comm/mail/components/unifiedtoolbar/content/mail-tab-button.mjs new file mode 100644 index 0000000000..a0eeee2279 --- /dev/null +++ b/comm/mail/components/unifiedtoolbar/content/mail-tab-button.mjs @@ -0,0 +1,153 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at http://mozilla.org/MPL/2.0/. */ + +import { UnifiedToolbarButton } from "./unified-toolbar-button.mjs"; + +/* import-globals-from ../../../base/content/globalOverlay.js */ + +/** + * Mail tab specific unified toolbar button. Instead of tracking a global + * command, its state gets re-evaluated every time the state of about:3pane or + * about:message tab changes in a relevant way. + */ +export class MailTabButton extends UnifiedToolbarButton { + /** + * Array of events to listen for on the about:3pane document. + * + * @type {string[]} + */ + observed3PaneEvents = ["folderURIChanged", "select"]; + + /** + * Array of events to listen for on the message browser. + * + * @type {string[]} + */ + observedAboutMessageEvents = ["load"]; + + /** + * Listeners we've added in tabs. + * + * @type {{tabId: any, target: EventTarget, event: string, callback: function}[]} + */ + #listeners = []; + + connectedCallback() { + super.connectedCallback(); + this.#addTabListeners(); + this.onCommandContextChange(); + } + + disconnectedCallback() { + super.disconnectedCallback(); + for (const listener of this.#listeners) { + listener.target.removeEventListener(listener.event, listener.callback); + } + this.#listeners.length = 0; + } + + /** + * Callback for customizable-element when the current tab is switched while + * this button is visible. + */ + onTabSwitched() { + this.#addTabListeners(); + this.onCommandContextChange(); + } + + /** + * Callback for customizable-element when a tab is closed. + * + * @param {TabInfo} tab + */ + onTabClosing(tab) { + this.#removeListenersForTab(tab.tabId); + } + + /** + * Remove all event listeners this button has for a given tab. + * + * @param {*} tabId - ID of the tab to remove listeners for. + */ + #removeListenersForTab(tabId) { + for (const listener of this.#listeners) { + if (listener.tabId === tabId) { + listener.target.removeEventListener(listener.event, listener.callback); + } + } + this.#listeners = this.#listeners.filter( + listener => listener.tabId !== tabId + ); + } + + /** + * Add missing event listeners for the current tab. + */ + #addTabListeners() { + const tabmail = document.getElementById("tabmail"); + const tabId = tabmail.currentTabInfo.tabId; + const existingListeners = this.#listeners.filter( + listener => listener.tabId === tabId + ); + let expectedEventListeners = []; + switch (tabmail.currentTabInfo.mode.name) { + case "mail3PaneTab": + expectedEventListeners = this.observed3PaneEvents.concat( + this.observedAboutMessageEvents + ); + break; + case "mailMessageTab": + expectedEventListeners = this.observedAboutMessageEvents.concat(); + break; + } + const missingListeners = expectedEventListeners.filter(event => + existingListeners.every(listener => listener.event !== event) + ); + if (!missingListeners.length) { + return; + } + const contentWindow = tabmail.currentTabInfo.chromeBrowser.contentWindow; + for (const event of missingListeners) { + const listener = { + event, + tabId, + callback: this.#handle3PaneChange, + target: contentWindow, + }; + if ( + this.observedAboutMessageEvents.includes(event) && + contentWindow.messageBrowser + ) { + listener.target = contentWindow.messageBrowser.contentWindow; + } + listener.target.addEventListener(listener.event, listener.callback); + this.#listeners.push(listener); + } + } + + /** + * Event handling callback when an event by a tab is fired. + */ + #handle3PaneChange = () => { + this.onCommandContextChange(); + }; + + /** + * Handle the context changing, updating the disabled state for the button + * etc. + */ + onCommandContextChange() { + if (!this.observedCommand) { + return; + } + try { + this.disabled = !getEnabledControllerForCommand(this.observedCommand); + } catch { + this.disabled = true; + } + } +} +customElements.define("mail-tab-button", MailTabButton, { + extends: "button", +}); -- cgit v1.2.3