tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 877354976e78b0dd3123a98ef33f996734e84cc4
parent 582212c838412f21b2bbddde9aeb7e9c4f552cf8
Author: Sandor Molnar <smolnar@mozilla.com>
Date:   Fri,  2 Jan 2026 19:41:22 +0200

Revert "Bug 1994948 - prefer theme_icons.dark for default themes r=robwu,desktop-theme-reviewers,jsudiaman,emilio" for causing bc failures @ browser_ext_browserAction_pageAction_icon.js

This reverts commit 0ccd53f89db7ae92e3b5e5e6174679d725f14757.

Diffstat:
Mbrowser/components/extensions/parent/ext-browserAction.js | 46+++++++++++++++++++++-------------------------
Mbrowser/components/extensions/test/browser/browser_ext_browserAction_theme_icons.js | 174++++++++++++++++++++++++++++++++++++++++---------------------------------------
Mbrowser/components/sidebar/browser-sidebar.js | 2--
Mbrowser/themes/shared/addons/unified-extensions.css | 11+++++++++--
Mtoolkit/components/extensions/ExtensionParent.sys.mjs | 8++++----
5 files changed, 123 insertions(+), 118 deletions(-)

diff --git a/browser/components/extensions/parent/ext-browserAction.js b/browser/components/extensions/parent/ext-browserAction.js @@ -913,41 +913,37 @@ this.browserAction = class extends ExtensionAPIPersistent { } getIconData(icons) { - const getIcon = (icon, theme) => { + let getIcon = (icon, theme) => { if (typeof icon === "object") { return IconDetails.escapeUrl(icon[theme]); } return IconDetails.escapeUrl(icon); }; - const getBackgroundImage = (icon1x, icon2x = icon1x) => { - const image1x = `url("${icon1x}")`; - if (icon2x === icon1x) { - return image1x; - } - - const image2x = `url("${icon2x}")`; - return `image-set(${image1x} 1dppx, ${image2x} 2dppx);`; - }; - - const getStyle = (cssVarName, icon1x, icon2x) => { - return `${cssVarName}: ${getBackgroundImage( - getIcon(icon1x, "light"), - getIcon(icon2x, "light") - )}; - ${cssVarName}-dark: ${getBackgroundImage( - getIcon(icon1x, "dark"), - getIcon(icon2x, "dark") - )};`; + let getStyle = (name, icon1x, icon2x) => { + return ` + --webextension-${name}: image-set( + url("${getIcon(icon1x, "default")}"), + url("${getIcon(icon2x, "default")}") 2x + ); + --webextension-${name}-light: image-set( + url("${getIcon(icon1x, "light")}"), + url("${getIcon(icon2x, "light")}") 2x + ); + --webextension-${name}-dark: image-set( + url("${getIcon(icon1x, "dark")}"), + url("${getIcon(icon2x, "dark")}") 2x + ); + `; }; - const icon16 = IconDetails.getPreferredIcon(icons, this.extension, 16).icon; - const icon32 = IconDetails.getPreferredIcon(icons, this.extension, 32).icon; - const icon64 = IconDetails.getPreferredIcon(icons, this.extension, 64).icon; + let icon16 = IconDetails.getPreferredIcon(icons, this.extension, 16).icon; + let icon32 = IconDetails.getPreferredIcon(icons, this.extension, 32).icon; + let icon64 = IconDetails.getPreferredIcon(icons, this.extension, 64).icon; return ` - ${getStyle("--webextension-menupanel-image", icon32, icon64)} - ${getStyle("--webextension-toolbar-image", icon16, icon32)} + ${getStyle("menupanel-image", icon32, icon64)} + ${getStyle("toolbar-image", icon16, icon32)} `; } diff --git a/browser/components/extensions/test/browser/browser_ext_browserAction_theme_icons.js b/browser/components/extensions/test/browser/browser_ext_browserAction_theme_icons.js @@ -17,25 +17,21 @@ const TOOLBAR_MAPPING = { tabstrip: "TabsToolbar", }; -const DEFAULT_ICON = "default.png"; -const LIGHT_THEME_ICON = "black.png"; -const DARK_THEME_ICON = "white.png"; - async function testBrowserAction(extension, expectedIcon) { - const browserActionWidget = getBrowserActionWidget(extension); + let browserActionWidget = getBrowserActionWidget(extension); await promiseAnimationFrame(); - const browserActionButton = browserActionWidget + let browserActionButton = browserActionWidget .forWindow(window) .node.querySelector(".unified-extensions-item-action-button"); - const image = getListStyleImage(browserActionButton); + let image = getListStyleImage(browserActionButton); ok( - image?.includes(expectedIcon), + image.includes(expectedIcon), `Expected browser action icon (${image}) to be ${expectedIcon}` ); } async function testStaticTheme(options) { - const { + let { themeData, themeIcons, withDefaultIcon, @@ -43,7 +39,7 @@ async function testStaticTheme(options) { defaultArea = "navbar", } = options; - const manifest = { + let manifest = { browser_action: { theme_icons: themeIcons, default_area: defaultArea, @@ -51,17 +47,17 @@ async function testStaticTheme(options) { }; if (withDefaultIcon) { - manifest.browser_action.default_icon = DEFAULT_ICON; + manifest.browser_action.default_icon = "default.png"; } - const extension = ExtensionTestUtils.loadExtension({ manifest }); + let extension = ExtensionTestUtils.loadExtension({ manifest }); await extension.startup(); // Ensure we show the menupanel at least once. This makes sure that the // elements we're going to query the style of are in the flat tree. if (defaultArea == "menupanel") { - const shown = BrowserTestUtils.waitForPopupEvent( + let shown = BrowserTestUtils.waitForPopupEvent( window.gUnifiedExtensions.panel, "shown" ); @@ -70,15 +66,17 @@ async function testStaticTheme(options) { } // Confirm that the browser action has the correct default icon before a theme is loaded. - const toolbarId = TOOLBAR_MAPPING[defaultArea]; - + let toolbarId = TOOLBAR_MAPPING[defaultArea]; + let expectedDefaultIcon; // Some platforms have dark toolbars by default, take it in account when picking the default icon. - const hasDarkToolbar = - toolbarId && document.getElementById(toolbarId).hasAttribute("brighttext"); - const expectedDefaultIcon = hasDarkToolbar - ? DARK_THEME_ICON - : LIGHT_THEME_ICON; - + if ( + toolbarId && + document.getElementById(toolbarId).hasAttribute("brighttext") + ) { + expectedDefaultIcon = "light.png"; + } else { + expectedDefaultIcon = withDefaultIcon ? "default.png" : "dark.png"; + } if (Services.appinfo.nativeMenubar) { ok( !document.getElementById("toolbar-menubar").hasAttribute("brighttext"), @@ -87,7 +85,7 @@ async function testStaticTheme(options) { } await testBrowserAction(extension, expectedDefaultIcon); - const theme = ExtensionTestUtils.loadExtension({ + let theme = ExtensionTestUtils.loadExtension({ manifest: { theme: { colors: themeData, @@ -98,7 +96,13 @@ async function testStaticTheme(options) { await theme.startup(); // Confirm that the correct icon is used when the theme is loaded. - await testBrowserAction(extension, expectedIcon); + if (expectedIcon == "dark") { + // The dark icon should be used if the area is light. + await testBrowserAction(extension, "dark.png"); + } else { + // The light icon should be used if the area is dark. + await testBrowserAction(extension, "light.png"); + } await theme.unload(); @@ -111,11 +115,11 @@ async function testStaticTheme(options) { add_task(async function browseraction_theme_icons_light_theme() { await testStaticTheme({ themeData: LIGHT_THEME_COLORS, - expectedIcon: LIGHT_THEME_ICON, + expectedIcon: "dark", themeIcons: [ { - dark: LIGHT_THEME_ICON, - light: DARK_THEME_ICON, + light: "light.png", + dark: "dark.png", size: 19, }, ], @@ -123,16 +127,16 @@ add_task(async function browseraction_theme_icons_light_theme() { }); await testStaticTheme({ themeData: LIGHT_THEME_COLORS, - expectedIcon: LIGHT_THEME_ICON, + expectedIcon: "dark", themeIcons: [ { - dark: LIGHT_THEME_ICON, - light: DARK_THEME_ICON, + light: "light.png", + dark: "dark.png", size: 16, }, { - dark: LIGHT_THEME_ICON, - light: DARK_THEME_ICON, + light: "light.png", + dark: "dark.png", size: 32, }, ], @@ -143,11 +147,11 @@ add_task(async function browseraction_theme_icons_light_theme() { add_task(async function browseraction_theme_icons_dark_theme() { await testStaticTheme({ themeData: DARK_THEME_COLORS, - expectedIcon: DARK_THEME_ICON, + expectedIcon: "light", themeIcons: [ { - dark: LIGHT_THEME_ICON, - light: DARK_THEME_ICON, + light: "light.png", + dark: "dark.png", size: 19, }, ], @@ -155,16 +159,16 @@ add_task(async function browseraction_theme_icons_dark_theme() { }); await testStaticTheme({ themeData: DARK_THEME_COLORS, - expectedIcon: DARK_THEME_ICON, + expectedIcon: "light", themeIcons: [ { - dark: LIGHT_THEME_ICON, - light: DARK_THEME_ICON, + light: "light.png", + dark: "dark.png", size: 16, }, { - dark: LIGHT_THEME_ICON, - light: DARK_THEME_ICON, + light: "light.png", + dark: "dark.png", size: 32, }, ], @@ -173,7 +177,7 @@ add_task(async function browseraction_theme_icons_dark_theme() { }); add_task(async function browseraction_theme_icons_different_toolbars() { - const themeData = { + let themeData = { frame: "#000", tab_background_text: "#fff", toolbar: "#fff", @@ -181,11 +185,11 @@ add_task(async function browseraction_theme_icons_different_toolbars() { }; await testStaticTheme({ themeData, - expectedIcon: LIGHT_THEME_ICON, + expectedIcon: "dark", themeIcons: [ { - dark: LIGHT_THEME_ICON, - light: DARK_THEME_ICON, + light: "light.png", + dark: "dark.png", size: 19, }, ], @@ -193,28 +197,28 @@ add_task(async function browseraction_theme_icons_different_toolbars() { }); await testStaticTheme({ themeData, - expectedIcon: LIGHT_THEME_ICON, + expectedIcon: "dark", themeIcons: [ { - dark: LIGHT_THEME_ICON, - light: DARK_THEME_ICON, + light: "light.png", + dark: "dark.png", size: 16, }, { - dark: LIGHT_THEME_ICON, - light: DARK_THEME_ICON, + light: "light.png", + dark: "dark.png", size: 32, }, ], }); await testStaticTheme({ themeData, - expectedIcon: DARK_THEME_ICON, + expectedIcon: "light", defaultArea: "tabstrip", themeIcons: [ { - dark: LIGHT_THEME_ICON, - light: DARK_THEME_ICON, + light: "light.png", + dark: "dark.png", size: 19, }, ], @@ -222,17 +226,17 @@ add_task(async function browseraction_theme_icons_different_toolbars() { }); await testStaticTheme({ themeData, - expectedIcon: DARK_THEME_ICON, + expectedIcon: "light", defaultArea: "tabstrip", themeIcons: [ { - dark: LIGHT_THEME_ICON, - light: DARK_THEME_ICON, + light: "light.png", + dark: "dark.png", size: 16, }, { - dark: LIGHT_THEME_ICON, - light: DARK_THEME_ICON, + light: "light.png", + dark: "dark.png", size: 32, }, ], @@ -240,17 +244,17 @@ add_task(async function browseraction_theme_icons_different_toolbars() { }); add_task(async function browseraction_theme_icons_overflow_panel() { - const themeData = { + let themeData = { popup: "#000", popup_text: "#fff", }; await testStaticTheme({ themeData, - expectedIcon: LIGHT_THEME_ICON, + expectedIcon: "dark", themeIcons: [ { - dark: LIGHT_THEME_ICON, - light: DARK_THEME_ICON, + light: "light.png", + dark: "dark.png", size: 19, }, ], @@ -258,16 +262,16 @@ add_task(async function browseraction_theme_icons_overflow_panel() { }); await testStaticTheme({ themeData, - expectedIcon: LIGHT_THEME_ICON, + expectedIcon: "dark", themeIcons: [ { - dark: LIGHT_THEME_ICON, - light: DARK_THEME_ICON, + light: "light.png", + dark: "dark.png", size: 16, }, { - dark: LIGHT_THEME_ICON, - light: DARK_THEME_ICON, + light: "light.png", + dark: "dark.png", size: 32, }, ], @@ -275,12 +279,12 @@ add_task(async function browseraction_theme_icons_overflow_panel() { await testStaticTheme({ themeData, - expectedIcon: DARK_THEME_ICON, + expectedIcon: "light", defaultArea: "menupanel", themeIcons: [ { - dark: LIGHT_THEME_ICON, - light: DARK_THEME_ICON, + light: "light.png", + dark: "dark.png", size: 19, }, ], @@ -288,17 +292,17 @@ add_task(async function browseraction_theme_icons_overflow_panel() { }); await testStaticTheme({ themeData, - expectedIcon: DARK_THEME_ICON, + expectedIcon: "light", defaultArea: "menupanel", themeIcons: [ { - dark: LIGHT_THEME_ICON, - light: DARK_THEME_ICON, + light: "light.png", + dark: "dark.png", size: 16, }, { - dark: LIGHT_THEME_ICON, - light: DARK_THEME_ICON, + light: "light.png", + dark: "dark.png", size: 32, }, ], @@ -306,7 +310,7 @@ add_task(async function browseraction_theme_icons_overflow_panel() { }); add_task(async function browseraction_theme_icons_dynamic_theme() { - const themeExtension = ExtensionTestUtils.loadExtension({ + let themeExtension = ExtensionTestUtils.loadExtension({ manifest: { permissions: ["theme"], }, @@ -324,20 +328,20 @@ add_task(async function browseraction_theme_icons_dynamic_theme() { await themeExtension.startup(); - const extension = ExtensionTestUtils.loadExtension({ + let extension = ExtensionTestUtils.loadExtension({ manifest: { browser_action: { - default_icon: DEFAULT_ICON, + default_icon: "default.png", default_area: "navbar", theme_icons: [ { - dark: LIGHT_THEME_ICON, - light: DARK_THEME_ICON, + light: "light.png", + dark: "dark.png", size: 16, }, { - dark: LIGHT_THEME_ICON, - light: DARK_THEME_ICON, + light: "light.png", + dark: "dark.png", size: 32, }, ], @@ -348,27 +352,27 @@ add_task(async function browseraction_theme_icons_dynamic_theme() { await extension.startup(); // Confirm that the browser action has the default icon before a theme is set. - await testBrowserAction(extension, LIGHT_THEME_ICON); + await testBrowserAction(extension, "default.png"); // Update the theme to a light theme. themeExtension.sendMessage("update-theme", LIGHT_THEME_COLORS); await themeExtension.awaitMessage("theme-updated"); // Confirm that the dark icon is used for the light theme. - await testBrowserAction(extension, LIGHT_THEME_ICON); + await testBrowserAction(extension, "dark.png"); // Update the theme to a dark theme. themeExtension.sendMessage("update-theme", DARK_THEME_COLORS); await themeExtension.awaitMessage("theme-updated"); // Confirm that the light icon is used for the dark theme. - await testBrowserAction(extension, DARK_THEME_ICON); + await testBrowserAction(extension, "light.png"); // Unload the theme. await themeExtension.unload(); - // Confirm that the light icon is used when the theme is unloaded. - await testBrowserAction(extension, LIGHT_THEME_ICON); + // Confirm that the default icon is used when the theme is unloaded. + await testBrowserAction(extension, "default.png"); await extension.unload(); }); diff --git a/browser/components/sidebar/browser-sidebar.js b/browser/components/sidebar/browser-sidebar.js @@ -1764,8 +1764,6 @@ var SidebarController = { sidebar.label = label; const updateAttributes = el => { - // TODO Bug 1996762 - Add support for dark-theme sidebar icons - // --webextension-menuitem-image-dark is used in dark themes el.style.setProperty("--webextension-menuitem-image", sidebar.icon); el.setAttribute("label", sidebar.label); }; diff --git a/browser/themes/shared/addons/unified-extensions.css b/browser/themes/shared/addons/unified-extensions.css @@ -119,13 +119,20 @@ unified-extensions-item { list-style-image: var(--webextension-toolbar-image, inherit); toolbar[brighttext] & { - /* separate image used for dark toolbars */ + list-style-image: var(--webextension-toolbar-image-light, inherit); + } + :root[lwtheme] toolbar:not([brighttext]) & { list-style-image: var(--webextension-toolbar-image-dark, inherit); } toolbaritem:is([overflowedItem="true"], [cui-areatype="panel"]) > .unified-extensions-item-row-wrapper > & { list-style-image: var(--webextension-menupanel-image, inherit); + /* TODO: This feels a bit odd, why do we have three images? It feels we + * should probably have only two (light/dark), and choose based on + * prefers-color-scheme + lwt-popup */ :root[lwt-popup="dark"] & { - /* separate image used for dark toolbars */ + list-style-image: var(--webextension-menupanel-image-light, inherit); + } + :root[lwt-popup="light"] & { list-style-image: var(--webextension-menupanel-image-dark, inherit); } } diff --git a/toolkit/components/extensions/ExtensionParent.sys.mjs b/toolkit/components/extensions/ExtensionParent.sys.mjs @@ -2151,15 +2151,15 @@ let IconDetails = { if (themeIcons) { themeIcons.forEach(({ size, light, dark }) => { - // light and dark are reversed. theme_icons specifies - // the color of the icon instead of the toolbar color - const lightURL = baseURI.resolve(dark); - const darkURL = baseURI.resolve(light); + let lightURL = baseURI.resolve(light); + let darkURL = baseURI.resolve(dark); this._checkURL(lightURL, extension); this._checkURL(darkURL, extension); + let defaultURL = result[size] || result[19]; // always fallback to default first result[size] = { + default: defaultURL || darkURL, // Fallback to the dark url if no default is specified. light: lightURL, dark: darkURL, };