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 --- .../extensions/parent/ext-messageDisplayAction.js | 251 +++++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100644 comm/mail/components/extensions/parent/ext-messageDisplayAction.js (limited to 'comm/mail/components/extensions/parent/ext-messageDisplayAction.js') diff --git a/comm/mail/components/extensions/parent/ext-messageDisplayAction.js b/comm/mail/components/extensions/parent/ext-messageDisplayAction.js new file mode 100644 index 0000000000..026ddfc736 --- /dev/null +++ b/comm/mail/components/extensions/parent/ext-messageDisplayAction.js @@ -0,0 +1,251 @@ +/* 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/. */ + +"use strict"; + +ChromeUtils.defineModuleGetter( + this, + "ToolbarButtonAPI", + "resource:///modules/ExtensionToolbarButtons.jsm" +); + +var { ExtensionCommon } = ChromeUtils.importESModule( + "resource://gre/modules/ExtensionCommon.sys.mjs" +); +var { makeWidgetId } = ExtensionCommon; + +const messageDisplayActionMap = new WeakMap(); + +this.messageDisplayAction = class extends ToolbarButtonAPI { + static for(extension) { + return messageDisplayActionMap.get(extension); + } + + async onManifestEntry(entryName) { + await super.onManifestEntry(entryName); + messageDisplayActionMap.set(this.extension, this); + } + + close() { + super.close(); + messageDisplayActionMap.delete(this.extension); + windowTracker.removeListener("TabSelect", this); + } + + constructor(extension) { + super(extension, global); + this.manifest_name = "message_display_action"; + this.manifestName = "messageDisplayAction"; + this.manifest = extension.manifest[this.manifest_name]; + this.moduleName = this.manifestName; + + this.windowURLs = [ + "chrome://messenger/content/messenger.xhtml", + "chrome://messenger/content/messageWindow.xhtml", + ]; + this.toolboxId = "header-view-toolbox"; + this.toolbarId = "header-view-toolbar"; + + windowTracker.addListener("TabSelect", this); + } + + static onUninstall(extensionId) { + let widgetId = makeWidgetId(extensionId); + let id = `${widgetId}-messageDisplayAction-toolbarbutton`; + let toolbar = "header-view-toolbar"; + + // Check all possible windows and remove the toolbarbutton if found. + // Sadly we have to hardcode these values here, as the add-on is already + // shutdown when onUninstall is called. + let windowURLs = [ + "chrome://messenger/content/messenger.xhtml", + "chrome://messenger/content/messageWindow.xhtml", + ]; + for (let windowURL of windowURLs) { + for (let setName of ["currentset", "extensionset"]) { + let set = Services.xulStore + .getValue(windowURL, toolbar, setName) + .split(","); + let newSet = set.filter(e => e != id); + if (newSet.length < set.length) { + Services.xulStore.setValue( + windowURL, + toolbar, + setName, + newSet.join(",") + ); + } + } + } + } + + /** + * Overrides the super class to update every about:message in this window. + */ + paint(window) { + window.addEventListener("aboutMessageLoaded", this); + for (let bc of window.browsingContext.getAllBrowsingContextsInSubtree()) { + if (bc.currentURI.spec == "about:message") { + super.paint(bc.window); + } + } + } + + /** + * Overrides the super class to update every about:message in this window. + */ + unpaint(window) { + window.removeEventListener("aboutMessageLoaded", this); + for (let bc of window.browsingContext.getAllBrowsingContextsInSubtree()) { + if (bc.currentURI.spec == "about:message") { + super.unpaint(bc.window); + } + } + } + + /** + * Overrides the super class to update every about:message in this window. + */ + async updateWindow(window) { + for (let bc of window.browsingContext.getAllBrowsingContextsInSubtree()) { + if (bc.currentURI.spec == "about:message") { + super.updateWindow(bc.window); + } + } + } + + /** + * Overrides the super class where `target` is a tab, to update + * about:message instead of the window. + */ + async updateOnChange(target) { + if (!target) { + await super.updateOnChange(target); + return; + } + + let window = Cu.getGlobalForObject(target); + if (window == target) { + await super.updateOnChange(target); + return; + } + + let tabmail = window.top.document.getElementById("tabmail"); + if (!tabmail || target != tabmail.selectedTab) { + return; + } + + switch (target.mode.name) { + case "mail3PaneTab": + await this.updateWindow( + target.chromeBrowser.contentWindow.messageBrowser.contentWindow + ); + break; + case "mailMessageTab": + await this.updateWindow(target.chromeBrowser.contentWindow); + break; + } + } + + handleEvent(event) { + super.handleEvent(event); + let window = event.target.ownerGlobal; + + switch (event.type) { + case "aboutMessageLoaded": + // Add the toolbar button to any about:message that comes along. + super.paint(event.target); + break; + case "popupshowing": + const menu = event.target; + if (menu.tagName != "menupopup") { + return; + } + + const trigger = menu.triggerNode; + const node = window.document.getElementById(this.id); + const contexts = ["header-toolbar-context-menu"]; + if (contexts.includes(menu.id) && node && node.contains(trigger)) { + global.actionContextMenu({ + tab: window.tabOrWindow, + pageUrl: window.getMessagePaneBrowser().currentURI.spec, + extension: this.extension, + onMessageDisplayAction: true, + menu, + }); + } + + if ( + menu.dataset.actionMenu == "messageDisplayAction" && + this.extension.id == menu.dataset.extensionId + ) { + global.actionContextMenu({ + tab: window.tabOrWindow, + pageUrl: window.getMessagePaneBrowser().currentURI.spec, + extension: this.extension, + inMessageDisplayActionMenu: true, + menu, + }); + } + break; + } + } + + /** + * Overrides the super class to trigger the action in the current about:message. + */ + async triggerAction(window, options) { + // Supported message browsers: + // - in mail tab (browser could be hidden) + // - in message tab + // - in message window + + // The passed in window could be the window of one of the supported message + // browsers already. To know if the browser is hidden, always re-search the + // message window and start at the top. + let tabmail = window.top.document.getElementById("tabmail"); + if (tabmail) { + // A mail tab or a message tab. + let isHidden = + tabmail.currentAbout3Pane && + tabmail.currentAbout3Pane.messageBrowser.hidden; + + if (tabmail.currentAboutMessage && !isHidden) { + return super.triggerAction(tabmail.currentAboutMessage, options); + } + } else if (window.top.messageBrowser) { + // A message window. + return super.triggerAction( + window.top.messageBrowser.contentWindow, + options + ); + } + + return false; + } + + /** + * Returns an element in the toolbar, which is to be used as default insertion + * point for new toolbar buttons in non-customizable toolbars. + * + * May return null to append new buttons to the end of the toolbar. + * + * @param {DOMElement} toolbar - a toolbar node + * @returns {DOMElement} a node which is to be used as insertion point, or null + */ + getNonCustomizableToolbarInsertionPoint(toolbar) { + return toolbar.querySelector("#otherActionsButton"); + } + + makeButton(window) { + let button = super.makeButton(window); + button.classList.add("message-header-view-button"); + // The header toolbar has no associated context menu. Add one directly to + // this button. + button.setAttribute("context", "header-toolbar-context-menu"); + return button; + } +}; + +global.messageDisplayActionFor = this.messageDisplayAction.for; -- cgit v1.2.3