Bug 1343921 - Put the icon support behind a pref so it can be enabled once we are satisfied with the performance. r?mikedeboer,mattw draft
authorJared Wein <jwein@mozilla.com>
Fri, 03 Mar 2017 09:52:44 -0500
changeset 493196 291ad98cf5169f346876d8ea5b335e476edd3769
parent 493194 59839362389849eb0b742fa1ccc75f4ba458cb33
child 493197 9003ab6b6c384b2ef9950c05e9a81ab19c79ed44
push id47679
push userjwein@mozilla.com
push dateFri, 03 Mar 2017 15:07:26 +0000
reviewersmikedeboer, mattw
bugs1343921
milestone54.0a1
Bug 1343921 - Put the icon support behind a pref so it can be enabled once we are satisfied with the performance. r?mikedeboer,mattw MozReview-Commit-ID: 8RkelQDFJLA
browser/app/profile/firefox.js
browser/base/content/theme-vars.inc.css
browser/components/extensions/ext-theme.js
browser/components/extensions/test/browser/browser_ext_themes_icons.js
toolkit/modules/LightweightThemeConsumer.jsm
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -62,16 +62,17 @@ pref("extensions.hotfix.certs.2.sha1Fing
 pref("extensions.systemAddon.update.url", "https://aus5.mozilla.org/update/3/SystemAddons/%VERSION%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/update.xml");
 
 // Disable add-ons that are not installed by the user in all scopes by default.
 // See the SCOPE constants in AddonManager.jsm for values to use here.
 pref("extensions.autoDisableScopes", 15);
 
 // Whether or not webextension themes are supported.
 pref("extensions.webextensions.themes.enabled", false);
+pref("extensions.webextensions.themes.icons.enabled", false);
 
 // Add-on content security policies.
 pref("extensions.webextensions.base-content-security-policy", "script-src 'self' https://* moz-extension: blob: filesystem: 'unsafe-eval' 'unsafe-inline'; object-src 'self' https://* moz-extension: blob: filesystem:;");
 pref("extensions.webextensions.default-content-security-policy", "script-src 'self'; object-src 'self';");
 
 // Require signed add-ons by default
 pref("xpinstall.signatures.required", true);
 pref("xpinstall.signatures.devInfoURL", "https://wiki.mozilla.org/Addons/Extension_Signing");
--- a/browser/base/content/theme-vars.inc.css
+++ b/browser/base/content/theme-vars.inc.css
@@ -1,166 +1,166 @@
 %if 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/. */
 %endif
 
-#back-button:-moz-lwtheme {
+:root[lwthemeicons~="--back-icon"] #back-button:-moz-lwtheme {
   list-style-image: var(--back-icon) !important;
 }
 
-#forward-button:-moz-lwtheme {
+:root[lwthemeicons~="--forward-icon"] #forward-button:-moz-lwtheme {
   list-style-image: var(--forward-icon) !important;
 }
 
-#urlbar-reload-button:-moz-lwtheme {
+:root[lwthemeicons~="--reload-icon"] #urlbar-reload-button:-moz-lwtheme {
   list-style-image: var(--reload-icon) !important;
 }
 
-#urlbar-stop-button:-moz-lwtheme {
+:root[lwthemeicons~="--stop-icon"] #urlbar-stop-button:-moz-lwtheme {
   list-style-image: var(--stop-icon) !important;
 }
 
-#bookmarks-menu-button:-moz-lwtheme {
+:root[lwthemeicons~="--bookmark_star-icon"] #bookmarks-menu-button:-moz-lwtheme {
   list-style-image: var(--bookmark_star-icon) !important;
 }
 
-#bookmarks-menu-button[cui-areatype='toolbar'] > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon:-moz-lwtheme {
+:root[lwthemeicons~="--bookmark_menu-icon"] #bookmarks-menu-button[cui-areatype='toolbar'] > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon:-moz-lwtheme {
   list-style-image: var(--bookmark_menu-icon) !important;
 }
 
-#downloads-button:-moz-lwtheme {
+:root[lwthemeicons~="--downloads-icon"] #downloads-button:-moz-lwtheme {
   list-style-image: var(--downloads-icon) !important;
 }
 
-#home-button:-moz-lwtheme {
+:root[lwthemeicons~="--home-icon"] #home-button:-moz-lwtheme {
   list-style-image: var(--home-icon) !important;
 }
 
-#PanelUI-menu-button:-moz-lwtheme {
+:root[lwthemeicons~="--app_menu-icon"] #PanelUI-menu-button:-moz-lwtheme {
   list-style-image: var(--app_menu-icon) !important;
 }
 
-#cut-button:-moz-lwtheme {
+:root[lwthemeicons~="--cut-icon"] #cut-button:-moz-lwtheme {
   list-style-image: var(--cut-icon) !important;
 }
 
-#copy-button:-moz-lwtheme {
+:root[lwthemeicons~="--copy-icon"] #copy-button:-moz-lwtheme {
   list-style-image: var(--copy-icon) !important;
 }
 
-#paste-button:-moz-lwtheme {
+:root[lwthemeicons~="--paste-icon"] #paste-button:-moz-lwtheme {
   list-style-image: var(--paste-icon) !important;
 }
 
-#new-window-button:-moz-lwtheme {
+:root[lwthemeicons~="--new_window-icon"] #new-window-button:-moz-lwtheme {
   list-style-image: var(--new_window-icon) !important;
 }
 
-#privatebrowsing-button:-moz-lwtheme {
+:root[lwthemeicons~="--new_private_window-icon"] #privatebrowsing-button:-moz-lwtheme {
   list-style-image: var(--new_private_window-icon) !important;
 }
 
-#save-page-button:-moz-lwtheme {
+:root[lwthemeicons~="--save_page-icon"] #save-page-button:-moz-lwtheme {
   list-style-image: var(--save_page-icon) !important;
 }
 
-#print-button:-moz-lwtheme {
+:root[lwthemeicons~="--print-icon"] #print-button:-moz-lwtheme {
   list-style-image: var(--print-icon) !important;
 }
 
-#history-panelmenu:-moz-lwtheme {
+:root[lwthemeicons~="--history-icon"] #history-panelmenu:-moz-lwtheme {
   list-style-image: var(--history-icon) !important;
 }
 
-#fullscreen-button:-moz-lwtheme {
+:root[lwthemeicons~="--full_screen-icon"] #fullscreen-button:-moz-lwtheme {
   list-style-image: var(--full_screen-icon) !important;
 }
 
-#find-button:-moz-lwtheme {
+:root[lwthemeicons~="--find-icon"] #find-button:-moz-lwtheme {
   list-style-image: var(--find-icon) !important;
 }
 
-#preferences-button:-moz-lwtheme {
+:root[lwthemeicons~="--options-icon"] #preferences-button:-moz-lwtheme {
   list-style-image: var(--options-icon) !important;
 }
 
-#add-ons-button:-moz-lwtheme {
+:root[lwthemeicons~="--addons-icon"] #add-ons-button:-moz-lwtheme {
   list-style-image: var(--addons-icon) !important;
 }
 
-#developer-button:-moz-lwtheme {
+:root[lwthemeicons~="--developer-icon"] #developer-button:-moz-lwtheme {
   list-style-image: var(--developer-icon) !important;
 }
 
-#sync-button:-moz-lwtheme {
+:root[lwthemeicons~="--synced_tabs-icon"] #sync-button:-moz-lwtheme {
   list-style-image: var(--synced_tabs-icon) !important;
 }
 
-#open-file-button:-moz-lwtheme {
+:root[lwthemeicons~="--open_file-icon"] #open-file-button:-moz-lwtheme {
   list-style-image: var(--open_file-icon) !important;
 }
 
-#sidebar-button:-moz-lwtheme {
+:root[lwthemeicons~="--sidebars-icon"] #sidebar-button:-moz-lwtheme {
   list-style-image: var(--sidebars-icon) !important;
 }
 
-#social-share-button:-moz-lwtheme {
+:root[lwthemeicons~="--share_page-icon"] #social-share-button:-moz-lwtheme {
   list-style-image: var(--share_page-icon) !important;
 }
 
-#feed-button:-moz-lwtheme {
+:root[lwthemeicons~="--subscribe-icon"] #feed-button:-moz-lwtheme {
   list-style-image: var(--subscribe-icon) !important;
 }
 
-#characterencoding-button:-moz-lwtheme {
+:root[lwthemeicons~="--text_encoding-icon"] #characterencoding-button:-moz-lwtheme {
   list-style-image: var(--text_encoding-icon) !important;
 }
 
-#email-link-button:-moz-lwtheme {
+:root[lwthemeicons~="--email_link-icon"] #email-link-button:-moz-lwtheme {
   list-style-image: var(--email_link-icon) !important;
 }
 
-#panic-button:-moz-lwtheme {
+:root[lwthemeicons~="--forget-icon"] #panic-button:-moz-lwtheme {
   list-style-image: var(--forget-icon) !important;
 }
 
-#pocket-button:-moz-lwtheme {
+:root[lwthemeicons~="--pocket-icon"] #pocket-button:-moz-lwtheme {
   list-style-image: var(--pocket-icon) !important;
 }
 
-#back-button:-moz-lwtheme,
-#forward-button:-moz-lwtheme,
-#bookmarks-menu-button:-moz-lwtheme,
-#bookmarks-menu-button[cui-areatype='toolbar'] > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon:-moz-lwtheme,
-#downloads-button:-moz-lwtheme,
-#home-button:-moz-lwtheme,
-#PanelUI-menu-button:-moz-lwtheme,
-#cut-button:-moz-lwtheme,
-#copy-button:-moz-lwtheme,
-#paste-button:-moz-lwtheme,
-#new-window-button:-moz-lwtheme,
-#privatebrowsing-button:-moz-lwtheme,
-#save-page-button:-moz-lwtheme,
-#print-button:-moz-lwtheme,
-#history-panelmenu:-moz-lwtheme,
-#fullscreen-button:-moz-lwtheme,
-#find-button:-moz-lwtheme,
-#preferences-button:-moz-lwtheme,
-#add-ons-button:-moz-lwtheme,
-#developer-button:-moz-lwtheme,
-#sync-button:-moz-lwtheme,
-#open-file-button:-moz-lwtheme,
-#sidebar-button:-moz-lwtheme,
-#social-share-button:-moz-lwtheme,
-#feed-button:-moz-lwtheme,
-#characterencoding-button:-moz-lwtheme,
-#email-link-button:-moz-lwtheme,
-#panic-button:-moz-lwtheme,
-#pocket-button:-moz-lwtheme {
+:root[lwthemeicons~="--back-icon"] #back-button:-moz-lwtheme,
+:root[lwthemeicons~="--forward-icon"] #forward-button:-moz-lwtheme,
+:root[lwthemeicons~="--bookmark_star-icon"] #bookmarks-menu-button:-moz-lwtheme,
+:root[lwthemeicons~="--bookmark_menu-icon"] #bookmarks-menu-button[cui-areatype='toolbar'] > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon:-moz-lwtheme,
+:root[lwthemeicons~="--downloads-icon"] #downloads-button:-moz-lwtheme,
+:root[lwthemeicons~="--home-icon"] #home-button:-moz-lwtheme,
+:root[lwthemeicons~="--app_menu-icon"] #PanelUI-menu-button:-moz-lwtheme,
+:root[lwthemeicons~="--cut-icon"] #cut-button:-moz-lwtheme,
+:root[lwthemeicons~="--copy-icon"] #copy-button:-moz-lwtheme,
+:root[lwthemeicons~="--paste-icon"] #paste-button:-moz-lwtheme,
+:root[lwthemeicons~="--new_window-icon"] #new-window-button:-moz-lwtheme,
+:root[lwthemeicons~="--new_private_window-icon"] #privatebrowsing-button:-moz-lwtheme,
+:root[lwthemeicons~="--save_page-icon"] #save-page-button:-moz-lwtheme,
+:root[lwthemeicons~="--print-icon"] #print-button:-moz-lwtheme,
+:root[lwthemeicons~="--history-icon"] #history-panelmenu:-moz-lwtheme,
+:root[lwthemeicons~="--full_screen-icon"] #fullscreen-button:-moz-lwtheme,
+:root[lwthemeicons~="--find-icon"] #find-button:-moz-lwtheme,
+:root[lwthemeicons~="--options-icon"] #preferences-button:-moz-lwtheme,
+:root[lwthemeicons~="--addons-icon"] #add-ons-button:-moz-lwtheme,
+:root[lwthemeicons~="--developer-icon"] #developer-button:-moz-lwtheme,
+:root[lwthemeicons~="--synced_tabs-icon"] #sync-button:-moz-lwtheme,
+:root[lwthemeicons~="--open_file-icon"] #open-file-button:-moz-lwtheme,
+:root[lwthemeicons~="--sidebars-icon"] #sidebar-button:-moz-lwtheme,
+:root[lwthemeicons~="--share_page-icon"] #social-share-button:-moz-lwtheme,
+:root[lwthemeicons~="--subscribe-icon"] #feed-button:-moz-lwtheme,
+:root[lwthemeicons~="--text_encoding-icon"] #characterencoding-button:-moz-lwtheme,
+:root[lwthemeicons~="--email_link-icon"] #email-link-button:-moz-lwtheme,
+:root[lwthemeicons~="--forget-icon"] #panic-button:-moz-lwtheme,
+:root[lwthemeicons~="--pocket-icon"] #pocket-button:-moz-lwtheme {
   -moz-image-region: rect(0, 18px, 18px, 0) !important;
 }
 
-#urlbar-reload-button:-moz-lwtheme,
-#urlbar-stop-button:-moz-lwtheme {
+:root[lwthemeicons~="--reload-icon"] #urlbar-reload-button:-moz-lwtheme,
+:root[lwthemeicons~="--stop-icon"] #urlbar-stop-button:-moz-lwtheme {
   -moz-image-region: rect(0, 14px, 14px, 0) !important;
 }
--- a/browser/components/extensions/ext-theme.js
+++ b/browser/components/extensions/ext-theme.js
@@ -140,16 +140,21 @@ class Theme {
           this.lwtStyles.headerURL = resolvedURL;
           break;
         }
       }
     }
   }
 
   loadIcons(icons) {
+    if (!Preferences.get("extensions.webextensions.themes.icons.enabled")) {
+      // Return early if icons are disabled.
+      return;
+    }
+
     let iconNames = Object.keys(ICONS_TO_VARIABLE_MAP);
     for (let icon of Object.keys(icons)) {
       let val = icons[icon];
       if (!val) {
         continue;
       }
       if (iconNames.includes(icon)) {
         let variableName = ICONS_TO_VARIABLE_MAP[icon];
@@ -158,19 +163,29 @@ class Theme {
       }
     }
   }
 
   /**
    * Unloads the currently applied theme.
    */
   unload() {
+    let lwtStyles = {
+      headerURL: "",
+      accentcolor: "",
+      textcolor: "",
+      icons: {},
+    };
+
+    for (let value of Object.values(ICONS_TO_VARIABLE_MAP)) {
+      lwtStyles.icons[value] = "";
+    }
     Services.obs.notifyObservers(null,
       "lightweight-theme-styling-update",
-      null);
+      JSON.stringify(lwtStyles));
   }
 }
 
 /* eslint-disable mozilla/balanced-listeners */
 extensions.on("manifest_theme", (type, directive, extension, manifest) => {
   if (!Preferences.get("extensions.webextensions.themes.enabled")) {
     // Return early if themes are disabled.
     return;
--- a/browser/components/extensions/test/browser/browser_ext_themes_icons.js
+++ b/browser/components/extensions/test/browser/browser_ext_themes_icons.js
@@ -2,21 +2,21 @@
 
 const ENCODED_IMAGE_DATA = "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgNjQgNjQiPjxwYXRoIGQ9Im01NS45IDMyLjFsLTIyLjctMTQuOWMwIDAgMTIuOS0xNy40IDE5LjQtMTQuOSAzLjEgMS4xIDUuNCAyNS4xIDMuMyAyOS44IiBmaWxsPSIjM2U0MzQ3Ii8+PHBhdGggZD0ibTU0LjkgMzMuOWwtOS00LjFjMCAwLTUuMy0xNCA2LjEtMjQuMSAyLjQgMiA1LjEgMjUgMi45IDI4LjIiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJtOC4xIDMyLjFsMjIuNi0xNC45YzAgMC0xMi45LTE3LjQtMTkuNC0xNC45LTMgMS4xLTUuMyAyNS4xLTMuMiAyOS44IiBmaWxsPSIjM2U0MzQ3Ii8+PHBhdGggZD0ibTkuMSAzMy45bDktNC4xYzAgMCA1LjMtMTQtNi4xLTI0LjEtMi40IDItNS4xIDI1LTIuOSAyOC4yIiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTMyLDEzQzE4LjksMTMsMiwzMy42LDIsNDUuNEMyMC41LDQ1LjQsMTkuNyw2MiwzMiw2MnMxMS41LTE2LjYsMzAtMTYuNkM2MiwzMy42LDQ1LjEsMTMsMzIsMTN6IiBmaWxsPSIjZmY4NzM2Ii8+PGcgZmlsbD0iI2ZmZiI+PHBhdGggZD0iTTMyLDU2LjJjMCw1LjEsOS42LDQuMiw5LjUtMi45YzYuNy05LjQsMTkuOS04LjcsMTkuOS04LjdDMzkuNiwzMi40LDMyLDU2LjIsMzIsNTYuMnoiLz48cGF0aCBkPSJNMzIsNTYuMmMwLDUuMS05LjYsNC4yLTkuNS0yLjlDMTUuOCw0NCwyLjYsNDQuNywyLjYsNDQuN0MyNC40LDMyLjQsMzIsNTYuMiwzMiw1Ni4yeiIvPjwvZz48ZyBmaWxsPSIjZmY4NzM2Ij48cGF0aCBkPSJtNTMuNCAxOC41Yy00IC43LTQuOSA2LjMtNC45IDYuM2w2IDUuM2MtMi4zLTUuOS0xLjEtMTEuNi0xLjEtMTEuNiIvPjxwYXRoIGQ9Im01MS4xIDEzLjVjLTQuNCAzLjktNS4xIDguNy01LjEgOC43bDYgNS4zYy0yLjQtNS44LS45LTE0LS45LTE0Ii8+PHBhdGggZD0ibTEwLjYgMTguNWM0IC43IDQuOSA2LjMgNC45IDYuM2wtNiA1LjNjMi4zLTUuOSAxLjEtMTEuNiAxLjEtMTEuNiIvPjxwYXRoIGQ9Im0xMi45IDEzLjVjNC40IDMuOSA1LjEgOC43IDUuMSA4LjdsLTYgNS4zYzIuNC01LjguOS0xNCAuOS0xNCIvPjwvZz48cGF0aCBkPSJtNTIuOCAzMS4xYy01LjctMS44LTEwLjktMy40LTEzLjguOS0yLjQgMy43LjcgOS40LjcgOS40IDExLjIgMS4yIDEzLjEtMTAuMyAxMy4xLTEwLjMiIGZpbGw9IiMzZTQzNDciLz48ZWxsaXBzZSBjeD0iNDMiIGN5PSIzNi4zIiByeD0iNC4yIiByeT0iNC4xIiBmaWxsPSIjZDVmZjgzIi8+PGcgZmlsbD0iIzNlNDM0NyI+PGVsbGlwc2UgY3g9IjQzIiBjeT0iMzYuMyIgcng9IjIuNyIgcnk9IjIuNyIvPjxwYXRoIGQ9Im0xMS4yIDMxLjFjNS43LTEuOCAxMC45LTMuNCAxMy43LjkgMi40IDMuNy0uNyA5LjQtLjcgOS40LTExLjEgMS4yLTEzLTEwLjMtMTMtMTAuMyIvPjwvZz48ZWxsaXBzZSBjeD0iMjEiIGN5PSIzNi4zIiByeD0iNC4yIiByeT0iNC4xIiBmaWxsPSIjZDVmZjgzIi8+PGcgZmlsbD0iIzNlNDM0NyI+PGVsbGlwc2UgY3g9IjIxIiBjeT0iMzYuMyIgcng9IjIuNyIgcnk9IjIuNyIvPjxwYXRoIGQ9Im00MS4yIDQ3LjljLS43LTIuMy0xLjgtNC40LTMtNi41IDEuMSAyLjEgMiA0LjMgMi41IDYuNi41IDIuMy43IDQuNyAwIDYuOC0uNCAxLTEgMi0xLjggMi42LS44LjYtMS44IDEtMi43IDEtLjkgMC0xLjktLjMtMi41LTEtLjYtLjctLjktMS42LS44LTIuNmwtLjkuMmgtLjljMCAxLS4yIDEuOS0uOCAyLjYtLjYuNy0xLjUgMS0yLjUgMS0uOSAwLTEuOS0uNC0yLjctMS0uOC0uNi0xLjQtMS42LTEuOC0yLjYtLjgtMi4xLS42LTQuNiAwLTYuOC41LTIuMyAxLjUtNC41IDIuNS02LjYtMS4yIDItMi4zIDQuMS0zIDYuNS0uNyAyLjMtMS4xIDQuOC0uNCA3LjMuMyAxLjIgMSAyLjQgMS45IDMuMy45LjkgMi4xIDEuNCAzLjQgMS41IDEuMi4xIDIuNi0uMiAzLjctMS4yLjMtLjIuNS0uNS43LS44LjIuMy40LjYuNy44IDEgMSAyLjQgMS4zIDMuNyAxLjIgMS4zLS4xIDIuNC0uNyAzLjQtMS41LjktLjkgMS42LTIgMS45LTMuMy41LTIuNi4xLTUuMi0uNi03LjUiLz48cGF0aCBkPSJtMzcuNiA1MC4zYy0xLjEtMS4xLTQuNS0xLjItNS42LTEuMi0xIDAtNC41LjEtNS42IDEuMi0uOC44LS4yIDIuOCAxLjkgNC41IDEuMyAxLjEgMi42IDEuNCAzLjYgMS40IDEgMCAyLjMtLjMgMy42LTEuNCAyLjMtMS43IDIuOS0zLjcgMi4xLTQuNSIvPjwvZz48L3N2Zz4=";
 
   /**
    * Verifies that the button uses the expected icon.
    *
    * @param {string} selector The CSS selector used to find the button
    *   within the DOM.
-   * @param {function} verifyFn The SimpleTest function (ok, notok).
+   * @param {function} resultModifierFn Used to invert the result, if needed.
    * @param {string} message The message that is printed to the console
    *   by the verifyFn.
    */
-function verifyButtonProperties(selector, verifyFn, message) {
+function verifyButtonProperties(selector, resultModifierFn, message) {
   try {
     let element;
     // This selector is different than the others because it's the only
     // toolbarbutton that we ship by default that has type="menu-button",
     // which don't place a unique ID on the associated dropmarker-icon.
     if (selector == "#bookmarks-menu-button > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon") {
       if (message.includes("panel")) {
         // The dropmarker isn't shown in the menupanel.
@@ -26,53 +26,47 @@ function verifyButtonProperties(selector
       element = document.getAnonymousElementByAttribute(element, "class", "toolbarbutton-menubutton-dropmarker");
       element = document.getAnonymousElementByAttribute(element, "class", "dropmarker-icon");
     } else {
       element = document.querySelector(selector);
     }
 
     let listStyleImage = getComputedStyle(element).listStyleImage;
     info(`listStyleImage for fox.svg is ${listStyleImage}`);
-    verifyFn(listStyleImage.includes("fox.svg"), message);
+    ok(resultModifierFn(listStyleImage.includes("fox.svg")), message);
   } catch (ex) {
     ok(false, `Unable to verify ${selector}: ${ex}`);
   }
 }
 
   /**
    * Verifies that the button uses default styling.
    *
    * @param {string} selector The CSS selector used to find the button
    *   within the DOM.
    * @param {string} message The message that is printed to the console
    *   by the verifyFn.
    */
 function verifyButtonWithoutCustomStyling(selector, message) {
-  verifyButtonProperties(selector, (result) => ok(!result), message);
+  verifyButtonProperties(selector, result => !result, message);
 }
 
   /**
    * Verifies that the button uses non-default styling.
    *
    * @param {string} selector The CSS selector used to find the button
    *   within the DOM.
    * @param {string} message The message that is printed to the console
    *   by the verifyFn.
    */
 function verifyButtonWithCustomStyling(selector, message) {
-  verifyButtonProperties(selector, ok, message);
+  verifyButtonProperties(selector, result => result, message);
 }
 
-add_task(function* setup() {
-  yield SpecialPowers.pushPrefEnv({
-    set: [["extensions.webextensions.themes.enabled", true]],
-  });
-});
-
-add_task(function* test_support_icons() {
+function* runTestWithIcons(icons) {
   const FRAME_COLOR = [71, 105, 91];
   const TAB_TEXT_COLOR = [207, 221, 192, .9];
   let manifest = {
     "theme": {
       "images": {
         "theme_frame": "fox.svg",
       },
       "colors": {
@@ -130,47 +124,146 @@ add_task(function* test_support_icons() 
   for (let button of ICON_INFO) {
     if (button[2]) {
       CustomizableUI.addWidgetToArea(button[2], CustomizableUI.AREA_NAVBAR);
     }
 
     verifyButtonWithoutCustomStyling(button[1],
       `The ${button[1]} should not have it's icon customized when the test starts`);
 
-    manifest.theme.icons[button[0]] = "fox.svg";
+    let iconInfo = icons.find(arr => arr[0] == button[0]);
+    manifest.theme.icons[button[0]] = iconInfo[1];
   }
 
   let extension = ExtensionTestUtils.loadExtension({manifest, files});
 
   yield extension.startup();
 
   for (let button of ICON_INFO) {
-    verifyButtonWithCustomStyling(button[1],
-      `The ${button[1]} should have it's icon customized in the toolbar`);
+    let iconInfo = icons.find(arr => arr[0] == button[0]);
+    if (iconInfo[1]) {
+      verifyButtonWithCustomStyling(button[1],
+        `The ${button[1]} should have it's icon customized in the toolbar`);
+    } else {
+      verifyButtonWithoutCustomStyling(button[1],
+        `The ${button[1]} should not have it's icon customized in the toolbar`);
+    }
   }
 
   for (let button of ICON_INFO) {
     if (button[2]) {
       CustomizableUI.addWidgetToArea(button[2], CustomizableUI.AREA_PANEL);
     }
   }
 
   yield PanelUI.show();
 
   for (let button of ICON_INFO) {
-    verifyButtonWithCustomStyling(button[1],
-      `The ${button[1]} should have it's icon customized in the panel`);
+    let iconInfo = icons.find(arr => arr[0] == button[0]);
+    if (iconInfo[1]) {
+      verifyButtonWithCustomStyling(button[1],
+        `The ${button[1]} should have it's icon customized in the panel`);
+    } else {
+      verifyButtonWithoutCustomStyling(button[1],
+        `The ${button[1]} should not have it's icon customized in the panel`);
+    }
   }
 
   yield PanelUI.hide();
 
   yield extension.unload();
 
   for (let button of ICON_INFO) {
     verifyButtonWithoutCustomStyling(button[1],
       `The ${button[1]} should not have it's icon customized when the theme is unloaded`);
   }
+}
+
+add_task(function* setup() {
+  yield SpecialPowers.pushPrefEnv({
+    set: [["extensions.webextensions.themes.enabled", true],
+          ["extensions.webextensions.themes.icons.enabled", true]],
+  });
+});
+
+add_task(function* test_all_icons() {
+  let icons = [
+    ["back", "fox.svg"],
+    ["forward", "fox.svg"],
+    ["reload", "fox.svg"],
+    ["stop", "fox.svg"],
+    ["bookmark_star", "fox.svg"],
+    ["bookmark_menu", "fox.svg"],
+    ["downloads", "fox.svg"],
+    ["home", "fox.svg"],
+    ["app_menu", "fox.svg"],
+    ["cut", "fox.svg"],
+    ["copy", "fox.svg"],
+    ["paste", "fox.svg"],
+    ["new_window", "fox.svg"],
+    ["new_private_window", "fox.svg"],
+    ["save_page", "fox.svg"],
+    ["print", "fox.svg"],
+    ["history", "fox.svg"],
+    ["full_screen", "fox.svg"],
+    ["find", "fox.svg"],
+    ["options", "fox.svg"],
+    ["addons", "fox.svg"],
+    ["developer", "fox.svg"],
+    ["synced_tabs", "fox.svg"],
+    ["open_file", "fox.svg"],
+    ["sidebars", "fox.svg"],
+    ["share_page", "fox.svg"],
+    ["subscribe", "fox.svg"],
+    ["text_encoding", "fox.svg"],
+    ["email_link", "fox.svg"],
+    ["forget", "fox.svg"],
+    ["pocket", "fox.svg"],
+  ];
+  yield runTestWithIcons(icons);
 });
 
 add_task(function* teardown() {
   CustomizableUI.reset();
   window.restore();
-});
\ No newline at end of file
+});
+
+add_task(function* test_some_icons() {
+  let icons = [
+    ["back", ""],
+    ["forward", ""],
+    ["reload", "fox.svg"],
+    ["stop", ""],
+    ["bookmark_star", ""],
+    ["bookmark_menu", ""],
+    ["downloads", ""],
+    ["home", "fox.svg"],
+    ["app_menu", "fox.svg"],
+    ["cut", ""],
+    ["copy", ""],
+    ["paste", ""],
+    ["new_window", ""],
+    ["new_private_window", ""],
+    ["save_page", ""],
+    ["print", ""],
+    ["history", ""],
+    ["full_screen", ""],
+    ["find", ""],
+    ["options", ""],
+    ["addons", ""],
+    ["developer", ""],
+    ["synced_tabs", ""],
+    ["open_file", ""],
+    ["sidebars", ""],
+    ["share_page", ""],
+    ["subscribe", ""],
+    ["text_encoding", ""],
+    ["email_link", ""],
+    ["forget", ""],
+    ["pocket", "fox.svg"],
+  ];
+  yield runTestWithIcons(icons);
+});
+
+add_task(function* teardown() {
+  CustomizableUI.reset();
+  window.restore();
+});
--- a/toolkit/modules/LightweightThemeConsumer.jsm
+++ b/toolkit/modules/LightweightThemeConsumer.jsm
@@ -118,18 +118,24 @@ LightweightThemeConsumer.prototype = {
       root.setAttribute("lwtheme", "true");
     } else {
       root.removeAttribute("lwthemetextcolor");
       root.removeAttribute("lwtheme");
     }
 
     this._active = active;
 
-    for (let [name, value] of Object.entries(aData.icons || {})) {
-      _setImage(root, active, value, name);
+    if (aData.icons) {
+      let activeIcons = active ? Object.keys(aData.icons).join(" ") : "";
+      root.setAttribute("lwthemeicons", activeIcons);
+      for (let [name, value] of Object.entries(aData.icons)) {
+        _setImage(root, active, value, name);
+      }
+    } else {
+      root.removeAttribute("lwthemeicons");
     }
 
     _setImage(root, active, aData.headerURL, "--lwt-header-image");
     if (this._footerId) {
       let footer = this._doc.getElementById(this._footerId);
       _setImage(footer, active, aData.footerURL, "--lwt-footer-image");
       if (active && aData.footerURL)
         footer.setAttribute("lwthemefooter", "true");