diff --git a/examples.json b/examples.json index caf2df7..702fa86 100644 --- a/examples.json +++ b/examples.json @@ -548,6 +548,11 @@ "javascript_apis": ["management.getAll", "management.setEnabled"], "name": "theme-switcher" }, + { + "description": "Demonstration of how to use the prefers-color-scheme media query to adapt an SVG icon to dark and light themes.", + "javascript_apis": ["runtime.getURL","tabs.query", "tabs.create", "tabs.update", "management.getAll","management.setEnabled","management.onEnabled", "pageAction.onClicked","action.onClicked"], + "name": "themed-icons" + }, { "description": "A collection of themes illustrating:", "javascript_apis": [], diff --git a/themed-icons/README.md b/themed-icons/README.md new file mode 100644 index 0000000..952fd11 --- /dev/null +++ b/themed-icons/README.md @@ -0,0 +1,27 @@ +# themed-icons + +This example demonstrates how to use the prefers-color-scheme media query to adapt an SVG icon to dark and light themes. + +## What it does + +This extension includes: + +* a background script, `background.js`. +* page (address bar) and browser (toolbar) action icons. + +The extension displays the [page action](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/pageAction) on any webpage, and the extension test page, which the extension opens when it starts, and the [browser action](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/browserAction) is pinned to the toolbar when the extension is installed. + +Clicking either icon opens the test extension page and switches to the next available theme. + +When the active theme is enabled, the page and browser action change color based on the dark or light background color used in the UI. + +For example: +- When the built-in Firefox Alpenglow or dark themes are active, the icons are black with a white outline. +- When the built-in Firefox light theme is active, the icons are red with a black outline. + +## NOTE: Implicit CSS filter applied to pageAction SVG icons in dark themes in Firefox Desktop 151 and earlier + +In builds where the `about:config` preference `extensions.webextensions.pageActionIconDarkModeFilter.enabled` is set to `true` or not defined, a greyscale and brightness CSS filter is applied to page action icons for dark themes. This filter can reduce the contrast of icons that use multiple colors, see [Bug 2001318](https://bugzilla.mozilla.org/2001318). + +This implicit CSS filter is turned off in Firefox Desktop Nightly in release 149 and later, and on the release channel +as part of [Bug 2016509](https://bugzilla.mozilla.org/2016509) \ No newline at end of file diff --git a/themed-icons/background.js b/themed-icons/background.js new file mode 100644 index 0000000..17e9ab4 --- /dev/null +++ b/themed-icons/background.js @@ -0,0 +1,34 @@ +async function openOrSelectTab(reloadExistingTab = false) { + const tabUrl = browser.runtime.getURL("/extpage.html"); + let [tab] = await browser.tabs.query({ url: tabUrl }); + if (!tab) { + await browser.tabs.create({ url: tabUrl, active: true }); + } else { + await browser.tabs.update(tab.id, { + active: true, + ...(reloadExistingTab ? { url: tabUrl } : {}) + }); + } +} + +async function switchToNextTheme() { + openOrSelectTab(); + const themes = await browser.management.getAll().then(extensions => { + return extensions.filter(ext => ext.type === "theme"); + }); + const activeThemeIndex = themes.findIndex(theme => theme.enabled); + const nextThemeIndex = activeThemeIndex < themes.length - 1 + ? activeThemeIndex + 1 + : 0 + const nextTheme = themes[nextThemeIndex]; + await browser.management.setEnabled(nextTheme.id, true); +} + +// Switch to the next theme available on pageAction or action icons clicks. +browser.pageAction.onClicked.addListener(switchToNextTheme); +browser.action.onClicked.addListener(switchToNextTheme); + +// Open the the extension page in a new tab after the add-on is installed. +browser.runtime.onInstalled.addListener(() => { + openOrSelectTab(true); +}); \ No newline at end of file diff --git a/themed-icons/extpage.html b/themed-icons/extpage.html new file mode 100644 index 0000000..c509aef --- /dev/null +++ b/themed-icons/extpage.html @@ -0,0 +1,32 @@ + + + + SVG themed icon using prefer-color-scheme media query + + + + +

SVG themed icon using prefer-color-scheme media query

+
+
Active theme:
+
ACTIVE THEME INFO
+
+

README.md

+
README.md content
+ + + diff --git a/themed-icons/extpage.js b/themed-icons/extpage.js new file mode 100644 index 0000000..250ae41 --- /dev/null +++ b/themed-icons/extpage.js @@ -0,0 +1,29 @@ +let activeThemeEl = document.querySelector("#active-theme"); +let readmeEl = document.querySelector("#read-me"); + +function updateThemeInfo(info) { + activeThemeEl.textContent = `${info.name} (${info.id})`; +} + +// Include the README.md file content into the test page. +fetch("/README.md").then(r => r.text()).then(text => { + readmeEl.textContent = text; +}); + +// Set active theme info element content on page load. +browser.management.getAll().then(addons => { + updateThemeInfo(addons.find(addon => addon.type == "theme" && addon.enabled)); +}); + +// Show pageAction icon on the extension page. +browser.tabs.getCurrent().then(tabInfo => { + browser.pageAction.show(tabInfo.id); +}); + +// Update active theme info when a theme is enabled. +browser.management.onEnabled.addListener(info => { + if (info.type !== "theme") { + return; + } + updateThemeInfo(info); +}); diff --git a/themed-icons/manifest.json b/themed-icons/manifest.json new file mode 100644 index 0000000..9cf8668 --- /dev/null +++ b/themed-icons/manifest.json @@ -0,0 +1,37 @@ +{ + + "description": "Adds page action and action SVG icons that adapt to dark and light themes using prefers-color-scheme media query.", + "manifest_version": 3, + "name": "themed-icons", + "version": "1.0", + "homepage_url": "https://github.com/mdn/webextensions-examples/tree/master/themed-icons", + "browser_specific_settings": { + "gecko": { + "id": "themed-icons@mozilla.org", + "data_collection_permissions": { + "required": ["none"] + } + } + }, + + "icons": { "32": "prefers-color-scheme-icon.svg" }, + + "background": { + "scripts": ["background.js"], + "type": "module" + }, + + "page_action": { + "default_icon": "prefers-color-scheme-icon.svg", + "show_matches": [""] + }, + + "action": { + "default_icon": "prefers-color-scheme-icon.svg", + "default_area": "navbar" + }, + + "permissions": [ + "management" + ] +} diff --git a/themed-icons/prefers-color-scheme-icon.svg b/themed-icons/prefers-color-scheme-icon.svg new file mode 100644 index 0000000..948731c --- /dev/null +++ b/themed-icons/prefers-color-scheme-icon.svg @@ -0,0 +1,13 @@ + + + + +