/* 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"; /* global MozElements, MozXULElement */ // Wrap in a block to prevent leaking to window scope. { /** * The MozTabmailTab widget behaves as a tab in the messenger window. * It is used to navigate between different views. It displays information * about the view: i.e. name and icon. * * @augments {MozElements.MozTab} */ class MozTabmailTab extends MozElements.MozTab { static get inheritedAttributes() { return { ".tab-background": "pinned,selected,titlechanged", ".tab-line": "selected=visuallyselected", ".tab-content": "pinned,selected,titlechanged,title=label", ".tab-throbber": "fadein,pinned,busy,progress,selected", ".tab-icon-image": "fadein,pinned,selected", ".tab-label-container": "pinned,selected=visuallyselected", ".tab-text": "text=label,accesskey,fadein,pinned,selected", ".tab-close-button": "fadein,pinned,selected=visuallyselected", }; } connectedCallback() { if (this.delayConnectedCallback() || this.hasChildNodes()) { return; } this.setAttribute("is", "tabmail-tab"); this.appendChild( MozXULElement.parseXULToFragment( ` `, ["chrome://messenger/locale/tabmail.dtd"] ) ); this.addEventListener( "dragstart", event => { document.dragTab = this; }, true ); this.addEventListener( "dragover", event => { document.dragTab = null; }, true ); let closeButton = this.querySelector(".tab-close-button"); // Prevent switching to the tab before closing it by stopping the // mousedown event. closeButton.addEventListener("mousedown", event => { if (event.button != 0) { return; } event.stopPropagation(); }); closeButton.addEventListener("click", () => document.getElementById("tabmail").removeTabByNode(this) ); // Middle mouse button click on the tab also closes it. this.addEventListener("click", event => { if (event.button != 1) { return; } document.getElementById("tabmail").removeTabByNode(this); }); this.setAttribute("context", "tabContextMenu"); this.mCorrespondingMenuitem = null; this.initializeAttributeInheritance(); } get linkedBrowser() { let tabmail = document.getElementById("tabmail"); let tab = tabmail._getTabContextForTabbyThing(this, false)[1]; return tabmail.getBrowserForTab(tab); } get mode() { let tabmail = document.getElementById("tabmail"); let tab = tabmail._getTabContextForTabbyThing(this, false)[1]; return tab.mode; } /** * Set the displayed icon for the tab. * * If a fallback source if given, it will be used instead if the given icon * source is missing or loads with an error. * * If both sources are null, then the icon will become invisible. * * @param {string|null} iconSrc - The icon source to display in the tab, or * null to just use the fallback source. * @param {?string} [fallbackSrc] - The fallback source to display if the * iconSrc is missing or broken. */ setIcon(iconSrc, fallbackSrc) { let icon = this.querySelector(".tab-icon-image"); if (!fallbackSrc) { if (iconSrc) { icon.setAttribute("src", iconSrc); } else { icon.removeAttribute("src"); } return; } if (!iconSrc) { icon.setAttribute("src", fallbackSrc); return; } if (iconSrc == icon.getAttribute("src")) { return; } // Set the tab image, and use the fallback if an error occurs. // Set up a one time listener for either error or load. let listener = event => { icon.removeEventListener("error", listener); icon.removeEventListener("load", listener); if (event.type == "error") { icon.setAttribute("src", fallbackSrc); } }; icon.addEventListener("error", listener); icon.addEventListener("load", listener); icon.setAttribute("src", iconSrc); } } MozXULElement.implementCustomInterface(MozTabmailTab, [ Ci.nsIDOMXULSelectControlItemElement, ]); customElements.define("tabmail-tab", MozTabmailTab, { extends: "tab" }); }