diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /comm/mail/components/unifiedtoolbar/content/items | |
parent | Initial commit. (diff) | |
download | thunderbird-upstream.tar.xz thunderbird-upstream.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
11 files changed, 756 insertions, 0 deletions
diff --git a/comm/mail/components/unifiedtoolbar/content/items/add-to-calendar-button.mjs b/comm/mail/components/unifiedtoolbar/content/items/add-to-calendar-button.mjs new file mode 100644 index 0000000000..9fe0aef11d --- /dev/null +++ b/comm/mail/components/unifiedtoolbar/content/items/add-to-calendar-button.mjs @@ -0,0 +1,38 @@ +/* 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 { MailTabButton } from "chrome://messenger/content/unifiedtoolbar/mail-tab-button.mjs"; + +/* import-globals-from ../../../../../calendar/base/content/calendar-extract.js */ + +/** + * Unified toolbar button to add the selected message to a calendar as event or + * task. + * Attributes: + * - type: "event" or "task", specifying the target type to create. + */ +class AddToCalendarButton extends MailTabButton { + onCommandContextChange() { + const about3Pane = document.getElementById("tabmail").currentAbout3Pane; + this.disabled = + (about3Pane && !about3Pane.gDBView) || + (about3Pane?.gDBView?.numSelected ?? -1) === 0; + } + + handleClick = event => { + const tabmail = document.getElementById("tabmail"); + const about3Pane = tabmail.currentAbout3Pane; + const type = this.getAttribute("type"); + calendarExtract.extractFromEmail( + tabmail.currentAboutMessage?.gMessage || + about3Pane.gDBView.hdrForFirstSelectedMessage, + type !== "task" + ); + event.preventDefault(); + event.stopPropagation(); + }; +} +customElements.define("add-to-calendar-button", AddToCalendarButton, { + extends: "button", +}); diff --git a/comm/mail/components/unifiedtoolbar/content/items/addons-button.mjs b/comm/mail/components/unifiedtoolbar/content/items/addons-button.mjs new file mode 100644 index 0000000000..593513cd35 --- /dev/null +++ b/comm/mail/components/unifiedtoolbar/content/items/addons-button.mjs @@ -0,0 +1,19 @@ +/* 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 "chrome://messenger/content/unifiedtoolbar/unified-toolbar-button.mjs"; + +/** + * Unified toolbar button that opens the add-ons manager. + */ +class AddonsButton extends UnifiedToolbarButton { + handleClick = event => { + window.openAddonsMgr(); + event.preventDefault(); + event.stopPropagation(); + }; +} +customElements.define("addons-button", AddonsButton, { + extends: "button", +}); diff --git a/comm/mail/components/unifiedtoolbar/content/items/compact-folder-button.mjs b/comm/mail/components/unifiedtoolbar/content/items/compact-folder-button.mjs new file mode 100644 index 0000000000..78abbaef3a --- /dev/null +++ b/comm/mail/components/unifiedtoolbar/content/items/compact-folder-button.mjs @@ -0,0 +1,40 @@ +/* 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 { MailTabButton } from "chrome://messenger/content/unifiedtoolbar/mail-tab-button.mjs"; + +/** + * Unified toolbar button for compacting the current folder. + */ +class CompactFolderButton extends MailTabButton { + observed3PaneEvents = ["folderURIChanged"]; + observedAboutMessageEvents = []; + + onCommandContextChange() { + const { gFolder } = + document.getElementById("tabmail").currentAbout3Pane ?? {}; + if (!gFolder) { + this.disabled = true; + return; + } + try { + this.disabled = !gFolder.isCommandEnabled("cmd_compactFolder"); + } catch { + this.disabled = true; + } + } + + handleClick = event => { + const about3Pane = document.getElementById("tabmail").currentAbout3Pane; + if (!about3Pane) { + return; + } + about3Pane.folderPane.compactFolder(about3Pane.gFolder); + event.preventDefault(); + event.stopPropagation(); + }; +} +customElements.define("compact-folder-button", CompactFolderButton, { + extends: "button", +}); diff --git a/comm/mail/components/unifiedtoolbar/content/items/delete-button.mjs b/comm/mail/components/unifiedtoolbar/content/items/delete-button.mjs new file mode 100644 index 0000000000..02b8bb8035 --- /dev/null +++ b/comm/mail/components/unifiedtoolbar/content/items/delete-button.mjs @@ -0,0 +1,44 @@ +/* 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 { MailTabButton } from "chrome://messenger/content/unifiedtoolbar/mail-tab-button.mjs"; + +/* import-globals-from ../../../../base/content/globalOverlay.js */ + +/** + * Unified toolbar button that deletes the selected message or folder. + */ +class DeleteButton extends MailTabButton { + onCommandContextChange() { + const tabmail = document.getElementById("tabmail"); + try { + const controller = getEnabledControllerForCommand("cmd_deleteMessage"); + const tab = tabmail.currentTabInfo; + const message = tab.message; + + this.disabled = !controller || !message; + + if (!this.disabled && message.flags & Ci.nsMsgMessageFlags.IMAPDeleted) { + this.setAttribute("label-id", "toolbar-undelete-label"); + document.l10n.setAttributes(this, "toolbar-undelete"); + } else { + this.setAttribute("label-id", "toolbar-delete-label"); + document.l10n.setAttributes(this, "toolbar-delete-title"); + } + } catch { + this.disabled = true; + } + } + + handleClick(event) { + goDoCommand( + event.shiftKey ? "cmd_shiftDeleteMessage" : "cmd_deleteMessage" + ); + event.preventDefault(); + event.stopPropagation(); + } +} +customElements.define("delete-button", DeleteButton, { + extends: "button", +}); diff --git a/comm/mail/components/unifiedtoolbar/content/items/folder-location-button.mjs b/comm/mail/components/unifiedtoolbar/content/items/folder-location-button.mjs new file mode 100644 index 0000000000..9d99dbbf30 --- /dev/null +++ b/comm/mail/components/unifiedtoolbar/content/items/folder-location-button.mjs @@ -0,0 +1,81 @@ +/* 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 { MailTabButton } from "chrome://messenger/content/unifiedtoolbar/mail-tab-button.mjs"; + +const lazy = {}; +ChromeUtils.defineModuleGetter( + lazy, + "FolderUtils", + "resource:///modules/FolderUtils.jsm" +); + +class FolderLocationButton extends MailTabButton { + /** + * Image element displaying the icon on the button. + * + * @type {Image?} + */ + #icon = null; + + /** + * If we've added our event listeners, especially to the current about3pane. + * + * @type {boolean} + */ + #addedListeners = false; + + observed3PaneEvents = ["folderURIChanged"]; + + observedAboutMessageEvents = []; + + connectedCallback() { + super.connectedCallback(); + if (this.#addedListeners) { + return; + } + this.#icon = this.querySelector(".button-icon"); + this.onCommandContextChange(); + this.#addedListeners = true; + const popup = document.getElementById(this.getAttribute("popup")); + popup.addEventListener("command", this.#handlePopupCommand); + } + + disconnectedCallback() { + super.disconnectedCallback(); + if (this.#addedListeners) { + const popup = document.getElementById(this.getAttribute("popup")); + popup.removeEventListener("command", this.#handlePopupCommand); + } + } + + #handlePopupCommand = event => { + const about3Pane = document.getElementById("tabmail").currentAbout3Pane; + about3Pane.displayFolder(event.target._folder.URI); + }; + + /** + * Update the label and icon of the button from the currently selected folder + * in the local 3pane. + */ + onCommandContextChange() { + if (!this.#icon) { + return; + } + const { gFolder } = + document.getElementById("tabmail").currentAbout3Pane ?? {}; + if (!gFolder) { + this.disabled = true; + return; + } + this.disabled = false; + this.label.textContent = gFolder.name; + this.#icon.style = `content: url(${lazy.FolderUtils.getFolderIcon( + gFolder + )});`; + } +} +customElements.define("folder-location-button", FolderLocationButton, { + extends: "button", +}); diff --git a/comm/mail/components/unifiedtoolbar/content/items/global-search-bar.mjs b/comm/mail/components/unifiedtoolbar/content/items/global-search-bar.mjs new file mode 100644 index 0000000000..924955c895 --- /dev/null +++ b/comm/mail/components/unifiedtoolbar/content/items/global-search-bar.mjs @@ -0,0 +1,223 @@ +/* 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 { SearchBar } from "chrome://messenger/content/unifiedtoolbar/search-bar.mjs"; + +const { XPCOMUtils } = ChromeUtils.importESModule( + "resource://gre/modules/XPCOMUtils.sys.mjs" +); + +const lazy = {}; + +ChromeUtils.defineESModuleGetters(lazy, { + GlodaIMSearcher: "resource:///modules/GlodaIMSearcher.sys.mjs", +}); +ChromeUtils.defineModuleGetter( + lazy, + "GlodaMsgSearcher", + "resource:///modules/gloda/GlodaMsgSearcher.jsm" +); +ChromeUtils.defineModuleGetter( + lazy, + "GlodaConstants", + "resource:///modules/gloda/GlodaConstants.jsm" +); +ChromeUtils.defineModuleGetter( + lazy, + "Gloda", + "resource:///modules/gloda/GlodaPublic.jsm" +); +XPCOMUtils.defineLazyGetter( + lazy, + "glodaCompleter", + () => + Cc["@mozilla.org/autocomplete/search;1?name=gloda"].getService( + Ci.nsIAutoCompleteSearch + ).wrappedJSObject +); + +/** + * Unified toolbar global search bar. + */ +class GlobalSearchBar extends SearchBar { + // Fields required for the auto complete popup to work. + + get popup() { + return document.getElementById("PopupGlodaAutocomplete"); + } + + controller = { + matchCount: 0, + searchString: "", + stopSearch() { + lazy.glodaCompleter.stopSearch(); + }, + handleEnter: (isAutocomplete, event) => { + if (!isAutocomplete) { + return; + } + this.#handleSearch({ detail: this.controller.searchString }); + this.reset(); + }, + }; + + _focus() { + this.focus(); + } + + #searchResultListener = { + onSearchResult: (result, search) => { + this.controller.matchCount = search.matchCount; + if (this.controller.matchCount < 1) { + this.popup.closePopup(); + return; + } + if (!this.popup.mPopupOpen) { + this.popup.openAutocompletePopup( + this, + this.shadowRoot.querySelector("input") + ); + return; + } + this.popup.invalidate(); + }, + }; + + // Normal custom element stuff + + connectedCallback() { + if (this.shadowRoot) { + return; + } + if ( + !Services.prefs.getBoolPref( + "mailnews.database.global.indexer.enabled", + true + ) + ) { + return; + } + // Need to call this after the shadow root test, since this will always set + // up a shadow root. + super.connectedCallback(); + this.addEventListener("search", this.#handleSearch); + this.addEventListener("autocomplete", this.#handleAutocomplete); + // Capturing to avoid the default cursor movements inside the input. + this.addEventListener("keydown", this.#handleKeydown, { + capture: true, + }); + this.addEventListener("focus", this.#handleFocus); + this.addEventListener("blur", this); + this.addEventListener("drop", this.#handleDrop, { capture: true }); + } + + handleEvent(event) { + switch (event.type) { + case "blur": + if (this.popup.mPopupOpen) { + this.popup.closePopup(); + } + break; + } + } + + #handleSearch = event => { + let tabmail = document.getElementById("tabmail"); + let args; + // Build the query from the autocomplete result. + const selectedIndex = this.popup.selectedIndex; + if (selectedIndex > -1) { + const curResult = lazy.glodaCompleter.curResult; + if (curResult) { + const row = curResult.getObjectAt(selectedIndex); + if (row && !row.fullText && row.nounDef) { + let query = lazy.Gloda.newQuery(lazy.GlodaConstants.NOUN_MESSAGE); + switch (row.nounDef.name) { + case "tag": + query = query.tags(row.item); + break; + case "identity": + query = query.involves(row.item); + break; + } + query.orderBy("-date"); + args = { query }; + } + } + } + // Or just do a normal full text search. + if (!args) { + let searchString = event.detail; + args = { + searcher: new lazy.GlodaMsgSearcher(null, searchString), + }; + if (Services.prefs.getBoolPref("mail.chat.enabled")) { + args.IMSearcher = new lazy.GlodaIMSearcher(null, searchString); + } + } + tabmail.openTab("glodaFacet", args); + this.popup.closePopup(); + this.controller.matchCount = 0; + this.controller.searchString = ""; + }; + + #handleAutocomplete = event => { + this.controller.searchString = event.detail; + if (!event.detail) { + this.popup.closePopup(); + this.controller.matchCount = 0; + return; + } + lazy.glodaCompleter.startSearch( + this.controller.searchString, + "global", + null, + this.#searchResultListener + ); + }; + + #handleKeydown = event => { + if (event.ctrlKey) { + return; + } + if (event.key == "ArrowDown") { + if (this.popup.selectedIndex < this.controller.matchCount - 1) { + ++this.popup.selectedIndex; + event.preventDefault(); + return; + } + this.popup.selectedIndex = -1; + event.preventDefault(); + return; + } + if (event.key == "ArrowUp") { + if (this.popup.selectedIndex > -1) { + --this.popup.selectedIndex; + event.preventDefault(); + return; + } + this.popup.selectedIndex = this.controller.matchCount - 1; + event.preventDefault(); + } + }; + + #handleFocus = event => { + if (this.controller.searchString && this.controller.matchCount >= 1) { + this.popup.openAutocompletePopup( + this, + this.shadowRoot.querySelector("input") + ); + } + }; + + #handleDrop = event => { + if (event.dataTransfer.types.includes("text/x-moz-address")) { + const searchTerm = event.dataTransfer.getData("text/plain"); + this.#handleSearch({ detail: searchTerm }); + } + event.stopPropagation(); + event.preventDefault(); + }; +} +customElements.define("global-search-bar", GlobalSearchBar); diff --git a/comm/mail/components/unifiedtoolbar/content/items/mail-go-button.mjs b/comm/mail/components/unifiedtoolbar/content/items/mail-go-button.mjs new file mode 100644 index 0000000000..df9266d077 --- /dev/null +++ b/comm/mail/components/unifiedtoolbar/content/items/mail-go-button.mjs @@ -0,0 +1,183 @@ +/* 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 { MailTabButton } from "chrome://messenger/content/unifiedtoolbar/mail-tab-button.mjs"; + +const { MailServices } = ChromeUtils.import( + "resource:///modules/MailServices.jsm" +); + +/** + * Map from the direction attribute value to the command the button executes on + * click. + * + * @type {{[string]: string}} + */ +const COMMAND_FOR_DIRECTION = { + forward: "cmd_goForward", + back: "cmd_goBack", +}; + +/** + * Unified toolbar button to add the selected message to a calendar as event or + * task. + * Attributes: + * - direction: "forward" or "back". + */ +class MailGoButton extends MailTabButton { + /** + * @type {?XULPopupElement} + */ + #contextMenu = null; + + connectedCallback() { + if (!this.hasConnected) { + const command = COMMAND_FOR_DIRECTION[this.getAttribute("direction")]; + if (!command) { + throw new Error( + `Unknown direction "${this.getAttribute("direction")}"` + ); + } + this.setAttribute("command", command); + this.#contextMenu = document.getElementById("messageHistoryPopup"); + this.addEventListener("contextmenu", this.#handleContextMenu, true); + } + super.connectedCallback(); + } + + /** + * Build and show the history popup containing a list of messages to navigate + * to. Messages that can't be found or that were in folders we can't find are + * ignored. The currently displayed message is marked. + * + * @param {MouseEvent} event - Event triggering the context menu. + */ + #handleContextMenu = event => { + event.preventDefault(); + event.stopPropagation(); + + const tabmail = document.getElementById("tabmail"); + const currentWindow = tabmail.currentTabInfo.chromeBrowser.contentWindow; + const { messageHistory } = tabmail.currentAboutMessage; + const { entries, currentIndex } = messageHistory.getHistory(); + + // For populating the back menu, we want the most recently visited + // messages first in the menu. So we go backward from curPos to 0. + // For the forward menu, we want to go forward from curPos to the end. + const items = []; + const relativePositionBase = entries.length - 1 - currentIndex; + for (const [index, entry] of entries.reverse().entries()) { + const folder = MailServices.folderLookup.getFolderForURL(entry.folderURI); + if (!folder) { + // Where did the folder go? + continue; + } + + let menuText = ""; + let msgHdr; + try { + msgHdr = MailServices.messageServiceFromURI( + entry.messageURI + ).messageURIToMsgHdr(entry.messageURI); + } catch (ex) { + // Let's just ignore this history entry. + continue; + } + const messageSubject = msgHdr.mime2DecodedSubject; + const messageAuthor = msgHdr.mime2DecodedAuthor; + + if (!messageAuthor && !messageSubject) { + // Avoid empty entries in the menu. The message was most likely (re)moved. + continue; + } + + // If the message was not being displayed via the current folder, prepend + // the folder name. We do not need to check underlying folders for + // virtual folders because 'folder' is the display folder, not the + // underlying one. + if (folder != currentWindow.gFolder) { + menuText = folder.prettyName + " - "; + } + + let subject = ""; + if (msgHdr.flags & Ci.nsMsgMessageFlags.HasRe) { + subject = "Re: "; + } + if (messageSubject) { + subject += messageSubject; + } + if (subject) { + menuText += subject + " - "; + } + + menuText += messageAuthor; + const newMenuItem = document.createXULElement("menuitem"); + newMenuItem.setAttribute("label", menuText); + const relativePosition = relativePositionBase - index; + newMenuItem.setAttribute("value", relativePosition); + newMenuItem.addEventListener("command", commandEvent => { + this.#navigateToUri(commandEvent.target); + commandEvent.stopPropagation(); + }); + if (relativePosition === 0 && !messageHistory.canPop(0)) { + newMenuItem.setAttribute("checked", true); + newMenuItem.setAttribute("type", "radio"); + } + items.push(newMenuItem); + } + this.#contextMenu.replaceChildren(...items); + + this.#contextMenu.openPopupAtScreen( + event.screenX, + event.screenY, + true, + event + ); + }; + + /** + * Select the message in the appropriate folder for the history popup entry. + * Finds the message based on the value of the item, which is the relative + * index of the item in the message history. + * + * @param {Element} target + */ + #navigateToUri(target) { + const nsMsgViewIndex_None = 0xffffffff; + const historyIndex = Number.parseInt(target.getAttribute("value"), 10); + const tabmail = document.getElementById("tabmail"); + const currentWindow = tabmail.currentTabInfo.chromeBrowser.contentWindow; + const messageHistory = tabmail.currentAboutMessage.messageHistory; + if (!messageHistory || !messageHistory.canPop(historyIndex)) { + return; + } + const item = messageHistory.pop(historyIndex); + + if ( + currentWindow.displayFolder && + currentWindow.gFolder?.URI !== item.folderURI + ) { + const folder = MailServices.folderLookup.getFolderForURL(item.folderURI); + currentWindow.displayFolder(folder); + } + const msgHdr = MailServices.messageServiceFromURI( + item.messageURI + ).messageURIToMsgHdr(item.messageURI); + const index = currentWindow.gDBView.findIndexOfMsgHdr(msgHdr, true); + if (index != nsMsgViewIndex_None) { + if (currentWindow.threadTree) { + currentWindow.threadTree.selectedIndex = index; + currentWindow.threadTree.table.body.focus(); + } else { + currentWindow.gViewWrapper.dbView.selection.select(index); + currentWindow.displayMessage( + currentWindow.gViewWrapper.dbView.URIForFirstSelectedMessage + ); + } + } + } +} +customElements.define("mail-go-button", MailGoButton, { + extends: "button", +}); diff --git a/comm/mail/components/unifiedtoolbar/content/items/quick-filter-bar-toggle.mjs b/comm/mail/components/unifiedtoolbar/content/items/quick-filter-bar-toggle.mjs new file mode 100644 index 0000000000..651502a934 --- /dev/null +++ b/comm/mail/components/unifiedtoolbar/content/items/quick-filter-bar-toggle.mjs @@ -0,0 +1,32 @@ +/* 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 { MailTabButton } from "chrome://messenger/content/unifiedtoolbar/mail-tab-button.mjs"; + +/** + * Unified toolbar button for toggling the quick filter bar. + */ +class QuickFilterBarToggle extends MailTabButton { + observed3PaneEvents = ["folderURIChanged", "select", "qfbtoggle"]; + observedAboutMessageEvents = []; + + onCommandContextChange() { + super.onCommandContextChange(); + const tabmail = document.getElementById("tabmail"); + const about3Pane = tabmail.currentAbout3Pane; + if ( + !about3Pane?.paneLayout || + about3Pane.paneLayout.accountCentralVisible + ) { + this.disabled = true; + this.setAttribute("aria-pressed", "false"); + return; + } + const active = about3Pane.quickFilterBar.filterer.visible; + this.setAttribute("aria-pressed", active.toString()); + } +} +customElements.define("quick-filter-bar-toggle", QuickFilterBarToggle, { + extends: "button", +}); diff --git a/comm/mail/components/unifiedtoolbar/content/items/reply-list-button.mjs b/comm/mail/components/unifiedtoolbar/content/items/reply-list-button.mjs new file mode 100644 index 0000000000..e3ce55e05e --- /dev/null +++ b/comm/mail/components/unifiedtoolbar/content/items/reply-list-button.mjs @@ -0,0 +1,15 @@ +/* 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 { MailTabButton } from "chrome://messenger/content/unifiedtoolbar/mail-tab-button.mjs"; + +/** + * Unified toolbar button for replying to a mailing list.. + */ +class ReplyListButton extends MailTabButton { + observedAboutMessageEvents = ["load", "MsgLoaded"]; +} +customElements.define("reply-list-button", ReplyListButton, { + extends: "button", +}); diff --git a/comm/mail/components/unifiedtoolbar/content/items/space-button.mjs b/comm/mail/components/unifiedtoolbar/content/items/space-button.mjs new file mode 100644 index 0000000000..75c23592bf --- /dev/null +++ b/comm/mail/components/unifiedtoolbar/content/items/space-button.mjs @@ -0,0 +1,41 @@ +/* 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 "chrome://messenger/content/unifiedtoolbar/unified-toolbar-button.mjs"; + +/* import-globals-from ../../../../base/content/spacesToolbar.js */ + +/** + * Unified toolbar button that opens a specific space. + * Attributes: + * - space: Space to open when the button is activated + */ +class SpaceButton extends UnifiedToolbarButton { + connectedCallback() { + super.connectedCallback(); + const spaceId = this.getAttribute("space"); + const space = gSpacesToolbar.spaces.find( + spaceDetails => spaceDetails.name == spaceId + ); + if (space.button.classList.contains("has-badge")) { + const badgeContainer = space.button.querySelector( + ".spaces-badge-container" + ); + this.badge = badgeContainer.textContent; + } + } + + handleClick = event => { + const spaceId = this.getAttribute("space"); + const space = gSpacesToolbar.spaces.find( + spaceDetails => spaceDetails.name == spaceId + ); + gSpacesToolbar.openSpace(document.getElementById("tabmail"), space); + event.preventDefault(); + event.stopPropagation(); + }; +} +customElements.define("space-button", SpaceButton, { + extends: "button", +}); diff --git a/comm/mail/components/unifiedtoolbar/content/items/view-picker-button.mjs b/comm/mail/components/unifiedtoolbar/content/items/view-picker-button.mjs new file mode 100644 index 0000000000..3cd7686b5e --- /dev/null +++ b/comm/mail/components/unifiedtoolbar/content/items/view-picker-button.mjs @@ -0,0 +1,40 @@ +/* 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 { MailTabButton } from "chrome://messenger/content/unifiedtoolbar/mail-tab-button.mjs"; + +class ViewPickerButton extends MailTabButton { + observed3PaneEvents = ["folderURIChanged", "MailViewChanged"]; + + observedAboutMessageEvents = []; + + /** + * Update the label and icon of the button from the currently selected folder + * in the local 3pane. + */ + onCommandContextChange() { + const { gViewWrapper } = + document.getElementById("tabmail").currentAbout3Pane ?? {}; + if (!gViewWrapper) { + this.disabled = true; + return; + } + this.disabled = false; + const viewPickerPopup = document.getElementById(this.getAttribute("popup")); + const value = window.ViewPickerBinding.currentViewValue; + let selectedItem = viewPickerPopup.querySelector(`[value="${value}"]`); + if (!selectedItem) { + // We may have a new item, so refresh to make it show up. + window.RefreshAllViewPopups(viewPickerPopup, true); + selectedItem = viewPickerPopup.querySelector(`[value="${value}"]`); + } + this.label.textContent = selectedItem?.getAttribute("label"); + if (!this.label.textContent) { + document.l10n.setAttributes(this.label, "toolbar-view-picker-label"); + } + } +} +customElements.define("view-picker-button", ViewPickerButton, { + extends: "button", +}); |