summaryrefslogtreecommitdiffstats
path: root/comm/mail/components/unifiedtoolbar/content/mail-tab-button.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mail/components/unifiedtoolbar/content/mail-tab-button.mjs')
-rw-r--r--comm/mail/components/unifiedtoolbar/content/mail-tab-button.mjs153
1 files changed, 153 insertions, 0 deletions
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",
+});