--- a/browser/components/extensions/ExtensionPopups.jsm
+++ b/browser/components/extensions/ExtensionPopups.jsm
@@ -119,16 +119,17 @@ class BasePopup {
if (this.viewNode) {
this.viewNode.removeEventListener(this.DESTROY_EVENT, this);
delete this.viewNode.customRectGetter;
}
let {panel} = this;
if (panel) {
panel.style.removeProperty("--arrowpanel-background");
+ panel.style.removeProperty("--arrowpanel-border-color");
panel.removeAttribute("remote");
}
this.browser = null;
this.stack = null;
this.viewNode = null;
});
}
@@ -345,19 +346,29 @@ class BasePopup {
this.browser.style.height = `${height}px`;
this.browser.style.minHeight = `${height}px`;
}
let event = new this.window.CustomEvent("WebExtPopupResized", {detail});
this.browser.dispatchEvent(event);
}
- setBackground(background = "") {
- if (background) {
- this.panel.style.setProperty("--arrowpanel-background", background);
+ setBackground(background) {
+ // Panels inherit the applied theme (light, dark, etc) and there is a high
+ // likelihood that most extension authors will not have tested with a dark theme.
+ // If they have not set a background-color, we force it to white to ensure visibility
+ // of the extension content. Passing `null` should be treated the same as no argument,
+ // which is why we can't use default parameters here.
+ if (!background) {
+ background = "#fff";
+ }
+ this.panel.style.setProperty("--arrowpanel-background", background);
+ if (background == "#fff") {
+ // Set a usable default color that work with the default background-color.
+ this.panel.style.setProperty("--arrowpanel-border-color", "hsla(210,4%,10%,.05)");
}
this.background = background;
}
}
/**
* A map of active popups for a given browser window.
*
--- a/browser/components/extensions/test/browser/browser_ext_popup_background.js
+++ b/browser/components/extensions/test/browser/browser_ext_popup_background.js
@@ -1,116 +1,125 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
/* eslint-disable mozilla/no-arbitrary-setTimeout */
"use strict";
-add_task(async function testPopupBackground() {
- let extension = ExtensionTestUtils.loadExtension({
- background() {
- browser.tabs.query({active: true, currentWindow: true}, tabs => {
- browser.pageAction.show(tabs[0].id);
- });
- },
-
- manifest: {
- "browser_action": {
- "default_popup": "popup.html",
- "browser_style": false,
- },
-
- "page_action": {
- "default_popup": "popup.html",
- "browser_style": false,
- },
- },
+async function testPanel(browser, standAlone, initial_background) {
+ let panel = getPanelForNode(browser);
+ let arrowContent = document.getAnonymousElementByAttribute(panel, "class", "panel-arrowcontent");
+ let arrow = document.getAnonymousElementByAttribute(panel, "anonid", "arrow");
- files: {
- "popup.html": `<!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- </head>
- <body style="width: 100px; height: 100px; background-color: green;">
- </body>
- </html>`,
- },
- });
-
- await extension.startup();
-
- async function testPanel(browser, standAlone) {
- let panel = getPanelForNode(browser);
- let arrowContent = document.getAnonymousElementByAttribute(panel, "class", "panel-arrowcontent");
- let arrow = document.getAnonymousElementByAttribute(panel, "anonid", "arrow");
-
- let checkArrow = (background = null) => {
- if (background == null || !standAlone) {
- ok(!arrow.style.hasOwnProperty("fill"), "Arrow fill should be the default one");
- return;
- }
-
- is(getComputedStyle(arrowContent).backgroundColor, background, "Arrow content should have correct background");
- is(getComputedStyle(arrow).fill, background, "Arrow should have correct background");
- };
-
- function getBackground(browser) {
- return ContentTask.spawn(browser, null, async function() {
- return content.getComputedStyle(content.document.body)
- .backgroundColor;
- });
+ let checkArrow = (background = null) => {
+ if (background == null || !standAlone) {
+ ok(!arrow.style.hasOwnProperty("fill"), "Arrow fill should be the default one");
+ return;
}
- let setBackground = color => {
- content.document.body.style.backgroundColor = color;
- };
-
- await new Promise(resolve => setTimeout(resolve, 100));
-
- info("Test that initial background color is applied");
-
- checkArrow(await getBackground(browser));
+ is(getComputedStyle(arrowContent).backgroundColor, background, "Arrow content should have correct background");
+ is(getComputedStyle(arrow).fill, background, "Arrow should have correct background");
+ };
- info("Test that dynamically-changed background color is applied");
-
- await alterContent(browser, setBackground, "black");
-
- checkArrow(await getBackground(browser));
-
- info("Test that non-opaque background color results in default styling");
-
- await alterContent(browser, setBackground, "rgba(1, 2, 3, .9)");
-
- checkArrow(null);
+ function getBackground(browser) {
+ return ContentTask.spawn(browser, null, async function() {
+ return content.getComputedStyle(content.document.body)
+ .backgroundColor;
+ });
}
- {
- info("Test stand-alone browserAction popup");
+ let setBackground = color => {
+ content.document.body.style.backgroundColor = color;
+ };
+
+ await new Promise(resolve => setTimeout(resolve, 100));
+
+ info("Test that initial background color is applied");
+ checkArrow(initial_background);
+
+ info("Test that dynamically-changed background color is applied");
+ await alterContent(browser, setBackground, "black");
+ checkArrow(await getBackground(browser));
+
+ info("Test that non-opaque background color results in default styling");
+ await alterContent(browser, setBackground, "rgba(1, 2, 3, .9)");
+ checkArrow(null);
+}
- clickBrowserAction(extension);
- let browser = await awaitExtensionPanel(extension);
- await testPanel(browser, true);
- await closeBrowserAction(extension);
- }
+add_task(async function testPopupBackground() {
+ let testCases = [{
+ "browser_style": false,
+ "background": "background-color: green;",
+ "initial_background": "rgb(0, 128, 0)",
+ }, {
+ "browser_style": true,
+ // Use white here instead of transparent, because
+ // when no background is supplied we will fill
+ // with white by default.
+ "initial_background": "rgb(255, 255, 255)",
+ }];
+ for (let testCase of testCases) {
+ info(`Testing browser_style: ${testCase.browser_style} with background? ${!!testCase.background}`);
+ let extension = ExtensionTestUtils.loadExtension({
+ background() {
+ browser.tabs.query({active: true, currentWindow: true}, tabs => {
+ browser.pageAction.show(tabs[0].id);
+ });
+ },
- {
- info("Test menu panel browserAction popup");
-
- let widget = getBrowserActionWidget(extension);
- CustomizableUI.addWidgetToArea(widget.id, getCustomizableUIPanelID());
+ manifest: {
+ "browser_action": {
+ "default_popup": "popup.html",
+ "browser_style": testCase.browser_style,
+ },
- clickBrowserAction(extension);
- let browser = await awaitExtensionPanel(extension);
- await testPanel(browser, false);
- await closeBrowserAction(extension);
- }
+ "page_action": {
+ "default_popup": "popup.html",
+ "browser_style": testCase.browser_style,
+ },
+ },
- {
- info("Test pageAction popup");
+ files: {
+ "popup.html": `<!DOCTYPE html>
+ <html>
+ <head>
+ <meta charset="utf-8">
+ </head>
+ <body style="width: 100px; height: 100px; ${testCase.background || ""}">
+ </body>
+ </html>`,
+ },
+ });
+
+ await extension.startup();
+
+ {
+ info("Test stand-alone browserAction popup");
- clickPageAction(extension);
- let browser = await awaitExtensionPanel(extension);
- await testPanel(browser, true);
- await closePageAction(extension);
+ clickBrowserAction(extension);
+ let browser = await awaitExtensionPanel(extension);
+ await testPanel(browser, true, testCase.initial_background);
+ await closeBrowserAction(extension);
+ }
+
+ {
+ info("Test menu panel browserAction popup");
+
+ let widget = getBrowserActionWidget(extension);
+ CustomizableUI.addWidgetToArea(widget.id, getCustomizableUIPanelID());
+
+ clickBrowserAction(extension);
+ let browser = await awaitExtensionPanel(extension);
+ await testPanel(browser, false, testCase.initial_background);
+ await closeBrowserAction(extension);
+ }
+
+ {
+ info("Test pageAction popup");
+
+ clickPageAction(extension);
+ let browser = await awaitExtensionPanel(extension);
+ await testPanel(browser, true, testCase.initial_background);
+ await closePageAction(extension);
+ }
+
+ await extension.unload();
}
-
- await extension.unload();
});