diff --git a/browser/actors/AboutNewTabParent.jsm b/browser/actors/AboutNewTabParent.jsm index 768737360446..659522458eaf 100644 --- a/browser/actors/AboutNewTabParent.jsm +++ b/browser/actors/AboutNewTabParent.jsm @@ -32,13 +32,6 @@ XPCOMUtils.defineLazyPreferenceGetter( false ); -XPCOMUtils.defineLazyPreferenceGetter( - this, - "PROTON_INFOBARS_ENABLED", - "browser.proton.infobars.enabled", - false -); - class AboutNewTabParent extends JSWindowActorParent { async receiveMessage(message) { switch (message.name) { @@ -162,9 +155,7 @@ var DefaultBrowserNotification = { let iconPixels = win.devicePixelRatio > 1 ? "64" : "32"; let iconURL = "chrome://branding/content/icon" + iconPixels + ".png"; - const priority = PROTON_INFOBARS_ENABLED - ? win.gNotificationBox.PRIORITY_SYSTEM - : win.gNotificationBox.PRIORITY_INFO_MEDIUM; + const priority = win.gNotificationBox.PRIORITY_INFO_MEDIUM; let callback = this._onNotificationEvent.bind(this); this._notification = gBrowser .getNotificationBox(browser) @@ -174,9 +165,7 @@ var DefaultBrowserNotification = { iconURL, priority, buttons, - callback, - null, - ["browser/defaultBrowserNotification.ftl"] + callback ); }, diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 2753a157b51b..0da11a6a129a 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -396,7 +396,7 @@ XPCOMUtils.defineLazyGetter(this, "gHighPriorityNotificationBox", () => { return new MozElements.NotificationBox(element => { element.classList.add("global-notificationbox"); element.setAttribute("notificationside", "top"); - if (gProtonInfobarsEnabled) { + if (Services.prefs.getBoolPref("browser.proton.infobars.enabled", false)) { // With Proton enabled all notification boxes are at the top, built into the browser chrome. let tabNotifications = document.getElementById("tab-notification-deck"); gNavToolbox.insertBefore(element, tabNotifications); @@ -408,7 +408,7 @@ XPCOMUtils.defineLazyGetter(this, "gHighPriorityNotificationBox", () => { // Regular notification bars shown at the bottom of the window. XPCOMUtils.defineLazyGetter(this, "gNotificationBox", () => { - return gProtonInfobarsEnabled + return Services.prefs.getBoolPref("browser.proton.infobars.enabled", false) ? gHighPriorityNotificationBox : new MozElements.NotificationBox(element => { element.classList.add("global-notificationbox"); @@ -587,14 +587,6 @@ XPCOMUtils.defineLazyPreferenceGetter( } ); -/* Temporary pref while the Proton infobars work stabilizes. */ -XPCOMUtils.defineLazyPreferenceGetter( - this, - "gProtonInfobarsEnabled", - "browser.proton.infobars.enabled", - false -); - /* Temporary pref while the dust settles around the updated tooltip design for tabs and bookmarks toolbar. This will eventually be removed and browser.proton.enabled will be used instead. */ @@ -1055,9 +1047,7 @@ const gStoragePressureObserver = { null, gHighPriorityNotificationBox.PRIORITY_WARNING_HIGH, buttons, - null, - null, - ["branding/brand.ftl", "browser/preferences/preferences.ftl"] + null ); // This seems to be necessary to get the buttons to display correctly diff --git a/browser/base/content/tabbrowser.js b/browser/base/content/tabbrowser.js index 95dbfec3c66c..3bc8adb6c348 100644 --- a/browser/base/content/tabbrowser.js +++ b/browser/base/content/tabbrowser.js @@ -826,7 +826,9 @@ if (!browser._notificationBox) { browser._notificationBox = new MozElements.NotificationBox(element => { element.setAttribute("notificationside", "top"); - if (gProtonInfobarsEnabled) { + if ( + Services.prefs.getBoolPref("browser.proton.infobars.enabled", false) + ) { element.setAttribute( "name", `tab-notification-box-${this._nextNotificationBoxId++}` @@ -1112,7 +1114,9 @@ this._appendStatusPanel(); - if (gProtonInfobarsEnabled) { + if ( + Services.prefs.getBoolPref("browser.proton.infobars.enabled", false) + ) { this._updateVisibleNotificationBox(newBrowser); } diff --git a/browser/components/aboutlogins/AboutLoginsParent.jsm b/browser/components/aboutlogins/AboutLoginsParent.jsm index a342b1ba7e17..008d90daad28 100644 --- a/browser/components/aboutlogins/AboutLoginsParent.jsm +++ b/browser/components/aboutlogins/AboutLoginsParent.jsm @@ -733,10 +733,7 @@ var AboutLogins = { id, iconURL, notificationBox[priority], - buttons, - null, - null, - ["browser/aboutLogins.ftl"] + buttons ); } }, diff --git a/browser/components/newtab/lib/InfoBar.jsm b/browser/components/newtab/lib/InfoBar.jsm index aa8dcf3f5b03..767ea91af169 100644 --- a/browser/components/newtab/lib/InfoBar.jsm +++ b/browser/components/newtab/lib/InfoBar.jsm @@ -13,11 +13,6 @@ XPCOMUtils.defineLazyModuleGetters(this, { Services: "resource://gre/modules/Services.jsm", }); -const FTL_PATHS = [ - "browser/newtab/asrouter.ftl", - "browser/defaultBrowserNotification.ftl", -]; - class InfoBarNotification { constructor(message, dispatch) { this._dispatch = dispatch; @@ -50,9 +45,7 @@ class InfoBarNotification { content.icon || "chrome://branding/content/icon64.png", notificationContainer.PRIORITY_INFO_MEDIUM, content.buttons.map(b => this.formatButtonConfig(b)), - this.infobarCallback, - null, - FTL_PATHS + this.infobarCallback ); this.addImpression(); @@ -138,9 +131,10 @@ const InfoBar = { }, maybeInsertFTL(win) { - for (let filepath of FTL_PATHS) { - win.MozXULElement.insertFTLIfNeeded(filepath); - } + win.MozXULElement.insertFTLIfNeeded("browser/newtab/asrouter.ftl"); + win.MozXULElement.insertFTLIfNeeded( + "browser/defaultBrowserNotification.ftl" + ); }, showInfoBarMessage(browser, message, dispatch) { diff --git a/browser/modules/ContentCrashHandlers.jsm b/browser/modules/ContentCrashHandlers.jsm index 1ba52586cd6d..eccbe509b38e 100644 --- a/browser/modules/ContentCrashHandlers.jsm +++ b/browser/modules/ContentCrashHandlers.jsm @@ -461,9 +461,7 @@ var TabCrashHandler = { closeAllNotifications(); } - }, - null, - "browser/browser.ftl" + } ); let existingItem = this.notificationsMap.get(childID); diff --git a/browser/themes/shared/browser.inc.css b/browser/themes/shared/browser.inc.css index 6974f6f38d4a..6a9c5b6251b7 100644 --- a/browser/themes/shared/browser.inc.css +++ b/browser/themes/shared/browser.inc.css @@ -944,5 +944,5 @@ popupnotificationcontent { } /** END Proton **/ #tab-notification-deck { - display: block; + display: flex; } diff --git a/toolkit/content/customElements.js b/toolkit/content/customElements.js index 691dd5ad8480..f01ec72e1aff 100644 --- a/toolkit/content/customElements.js +++ b/toolkit/content/customElements.js @@ -838,7 +838,6 @@ ["button-group", "chrome://global/content/elements/named-deck.js"], ["findbar", "chrome://global/content/elements/findbar.js"], ["menulist", "chrome://global/content/elements/menulist.js"], - ["message-bar", "chrome://global/content/elements/message-bar.js"], ["named-deck", "chrome://global/content/elements/named-deck.js"], ["named-deck-button", "chrome://global/content/elements/named-deck.js"], ["search-textbox", "chrome://global/content/elements/search-textbox.js"], diff --git a/toolkit/content/jar.mn b/toolkit/content/jar.mn index dc2ba69bdfbd..091027f2ff58 100644 --- a/toolkit/content/jar.mn +++ b/toolkit/content/jar.mn @@ -83,8 +83,6 @@ toolkit.jar: content/global/elements/findbar.js (widgets/findbar.js) content/global/elements/editor.js (widgets/editor.js) content/global/elements/general.js (widgets/general.js) - content/global/elements/message-bar.css (widgets/message-bar.css) - content/global/elements/message-bar.js (widgets/message-bar.js) content/global/elements/menu.js (widgets/menu.js) content/global/elements/menupopup.js (widgets/menupopup.js) content/global/elements/moz-input-box.js (widgets/moz-input-box.js) diff --git a/toolkit/content/tests/chrome/test_notificationbox.xhtml b/toolkit/content/tests/chrome/test_notificationbox.xhtml index 31034e9438c2..58ffe7514baa 100644 --- a/toolkit/content/tests/chrome/test_notificationbox.xhtml +++ b/toolkit/content/tests/chrome/test_notificationbox.xhtml @@ -411,7 +411,7 @@ var tests = test(nb, ntf) { var exh = false; try { - nb.appendNotification("no", "no", "no", -1, null); + nb.appendNotification("no", "no", "no", 0, null); } catch (ex) { exh = true; } SimpleTest.is(exh, true, "appendNotification priority too low"); diff --git a/toolkit/content/widgets/message-bar.js b/toolkit/content/widgets/message-bar.js deleted file mode 100644 index 0fb1364c42fc..000000000000 --- a/toolkit/content/widgets/message-bar.js +++ /dev/null @@ -1,84 +0,0 @@ -/* 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"; - -// This is loaded into chrome windows with the subscript loader. Wrap in -// a block to prevent accidentally leaking globals onto `window`. -{ - class MessageBarElement extends HTMLElement { - constructor() { - super(); - const shadowRoot = this.attachShadow({ mode: "open" }); - const content = this.constructor.template.content.cloneNode(true); - shadowRoot.append(content); - this.closeButton.addEventListener("click", () => this.dismiss(), { - once: true, - }); - } - - disconnectedCallback() { - this.dispatchEvent(new CustomEvent("message-bar:close")); - } - - get closeButton() { - return this.shadowRoot.querySelector("button.close"); - } - - static get template() { - const template = document.createElement("template"); - - const commonStyles = document.createElement("link"); - commonStyles.rel = "stylesheet"; - commonStyles.href = "chrome://global/skin/in-content/common.css"; - const messageBarStyles = document.createElement("link"); - messageBarStyles.rel = "stylesheet"; - messageBarStyles.href = - "chrome://global/content/elements/message-bar.css"; - template.content.append(commonStyles, messageBarStyles); - - // A container for the entire message bar content, - // most of the css rules needed to provide the - // expected message bar layout is applied on this - // element. - const container = document.createElement("div"); - container.classList.add("container"); - template.content.append(container); - - const icon = document.createElement("span"); - icon.classList.add("icon"); - container.append(icon); - - const barcontent = document.createElement("span"); - barcontent.classList.add("content"); - barcontent.append(document.createElement("slot")); - container.append(barcontent); - - const spacer = document.createElement("span"); - spacer.classList.add("spacer"); - container.append(spacer); - - const closeIcon = document.createElement("button"); - closeIcon.classList.add("close", "ghost-button"); - container.append(closeIcon); - - Object.defineProperty(this, "template", { - value: template, - }); - - return template; - } - - dismiss() { - this.dispatchEvent(new CustomEvent("message-bar:user-dismissed")); - this.close(); - } - - close() { - this.remove(); - } - } - - customElements.define("message-bar", MessageBarElement); -} diff --git a/toolkit/content/widgets/notificationbox.js b/toolkit/content/widgets/notificationbox.js index 7000dcc2ffbf..93734bc221ef 100644 --- a/toolkit/content/widgets/notificationbox.js +++ b/toolkit/content/widgets/notificationbox.js @@ -28,19 +28,13 @@ get stack() { if (!this._stack) { - let stack; - stack = document.createXULElement( - this.protonInfobarsEnabled ? "vbox" : "legacy-stack" - ); + let stack = document.createXULElement("legacy-stack"); stack._notificationBox = this; stack.className = "notificationbox-stack"; - if (!this.protonInfobarsEnabled) { - stack.appendChild(document.createXULElement("spacer")); - } + stack.appendChild(document.createXULElement("spacer")); stack.addEventListener("transitionend", event => { if ( - (event.target.localName == "notification" || - event.target.localName == "notification-message") && + event.target.localName == "notification" && event.propertyName == "margin-top" ) { this._finishAnimation(); @@ -64,9 +58,7 @@ } var closedNotification = this._closedNotification; - var notifications = this.stack.getElementsByTagName( - this.protonInfobarsEnabled ? "notification-message" : "notification" - ); + var notifications = this.stack.getElementsByTagName("notification"); return Array.prototype.filter.call( notifications, n => n != closedNotification @@ -148,11 +140,10 @@ aPriority, aButtons, aEventCallback, - aNotificationIs, - aFtlFilePaths + aNotificationIs ) { if ( - aPriority < this.PRIORITY_SYSTEM || + aPriority < this.PRIORITY_INFO_LOW || aPriority > this.PRIORITY_CRITICAL_HIGH ) { throw new Error("Invalid notification priority " + aPriority); @@ -172,24 +163,10 @@ MozXULElement.insertFTLIfNeeded("toolkit/global/notification.ftl"); // Create the Custom Element and connect it to the document immediately. - var newitem; - if (this.protonInfobarsEnabled) { - if (!customElements.get("notification-message")) { - // There's some weird timing stuff when this element is created at - // script load time, we don't need it until now anyway so be lazy. - createNotificationMessageElement(); - } - newitem = document.createElement("notification-message"); - newitem.setAttribute("message-bar-type", "infobar"); - if (aFtlFilePaths) { - newitem.addFtl(aFtlFilePaths); - } - } else { - newitem = document.createXULElement( - "notification", - aNotificationIs ? { is: aNotificationIs } : {} - ); - } + var newitem = document.createXULElement( + "notification", + aNotificationIs ? { is: aNotificationIs } : {} + ); this.stack.insertBefore(newitem, insertPos); // Custom notification classes may not have the messageText property. @@ -207,20 +184,65 @@ } } newitem.setAttribute("value", aValue); - - if (aImage && !this.protonInfobarsEnabled) { + if (aImage) { newitem.messageImage.setAttribute("src", aImage); } newitem.eventCallback = aEventCallback; if (aButtons) { - newitem.setButtons(aButtons); + for (var b = 0; b < aButtons.length; b++) { + let button = aButtons[b]; + let buttonElem; + + let link = button.link; + let localeId = button["l10n-id"]; + if (!link && button.supportPage) { + link = + Services.urlFormatter.formatURLPref("app.support.baseURL") + + button.supportPage; + if (!button.label && !localeId) { + localeId = "notification-learnmore-default-label"; + } + } + + if (link) { + buttonElem = document.createXULElement("label", { + is: "text-link", + }); + buttonElem.setAttribute("href", link); + buttonElem.classList.add("notification-link"); + } else { + buttonElem = document.createXULElement( + "button", + button.is ? { is: button.is } : {} + ); + buttonElem.classList.add("notification-button"); + + if (button.primary) { + buttonElem.classList.add("primary"); + } + } + + if (localeId) { + buttonElem.setAttribute("data-l10n-id", localeId); + } else { + buttonElem.setAttribute(link ? "value" : "label", button.label); + if (typeof button.accessKey == "string") { + buttonElem.setAttribute("accesskey", button.accessKey); + } + } + + if (link) { + newitem.messageText.appendChild(buttonElem); + } else { + newitem.messageDetails.appendChild(buttonElem); + } + buttonElem.buttonInfo = button; + } } newitem.priority = aPriority; - if (aPriority == this.PRIORITY_SYSTEM) { - newitem.setAttribute("type", "system"); - } else if (aPriority >= this.PRIORITY_CRITICAL_LOW) { + if (aPriority >= this.PRIORITY_CRITICAL_LOW) { newitem.setAttribute("type", "critical"); } else if (aPriority <= this.PRIORITY_INFO_HIGH) { newitem.setAttribute("type", "info"); @@ -249,10 +271,7 @@ if (!aItem.parentNode) { return; } - if (this.protonInfobarsEnabled) { - this.currentNotification = aItem; - this.removeCurrentNotification(aSkipAnimation); - } else if (aItem == this.currentNotification) { + if (aItem == this.currentNotification) { this.removeCurrentNotification(aSkipAnimation); } else if (aItem != this._closedNotification) { this._removeNotificationElement(aItem); @@ -317,11 +336,7 @@ _showNotification(aNotification, aSlideIn, aSkipAnimation) { this._finishAnimation(); - let { marginTop, marginBottom } = getComputedStyle(aNotification); - var height = - aNotification.getBoundingClientRect().height + - parseInt(marginTop, 10) + - parseInt(marginBottom, 10); + var height = aNotification.getBoundingClientRect().height; var skipAnimation = aSkipAnimation || height == 0 || !this._allowAnimation; aNotification.classList.toggle("animated", !skipAnimation); @@ -365,18 +380,10 @@ } } } - - get protonInfobarsEnabled() { - return Services.prefs.getBoolPref( - "browser.proton.infobars.enabled", - false - ); - } }; // These are defined on the instance prototype for backwards compatibility. Object.assign(MozElements.NotificationBox.prototype, { - PRIORITY_SYSTEM: 0, PRIORITY_INFO_LOW: 1, PRIORITY_INFO_MEDIUM: 2, PRIORITY_INFO_HIGH: 3, @@ -434,57 +441,6 @@ } } - setButtons(aButtons) { - for (let button of aButtons) { - let buttonElem; - - let link = button.link; - let localeId = button["l10n-id"]; - if (!link && button.supportPage) { - link = - Services.urlFormatter.formatURLPref("app.support.baseURL") + - button.supportPage; - if (!button.label && !localeId) { - localeId = "notification-learnmore-default-label"; - } - } - - if (link) { - buttonElem = document.createXULElement("label", { - is: "text-link", - }); - buttonElem.setAttribute("href", link); - buttonElem.classList.add("notification-link"); - } else { - buttonElem = document.createXULElement( - "button", - button.is ? { is: button.is } : {} - ); - buttonElem.classList.add("notification-button"); - - if (button.primary) { - buttonElem.classList.add("primary"); - } - } - - if (localeId) { - buttonElem.setAttribute("data-l10n-id", localeId); - } else { - buttonElem.setAttribute(link ? "value" : "label", button.label); - if (typeof button.accessKey == "string") { - buttonElem.setAttribute("accesskey", button.accessKey); - } - } - - if (link) { - this.messageText.appendChild(buttonElem); - } else { - this.messageDetails.appendChild(buttonElem); - } - buttonElem.buttonInfo = button; - } - } - get control() { return this.closest(".notificationbox-stack")._notificationBox; } @@ -546,159 +502,7 @@ } } } - - get protonInfobarsEnabled() { - return Services.prefs.getBoolPref( - "browser.proton.infobars.enabled", - false - ); - } }; customElements.define("notification", MozElements.Notification); - - function createNotificationMessageElement() { - // Get a reference to MessageBarElement from a created element so the import - // gets handled automatically if needed. - class NotificationMessage extends document.createElement("message-bar") - .constructor { - connectedCallback() { - this.toggleAttribute("dismissable", true); - this.closeButton.classList.add("notification-close"); - this.shadowRoot.querySelector(".container").classList.add("infobar"); - let messageContent = this.shadowRoot.querySelector(".content"); - messageContent.classList.add("notification-content"); - - // Remove the , API surface is `set label()` and `setButtons()`. - messageContent.textContent = ""; - - this.messageText = document.createElement("span"); - this.messageText.classList.add("notification-message"); - this.buttonContainer = document.createElement("span"); - this.buttonContainer.classList.add("notification-button-container"); - - messageContent.append(this.messageText, this.buttonContainer); - this.shadowRoot.addEventListener("click", this); - } - - disconnectedCallback() { - if (this.eventCallback) { - this.eventCallback("disconnected"); - } - } - - close() { - this.closest( - ".notificationbox-stack" - )._notificationBox.removeNotification(this); - } - - addFtl(filepaths) { - for (let filepath of filepaths) { - let link = document.createElement("link"); - link.setAttribute("rel", "localization"); - link.href = filepath; - this.shadowRoot.append(link); - } - document.l10n.connectRoot(this.shadowRoot); - } - - _insertNotificationFtl() { - if (!this._insertedNotificationFtl) { - this._insertedNotificationFtl = true; - this.addFtl(["toolkit/global/notification.ftl"]); - } - } - - handleEvent(e) { - if (e.type == "click" && "buttonInfo" in e.target) { - let { buttonInfo } = e.target; - let { callback, popup } = buttonInfo; - if (callback) { - if (!callback(this, buttonInfo, e.target, e)) { - this.close(); - } - e.stopPropagation(); - } else if (popup) { - document - .getElementById(popup) - .openPopup( - e.originalTarget, - "after_start", - 0, - 0, - false, - false, - e - ); - e.stopPropagation(); - } - } - } - - set label(value) { - this.messageText.textContent = value; - } - - setButtons(buttons) { - this._buttons = buttons; - for (let button of buttons) { - let link = button.link; - let localeId = button["l10n-id"]; - if (!link && button.supportPage) { - link = - Services.urlFormatter.formatURLPref("app.support.baseURL") + - button.supportPage; - if (!button.label && !localeId) { - localeId = "notification-learnmore-default-label"; - } - this._insertNotificationFtl(); - } - - let buttonElem; - if (link) { - buttonElem = document.createXULElement("label", { - is: "text-link", - }); - buttonElem.setAttribute("href", link); - buttonElem.classList.add("notification-link"); - } else { - buttonElem = document.createXULElement( - "button", - button.is ? { is: button.is } : {} - ); - buttonElem.classList.add("notification-button", "small"); - - if (button.primary) { - buttonElem.classList.add("primary"); - } - } - - if (localeId) { - document.l10n.setAttributes(buttonElem, localeId); - } else { - buttonElem.textContent = button.label; - if (typeof button.accessKey == "string") { - buttonElem.setAttribute("accesskey", button.accessKey); - } - } - - if (link) { - this.messageText.append(new Text(" "), buttonElem); - } else { - this.buttonContainer.appendChild(buttonElem); - } - buttonElem.buttonInfo = button; - } - } - - dismiss() { - if (this.eventCallback) { - this.eventCallback("dismissed"); - } - super.dismiss(); - } - } - customElements.define("notification-message", NotificationMessage); - } } diff --git a/toolkit/mozapps/extensions/content/aboutaddons.html b/toolkit/mozapps/extensions/content/aboutaddons.html index 70e608beccf8..1ccf9b70dbe9 100644 --- a/toolkit/mozapps/extensions/content/aboutaddons.html +++ b/toolkit/mozapps/extensions/content/aboutaddons.html @@ -25,6 +25,7 @@ + @@ -330,10 +331,7 @@
- +
diff --git a/toolkit/mozapps/extensions/content/aboutaddons.js b/toolkit/mozapps/extensions/content/aboutaddons.js index 6610e6a0a5ef..8199a39cbf2d 100644 --- a/toolkit/mozapps/extensions/content/aboutaddons.js +++ b/toolkit/mozapps/extensions/content/aboutaddons.js @@ -5,7 +5,7 @@ /* import-globals-from aboutaddonsCommon.js */ /* import-globals-from abuse-reports.js */ /* import-globals-from view-controller.js */ -/* global MozXULElement, windowRoot */ +/* global MozXULElement, MessageBarStackElement, windowRoot */ "use strict"; @@ -1239,77 +1239,6 @@ class SearchAddons extends HTMLElement { } customElements.define("search-addons", SearchAddons); -class MessageBarStackElement extends HTMLElement { - constructor() { - super(); - this._observer = null; - const shadowRoot = this.attachShadow({ mode: "open" }); - shadowRoot.append(this.constructor.template.content.cloneNode(true)); - } - - connectedCallback() { - // Close any message bar that should be allowed based on the - // maximum number of message bars. - this.closeMessageBars(); - - // Observe mutations to close older bars when new ones have been - // added. - this._observer = new MutationObserver(() => { - this._observer.disconnect(); - this.closeMessageBars(); - this._observer.observe(this, { childList: true }); - }); - this._observer.observe(this, { childList: true }); - } - - disconnectedCallback() { - this._observer.disconnect(); - this._observer = null; - } - - closeMessageBars() { - const { maxMessageBarCount } = this; - if (maxMessageBarCount > 1) { - // Remove the older message bars if the stack reached the - // maximum number of message bars allowed. - while (this.childElementCount > maxMessageBarCount) { - this.firstElementChild.remove(); - } - } - } - - get maxMessageBarCount() { - return parseInt(this.getAttribute("max-message-bar-count"), 10); - } - - static get template() { - const template = document.createElement("template"); - - const style = document.createElement("style"); - // Render the stack in the reverse order if the stack has the - // reverse attribute set. - style.textContent = ` - :host { - display: block; - } - :host([reverse]) > slot { - display: flex; - flex-direction: column-reverse; - } - `; - template.content.append(style); - template.content.append(document.createElement("slot")); - - Object.defineProperty(this, "template", { - value: template, - }); - - return template; - } -} - -customElements.define("message-bar-stack", MessageBarStackElement); - class GlobalWarnings extends MessageBarStackElement { constructor() { super(); @@ -4452,6 +4381,7 @@ class TaarMessageBar extends HTMLElement { e.type == "click" && e.target.getAttribute("action") == "notice-learn-more" ) { + // The element is a button but opens a URL, so record as link. AMTelemetry.recordLinkEvent({ object: "aboutAddons", value: "disconotice", @@ -4459,6 +4389,10 @@ class TaarMessageBar extends HTMLElement { view: getTelemetryViewName(this), }, }); + windowRoot.ownerGlobal.openTrustedLinkIn( + SUPPORT_URL + "personalized-addons", + "tab" + ); } else if (e.type == "message-bar:user-dismissed") { Services.prefs.setBoolPref(PREF_RECOMMENDATION_HIDE_NOTICE, true); } diff --git a/toolkit/content/widgets/message-bar.css b/toolkit/mozapps/extensions/content/message-bar.css similarity index 50% rename from toolkit/content/widgets/message-bar.css rename to toolkit/mozapps/extensions/content/message-bar.css index 948237bc1023..6410c2f8f8c4 100644 --- a/toolkit/content/widgets/message-bar.css +++ b/toolkit/mozapps/extensions/content/message-bar.css @@ -12,35 +12,38 @@ --close-icon-size: 32px; } -:host([message-bar-type=infobar]) { - --close-icon-size: 24px; -} - /* MessageBar colors by message type */ /* Colors from: https://design.firefox.com/photon/components/message-bars.html#type-specific-style */ :host { - --message-bar-background-color: var(--in-content-box-info-background); - --message-bar-text-color: var(--in-content-text-color); + /* Colors used by default, and for [type=generic] message bars.*/ + background-color: var(--in-content-box-info-background); + color: var(--in-content-text-color); + --message-bar-icon-url: var(--info-icon-url); /* The default values of --in-content-button* are sufficient, even for dark themes */ } -:host([type=warning]:not([message-bar-type=infobar])) { - --message-bar-background-color: var(--yellow-50); - --message-bar-text-color: var(--yellow-90); +:host([type=warning]) { + background-color: var(--yellow-50); + color: var(--yellow-90); + --message-bar-icon-url: var(--warn-icon-url); --in-content-button-background: var(--yellow-60); --in-content-button-background-hover: var(--yellow-70); --in-content-button-background-active: var(--yellow-80); } -:host([type=warning]) { - --message-bar-icon-url: var(--warn-icon-url); +:host([type=warning]) ::slotted(button:enabled:hover), +:host([type=warning]) ::slotted(button:enabled:hover), +:host([type=warning]) .close:enabled:hover, +:host([type=warning]) .close:enabled:hover:active { + /* common.css sets color: inherit !important... */ + color: white !important; } -:host([type=success]:not([message-bar-type=infobar])) { - --message-bar-background-color: var(--green-50); - --message-bar-text-color: var(--green-90); +:host([type=success]) { + background-color: var(--green-50); + color: var(--green-90); --message-bar-icon-url: var(--success-icon-url); --in-content-button-background: var(--green-60); @@ -48,18 +51,15 @@ --in-content-button-background-active: var(--green-80); } -:host([type=error]:not([message-bar-type=infobar])) { - --message-bar-background-color: var(--red-60); - --message-bar-text-color: #ffffff; +:host([type=error]) { + background-color: var(--red-60); + color: #ffffff; + --message-bar-icon-url: var(--error-icon-url); --in-content-button-background: var(--red-70); --in-content-button-background-hover: var(--red-80); --in-content-button-background-active: var(--red-90); } -:host([type=error]), -:host([type=critical]) { - --message-bar-icon-url: var(--error-icon-url); -} :host { border-radius: 4px; @@ -78,12 +78,12 @@ /* MessageBar Grid Layout */ .container { - background: var(--message-bar-background-color); - color: var(--message-bar-text-color); + background: inherit; + color: inherit; - padding: 4px 8px; - position: relative; + padding: 8px; + min-height: 32px; border-radius: 4px; display: flex; @@ -97,7 +97,7 @@ .content { margin: 0 4px; - display: inline-block; + display: flex; /* Ensure that the message bar content is vertically aligned. */ align-items: center; /* Ensure that the message bar content is wrapped. */ @@ -144,150 +144,7 @@ width: var(--close-icon-size); height: var(--close-icon-size); margin: 0; + margin-inline-end: 4px; padding: 0; flex-shrink: 0; } - -@supports -moz-bool-pref("browser.proton.infobars.enabled") { -@media not (prefers-contrast) { - .container.infobar { - box-shadow: 0 1px 2px rgba(58, 57, 68, 0.1); - background: var(--in-content-page-background); - } -} - -.close { - fill: var(--in-content-icon-color); -} - -@media (prefers-color-scheme: dark) { - .container.infobar { - background: rgb(66,65,77); - } -} - -:host([message-bar-type=infobar]:first-of-type) { - margin-top: 4px; -} - -:host([message-bar-type=infobar]) { - margin: 0 4px 4px; -} - -.container.infobar { - /* Don't let lwthemes set a text-shadow. */ - text-shadow: none; - padding: 0; -} - -.container.infobar::before { - content: ""; - display: block; - width: 2px; - position: absolute; - background-image: linear-gradient(0, #9059ff 0%, #ff4aa2 52.08%, #ffbd4f 100%); - top: 0; - inset-inline-start: 0; - height: 100%; - border-start-start-radius: 4px; - border-end-start-radius: 4px; -} - -.container.infobar { - align-items: flex-start; -} - -/* Infobars styling. */ -.notification-content { - margin: 0; - margin-inline-start: 8px; -} - -.notification-message { - min-height: 16px; /* min-height: 32px with block padding */ - padding-block: 8px; - margin-inline-end: 20px; -} - -.notification-button-container, -.notification-message { - display: inline-block; - vertical-align: middle; -} - -.close { - margin: 4px 8px; - background-size: 16px; -} - -.notification-button { - margin: 4px; - /* This is supposed to be 6px but then the buttons are 26px tall by default - * on Windows. Drop it down to 4px (with the 1px border) */ - padding-block: 3px; -} - -.notification-button:first-of-type { - /* When the buttons wrap to their own line we want to match the 8px on the message. */ - margin-inline-start: 0; -} - -strong { - font-weight: 600; -} - -.text-link:hover { - cursor: pointer; -} - -.infobar > .icon { - padding: 0; - margin: 8px 0; -} - -.infobar > .icon, -:host([type=system]) .notification-content { - margin-inline-start: 16px; -} - -:host([type=system]) .icon { - display: none; -} -:host([type=info]) .icon { - color: rgb(128,235,255); -} -:host([type=warning]) .icon { - color: rgb(255,164,54); -} -:host([type=critical]) .icon { - color: rgb(226,40,80); -} - -@media (prefers-color-scheme: dark) { - :host([type=info]) .icon { - color: rgb(0,221,255); - } - :host([type=warning]) .icon { - color: rgb(255,189,79); - } - :host([type=critical]) .icon { - color: rgb(255,154,162); - } -} -} - -@supports not -moz-bool-pref("browser.proton.infobars.enabled") { -:host { - /* Colors used by default, and for [type=generic] message bars.*/ - background-color: var(--in-content-box-info-background); - color: var(--in-content-text-color); -} -.container { - padding: 8px; - min-height: 32px; -} - -.close { - margin-inline-end: 4px; -} -} diff --git a/toolkit/mozapps/extensions/content/message-bar.js b/toolkit/mozapps/extensions/content/message-bar.js new file mode 100644 index 000000000000..0ab5a3c56310 --- /dev/null +++ b/toolkit/mozapps/extensions/content/message-bar.js @@ -0,0 +1,148 @@ +/* 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/. */ + +/* eslint max-len: ["error", 80] */ + +"use strict"; + +class MessageBarStackElement extends HTMLElement { + constructor() { + super(); + this._observer = null; + const shadowRoot = this.attachShadow({ mode: "open" }); + shadowRoot.append(this.constructor.template.content.cloneNode(true)); + } + + connectedCallback() { + // Close any message bar that should be allowed based on the + // maximum number of message bars. + this.closeMessageBars(); + + // Observe mutations to close older bars when new ones have been + // added. + this._observer = new MutationObserver(() => { + this._observer.disconnect(); + this.closeMessageBars(); + this._observer.observe(this, { childList: true }); + }); + this._observer.observe(this, { childList: true }); + } + + disconnectedCallback() { + this._observer.disconnect(); + this._observer = null; + } + + closeMessageBars() { + const { maxMessageBarCount } = this; + if (maxMessageBarCount > 1) { + // Remove the older message bars if the stack reached the + // maximum number of message bars allowed. + while (this.childElementCount > maxMessageBarCount) { + this.firstElementChild.remove(); + } + } + } + + get maxMessageBarCount() { + return parseInt(this.getAttribute("max-message-bar-count"), 10); + } + + static get template() { + const template = document.createElement("template"); + + const style = document.createElement("style"); + // Render the stack in the reverse order if the stack has the + // reverse attribute set. + style.textContent = ` + :host { + display: block; + } + :host([reverse]) > slot { + display: flex; + flex-direction: column-reverse; + } + `; + template.content.append(style); + template.content.append(document.createElement("slot")); + + Object.defineProperty(this, "template", { + value: template, + }); + + return template; + } +} + +class MessageBarElement extends HTMLElement { + constructor() { + super(); + const shadowRoot = this.attachShadow({ mode: "open" }); + const content = this.constructor.template.content.cloneNode(true); + shadowRoot.append(content); + this.closeButton.addEventListener( + "click", + () => { + this.dispatchEvent(new CustomEvent("message-bar:user-dismissed")); + this.remove(); + }, + { + once: true, + } + ); + } + + disconnectedCallback() { + this.dispatchEvent(new CustomEvent("message-bar:close")); + } + + get closeButton() { + return this.shadowRoot.querySelector("button.close"); + } + + static get template() { + const template = document.createElement("template"); + + const style = document.createElement("style"); + style.textContent = ` + @import "chrome://global/skin/in-content/common.css"; + @import "chrome://mozapps/content/extensions/message-bar.css"; + `; + template.content.append(style); + + // A container for the entire message bar content, + // most of the css rules needed to provide the + // expected message bar layout is applied on this + // element. + const container = document.createElement("div"); + container.setAttribute("class", "container"); + template.content.append(container); + + const icon = document.createElement("span"); + icon.setAttribute("class", "icon"); + container.append(icon); + + const barcontent = document.createElement("span"); + barcontent.setAttribute("class", "content"); + barcontent.append(document.createElement("slot")); + container.append(barcontent); + + const spacer = document.createElement("span"); + spacer.classList.add("spacer"); + container.append(spacer); + + const closeIcon = document.createElement("button"); + closeIcon.setAttribute("class", "close"); + container.append(closeIcon); + + Object.defineProperty(this, "template", { + value: template, + }); + + return template; + } +} + +customElements.define("message-bar", MessageBarElement); +customElements.define("message-bar-stack", MessageBarStackElement); diff --git a/toolkit/mozapps/extensions/jar.mn b/toolkit/mozapps/extensions/jar.mn index b77eac038b10..91fd7033d09c 100644 --- a/toolkit/mozapps/extensions/jar.mn +++ b/toolkit/mozapps/extensions/jar.mn @@ -21,6 +21,8 @@ toolkit.jar: content/mozapps/extensions/firefox-compact-dark.svg (content/firefox-compact-dark.svg) content/mozapps/extensions/firefox-compact-light.svg (content/firefox-compact-light.svg) content/mozapps/extensions/firefox-alpenglow.svg (content/firefox-alpenglow.svg) + content/mozapps/extensions/message-bar.css (content/message-bar.css) + content/mozapps/extensions/message-bar.js (content/message-bar.js) content/mozapps/extensions/panel-list.css (content/panel-list.css) content/mozapps/extensions/panel-item.css (content/panel-item.css) content/mozapps/extensions/rating-star.css (content/rating-star.css) diff --git a/toolkit/themes/shared/in-content/common.inc.css b/toolkit/themes/shared/in-content/common.inc.css index 5fed9956af51..2cfee35dfac6 100644 --- a/toolkit/themes/shared/in-content/common.inc.css +++ b/toolkit/themes/shared/in-content/common.inc.css @@ -6,7 +6,6 @@ @namespace html "http://www.w3.org/1999/xhtml"; @namespace xul "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; -:host, :root { --in-content-page-color: #0c0c0d; --in-content-page-background: #fff; @@ -19,7 +18,6 @@ --in-content-item-hover: rgba(69, 161, 255, 0.2); /* blue 40 a20 */ --in-content-item-selected: #0a84ff; --in-content-item-selected-text: #fff; - --in-content-icon-color: rgb(91,91,102); --in-content-accent-color: #0a84ff; --in-content-accent-color-active: #0060df; --in-content-border-hover: var(--grey-90-a50); @@ -105,7 +103,6 @@ } @supports not -moz-bool-pref("browser.proton.enabled") { -:host, :root { --in-content-page-background: #f9f9fa; --in-content-box-info-background: var(--grey-20); @@ -126,7 +123,6 @@ } @media (prefers-color-scheme: dark) { - :host, :root { /* Keep these in sync with layout/base/PresShell.cpp, and plaintext.css */ --in-content-page-background: rgb(28,27,34); @@ -146,7 +142,6 @@ --in-content-button-background: rgb(43,42,51); --in-content-button-background-hover: rgb(82,82,94); --in-content-button-background-active: rgb(91,91,102); - --in-content-icon-color: rgb(251,251,254); --in-content-primary-button-text-color: rgb(21,20,26); --in-content-primary-button-background: rgb(0,221,255); @@ -179,7 +174,6 @@ @supports not -moz-bool-pref("browser.proton.enabled") { @media (prefers-color-scheme: dark) { - :host, :root { --in-content-page-background: #2A2A2E; --in-content-page-color: rgb(249, 249, 250); @@ -203,7 +197,6 @@ } } } - :root { font: message-box; appearance: none; @@ -453,16 +446,6 @@ html|button.ghost-button:enabled:hover:active { background-color: var(--in-content-button-background-hover); } -@supports -moz-bool-pref("browser.proton.enabled") { -html|button.ghost-button:enabled:hover { - background-color: var(--in-content-button-background-hover); -} - -html|button.ghost-button:enabled:hover:active { - background-color: var(--in-content-button-background-active); -} -} - html|input[type="color"] { padding: 6px; width: 50px; diff --git a/toolkit/themes/shared/notification.css b/toolkit/themes/shared/notification.css index a87b7f2e45c5..e9ec846c8fb2 100644 --- a/toolkit/themes/shared/notification.css +++ b/toolkit/themes/shared/notification.css @@ -3,7 +3,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); -@namespace html "http://www.w3.org/1999/xhtml"; .notificationbox-stack { /* Prevent the animation from overlapping the navigation toolbar */ @@ -14,13 +13,8 @@ /* Create a stacking context for the box-shadow */ position: relative; z-index: 1; -} - -@supports not -moz-bool-pref("browser.proton.enabled") { -.notificationbox-stack[notificationside="top"] { box-shadow: 0 3px 10px -7px #00000080; } -} notification { min-height: 40px; @@ -54,7 +48,6 @@ notification[type="info"]:-moz-lwtheme-brighttext { --notification-button-background-active: rgba(249,249,250,.3); } -html|notification-message.animated, notification.animated { transition: margin-top 300ms var(--animation-easing-function), opacity 300ms var(--animation-easing-function); } @@ -192,8 +185,8 @@ notification[type="critical"] > hbox > .messageImage { } @supports -moz-bool-pref("browser.proton.infobars.enabled") { -.notificationbox-stack { - background-color: var(--toolbar-bgcolor); +.notificationbox-stack, +notification { width: 100%; } }