Bug 1384608 Show complete themes with legacy extensions r=rhelmer
authorAndrew Swan <aswan@mozilla.com>
Wed, 13 Sep 2017 13:23:39 -0700
changeset 430574 f2aa9d36be3f30e79a76277ab5dc88e2ed7c7d64
parent 430573 eae22389b267d0603db9162d878881505dd94519
child 430575 e2f8c9f76b711c89b04ca0e2f2ac324e638ac704
push id7768
push userryanvm@gmail.com
push dateSat, 16 Sep 2017 16:13:49 +0000
treeherdermozilla-beta@3b375d85383a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrhelmer
bugs1384608
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1384608 Show complete themes with legacy extensions r=rhelmer MozReview-Commit-ID: 6jiQZ8SQpzI
toolkit/locales/en-US/chrome/mozapps/extensions/extensions.dtd
toolkit/locales/en-US/chrome/mozapps/extensions/extensions.properties
toolkit/mozapps/extensions/content/extensions.js
toolkit/mozapps/extensions/content/extensions.xml
toolkit/mozapps/extensions/content/extensions.xul
toolkit/mozapps/extensions/test/browser/browser.ini
toolkit/mozapps/extensions/test/browser/browser_legacy.js
toolkit/mozapps/extensions/test/browser/browser_legacy_themes.js
--- a/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.dtd
+++ b/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.dtd
@@ -253,13 +253,12 @@
      being a link to an external site. -->
 <!ENTITY disabledUnsigned.devInfo.start "Developers interested in getting their add-ons verified can continue by reading our ">
 <!ENTITY disabledUnsigned.devInfo.linkToManual "manual">
 <!ENTITY disabledUnsigned.devInfo.end ".">
 
 <!ENTITY pluginDeprecation.description "Missing something? Some plugins are no longer supported by &brandShortName;.">
 <!ENTITY pluginDeprecation.learnMore "Learn More.">
 
-<!ENTITY legacyWarning.description "Missing something? Some extensions are no longer supported by &brandShortName;.">
 <!ENTITY legacyWarning.showLegacy "Show legacy extensions">
 <!ENTITY legacyExtensions.title "Legacy Extensions">
 <!ENTITY legacyExtensions.description "These extensions do not meet current &brandShortName; standards so they have been deactivated.">
 <!ENTITY legacyExtensions.learnMore "Learn about the changes to add-ons">
--- a/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.properties
+++ b/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.properties
@@ -185,8 +185,13 @@ type.extension.name=Extensions
 type.themes.name=Themes
 type.locale.name=Languages
 type.plugin.name=Plugins
 type.dictionary.name=Dictionaries
 type.service.name=Services
 type.experiment.name=Experiments
 type.legacy.name=Legacy Extensions
 type.unsupported.name=Unsupported
+
+#LOCALIZATION NOTE(legacyWarning.description) %S is the brandShortName
+legacyWarning.description=Missing something? Some extensions are no longer supported by %S.
+#LOCALIZATION NOTE(legacyThemeWarning.description) %S is the brandShortName
+legacyThemeWarning.description=Missing something? Some themes are no longer supported by %S.
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -2797,17 +2797,17 @@ var gLegacyView = {
     gEventManager.unregisterAddonListener(this, "ANY");
   },
 
   onUninstalled() {
     this.refreshVisibility();
   },
 
   async show(type, request) {
-    let addons = await AddonManager.getAddonsByTypes(["extension"]);
+    let addons = await AddonManager.getAddonsByTypes(["extension", "theme"]);
     addons = addons.filter(a => !a.hidden &&
                               (isDisabledLegacy(a) || isDisabledUnsigned(a)));
 
     while (this._listBox.itemCount > 0)
       this._listBox.removeItemAt(0);
 
     let elements = addons.map(a => createItem(a));
     if (elements.length == 0) {
@@ -2835,17 +2835,17 @@ var gLegacyView = {
   },
 
   async refreshVisibility() {
     if (legacyExtensionsEnabled) {
       this._categoryItem.disabled = true;
       return;
     }
 
-    let extensions = await AddonManager.getAddonsByTypes(["extension"]);
+    let extensions = await AddonManager.getAddonsByTypes(["extension", "theme"]);
 
     let haveUnsigned = false;
     let haveLegacy = false;
     for (let extension of extensions) {
       if (isDisabledUnsigned(extension)) {
         haveUnsigned = true;
       }
       if (isLegacyExtension(extension)) {
@@ -2974,17 +2974,31 @@ var gListView = {
       this.showEmptyNotice(elements.length == 0);
       if (elements.length > 0) {
         sortElements(elements, ["uiState", "name"], true);
         for (let element of elements)
           this._listBox.appendChild(element);
       }
 
       this.filterDisabledUnsigned(showOnlyDisabledUnsigned);
-      document.getElementById("legacy-extensions-notice").hidden = !showLegacyInfo;
+      let legacyNotice = document.getElementById("legacy-extensions-notice");
+      if (showLegacyInfo) {
+        let el = document.getElementById("legacy-extensions-description");
+        if (el.childNodes[0].nodeName == "#text") {
+          el.removeChild(el.childNodes[0]);
+        }
+
+        let descriptionId = (aType == "theme") ?
+                            "legacyThemeWarning.description" : "legacyWarning.description";
+        let text = gStrings.ext.formatStringFromName(descriptionId, [gStrings.brandShortName], 1) + " ";
+        el.insertBefore(document.createTextNode(text), el.childNodes[0]);
+        legacyNotice.hidden = false;
+      } else {
+        legacyNotice.hidden = true;
+      }
 
       gEventManager.registerInstallListener(this);
       gViewController.updateCommands();
       gViewController.notifyViewChanged();
     });
   },
 
   hide() {
--- a/toolkit/mozapps/extensions/content/extensions.xml
+++ b/toolkit/mozapps/extensions/content/extensions.xml
@@ -1298,16 +1298,17 @@
               this.setAttribute("notification", "warning");
               this._warning.textContent = gStrings.ext.formatStringFromName(
                 "notification.incompatible",
                 [this.mAddon.name, gStrings.brandShortName, gStrings.appVersion], 3
               );
               this._warningLink.hidden = true;
               this._warningBtn.hidden = true;
             } else if (!isUpgrade && this.mAddon.appDisabled &&
+                       this.mAddon.type == "extension" &&
                        !this.mAddon.multiprocessCompatible &&
                        !Services.prefs.getBoolPref("extensions.allow-non-mpc-extensions", true)) {
               this.setAttribute("notification", "error");
               this._error.textContent = gStrings.ext.formatStringFromName(
                 "notification.nonMpcDisabled", [this.mAddon.name], 1
               );
               this._errorLink.value = gStrings.ext.GetStringFromName("notification.nonMpcDisabled.link");
               this._errorLink.href = "https://wiki.mozilla.org/Add-ons/ShimsNightly";
@@ -1642,17 +1643,20 @@
         <body><![CDATA[
           gViewController.loadView("addons://detail/" +
                                    encodeURIComponent(this.mAddon.id));
         ]]></body>
       </method>
 
       <method name="findReplacement">
         <body><![CDATA[
-          openURL(`https://addons.mozilla.org/find-replacement/?guid=${this.mAddon.id}`);
+          let url = (this.mAddon.type == "theme") ?
+            SUPPORT_URL + "complete-themes" :
+            `https://addons.mozilla.org/find-replacement/?guid=${this.mAddon.id}`;
+            openURL(url);
         ]]></body>
       </method>
 
       <method name="onIncludeUpdateChanged">
         <body><![CDATA[
           var event = document.createEvent("Events");
           event.initEvent("IncludeUpdateChanged", true, true);
           this.dispatchEvent(event);
--- a/toolkit/mozapps/extensions/content/extensions.xul
+++ b/toolkit/mozapps/extensions/content/extensions.xul
@@ -376,17 +376,17 @@
                 </description>
                 <hbox pack="start"><label class="text-link" id="signing-learn-more">&disabledUnsigned.learnMore;</label></hbox>
                 <description id="signing-dev-info">
                   &disabledUnsigned.devInfo.start;<label class="text-link plain" id="signing-dev-manual-link">&disabledUnsigned.devInfo.linkToManual;</label>&disabledUnsigned.devInfo.end;
                 </description>
               </vbox>
               <vbox id="legacy-extensions-notice" class="alert-container" hidden="true">
                 <vbox class="alert">
-                  <description>&legacyWarning.description;
+                  <description id="legacy-extensions-description">
                     <label class="text-link plain" id="legacy-extensions-learnmore-link">&legacyWarning.showLegacy;</label>
                   </description>
                 </vbox>
               </vbox>
               <vbox id="plugindeprecation-notice" class="alert-container">
                 <vbox class="alert">
                   <description>&pluginDeprecation.description; &#160;
                     <label class="text-link plain" id="plugindeprecation-learnmore-link">&pluginDeprecation.learnMore;</label>
--- a/toolkit/mozapps/extensions/test/browser/browser.ini
+++ b/toolkit/mozapps/extensions/test/browser/browser.ini
@@ -48,16 +48,17 @@ support-files =
 skip-if = buildapp == 'mulet'
 [browser_file_xpi_no_process_switch.js]
 [browser_getmorethemes.js]
 [browser_gmpProvider.js]
 [browser_install.js]
 [browser_installssl.js]
 [browser_legacy.js]
 [browser_legacy_pre57.js]
+[browser_legacy_themes.js]
 [browser_newaddon.js]
 [browser_non_mpc.js]
 [browser_searching.js]
 [browser_system_addons_are_e10s.js]
 [browser_task_next_test.js]
 [browser_update.js]
 [browser_updatessl.js]
 [browser_webapi.js]
--- a/toolkit/mozapps/extensions/test/browser/browser_legacy.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_legacy.js
@@ -127,17 +127,17 @@ add_task(async function() {
 
   let catItem = mgrWin.gLegacyView._categoryItem;
   is(catItem.disabled, false, "Legacy category is visible");
   is(catItem.getAttribute("name"), get_string("type.legacy.name"),
      "Category label with no unsigned extensions is correct");
 
   // Follow the link to the legacy extensions page
   let legacyLink = mgrWin.document.getElementById("legacy-extensions-learnmore-link");
-  is_element_visible(legacyLink, "Link to leagcy extension is visible");
+  is_element_visible(legacyLink, "Link to legacy extension is visible");
 
   let loadPromise = new Promise(resolve => wait_for_view_load(mgrWin, resolve, true));
   legacyLink.click();
   await loadPromise;
 
   is(mgrWin.gViewController.currentViewId, "addons://legacy/",
      "Legacy extensions link leads to the correct view");
 
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/browser/browser_legacy_themes.js
@@ -0,0 +1,79 @@
+
+add_task(async function() {
+  // The mochitest framework installs a bunch of legacy extensions.
+  // Fortunately, the extensions.legacy.exceptions preference exists to
+  // avoid treating some extensions as legacy for the purposes of the UI.
+  const IGNORE = [
+    "special-powers@mozilla.org",
+    "mochikit@mozilla.org",
+    "workerbootstrap-test@mozilla.org",
+    "worker-test@mozilla.org",
+  ];
+
+  let exceptions = Services.prefs.getCharPref("extensions.legacy.exceptions");
+  exceptions = [ exceptions, ...IGNORE ].join(",");
+
+  await SpecialPowers.pushPrefEnv({
+    set: [
+      ["extensions.legacy.enabled", false],
+      ["extensions.legacy.exceptions", exceptions],
+    ],
+  });
+
+  const ID = "theme@tests.mozilla.org";
+
+  let provider = new MockProvider();
+  provider.createAddons([{
+    id: ID,
+    name: "Complete Theme",
+    type: "theme",
+    appDisabled: true,
+  }]);
+
+  // Open about:addons and go to the themes list
+  let mgrWin = await open_manager(null);
+  let catUtils = new CategoryUtilities(mgrWin);
+  await catUtils.openType("theme");
+
+  // Our complete theme should not be displayed
+  let list = mgrWin.document.getElementById("addon-list");
+  let item = list.children.find(item => item.mAddon.id == ID);
+  is(item, undefined, `Theme ${ID} should not be in the list of active themes`);
+
+  // The warning banner and the legacy category should both be visible
+  let banner = mgrWin.document.getElementById("legacy-extensions-notice");
+  is_element_visible(banner, "Warning about legacy themes should be visible");
+  is(mgrWin.gLegacyView._categoryItem.disabled, false, "Legacy category should be visible ");
+
+  // Follow the link to the legacy extensions page
+  let legacyLink = mgrWin.document.getElementById("legacy-extensions-learnmore-link");
+  is_element_visible(legacyLink, "Link to legacy extensions is visible");
+
+  let loadPromise = new Promise(resolve => wait_for_view_load(mgrWin, resolve, true));
+  legacyLink.click();
+  await loadPromise;
+
+  is(mgrWin.gViewController.currentViewId, "addons://legacy/",
+     "Legacy extensions link leads to the correct view");
+
+  list = mgrWin.document.getElementById("legacy-list");
+  is(list.children.length, 1, "Should have 1 item in the legacy list");
+  item = list.children[0];
+  is(item.mAddon.id, ID, "Complete theme should be in the list");
+
+  // Click the find a replacement button
+  let button = document.getAnonymousElementByAttribute(item, "anonid", "replacement-btn");
+  is_element_visible(button, "Find a replacement butotn is visible");
+
+  // In automation, app.support.baseURL points to a page on localhost.
+  // The actual page is 404 in the test but that doesn't matter here,
+  // just the fact that we load the right URL.
+  let url = Services.prefs.getStringPref("app.support.baseURL") + "complete-themes";
+  let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, url);
+  button.click();
+  let tab = await tabPromise;
+  ok(true, "Find a replacement button opened SUMO page");
+  await BrowserTestUtils.removeTab(tab);
+
+  await close_manager(mgrWin);
+});