Bug 1563062 Part 2: Remove unused bits of old about:addons r=mstriemer
authorAndrew Swan <aswan@mozilla.com>
Tue, 02 Jul 2019 17:18:51 -0700
changeset 482137 4fb3655540652629dffdbe4c93f43f3d982f5fe2
parent 482136 f03444317763648d5375cfec9a1a8078a8722d29
child 482138 d3ff15541677cdddddbb95e5ab9ffa194be0a8ba
push id113652
push useraswan@mozilla.com
push dateWed, 10 Jul 2019 19:52:44 +0000
treeherdermozilla-inbound@4fb365554065 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstriemer
bugs1563062
milestone70.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 1563062 Part 2: Remove unused bits of old about:addons r=mstriemer Differential Revision: https://phabricator.services.mozilla.com/D36694
toolkit/mozapps/extensions/content/abuse-report-frame.js
toolkit/mozapps/extensions/content/extensions.css
toolkit/mozapps/extensions/content/extensions.js
toolkit/mozapps/extensions/content/extensions.xml
toolkit/mozapps/extensions/content/extensions.xul
toolkit/mozapps/extensions/jar.mn
toolkit/themes/shared/in-content/common.inc.css
--- a/toolkit/mozapps/extensions/content/abuse-report-frame.js
+++ b/toolkit/mozapps/extensions/content/abuse-report-frame.js
@@ -1,11 +1,11 @@
 "use strict";
 
-/* globals MozXULElement, Services, useHtmlViews, getHtmlBrowser, htmlBrowserLoaded */
+/* globals MozXULElement, Services, getHtmlBrowser, htmlBrowserLoaded */
 
 {
   const ABUSE_REPORT_ENABLED = Services.prefs.getBoolPref(
     "extensions.abuseReport.enabled",
     false
   );
   const ABUSE_REPORT_FRAME_URL =
     "chrome://mozapps/content/extensions/abuse-report-frame.html";
@@ -261,17 +261,17 @@
     set reportEntryPoint(value) {
       this.setAttribute("report-entry-point", value);
     }
   }
 
   // If the html about:addons and the abuse report are both enabled, register
   // the custom XUL WebComponent and append it to the XUL stack element
   // (if not registered the element will be just a dummy hidden box)
-  if (useHtmlViews && ABUSE_REPORT_ENABLED) {
+  if (ABUSE_REPORT_ENABLED) {
     customElements.define(
       "addon-abuse-report-xulframe",
       AddonAbuseReportsXULFrame
     );
   }
 
   // Helper method exported into the about:addons global, used to open the
   // abuse report panel from outside of the about:addons page
--- a/toolkit/mozapps/extensions/content/extensions.css
+++ b/toolkit/mozapps/extensions/content/extensions.css
@@ -13,135 +13,25 @@ xhtml|link {
   -moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#category");
 }
 
 .sidebar-footer-button > .text-link {
   margin-top: 0;
   margin-bottom: 0;
 }
 
-.addon[status="installed"] {
-  -moz-box-orient: vertical;
-  -moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#addon-generic");
-}
-
-.addon[status="installing"] {
-  -moz-box-orient: vertical;
-  -moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#addon-installing");
-}
-
-.addon[pending="uninstall"] {
-  -moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#addon-uninstalled");
-}
-
-.creator {
-  -moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#creator-link");
-}
-
-.meta-rating {
-  -moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#rating");
-}
-
-.download-progress, .download-progress[mode="undetermined"] {
-  -moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#download-progress");
-}
-
-.install-status {
-  -moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#install-status");
-}
-
-.detail-row {
-  -moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#detail-row");
-}
 
 .text-list {
   white-space: pre-line;
 }
 
-row[unsupported="true"] {
-  display: none;
-}
-
-#addonitem-popup > menuitem[disabled="true"] {
-  display: none;
-}
-
-#addonitem-popup[addontype="theme"] > #menuitem_enableItem,
-#addonitem-popup[addontype="theme"] > #menuitem_disableItem,
-#addonitem-popup:not([addontype="theme"]) > #menuitem_enableTheme,
-#addonitem-popup:not([addontype="theme"]) > #menuitem_disableTheme {
-  display: none;
-}
-
-#show-disabled-unsigned-extensions .button-text {
-  margin-inline-start: 3px !important;
-  margin-inline-end: 2px !important;
-}
-
 #header-searching:not([active]) {
   visibility: hidden;
 }
 
-#detail-view {
-  overflow: auto;
-}
-
-.addon:not([notification="warning"]) .warning,
-.addon:not([notification="error"]) .error,
-.addon:not([notification="info"]) .info,
-.addon:not([pending]) .pending,
-.addon:not([upgrade="true"]) .update-postfix,
-.addon[active="true"] .disabled-postfix,
-.addon[pending="install"] .update-postfix,
-.addon[pending="install"] .disabled-postfix,
-.addon[legacy="false"] .legacy-warning,
-#detail-view:not([notification="warning"]) .warning,
-#detail-view:not([notification="error"]) .error,
-#detail-view:not([notification="info"]) .info,
-#detail-view:not([pending]) .pending,
-#detail-view:not([upgrade="true"]) .update-postfix,
-#detail-view[active="true"] .disabled-postfix,
-#detail-view[legacy="false"] .legacy-warning,
-#detail-view[loading] .detail-view-container,
-#detail-view:not([loading]) .alert-container,
-.detail-row:not([value]),
-#legacy-list .addon .disabled-postfix {
-  display: none;
-}
-
-.addon .privateBrowsing-notice {
-  display: none;
-}
-.addon[privateBrowsing="true"] .privateBrowsing-notice-container {
-  /* 40px is width and margin of .icon-container */
-  margin-inline-start: 40px;
-}
-.addon[privateBrowsing="true"] .privateBrowsing-notice {
-  margin: 4px 0 0;
-  display: inline-block;
-}
-.addon[active="false"] .privateBrowsing-notice {
-  background-color: var(--purple-70-a40);
-}
-
-#addons-page:not([warning]) #list-view > .global-warning-container {
-  display: none;
-}
-#addon-list .date-updated,
-#legacy-list .date-updated {
-  display: none;
-}
-
-.view-pane:not(#updates-view) .addon .relnotes-toggle,
-.view-pane:not(#updates-view) .addon .include-update,
-#updates-view:not([updatetype="available"]) .addon .include-update,
-#updates-view[updatetype="available"] .addon .update-available-notice {
-  display: none;
-}
-
 #addons-page:not([warning]) .global-warning,
 #addons-page:not([warning="safemode"]) .global-warning-safemode,
 #addons-page:not([warning="checkcompatibility"]) .global-warning-checkcompatibility,
 #addons-page:not([warning="updatesecurity"]) .global-warning-updatesecurity {
   display: none;
 }
 
 /* Plugins aren't yet disabled by safemode (bug 342333),
@@ -150,65 +40,28 @@ row[unsupported="true"] {
 #addons-page[warning="safemode"] .view-pane[type="plugin"] .global-warning-container,
 #addons-page[warning="safemode"] #detail-view[loading="true"] .global-warning {
   display: none;
 }
 #addons-page .view-pane:not([type="plugin"]) #plugindeprecation-notice {
   display: none;
 }
 
-.list-view-notice {
-  margin-inline-start: 28px;
-  margin-bottom: 16px;
-}
-
-.list-view-notice > .message-bar {
-  width: 664px;
-}
-
 .html-alert-container > .message-bar {
   margin-bottom: 8px;
 }
 
 .html-global-warning-button {
   margin-inline: 0;
 }
 
-.addon .relnotes {
-  -moz-user-select: text;
-}
-#detail-name, #detail-desc, #detail-fulldesc {
-  -moz-user-select: text;
-  word-wrap: break-word;
-}
-
-#detail-name-container {
-  /* Set a max-width on this so the labels inside of this will wrap instead of
-     growing the card horizontally with long names. */
-  max-width: 580px;
-}
-
-/* Make sure we're not animating hidden images. See bug 623739. */
-#view-port:not([selectedIndex="0"]) #discover-view .loading,
-#discover-view:not([selectedIndex="0"]) .loading {
-  display: none;
-}
-
 /* Elements in unselected richlistitems cannot be focused */
 richlistitem:not([selected]) * {
   -moz-user-focus: ignore;
 }
 
 #header-search {
   width: 22em;
 }
 
-.discover-button[disabled="true"] {
-  display: none;
-}
-
-.view-pane:not(#legacy-view) .addon-control.replacement {
-  display: none;
-}
-
 #pluginFlashBlockingCheckbox .checkbox-label-box {
   display: none; /*see bug 1508724*/
 }
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -2,17 +2,17 @@
  * 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/. */
 
 "use strict";
 
 /* import-globals-from ../../../content/contentAreaUtils.js */
 /* import-globals-from aboutaddonsCommon.js */
 /* globals ProcessingInstruction */
-/* exported gBrowser, loadView */
+/* exported loadView */
 
 const { DeferredTask } = ChromeUtils.import(
   "resource://gre/modules/DeferredTask.jsm"
 );
 const { AddonManager } = ChromeUtils.import(
   "resource://gre/modules/AddonManager.jsm"
 );
 const { AddonRepository } = ChromeUtils.import(
@@ -21,41 +21,16 @@ const { AddonRepository } = ChromeUtils.
 
 ChromeUtils.defineModuleGetter(
   this,
   "AMTelemetry",
   "resource://gre/modules/AddonManager.jsm"
 );
 ChromeUtils.defineModuleGetter(
   this,
-  "E10SUtils",
-  "resource://gre/modules/E10SUtils.jsm"
-);
-ChromeUtils.defineModuleGetter(
-  this,
-  "ExtensionParent",
-  "resource://gre/modules/ExtensionParent.jsm"
-);
-ChromeUtils.defineModuleGetter(
-  this,
-  "ExtensionPermissions",
-  "resource://gre/modules/ExtensionPermissions.jsm"
-);
-ChromeUtils.defineModuleGetter(
-  this,
-  "PluralForm",
-  "resource://gre/modules/PluralForm.jsm"
-);
-ChromeUtils.defineModuleGetter(
-  this,
-  "Preferences",
-  "resource://gre/modules/Preferences.jsm"
-);
-ChromeUtils.defineModuleGetter(
-  this,
   "ClientID",
   "resource://gre/modules/ClientID.jsm"
 );
 ChromeUtils.defineModuleGetter(
   this,
   "PrivateBrowsingUtils",
   "resource://gre/modules/PrivateBrowsingUtils.jsm"
 );
@@ -64,68 +39,35 @@ XPCOMUtils.defineLazyPreferenceGetter(
   this,
   "XPINSTALL_ENABLED",
   "xpinstall.enabled",
   true
 );
 
 XPCOMUtils.defineLazyPreferenceGetter(
   this,
-  "allowPrivateBrowsingByDefault",
-  "extensions.allowPrivateBrowsingByDefault",
-  true
-);
-
-XPCOMUtils.defineLazyPreferenceGetter(
-  this,
-  "SUPPORT_URL",
-  "app.support.baseURL",
-  "",
-  null,
-  val => Services.urlFormatter.formatURL(val)
-);
-XPCOMUtils.defineLazyPreferenceGetter(
-  this,
-  "useHtmlViews",
-  "extensions.htmlaboutaddons.enabled"
-);
-XPCOMUtils.defineLazyPreferenceGetter(
-  this,
   "useHtmlDiscover",
   "extensions.htmlaboutaddons.discover.enabled"
 );
 XPCOMUtils.defineLazyPreferenceGetter(
   this,
   "useNewAboutDebugging",
   "devtools.aboutdebugging.new-enabled"
 );
 
 const PREF_DISCOVERURL = "extensions.webservice.discoverURL";
 const PREF_DISCOVER_ENABLED = "extensions.getAddons.showPane";
 const PREF_GETADDONS_CACHE_ENABLED = "extensions.getAddons.cache.enabled";
 const PREF_GETADDONS_CACHE_ID_ENABLED =
   "extensions.%ID%.getAddons.cache.enabled";
 const PREF_UI_TYPE_HIDDEN = "extensions.ui.%TYPE%.hidden";
 const PREF_UI_LASTCATEGORY = "extensions.ui.lastCategory";
-const PREF_LEGACY_EXCEPTIONS = "extensions.legacy.exceptions";
-const PREF_LEGACY_ENABLED = "extensions.legacy.enabled";
-
-const LOADING_MSG_DELAY = 100;
-
-const UPDATES_RECENT_TIMESPAN = 2 * 24 * 3600000; // 2 days (in milliseconds)
 
 var gViewDefault = "addons://discover/";
 
-XPCOMUtils.defineLazyGetter(this, "extensionStylesheets", () => {
-  const { ExtensionParent } = ChromeUtils.import(
-    "resource://gre/modules/ExtensionParent.jsm"
-  );
-  return ExtensionParent.extensionStylesheets;
-});
-
 var gStrings = {};
 XPCOMUtils.defineLazyServiceGetter(
   gStrings,
   "bundleSvc",
   "@mozilla.org/intl/stringbundle;1",
   "nsIStringBundleService"
 );
 
@@ -147,31 +89,16 @@ XPCOMUtils.defineLazyGetter(gStrings, "d
 
 XPCOMUtils.defineLazyGetter(gStrings, "brandShortName", function() {
   return this.brand.GetStringFromName("brandShortName");
 });
 XPCOMUtils.defineLazyGetter(gStrings, "appVersion", function() {
   return Services.appinfo.version;
 });
 
-XPCOMUtils.defineLazyPreferenceGetter(
-  this,
-  "legacyWarningExceptions",
-  PREF_LEGACY_EXCEPTIONS,
-  "",
-  raw => raw.split(",")
-);
-XPCOMUtils.defineLazyPreferenceGetter(
-  this,
-  "legacyExtensionsEnabled",
-  PREF_LEGACY_ENABLED,
-  true,
-  () => gLegacyView.refreshVisibility()
-);
-
 document.addEventListener("load", initialize, true);
 window.addEventListener("unload", shutdown);
 
 var gPendingInitializations = 1;
 Object.defineProperty(this, "gIsInitializing", {
   get: () => gPendingInitializations > 0,
 });
 
@@ -183,24 +110,16 @@ function initialize(event) {
   }
   document.removeEventListener("load", initialize, true);
 
   let globalCommandSet = document.getElementById("globalCommandSet");
   globalCommandSet.addEventListener("command", function(event) {
     gViewController.doCommand(event.target.id);
   });
 
-  let viewCommandSet = document.getElementById("viewCommandSet");
-  viewCommandSet.addEventListener("commandupdate", function(event) {
-    gViewController.updateCommands();
-  });
-  viewCommandSet.addEventListener("command", function(event) {
-    gViewController.doCommand(event.target.id);
-  });
-
   let addonPage = document.getElementById("addons-page");
   addonPage.addEventListener("dragenter", function(event) {
     gDragDrop.onDragOver(event);
   });
   addonPage.addEventListener("dragover", function(event) {
     gDragDrop.onDragOver(event);
   });
   addonPage.addEventListener("drop", function(event) {
@@ -348,31 +267,16 @@ function recordSetUpdatePolicyTelemetry(
     updatePolicy.push("enabled");
   }
   recordActionTelemetry({
     action: "setUpdatePolicy",
     value: updatePolicy.join(","),
   });
 }
 
-function recordSetAddonUpdateTelemetry(addon) {
-  let updates = addon.applyBackgroundUpdates;
-  let updatePolicy = "";
-  if (updates == "1") {
-    updatePolicy = "default";
-  } else if (updates == "2") {
-    updatePolicy = "enabled";
-  }
-  recordActionTelemetry({
-    action: "setAddonUpdate",
-    value: updatePolicy,
-    addon,
-  });
-}
-
 function getCurrentViewName() {
   let view = gViewController.currentViewObj;
   let entries = Object.entries(gViewController.viewObjects);
   let viewIndex = entries.findIndex(([name, viewObj]) => {
     return viewObj == view;
   });
   if (viewIndex != -1) {
     return entries[viewIndex][0];
@@ -387,43 +291,16 @@ function loadView(aViewId) {
     // should be the initial history entry
 
     gViewController.loadInitialView(aViewId);
   } else {
     gViewController.loadView(aViewId);
   }
 }
 
-function isLegacyExtension(addon) {
-  let legacy = false;
-  if (addon.type == "extension" && !addon.isWebExtension) {
-    legacy = true;
-  }
-  if (addon.type == "theme") {
-    legacy = false;
-  }
-
-  if (
-    legacy &&
-    (addon.hidden || addon.signedState == AddonManager.SIGNEDSTATE_PRIVILEGED)
-  ) {
-    legacy = false;
-  }
-  // Exceptions that can slip through above: the default theme plus
-  // test pilot addons until we get SIGNEDSTATE_PRIVILEGED deployed.
-  if (legacy && legacyWarningExceptions.includes(addon.id)) {
-    legacy = false;
-  }
-  return legacy;
-}
-
-function isDisabledLegacy(addon) {
-  return !legacyExtensionsEnabled && isLegacyExtension(addon);
-}
-
 function isDiscoverEnabled() {
   if (
     Services.prefs.getPrefType(PREF_DISCOVERURL) == Services.prefs.PREF_INVALID
   ) {
     return false;
   }
 
   try {
@@ -629,66 +506,16 @@ var gEventManager = {
     }
 
     AddonManager.addManagerListener(this);
     AddonManager.addInstallListener(this);
     AddonManager.addAddonListener(this);
 
     this.refreshGlobalWarning();
     this.refreshAutoUpdateDefault();
-
-    var contextMenu = document.getElementById("addonitem-popup");
-    contextMenu.addEventListener("popupshowing", function() {
-      var addon = gViewController.currentViewObj.getSelectedAddon();
-      contextMenu.setAttribute("addontype", addon.type);
-
-      var menuSep = document.getElementById("addonitem-menuseparator");
-      var countMenuItemsBeforeSep = 0;
-      for (let child of contextMenu.children) {
-        if (child == menuSep) {
-          break;
-        }
-        if (
-          child.nodeName == "menuitem" &&
-          gViewController.isCommandEnabled(child.command)
-        ) {
-          countMenuItemsBeforeSep++;
-        }
-      }
-
-      // Hide the separator if there are no visible menu items before it
-      menuSep.hidden = countMenuItemsBeforeSep == 0;
-    });
-
-    let addonTooltip = document.getElementById("addonitem-tooltip");
-    addonTooltip.addEventListener("popupshowing", function() {
-      let addonItem = addonTooltip.triggerNode;
-      // The way the test triggers the tooltip the richlistitem is the
-      // tooltipNode but in normal use it is the anonymous node. This allows
-      // any case
-      if (addonItem.localName != "richlistitem") {
-        addonItem = document.getBindingParent(addonItem);
-      }
-
-      let tiptext = addonItem.getAttribute("name");
-
-      if (addonItem.mAddon) {
-        if (shouldShowVersionNumber(addonItem.mAddon)) {
-          tiptext +=
-            " " +
-            (addonItem.hasAttribute("upgrade")
-              ? addonItem.mManualUpdate.version
-              : addonItem.mAddon.version);
-        }
-      } else if (shouldShowVersionNumber(addonItem.mInstall)) {
-        tiptext += " " + addonItem.mInstall.version;
-      }
-
-      addonTooltip.label = tiptext;
-    });
   },
 
   shutdown() {
     AddonManager.removeManagerListener(this);
     AddonManager.removeInstallListener(this);
     AddonManager.removeAddonListener(this);
   },
 
@@ -830,31 +657,24 @@ var gViewController = {
   backButton: null,
 
   initialize() {
     this.viewPort = document.getElementById("view-port");
     this.headeredViews = document.getElementById("headered-views");
     this.headeredViewsDeck = document.getElementById("headered-views-content");
     this.backButton = document.getElementById("go-back");
 
-    this.viewObjects.legacy = gLegacyView;
     this.viewObjects.shortcuts = gShortcutsView;
 
-    if (useHtmlViews) {
-      this.viewObjects.list = htmlView("list");
-      this.viewObjects.detail = htmlView("detail");
-      this.viewObjects.updates = htmlView("updates");
-      // gUpdatesView still handles when the Available Updates category is
-      // shown. Include it in viewObjects so it gets initialized and shutdown.
-      this.viewObjects._availableUpdatesSidebar = gUpdatesView;
-    } else {
-      this.viewObjects.list = gListView;
-      this.viewObjects.detail = gDetailView;
-      this.viewObjects.updates = gUpdatesView;
-    }
+    this.viewObjects.list = htmlView("list");
+    this.viewObjects.detail = htmlView("detail");
+    this.viewObjects.updates = htmlView("updates");
+    // gUpdatesView still handles when the Available Updates category is
+    // shown. Include it in viewObjects so it gets initialized and shutdown.
+    this.viewObjects._availableUpdatesSidebar = gUpdatesView;
 
     if (useHtmlDiscover && isDiscoverEnabled()) {
       this.viewObjects.discover = htmlView("discover");
     } else {
       this.viewObjects.discover = gDiscoverView;
     }
 
     for (let type in this.viewObjects) {
@@ -1183,29 +1003,16 @@ var gViewController = {
       isEnabled() {
         return true;
       },
       doCommand() {
         gViewController.loadView("addons://updates/available");
       },
     },
 
-    cmd_showItemDetails: {
-      isEnabled(aAddon) {
-        return !!aAddon && gViewController.currentViewObj != gDetailView;
-      },
-      doCommand(aAddon, aScrollToPreferences) {
-        gViewController.loadView(
-          "addons://detail/" +
-            encodeURIComponent(aAddon.id) +
-            (aScrollToPreferences ? "/preferences" : "")
-        );
-      },
-    },
-
     cmd_findAllUpdates: {
       inProgress: false,
       isEnabled() {
         return !this.inProgress;
       },
       async doCommand() {
         this.inProgress = true;
         gViewController.updateCommand("cmd_findAllUpdates");
@@ -1306,192 +1113,16 @@ var gViewController = {
         recordActionTelemetry({ action: "checkForUpdates" });
 
         if (pendingChecks == 0) {
           updateStatus();
         }
       },
     },
 
-    cmd_findItemUpdates: {
-      isEnabled(aAddon) {
-        if (!aAddon) {
-          return false;
-        }
-        return hasPermission(aAddon, "upgrade");
-      },
-      doCommand(aAddon) {
-        var listener = {
-          onUpdateAvailable(aAddon, aInstall) {
-            gEventManager.delegateAddonEvent("onUpdateAvailable", [
-              aAddon,
-              aInstall,
-            ]);
-            attachUpdateHandler(aInstall);
-            if (AddonManager.shouldAutoUpdate(aAddon)) {
-              aInstall.install();
-            }
-          },
-          onNoUpdateAvailable(aAddon) {
-            gEventManager.delegateAddonEvent("onNoUpdateAvailable", [aAddon]);
-          },
-        };
-        gEventManager.delegateAddonEvent("onCheckingUpdate", [aAddon]);
-        aAddon.findUpdates(listener, AddonManager.UPDATE_WHEN_USER_REQUESTED);
-        recordActionTelemetry({ action: "checkForUpdate", addon: aAddon });
-      },
-    },
-
-    cmd_showItemPreferences: {
-      isEnabled(aAddon) {
-        if (!aAddon || (!aAddon.isActive && aAddon.type !== "plugin")) {
-          return false;
-        }
-        if (gViewController.currentViewObj == gDetailView) {
-          return aAddon.optionsType && !hasInlineOptions(aAddon);
-        }
-        return aAddon.type == "plugin" || aAddon.optionsType;
-      },
-      doCommand(aAddon) {
-        let inline = hasInlineOptions(aAddon);
-        let view = getCurrentViewName();
-
-        if (inline) {
-          gViewController.commands.cmd_showItemDetails.doCommand(aAddon, true);
-        } else if (aAddon.optionsType == AddonManager.OPTIONS_TYPE_TAB) {
-          openOptionsInTab(aAddon.optionsURL);
-        }
-
-        let value = inline ? "inline" : "external";
-        recordActionTelemetry({
-          action: "preferences",
-          value,
-          view,
-          addon: aAddon,
-        });
-      },
-    },
-
-    cmd_enableItem: {
-      isEnabled(aAddon) {
-        if (!aAddon) {
-          return false;
-        }
-        let addonType = AddonManager.addonTypes[aAddon.type];
-        return (
-          !(addonType.flags & AddonManager.TYPE_SUPPORTS_ASK_TO_ACTIVATE) &&
-          hasPermission(aAddon, "enable")
-        );
-      },
-      doCommand(aAddon) {
-        if (shouldShowPermissionsPrompt(aAddon)) {
-          showPermissionsPrompt(aAddon).then(() => {
-            // Record telemetry if the addon has been enabled.
-            recordActionTelemetry({ action: "enable", addon: aAddon });
-          });
-        } else {
-          aAddon.enable();
-          recordActionTelemetry({ action: "enable", addon: aAddon });
-        }
-      },
-      getTooltip(aAddon) {
-        if (!aAddon) {
-          return "";
-        }
-        return gStrings.ext.GetStringFromName("enableAddonTooltip");
-      },
-    },
-
-    cmd_disableItem: {
-      isEnabled(aAddon) {
-        if (!aAddon) {
-          return false;
-        }
-        let addonType = AddonManager.addonTypes[aAddon.type];
-        return (
-          !(addonType.flags & AddonManager.TYPE_SUPPORTS_ASK_TO_ACTIVATE) &&
-          hasPermission(aAddon, "disable")
-        );
-      },
-      doCommand(aAddon) {
-        aAddon.disable();
-        recordActionTelemetry({ action: "disable", addon: aAddon });
-      },
-      getTooltip(aAddon) {
-        if (!aAddon) {
-          return "";
-        }
-        return gStrings.ext.GetStringFromName("disableAddonTooltip");
-      },
-    },
-
-    cmd_installItem: {
-      isEnabled(aAddon) {
-        if (!aAddon) {
-          return false;
-        }
-        return (
-          aAddon.install && aAddon.install.state == AddonManager.STATE_AVAILABLE
-        );
-      },
-      doCommand(aAddon) {
-        function doInstall() {
-          gViewController.currentViewObj
-            .getListItemForID(aAddon.id)
-            ._installStatus.installRemote();
-        }
-
-        if (gViewController.currentViewObj == gDetailView) {
-          gViewController.popState(doInstall);
-        } else {
-          doInstall();
-        }
-      },
-    },
-
-    cmd_uninstallItem: {
-      isEnabled(aAddon) {
-        if (!aAddon) {
-          return false;
-        }
-        return hasPermission(aAddon, "uninstall");
-      },
-      async doCommand(aAddon) {
-        let view = getCurrentViewName();
-
-        // Make sure we're on the list view, which supports undo.
-        if (gViewController.currentViewObj != gListView) {
-          await new Promise(resolve => {
-            document.addEventListener("ViewChanged", resolve, { once: true });
-            gViewController.loadView(`addons://list/${aAddon.type}`);
-          });
-        }
-        recordActionTelemetry({ action: "uninstall", view, addon: aAddon });
-        gViewController.currentViewObj.getListItemForID(aAddon.id).uninstall();
-      },
-      getTooltip(aAddon) {
-        if (!aAddon) {
-          return "";
-        }
-        return gStrings.ext.GetStringFromName("uninstallAddonTooltip");
-      },
-    },
-
-    cmd_cancelUninstallItem: {
-      isEnabled(aAddon) {
-        if (!aAddon) {
-          return false;
-        }
-        return isPending(aAddon, "uninstall");
-      },
-      doCommand(aAddon) {
-        aAddon.cancelUninstall();
-      },
-    },
-
     cmd_installFromFile: {
       isEnabled() {
         return XPINSTALL_ENABLED;
       },
       doCommand() {
         const nsIFilePicker = Ci.nsIFilePicker;
         var fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
         fp.init(
@@ -1549,109 +1180,16 @@ var gViewController = {
           let path = useNewAboutDebugging ? "/runtime/this-firefox" : "addons";
           mainWindow.switchToTabHavingURI(`about:debugging#${path}`, true, {
             triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
           });
         }
       },
     },
 
-    cmd_cancelOperation: {
-      isEnabled(aAddon) {
-        if (!aAddon) {
-          return false;
-        }
-        return aAddon.pendingOperations != AddonManager.PENDING_NONE;
-      },
-      doCommand(aAddon) {
-        if (isPending(aAddon, "uninstall")) {
-          aAddon.cancelUninstall();
-        }
-      },
-    },
-
-    cmd_contribute: {
-      isEnabled(aAddon) {
-        if (!aAddon) {
-          return false;
-        }
-        return "contributionURL" in aAddon && aAddon.contributionURL;
-      },
-      doCommand(aAddon) {
-        openURL(aAddon.contributionURL);
-        recordActionTelemetry({ action: "contribute", addon: aAddon });
-      },
-    },
-
-    cmd_askToActivateItem: {
-      isEnabled(aAddon) {
-        if (!aAddon) {
-          return false;
-        }
-        let addonType = AddonManager.addonTypes[aAddon.type];
-        return (
-          addonType.flags & AddonManager.TYPE_SUPPORTS_ASK_TO_ACTIVATE &&
-          hasPermission(aAddon, "ask_to_activate")
-        );
-      },
-      doCommand(aAddon) {
-        aAddon.userDisabled = AddonManager.STATE_ASK_TO_ACTIVATE;
-      },
-    },
-
-    cmd_alwaysActivateItem: {
-      isEnabled(aAddon) {
-        if (!aAddon) {
-          return false;
-        }
-        let addonType = AddonManager.addonTypes[aAddon.type];
-        return (
-          addonType.flags & AddonManager.TYPE_SUPPORTS_ASK_TO_ACTIVATE &&
-          hasPermission(aAddon, "enable")
-        );
-      },
-      doCommand(aAddon) {
-        aAddon.userDisabled = false;
-      },
-    },
-
-    cmd_neverActivateItem: {
-      isEnabled(aAddon) {
-        if (!aAddon) {
-          return false;
-        }
-        let addonType = AddonManager.addonTypes[aAddon.type];
-        return (
-          addonType.flags & AddonManager.TYPE_SUPPORTS_ASK_TO_ACTIVATE &&
-          hasPermission(aAddon, "disable")
-        );
-      },
-      doCommand(aAddon) {
-        aAddon.userDisabled = true;
-      },
-    },
-
-    cmd_showUnsignedExtensions: {
-      isEnabled() {
-        return true;
-      },
-      doCommand() {
-        gViewController.loadView("addons://list/extension?unsigned=true");
-      },
-    },
-
-    cmd_showAllExtensions: {
-      isEnabled() {
-        return true;
-      },
-      doCommand() {
-        gViewController.loadView("addons://list/extension");
-      },
-    },
-
     cmd_showShortcuts: {
       isEnabled() {
         return true;
       },
       doCommand() {
         gViewController.loadView("addons://shortcuts/shortcuts");
       },
     },
@@ -1709,281 +1247,21 @@ var gViewController = {
       return;
     }
     cmd.doCommand(aAddon);
   },
 
   onEvent() {},
 };
 
-async function isAddonAllowedInCurrentWindow(aAddon) {
-  if (
-    allowPrivateBrowsingByDefault ||
-    aAddon.type !== "extension" ||
-    !PrivateBrowsingUtils.isContentWindowPrivate(window)
-  ) {
-    return true;
-  }
-
-  const perms = await ExtensionPermissions.get(aAddon.id);
-  return perms.permissions.includes("internal:privateBrowsingAllowed");
-}
-
-function hasInlineOptions(aAddon) {
-  return (
-    aAddon.optionsType == AddonManager.OPTIONS_TYPE_INLINE_BROWSER ||
-    aAddon.type == "plugin"
-  );
-}
-
-function formatDate(aDate) {
-  const dtOptions = { year: "numeric", month: "long", day: "numeric" };
-  return aDate.toLocaleDateString(undefined, dtOptions);
-}
-
-function hasPermission(aAddon, aPerm) {
-  var perm = AddonManager["PERM_CAN_" + aPerm.toUpperCase()];
-  return !!(aAddon.permissions & perm);
-}
-
-function isPending(aAddon, aAction) {
-  var action = AddonManager["PENDING_" + aAction.toUpperCase()];
-  return !!(aAddon.pendingOperations & action);
-}
-
 function isInState(aInstall, aState) {
   var state = AddonManager["STATE_" + aState.toUpperCase()];
   return aInstall.state == state;
 }
 
-function shouldShowVersionNumber(aAddon) {
-  if (!aAddon.version) {
-    return false;
-  }
-
-  // The version number is hidden for lightweight themes.
-  if (aAddon.type == "theme") {
-    return !/@personas\.mozilla\.org$/.test(aAddon.id);
-  }
-
-  return true;
-}
-
-function createItem(aObj, aIsInstall) {
-  let item = document.createXULElement("richlistitem");
-
-  item.setAttribute("class", "addon addon-view card");
-  item.setAttribute("name", aObj.name);
-  item.setAttribute("type", aObj.type);
-
-  if (aIsInstall) {
-    item.mInstall = aObj;
-
-    if (aObj.state != AddonManager.STATE_INSTALLED) {
-      item.setAttribute("status", "installing");
-      return item;
-    }
-    aObj = aObj.addon;
-  }
-
-  item.mAddon = aObj;
-
-  item.setAttribute("status", "installed");
-
-  // set only attributes needed for sorting and XBL binding,
-  // the binding handles the rest
-  item.setAttribute("value", aObj.id);
-
-  return item;
-}
-
-function sortElements(aElements, aSortBy, aAscending) {
-  // aSortBy is an Array of attributes to sort by, in decending
-  // order of priority.
-
-  const DATE_FIELDS = ["updateDate"];
-  const NUMERIC_FIELDS = ["relevancescore"];
-
-  // We're going to group add-ons into the following buckets:
-  //
-  //  enabledInstalled
-  //    * Enabled
-  //    * Incompatible but enabled because compatibility checking is off
-  //    * Waiting to be installed
-  //    * Waiting to be enabled
-  //
-  //  pendingDisable
-  //    * Waiting to be disabled
-  //
-  //  pendingUninstall
-  //    * Waiting to be removed
-  //
-  //  disabledIncompatibleBlocked
-  //    * Disabled
-  //    * Incompatible
-  //    * Blocklisted
-
-  const UISTATE_ORDER = [
-    "enabled",
-    "askToActivate",
-    "pendingDisable",
-    "pendingUninstall",
-    "disabled",
-  ];
-
-  function dateCompare(a, b) {
-    var aTime = a.getTime();
-    var bTime = b.getTime();
-    if (aTime < bTime) {
-      return -1;
-    }
-    if (aTime > bTime) {
-      return 1;
-    }
-    return 0;
-  }
-
-  function numberCompare(a, b) {
-    return a - b;
-  }
-
-  function stringCompare(a, b) {
-    return a.localeCompare(b);
-  }
-
-  function uiStateCompare(a, b) {
-    // If we're in descending order, swap a and b, because
-    // we don't ever want to have descending uiStates
-    if (!aAscending) {
-      [a, b] = [b, a];
-    }
-
-    return UISTATE_ORDER.indexOf(a) - UISTATE_ORDER.indexOf(b);
-  }
-
-  // Prioritize themes that have screenshots.
-  function hasPreview(aHasStr, bHasStr) {
-    let aHas = aHasStr == "true";
-    let bHas = bHasStr == "true";
-    if (aHas == bHas) {
-      return 0;
-    }
-    return aHas ? -1 : 1;
-  }
-
-  function getValue(aObj, aKey) {
-    if (!aObj) {
-      return null;
-    }
-
-    if (aObj.hasAttribute(aKey)) {
-      return aObj.getAttribute(aKey);
-    }
-
-    var addon = aObj.mAddon || aObj.mInstall;
-    var addonType = aObj.mAddon && AddonManager.addonTypes[aObj.mAddon.type];
-
-    if (!addon) {
-      return null;
-    }
-
-    if (aKey == "uiState") {
-      if (addon.pendingOperations == AddonManager.PENDING_DISABLE) {
-        return "pendingDisable";
-      }
-      if (addon.pendingOperations == AddonManager.PENDING_UNINSTALL) {
-        return "pendingUninstall";
-      }
-      if (
-        !addon.isActive &&
-        (addon.pendingOperations != AddonManager.PENDING_ENABLE &&
-          addon.pendingOperations != AddonManager.PENDING_INSTALL)
-      ) {
-        return "disabled";
-      }
-      if (
-        addonType &&
-        addonType.flags & AddonManager.TYPE_SUPPORTS_ASK_TO_ACTIVATE &&
-        addon.userDisabled == AddonManager.STATE_ASK_TO_ACTIVATE
-      ) {
-        return "askToActivate";
-      }
-      return "enabled";
-    }
-
-    return addon[aKey];
-  }
-
-  // aSortFuncs will hold the sorting functions that we'll
-  // use per element, in the correct order.
-  var aSortFuncs = [];
-
-  for (let i = 0; i < aSortBy.length; i++) {
-    var sortBy = aSortBy[i];
-
-    aSortFuncs[i] = stringCompare;
-
-    if (sortBy == "uiState") {
-      aSortFuncs[i] = uiStateCompare;
-    } else if (DATE_FIELDS.includes(sortBy)) {
-      aSortFuncs[i] = dateCompare;
-    } else if (NUMERIC_FIELDS.includes(sortBy)) {
-      aSortFuncs[i] = numberCompare;
-    } else if (sortBy == "hasPreview") {
-      aSortFuncs[i] = hasPreview;
-    }
-  }
-
-  aElements.sort(function(a, b) {
-    if (!aAscending) {
-      [a, b] = [b, a];
-    }
-
-    for (let i = 0; i < aSortFuncs.length; i++) {
-      var sortBy = aSortBy[i];
-      var aValue = getValue(a, sortBy);
-      var bValue = getValue(b, sortBy);
-
-      if (!aValue && !bValue) {
-        return 0;
-      }
-      if (!aValue) {
-        return -1;
-      }
-      if (!bValue) {
-        return 1;
-      }
-      if (aValue != bValue) {
-        var result = aSortFuncs[i](aValue, bValue);
-
-        if (result != 0) {
-          return result;
-        }
-      }
-    }
-
-    // If we got here, then all values of a and b
-    // must have been equal.
-    return 0;
-  });
-}
-
-function sortList(aList, aSortBy, aAscending) {
-  var elements = Array.from(aList.childNodes);
-  sortElements(elements, [aSortBy], aAscending);
-
-  while (aList.lastChild) {
-    aList.lastChild.remove();
-  }
-
-  for (let element of elements) {
-    aList.appendChild(element);
-  }
-}
-
 async function getAddonsAndInstalls(aType, aCallback) {
   let addons = null,
     installs = null;
   let types = aType != null ? [aType] : null;
 
   let aAddonsList = await AddonManager.getAddonsByTypes(types);
   addons = aAddonsList.filter(a => !a.hidden);
   if (installs != null) {
@@ -1997,33 +1275,16 @@ async function getAddonsAndInstalls(aTyp
     );
   });
 
   if (addons != null) {
     aCallback(addons, installs);
   }
 }
 
-function doPendingUninstalls(aListBox) {
-  // Uninstalling add-ons can mutate the list so find the add-ons first then
-  // uninstall them
-  var items = [];
-  var listitem = aListBox.firstChild;
-  while (listitem) {
-    if (listitem.getAttribute("pending") == "uninstall") {
-      items.push(listitem.mAddon);
-    }
-    listitem = listitem.nextSibling;
-  }
-
-  for (let addon of items) {
-    addon.uninstall();
-  }
-}
-
 var gCategories = {
   node: null,
 
   initialize() {
     this.node = document.getElementById("categories");
 
     var types = AddonManager.addonTypes;
     for (var type in types) {
@@ -2664,1513 +1925,52 @@ var gDiscoverView = {
     Ci.nsISupportsWeakReference,
   ]),
 
   getSelectedAddon() {
     return null;
   },
 };
 
-var gLegacyView = {
-  node: null,
-  _listBox: null,
+var gUpdatesView = {
   _categoryItem: null,
   isRoot: true,
 
   initialize() {
-    this.node = document.getElementById("legacy-view");
-    this._listBox = document.getElementById("legacy-list");
-    this._categoryItem = gCategories.get("addons://legacy/");
-
-    document.getElementById("legacy-learnmore").href =
-      SUPPORT_URL + "webextensions";
-
-    gEventManager.registerAddonListener(this, "ANY");
-
-    this.refreshVisibility();
-  },
-
-  shutdown() {
-    gEventManager.unregisterAddonListener(this, "ANY");
-  },
-
-  onUninstalled() {
-    this.refreshVisibility();
-  },
-
-  async show(type, request) {
-    let addons = await AddonManager.getAddonsByTypes(["extension", "theme"]);
-    addons = addons.filter(
-      a => !a.hidden && (isDisabledLegacy(a) || isDisabledUnsigned(a))
-    );
-
-    this._listBox.textContent = "";
-
-    let elements = addons.map(a => createItem(a));
-    if (elements.length == 0) {
-      gViewController.loadView("addons://list/extension");
-      return;
-    }
-
-    sortElements(elements, ["uiState", "name"], true);
-    for (let element of elements) {
-      this._listBox.appendChild(element);
-    }
-
-    gViewController.notifyViewChanged();
-  },
-
-  hide() {
-    doPendingUninstalls(this._listBox);
-  },
-
-  getSelectedAddon() {
-    var item = this._listBox.selectedItem;
-    if (item) {
-      return item.mAddon;
-    }
-    return null;
-  },
-
-  async refreshVisibility() {
-    if (legacyExtensionsEnabled) {
-      this._categoryItem.disabled = true;
-      return;
-    }
-
-    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)) {
-        haveLegacy = true;
-      }
-    }
-
-    if (haveLegacy || haveUnsigned) {
-      this._categoryItem.disabled = false;
-      let name = gStrings.ext.GetStringFromName(
-        `type.${haveUnsigned ? "unsupported" : "legacy"}.name`
-      );
-      this._categoryItem.setAttribute("name", name);
-      this._categoryItem.tooltiptext = name;
-    } else {
-      this._categoryItem.disabled = true;
-    }
-  },
-
-  getListItemForID(aId) {
-    var listitem = this._listBox.firstChild;
-    while (listitem) {
-      if (
-        listitem.getAttribute("status") == "installed" &&
-        listitem.mAddon.id == aId
-      ) {
-        return listitem;
-      }
-      listitem = listitem.nextSibling;
-    }
-    return null;
-  },
-};
-
-var gListView = {
-  node: null,
-  _listBox: null,
-  _emptyNotice: null,
-  _type: null,
-  isRoot: true,
-
-  initialize() {
-    this.node = document.getElementById("list-view");
-    this._listBox = document.getElementById("addon-list");
-    this._emptyNotice = document.getElementById("addon-list-empty");
-
-    this._listBox.addEventListener("keydown", aEvent => {
-      if (aEvent.keyCode == aEvent.DOM_VK_RETURN) {
-        var item = this._listBox.selectedItem;
-        if (item) {
-          item.showInDetailView();
-        }
-      }
-    });
-    this._listBox.addEventListener("Uninstall", event =>
-      recordActionTelemetry({
-        action: "uninstall",
-        view: "list",
-        addon: event.target.mAddon,
-      })
-    );
-    this._listBox.addEventListener("Undo", event =>
-      recordActionTelemetry({ action: "undo", addon: event.target.mAddon })
-    );
-
-    document
-      .getElementById("signing-learn-more")
-      .setAttribute("href", SUPPORT_URL + "unsigned-addons");
-    document
-      .getElementById("legacy-extensions-learnmore-link")
-      .addEventListener("click", evt => {
-        gViewController.loadView("addons://legacy/");
-      });
-
-    try {
-      document
-        .getElementById("private-browsing-learnmore-link")
-        .setAttribute("href", SUPPORT_URL + "extensions-pb");
-    } catch (e) {
-      document.getElementById("private-browsing-notice").hidden = true;
-    }
-
-    let findSignedAddonsLink = document.getElementById(
-      "find-alternative-addons"
-    );
-    try {
-      findSignedAddonsLink.setAttribute(
-        "href",
-        Services.urlFormatter.formatURLPref("extensions.getAddons.link.url")
-      );
-    } catch (e) {
-      findSignedAddonsLink.classList.remove("text-link");
-    }
-
-    try {
-      document
-        .getElementById("signing-dev-manual-link")
-        .setAttribute(
-          "href",
-          Services.prefs.getCharPref("xpinstall.signatures.devInfoURL")
-        );
-    } catch (e) {
-      document.getElementById("signing-dev-info").hidden = true;
-    }
-
-    if (Preferences.get("plugin.load_flash_only", true)) {
-      document
-        .getElementById("plugindeprecation-learnmore-link")
-        .setAttribute("href", SUPPORT_URL + "npapi");
-    } else {
-      document.getElementById("plugindeprecation-notice").hidden = true;
-    }
-  },
-
-  show(aType, aRequest) {
-    let showOnlyDisabledUnsigned = false;
-    if (aType.endsWith("?unsigned=true")) {
-      aType = aType.replace(/\?.*/, "");
-      showOnlyDisabledUnsigned = true;
-    }
-
-    if (!(aType in AddonManager.addonTypes)) {
-      throw Components.Exception(
-        "Attempting to show unknown type " + aType,
-        Cr.NS_ERROR_INVALID_ARG
-      );
-    }
-
-    this._type = aType;
-    this.node.setAttribute("type", aType);
-    this.showEmptyNotice(false);
-
-    this._listBox.textContent = "";
-
-    if (aType == "plugin") {
-      navigator.plugins.refresh(false);
-    }
-
-    getAddonsAndInstalls(aType, (aAddonsList, aInstallsList) => {
-      if (gViewController && aRequest != gViewController.currentViewRequest) {
-        return;
-      }
-
-      let showLegacyInfo = false;
-      if (!legacyExtensionsEnabled && aType != "locale") {
-        let preLen = aAddonsList.length;
-        aAddonsList = aAddonsList.filter(
-          addon => !isLegacyExtension(addon) && !isDisabledUnsigned(addon)
-        );
-        if (aAddonsList.length != preLen) {
-          showLegacyInfo = true;
-        }
-      }
-
-      let privateNotice = document.getElementById("private-browsing-notice");
-      privateNotice.hidden =
-        allowPrivateBrowsingByDefault || aType != "extension";
-
-      var elements = [];
-
-      for (let addonItem of aAddonsList) {
-        elements.push(createItem(addonItem));
-      }
-
-      for (let installItem of aInstallsList) {
-        elements.push(createItem(installItem, true));
-      }
-
-      this.showEmptyNotice(elements.length == 0);
-      if (elements.length > 0) {
-        let sortBy;
-        if (aType == "theme") {
-          sortBy = ["uiState", "hasPreview", "name"];
-        } else {
-          sortBy = ["uiState", "name"];
-        }
-        sortElements(elements, sortBy, true);
-        for (let element of elements) {
-          this._listBox.appendChild(element);
-        }
-      }
-
-      this.filterDisabledUnsigned(showOnlyDisabledUnsigned);
-      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,
-          ]) + " ";
-        el.insertBefore(document.createTextNode(text), el.childNodes[0]);
-        legacyNotice.hidden = false;
-      } else {
-        legacyNotice.hidden = true;
-      }
-
-      gEventManager.registerInstallListener(this);
-      gViewController.updateCommands();
-      gViewController.notifyViewChanged();
-    });
-  },
-
-  hide() {
-    gEventManager.unregisterInstallListener(this);
-    doPendingUninstalls(this._listBox);
-  },
-
-  filterDisabledUnsigned(aFilter = true) {
-    let foundDisabledUnsigned = false;
-
-    for (let item of this._listBox.childNodes) {
-      if (isDisabledUnsigned(item.mAddon)) {
-        foundDisabledUnsigned = true;
-      } else {
-        item.hidden = aFilter;
-      }
-    }
-
-    document.getElementById("show-disabled-unsigned-extensions").hidden =
-      aFilter || !foundDisabledUnsigned;
-
-    document.getElementById("show-all-extensions").hidden = !aFilter;
-    document.getElementById("disabled-unsigned-addons-info").hidden = !aFilter;
-  },
-
-  showEmptyNotice(aShow) {
-    this._emptyNotice.hidden = !aShow;
-    this._listBox.hidden = aShow;
-  },
-
-  onSortChanged(aSortBy, aAscending) {
-    sortList(this._listBox, aSortBy, aAscending);
-  },
-
-  onExternalInstall(aAddon, aExistingAddon) {
-    // The existing list item will take care of upgrade installs
-    if (aExistingAddon) {
-      return;
-    }
-
-    if (aAddon.hidden) {
-      return;
-    }
-
-    this.addItem(aAddon);
-  },
-
-  onDownloadStarted(aInstall) {
-    this.addItem(aInstall, true);
-  },
-
-  onInstallStarted(aInstall) {
-    this.addItem(aInstall, true);
-  },
-
-  onDownloadCancelled(aInstall) {
-    this.removeItem(aInstall, true);
-  },
-
-  onInstallCancelled(aInstall) {
-    this.removeItem(aInstall, true);
-  },
-
-  onInstallEnded(aInstall) {
-    // Remove any install entries for upgrades, their status will appear against
-    // the existing item
-    if (aInstall.existingAddon) {
-      this.removeItem(aInstall, true);
-    }
-  },
-
-  addItem(aObj, aIsInstall) {
-    if (aObj.type != this._type) {
-      return;
-    }
-
-    if (aIsInstall && aObj.existingAddon) {
-      return;
-    }
-
-    if (aObj.addon && aObj.addon.hidden) {
-      return;
-    }
-
-    let prop = aIsInstall ? "mInstall" : "mAddon";
-    for (let item of this._listBox.childNodes) {
-      if (item[prop] == aObj) {
-        return;
-      }
-    }
-
-    let item = createItem(aObj, aIsInstall);
-    this._listBox.insertBefore(item, this._listBox.firstChild);
-    this.showEmptyNotice(false);
-  },
-
-  removeItem(aObj, aIsInstall) {
-    let prop = aIsInstall ? "mInstall" : "mAddon";
-
-    for (let item of this._listBox.childNodes) {
-      if (item[prop] == aObj) {
-        this._listBox.removeChild(item);
-        this.showEmptyNotice(this._listBox.itemCount == 0);
-        return;
-      }
-    }
-  },
-
-  getSelectedAddon() {
-    var item = this._listBox.selectedItem;
-    if (item) {
-      return item.mAddon;
-    }
-    return null;
-  },
-
-  getListItemForID(aId) {
-    var listitem = this._listBox.firstChild;
-    while (listitem) {
-      if (
-        listitem.getAttribute("status") == "installed" &&
-        listitem.mAddon.id == aId
-      ) {
-        return listitem;
-      }
-      listitem = listitem.nextSibling;
-    }
-    return null;
-  },
-};
-
-var gDetailView = {
-  node: null,
-  _addon: null,
-  _loadingTimer: null,
-  _autoUpdate: null,
-  isRoot: false,
-  restartingAddon: false,
-
-  initialize() {
-    this.node = document.getElementById("detail-view");
-    this.node.addEventListener("click", this.recordClickTelemetry);
-    this.headingImage = this.node.querySelector(".card-heading-image");
-
-    this._autoUpdate = document.getElementById("detail-autoUpdate");
-    this._autoUpdate.addEventListener(
-      "command",
-      () => {
-        this._addon.applyBackgroundUpdates = this._autoUpdate.value;
-        recordSetAddonUpdateTelemetry(this._addon);
-      },
-      true
-    );
-
-    for (let el of document.getElementsByClassName("private-learnmore")) {
-      el.setAttribute("href", SUPPORT_URL + "extensions-pb");
-    }
-
-    this._privateBrowsing = document.getElementById("detail-privateBrowsing");
-    this._privateBrowsing.addEventListener(
-      "command",
-      async () => {
-        let addon = this._addon;
-        let policy = WebExtensionPolicy.getByID(addon.id);
-        let extension = policy && policy.extension;
-
-        let perms = {
-          permissions: ["internal:privateBrowsingAllowed"],
-          origins: [],
-        };
-        if (this._privateBrowsing.value == "1") {
-          await ExtensionPermissions.add(addon.id, perms, extension);
-          recordActionTelemetry({
-            action: "privateBrowsingAllowed",
-            value: "on",
-            addon,
-          });
-        } else {
-          await ExtensionPermissions.remove(addon.id, perms, extension);
-          recordActionTelemetry({
-            action: "privateBrowsingAllowed",
-            value: "off",
-            addon,
-          });
-        }
-
-        // Reload the extension if it is already enabled.  This ensures any change
-        // on the private browsing permission is properly handled.
-        if (addon.isActive) {
-          try {
-            this.restartingAddon = true;
-            await addon.reload();
-          } finally {
-            this.restartingAddon = false;
-            this.updateState();
-            this._updateView(addon, false);
-          }
-        }
-      },
-      true
-    );
-  },
-
-  shutdown() {
-    AddonManager.removeManagerListener(this);
-  },
-
-  onUpdateModeChanged() {
-    this.onPropertyChanged(["applyBackgroundUpdates"]);
-  },
-
-  recordClickTelemetry(event) {
-    if (event.target.id == "detail-reviews") {
-      recordLinkTelemetry("rating");
-    } else if (event.target.id == "detail-homepage") {
-      recordLinkTelemetry("homepage");
-    } else if (event.originalTarget.getAttribute("anonid") == "creator-link") {
-      recordLinkTelemetry("author");
-    }
-  },
-
-  async _updateView(aAddon, aIsRemote, aScrollToPreferences) {
-    // Skip updates to avoid flickering while restarting the addon.
-    if (this.restartingAddon) {
-      return;
-    }
-
-    setSearchLabel(aAddon.type);
-
-    // Set the preview image for themes, if available.
-    this.headingImage.src = "";
-    if (aAddon.type == "theme") {
-      let previewURL =
-        aAddon.screenshots &&
-        aAddon.screenshots[0] &&
-        aAddon.screenshots[0].url;
-      if (previewURL) {
-        this.headingImage.src = previewURL;
-      }
-    }
-
-    AddonManager.addManagerListener(this);
-    this.clearLoading();
-
-    this._addon = aAddon;
-    gEventManager.registerAddonListener(this, aAddon.id);
-    gEventManager.registerInstallListener(this);
-
-    this.node.setAttribute("type", aAddon.type);
-
-    let legacy = false;
-    if (!aAddon.install) {
-      legacy = isLegacyExtension(aAddon);
-    }
-    this.node.setAttribute("legacy", legacy);
-    document.getElementById("detail-legacy-warning").href =
-      SUPPORT_URL + "webextensions";
-
-    // Make sure to select the correct category
-    let category =
-      isDisabledLegacy(aAddon) || isDisabledUnsigned(aAddon)
-        ? "addons://legacy"
-        : `addons://list/${aAddon.type}`;
-    gCategories.select(category);
-
-    document.getElementById("detail-name").textContent = aAddon.name;
-    var icon = AddonManager.getPreferredIconURL(aAddon, 32, window);
-    document.getElementById("detail-icon").src = icon ? icon : "";
-    document
-      .getElementById("detail-creator")
-      .setCreator(aAddon.creator, aAddon.homepageURL);
-
-    var version = document.getElementById("detail-version");
-    if (shouldShowVersionNumber(aAddon)) {
-      version.hidden = false;
-      version.value = aAddon.version;
-    } else {
-      version.hidden = true;
-    }
-
-    var desc = document.getElementById("detail-desc");
-    desc.textContent = aAddon.description;
-
-    var fullDesc = document.getElementById("detail-fulldesc");
-    if (aAddon.getFullDescription) {
-      fullDesc.textContent = "";
-      fullDesc.append(aAddon.getFullDescription(document));
-      fullDesc.hidden = false;
-    } else if (aAddon.fullDescription) {
-      fullDesc.textContent = aAddon.fullDescription;
-      fullDesc.hidden = false;
-    } else {
-      fullDesc.hidden = true;
-    }
-
-    var contributions = document.getElementById("detail-contributions");
-    if ("contributionURL" in aAddon && aAddon.contributionURL) {
-      contributions.hidden = false;
-    } else {
-      contributions.hidden = true;
-    }
-
-    var updateDateRow = document.getElementById("detail-dateUpdated");
-    if (aAddon.updateDate) {
-      var date = formatDate(aAddon.updateDate);
-      updateDateRow.value = date;
-    } else {
-      updateDateRow.value = null;
-    }
-
-    // TODO if the add-on was downloaded from releases.mozilla.org link to the
-    // AMO profile (bug 590344)
-    if (false) {
-      document.getElementById("detail-repository-row").hidden = false;
-      document.getElementById("detail-homepage-row").hidden = true;
-      var repository = document.getElementById("detail-repository");
-      repository.value = aAddon.homepageURL;
-      repository.href = aAddon.homepageURL;
-    } else if (aAddon.homepageURL) {
-      document.getElementById("detail-repository-row").hidden = true;
-      document.getElementById("detail-homepage-row").hidden = false;
-      var homepage = document.getElementById("detail-homepage");
-      homepage.value = aAddon.homepageURL;
-      homepage.href = aAddon.homepageURL;
-    } else {
-      document.getElementById("detail-repository-row").hidden = true;
-      document.getElementById("detail-homepage-row").hidden = true;
-    }
-
-    var rating = document.getElementById("detail-rating");
-    if (aAddon.averageRating) {
-      rating.averageRating = aAddon.averageRating;
-      rating.hidden = false;
-    } else {
-      rating.hidden = true;
-    }
-
-    var reviews = document.getElementById("detail-reviews");
-    if (aAddon.reviewURL) {
-      var text = gStrings.ext.GetStringFromName("numReviews");
-      text = PluralForm.get(aAddon.reviewCount, text);
-      text = text.replace("#1", aAddon.reviewCount);
-      reviews.value = text;
-      reviews.hidden = false;
-      reviews.href = aAddon.reviewURL;
-    } else {
-      reviews.hidden = true;
-    }
-
-    document.getElementById("detail-rating-row").hidden =
-      !aAddon.averageRating && !aAddon.reviewURL;
-
-    var canUpdate = !aIsRemote && hasPermission(aAddon, "upgrade");
-    document.getElementById("detail-updates-row").hidden = !canUpdate;
-
-    if ("applyBackgroundUpdates" in aAddon) {
-      this._autoUpdate.hidden = false;
-      this._autoUpdate.value = aAddon.applyBackgroundUpdates;
-      let hideFindUpdates = AddonManager.shouldAutoUpdate(this._addon);
-      document.getElementById(
-        "detail-findUpdates-btn"
-      ).hidden = hideFindUpdates;
-    } else {
-      this._autoUpdate.hidden = true;
-      document.getElementById("detail-findUpdates-btn").hidden = false;
-    }
-
-    // Only type = "extension" will ever get privateBrowsingAllowed, other types have
-    // no code that would be affected by the setting.  The permission is read directly
-    // from ExtensionPermissions so we can get it whether or not the extension is
-    // currently active.
-    // Ensure that all private browsing rows are hidden by default, we'll then
-    // unhide what we want.
-    for (let el of document.getElementsByClassName("detail-privateBrowsing")) {
-      el.hidden = true;
-    }
-    if (!allowPrivateBrowsingByDefault && aAddon.type === "extension") {
-      if (
-        aAddon.permissions & AddonManager.PERM_CAN_CHANGE_PRIVATEBROWSING_ACCESS
-      ) {
-        let privateBrowsingRow = document.getElementById(
-          "detail-privateBrowsing-row"
-        );
-        let privateBrowsingFooterRow = document.getElementById(
-          "detail-privateBrowsing-row-footer"
-        );
-        let perms = await ExtensionPermissions.get(aAddon.id);
-        this._privateBrowsing.hidden = false;
-        privateBrowsingRow.hidden = false;
-        privateBrowsingFooterRow.hidden = false;
-        this._privateBrowsing.value = perms.permissions.includes(
-          "internal:privateBrowsingAllowed"
-        )
-          ? "1"
-          : "0";
-      } else if (aAddon.incognito == "spanning") {
-        document.getElementById(
-          "detail-privateBrowsing-required"
-        ).hidden = false;
-        document.getElementById(
-          "detail-privateBrowsing-required-footer"
-        ).hidden = false;
-      } else if (aAddon.incognito == "not_allowed") {
-        document.getElementById(
-          "detail-privateBrowsing-disallowed"
-        ).hidden = false;
-        document.getElementById(
-          "detail-privateBrowsing-disallowed-footer"
-        ).hidden = false;
-      }
-    }
-
-    // While updating the addon details view, also check if the preferences button should be disabled because
-    // we are in a private window and the addon is not allowed to access it.
-    let hidePreferences =
-      (!aIsRemote &&
-        !gViewController.commands.cmd_showItemPreferences.isEnabled(aAddon)) ||
-      !(await isAddonAllowedInCurrentWindow(aAddon));
-    document.getElementById("detail-prefs-btn").hidden = hidePreferences;
-
-    var gridRows = document.querySelectorAll("#detail-grid rows row");
-    let first = true;
-    for (let gridRow of gridRows) {
-      if (
-        first &&
-        window.getComputedStyle(gridRow).getPropertyValue("display") != "none"
-      ) {
-        gridRow.setAttribute("first-row", true);
-        first = false;
-      } else {
-        gridRow.removeAttribute("first-row");
-      }
-    }
-
-    this.fillSettingsRows(aScrollToPreferences, () => {
-      this.updateState();
-      gViewController.notifyViewChanged();
-    });
-  },
-
-  async show(aAddonId, aRequest) {
-    let index = aAddonId.indexOf("/preferences");
-    let scrollToPreferences = false;
-    if (index >= 0) {
-      aAddonId = aAddonId.substring(0, index);
-      scrollToPreferences = true;
-    }
-
-    this._loadingTimer = setTimeout(() => {
-      this.node.setAttribute("loading-extended", true);
-    }, LOADING_MSG_DELAY);
-
-    let aAddon = await AddonManager.getAddonByID(aAddonId);
-    if (gViewController && aRequest != gViewController.currentViewRequest) {
-      return;
-    }
-
-    if (aAddon) {
-      this._updateView(aAddon, false, scrollToPreferences);
-      return;
-    }
-
-    // Look for an add-on pending install
-    let aInstalls = await AddonManager.getAllInstalls();
-    for (let install of aInstalls) {
-      if (
-        install.state == AddonManager.STATE_INSTALLED &&
-        install.addon.id == aAddonId
-      ) {
-        this._updateView(install.addon, false);
-        return;
-      }
-    }
-
-    // This might happen due to session restore restoring us back to an
-    // add-on that doesn't exist but otherwise shouldn't normally happen.
-    // Either way just revert to the default view.
-    gViewController.replaceView(gViewDefault);
-  },
-
-  hide() {
-    AddonManager.removeManagerListener(this);
-    this.clearLoading();
-    if (this._addon) {
-      if (hasInlineOptions(this._addon)) {
-        Services.obs.notifyObservers(
-          document,
-          AddonManager.OPTIONS_NOTIFICATION_HIDDEN,
-          this._addon.id
-        );
-      }
-
-      gEventManager.unregisterAddonListener(this, this._addon.id);
-      gEventManager.unregisterInstallListener(this);
-      this._addon = null;
-
-      // Flush the preferences to disk so they survive any crash
-      if (this.node.getElementsByTagName("setting").length) {
-        Services.prefs.savePrefFile(null);
-      }
-    }
-  },
-
-  updateState() {
-    // Skip updates to avoid flickering while restarting the addon.
-    if (this.restartingAddon) {
-      return;
-    }
-
-    gViewController.updateCommands();
-
-    var pending = this._addon.pendingOperations;
-    if (pending & AddonManager.PENDING_UNINSTALL) {
-      this.node.removeAttribute("notification");
-
-      // We don't care about pending operations other than uninstall.
-      // They're transient, and cannot be undone.
-      this.node.setAttribute("pending", "uninstall");
-      document.getElementById(
-        "detail-pending"
-      ).textContent = gStrings.ext.formatStringFromName(
-        "details.notification.restartless-uninstall",
-        [this._addon.name]
-      );
-    } else {
-      this.node.removeAttribute("pending");
-
-      if (this._addon.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED) {
-        this.node.setAttribute("notification", "error");
-        document.getElementById(
-          "detail-error"
-        ).textContent = gStrings.ext.formatStringFromName(
-          "details.notification.blocked",
-          [this._addon.name]
-        );
-        var errorLink = document.getElementById("detail-error-link");
-        errorLink.value = gStrings.ext.GetStringFromName(
-          "details.notification.blocked.link"
-        );
-        this._addon.getBlocklistURL().then(url => {
-          errorLink.href = url;
-          errorLink.hidden = false;
-        });
-      } else if (isDisabledUnsigned(this._addon)) {
-        this.node.setAttribute("notification", "error");
-        document.getElementById(
-          "detail-error"
-        ).textContent = gStrings.ext.formatStringFromName(
-          "details.notification.unsignedAndDisabled",
-          [this._addon.name, gStrings.brandShortName]
-        );
-        let errorLink = document.getElementById("detail-error-link");
-        errorLink.value = gStrings.ext.GetStringFromName(
-          "details.notification.unsigned.link"
-        );
-        errorLink.href = SUPPORT_URL + "unsigned-addons";
-        errorLink.hidden = false;
-      } else if (
-        !this._addon.isCompatible &&
-        (AddonManager.checkCompatibility ||
-          this._addon.blocklistState !=
-            Ci.nsIBlocklistService.STATE_SOFTBLOCKED)
-      ) {
-        this.node.setAttribute("notification", "warning");
-        document.getElementById(
-          "detail-warning"
-        ).textContent = gStrings.ext.formatStringFromName(
-          "details.notification.incompatible",
-          [this._addon.name, gStrings.brandShortName, gStrings.appVersion]
-        );
-        document.getElementById("detail-warning-link").hidden = true;
-      } else if (!isCorrectlySigned(this._addon)) {
-        this.node.setAttribute("notification", "warning");
-        document.getElementById(
-          "detail-warning"
-        ).textContent = gStrings.ext.formatStringFromName(
-          "details.notification.unsigned",
-          [this._addon.name, gStrings.brandShortName]
-        );
-        var warningLink = document.getElementById("detail-warning-link");
-        warningLink.value = gStrings.ext.GetStringFromName(
-          "details.notification.unsigned.link"
-        );
-        warningLink.href = SUPPORT_URL + "unsigned-addons";
-        warningLink.hidden = false;
-      } else if (
-        this._addon.blocklistState == Ci.nsIBlocklistService.STATE_SOFTBLOCKED
-      ) {
-        this.node.setAttribute("notification", "warning");
-        document.getElementById(
-          "detail-warning"
-        ).textContent = gStrings.ext.formatStringFromName(
-          "details.notification.softblocked",
-          [this._addon.name]
-        );
-        let warningLink = document.getElementById("detail-warning-link");
-        warningLink.value = gStrings.ext.GetStringFromName(
-          "details.notification.softblocked.link"
-        );
-        this._addon.getBlocklistURL().then(url => {
-          warningLink.href = url;
-          warningLink.hidden = false;
-        });
-      } else if (
-        this._addon.blocklistState == Ci.nsIBlocklistService.STATE_OUTDATED
-      ) {
-        this.node.setAttribute("notification", "warning");
-        document.getElementById(
-          "detail-warning"
-        ).textContent = gStrings.ext.formatStringFromName(
-          "details.notification.outdated",
-          [this._addon.name]
-        );
-        let warningLink = document.getElementById("detail-warning-link");
-        warningLink.value = gStrings.ext.GetStringFromName(
-          "details.notification.outdated.link"
-        );
-        this._addon.getBlocklistURL().then(url => {
-          warningLink.href = url;
-          warningLink.hidden = false;
-        });
-      } else if (
-        this._addon.blocklistState ==
-        Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE
-      ) {
-        this.node.setAttribute("notification", "error");
-        document.getElementById(
-          "detail-error"
-        ).textContent = gStrings.ext.formatStringFromName(
-          "details.notification.vulnerableUpdatable",
-          [this._addon.name]
-        );
-        let errorLink = document.getElementById("detail-error-link");
-        errorLink.value = gStrings.ext.GetStringFromName(
-          "details.notification.vulnerableUpdatable.link"
-        );
-        this._addon.getBlocklistURL().then(url => {
-          errorLink.href = url;
-          errorLink.hidden = false;
-        });
-      } else if (
-        this._addon.blocklistState ==
-        Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE
-      ) {
-        this.node.setAttribute("notification", "error");
-        document.getElementById(
-          "detail-error"
-        ).textContent = gStrings.ext.formatStringFromName(
-          "details.notification.vulnerableNoUpdate",
-          [this._addon.name]
-        );
-        let errorLink = document.getElementById("detail-error-link");
-        errorLink.value = gStrings.ext.GetStringFromName(
-          "details.notification.vulnerableNoUpdate.link"
-        );
-        this._addon.getBlocklistURL().then(url => {
-          errorLink.href = url;
-          errorLink.hidden = false;
-        });
-      } else if (
-        this._addon.isGMPlugin &&
-        !this._addon.isInstalled &&
-        this._addon.isActive
-      ) {
-        this.node.setAttribute("notification", "warning");
-        let warning = document.getElementById("detail-warning");
-        warning.textContent = gStrings.ext.formatStringFromName(
-          "details.notification.gmpPending",
-          [this._addon.name]
-        );
-      } else {
-        this.node.removeAttribute("notification");
-      }
-    }
-
-    let menulist = document.getElementById("detail-state-menulist");
-    let addonType = AddonManager.addonTypes[this._addon.type];
-    if (addonType.flags & AddonManager.TYPE_SUPPORTS_ASK_TO_ACTIVATE) {
-      let askItem = document.getElementById("detail-ask-to-activate-menuitem");
-      let alwaysItem = document.getElementById(
-        "detail-always-activate-menuitem"
-      );
-      let neverItem = document.getElementById("detail-never-activate-menuitem");
-      let hasActivatePermission = ["ask_to_activate", "enable", "disable"].some(
-        perm => hasPermission(this._addon, perm)
-      );
-
-      if (!this._addon.isActive) {
-        menulist.selectedItem = neverItem;
-      } else if (
-        this._addon.userDisabled == AddonManager.STATE_ASK_TO_ACTIVATE
-      ) {
-        menulist.selectedItem = askItem;
-      } else {
-        menulist.selectedItem = alwaysItem;
-      }
-
-      menulist.disabled = !hasActivatePermission;
-      menulist.hidden = false;
-      menulist.classList.add("no-auto-hide");
-    } else {
-      menulist.hidden = true;
-    }
-
-    this.node.setAttribute("active", this._addon.isActive);
-  },
-
-  clearLoading() {
-    if (this._loadingTimer) {
-      clearTimeout(this._loadingTimer);
-      this._loadingTimer = null;
-    }
-
-    this.node.removeAttribute("loading-extended");
-  },
-
-  emptySettingsRows() {
-    var lastRow = document.getElementById("detail-rating-row");
-    var rows = lastRow.parentNode;
-    while (lastRow.nextSibling) {
-      rows.removeChild(rows.lastChild);
-    }
-  },
-
-  fillSettingsRows(aScrollToPreferences, aCallback) {
-    this.emptySettingsRows();
-    if (!hasInlineOptions(this._addon)) {
-      if (aCallback) {
-        aCallback();
-      }
-      return;
-    }
-
-    // We can't use a promise for this, since some code (especially in tests)
-    // relies on us finishing before the ViewChanged event bubbles up to its
-    // listeners, and promises resolve asynchronously.
-    let whenViewLoaded = callback => {
-      if (gViewController.displayedView.hasAttribute("loading")) {
-        gDetailView.node.addEventListener(
-          "ViewChanged",
-          function() {
-            callback();
-          },
-          { once: true }
-        );
-      } else {
-        callback();
-      }
-    };
-
-    let finish = firstSetting => {
-      // Ensure the page has loaded and force the XBL bindings to be synchronously applied,
-      // then notify observers.
-      whenViewLoaded(() => {
-        if (firstSetting) {
-          firstSetting.clientTop;
-        }
-        Services.obs.notifyObservers(
-          document,
-          AddonManager.OPTIONS_NOTIFICATION_DISPLAYED,
-          this._addon.id
-        );
-        if (aScrollToPreferences) {
-          gDetailView.scrollToPreferencesRows();
-        }
-      });
-    };
-
-    var rows = document.getElementById("detail-rows");
-
-    if (this._addon.optionsType == AddonManager.OPTIONS_TYPE_INLINE_BROWSER) {
-      whenViewLoaded(async () => {
-        const addon = this._addon;
-        await addon.startupPromise;
-
-        // Do not create the inline addon options if about:addons is opened in a private window
-        // and the addon is not allowed to access it.
-        if (!(await isAddonAllowedInCurrentWindow(addon))) {
-          return;
-        }
-
-        const browserContainer = await this.createOptionsBrowser(rows);
-
-        if (browserContainer) {
-          // Make sure the browser is unloaded as soon as we change views,
-          // rather than waiting for the next detail view to load.
-          document.addEventListener(
-            "ViewChanged",
-            function() {
-              // Do not remove the addon options container if the view changed
-              // event is not related to a change to the current selected view
-              // or the current selected addon (e.g. it could be related to the
-              // disco pane view that has completed to load, See Bug 1435705 for
-              // a rationale).
-              if (
-                gViewController.currentViewObj === gDetailView &&
-                gDetailView._addon === addon
-              ) {
-                return;
-              }
-              browserContainer.remove();
-            },
-            { once: true }
-          );
-        }
-
-        finish(browserContainer);
-      });
-    }
-
-    if (aCallback) {
-      aCallback();
-    }
-  },
-
-  scrollToPreferencesRows() {
-    // We find this row, rather than remembering it from above,
-    // in case it has been changed by the observers.
-    let firstRow = gDetailView.node.querySelector('setting[first-row="true"]');
-    if (firstRow) {
-      let top = firstRow.getBoundingClientRect().y;
-      top -= parseInt(
-        window.getComputedStyle(firstRow).getPropertyValue("margin-top")
-      );
-
-      let detailView = gDetailView.node;
-      top -= detailView.getBoundingClientRect().y;
-
-      detailView.scrollTo(0, top);
-    }
-  },
-
-  async createOptionsBrowser(parentNode) {
-    const containerId = "addon-options-prompts-stack";
-
-    let stack = document.getElementById(containerId);
-
-    if (stack) {
-      // Remove the existent options container (if any).
-      stack.remove();
-    }
-
-    stack = document.createXULElement("stack");
-    stack.setAttribute("id", containerId);
-
-    let browser = document.createXULElement("browser");
-    browser.setAttribute("type", "content");
-    browser.setAttribute("disableglobalhistory", "true");
-    browser.setAttribute("id", "addon-options");
-    browser.setAttribute("class", "inline-options-browser");
-    browser.setAttribute("transparent", "true");
-    browser.setAttribute("forcemessagemanager", "true");
-    browser.setAttribute("selectmenulist", "ContentSelectDropdown");
-    browser.setAttribute("autocompletepopup", "PopupAutoComplete");
-
-    // The outer about:addons document listens for key presses to focus
-    // the search box when / is pressed.  But if we're focused inside an
-    // options page, don't let those keypresses steal focus.
-    browser.addEventListener("keypress", event => {
-      event.stopPropagation();
-    });
-
-    let { optionsURL, optionsBrowserStyle } = this._addon;
-    if (this._addon.isWebExtension) {
-      let policy = ExtensionParent.WebExtensionPolicy.getByID(this._addon.id);
-      browser.sameProcessAsFrameLoader = policy.extension.groupFrameLoader;
-    }
-
-    let remoteSubframes = window.docShell.QueryInterface(Ci.nsILoadContext)
-      .useRemoteSubframes;
-
-    let readyPromise;
-    if (
-      E10SUtils.canLoadURIInRemoteType(
-        optionsURL,
-        remoteSubframes,
-        E10SUtils.EXTENSION_REMOTE_TYPE
-      )
-    ) {
-      browser.setAttribute("remote", "true");
-      browser.setAttribute("remoteType", E10SUtils.EXTENSION_REMOTE_TYPE);
-      readyPromise = promiseEvent("XULFrameLoaderCreated", browser);
-
-      readyPromise.then(() => {
-        if (!browser.messageManager) {
-          // Early exit if the the extension page's XUL browser has been destroyed in the meantime
-          // (e.g. because the extension has been reloaded while the options page was still loading).
-          return;
-        }
-        const parentChromeWindow = window.docShell.parent.domWindow;
-        const parentContextMenuPopup = parentChromeWindow.document.getElementById(
-          "contentAreaContextMenu"
-        );
-
-        // Override openPopupAtScreen on the dummy menupopup element, so that we can forward
-        // "nsContextMenu.js openContextMenu"'s calls related to the extensions "options page"
-        // context menu events.
-        document.getElementById("contentAreaContextMenu").openPopupAtScreen = (
-          ...args
-        ) => {
-          return parentContextMenuPopup.openPopupAtScreen(...args);
-        };
-      });
-    } else {
-      readyPromise = promiseEvent("load", browser, true);
-    }
-
-    stack.appendChild(browser);
-    parentNode.appendChild(stack);
-
-    // Force bindings to apply synchronously.
-    browser.clientTop;
-
-    await readyPromise;
-
-    if (!browser.messageManager) {
-      // If the browser.messageManager is undefined, the browser element has been
-      // removed from the document in the meantime (e.g. due to a rapid sequence
-      // of addon reload), ensure that the stack is also removed and return null.
-      stack.remove();
-      return null;
-    }
-
-    ExtensionParent.apiManager.emit("extension-browser-inserted", browser);
-
-    return new Promise(resolve => {
-      let messageListener = {
-        receiveMessage({ name, data }) {
-          if (name === "Extension:BrowserResized") {
-            browser.style.height = `${data.height}px`;
-          } else if (name === "Extension:BrowserContentLoaded") {
-            resolve(stack);
-          }
-        },
-      };
-
-      let mm = browser.messageManager;
-
-      if (!mm) {
-        // If the browser.messageManager is undefined, the browser element has been
-        // removed from the document in the meantime (e.g. due to a rapid sequence
-        // of addon reload), ensure that the stack is also removed and return null.
-        stack.remove();
-        resolve(null);
-        return;
-      }
-
-      mm.loadFrameScript(
-        "chrome://extensions/content/ext-browser-content.js",
-        false,
-        true
-      );
-      mm.loadFrameScript("chrome://browser/content/content.js", false, true);
-      mm.addMessageListener("Extension:BrowserContentLoaded", messageListener);
-      mm.addMessageListener("Extension:BrowserResized", messageListener);
-
-      let browserOptions = {
-        fixedWidth: true,
-        isInline: true,
-      };
-
-      if (optionsBrowserStyle) {
-        browserOptions.stylesheets = extensionStylesheets;
-      }
-
-      mm.sendAsyncMessage("Extension:InitBrowser", browserOptions);
-
-      browser.loadURI(optionsURL, {
-        triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
-      });
-    });
-  },
-
-  getSelectedAddon() {
-    return this._addon;
-  },
-
-  onEnabling() {
-    this.updateState();
-  },
-
-  onEnabled() {
-    this.updateState();
-    this.fillSettingsRows();
-  },
-
-  onDisabling() {
-    this.updateState();
-    if (hasInlineOptions(this._addon)) {
-      Services.obs.notifyObservers(
-        document,
-        AddonManager.OPTIONS_NOTIFICATION_HIDDEN,
-        this._addon.id
-      );
-    }
-  },
-
-  onDisabled() {
-    this.updateState();
-    this.emptySettingsRows();
-  },
-
-  onUninstalling() {
-    this.updateState();
-  },
-
-  onUninstalled() {
-    gViewController.popState();
-  },
-
-  onOperationCancelled() {
-    this.updateState();
-  },
-
-  onPropertyChanged(aProperties) {
-    if (aProperties.includes("applyBackgroundUpdates")) {
-      this._autoUpdate.value = this._addon.applyBackgroundUpdates;
-      let hideFindUpdates = AddonManager.shouldAutoUpdate(this._addon);
-      document.getElementById(
-        "detail-findUpdates-btn"
-      ).hidden = hideFindUpdates;
-    }
-
-    if (
-      aProperties.includes("appDisabled") ||
-      aProperties.includes("signedState") ||
-      aProperties.includes("userDisabled")
-    ) {
-      this.updateState();
-    }
-  },
-
-  onExternalInstall(aAddon, aExistingAddon) {
-    // Only care about upgrades for the currently displayed add-on
-    if (!aExistingAddon || aExistingAddon.id != this._addon.id) {
-      return;
-    }
-
-    this._updateView(aAddon, false);
-  },
-
-  onInstallCancelled(aInstall) {
-    if (aInstall.addon.id == this._addon.id) {
-      gViewController.popState();
-    }
-  },
-};
-
-var gUpdatesView = {
-  node: null,
-  _listBox: null,
-  _emptyNotice: null,
-  _updateSelected: null,
-  _categoryItem: null,
-  isRoot: true,
-
-  initialize() {
-    this.node = document.getElementById("updates-view");
-    this._listBox = document.getElementById("updates-list");
-    this._emptyNotice = document.getElementById("updates-list-empty");
-
     this._categoryItem = gCategories.get("addons://updates/available");
-
-    this._updateSelected = document.getElementById("update-selected-btn");
-    this._updateSelected.addEventListener("command", function() {
-      gUpdatesView.installSelected();
-    });
-    this.node.addEventListener("RelNotesShow", event => {
-      recordActionTelemetry({
-        action: "releaseNotes",
-        addon: event.target.mAddon,
-      });
-    });
-
     this.updateAvailableCount(true);
 
     AddonManager.addAddonListener(this);
     AddonManager.addInstallListener(this);
   },
 
   shutdown() {
     AddonManager.removeAddonListener(this);
     AddonManager.removeInstallListener(this);
   },
 
   show(aType, aRequest) {
-    document.getElementById("empty-availableUpdates-msg").hidden =
-      aType != "available";
-    document.getElementById("empty-recentUpdates-msg").hidden =
-      aType != "recent";
-    this.showEmptyNotice(false);
-
-    this._listBox.textContent = "";
-
-    this.node.setAttribute("updatetype", aType);
-    if (aType == "recent") {
-      this._showRecentUpdates(aRequest);
-    } else {
-      this._showAvailableUpdates(false, aRequest);
-    }
-  },
-
-  hide() {
-    this._updateSelected.hidden = true;
-    this._categoryItem.hidden = this._categoryItem.badgeCount == 0;
-    doPendingUninstalls(this._listBox);
-  },
-
-  async _showRecentUpdates(aRequest) {
-    let aAddonsList = await AddonManager.getAllAddons();
-    if (gViewController && aRequest != gViewController.currentViewRequest) {
-      return;
-    }
-
-    var elements = [];
-    let threshold = Date.now() - UPDATES_RECENT_TIMESPAN;
-    for (let addon of aAddonsList) {
-      if (
-        addon.hidden ||
-        !addon.updateDate ||
-        addon.updateDate.getTime() < threshold
-      ) {
-        continue;
-      }
-
-      elements.push(createItem(addon));
-    }
-
-    this.showEmptyNotice(elements.length == 0);
-    if (elements.length > 0) {
-      sortElements(elements, ["updateDate"], false);
-      for (let element of elements) {
-        this._listBox.appendChild(element);
-      }
-    }
-
-    gViewController.notifyViewChanged();
+    throw new Error(
+      "should not get here (available updates view is in aboutaddons.js"
+    );
   },
 
-  async _showAvailableUpdates(aIsRefresh, aRequest) {
-    /* Disable the Update Selected button so it can't get clicked
-       before everything is initialized asynchronously.
-       It will get re-enabled by maybeDisableUpdateSelected(). */
-    this._updateSelected.disabled = true;
-
-    let aInstallsList = await AddonManager.getAllInstalls();
-    if (
-      !aIsRefresh &&
-      gViewController &&
-      aRequest &&
-      aRequest != gViewController.currentViewRequest
-    ) {
-      return;
-    }
-
-    if (aIsRefresh) {
-      this.showEmptyNotice(false);
-      this._updateSelected.hidden = true;
-
-      while (this._listBox.childNodes.length > 0) {
-        this._listBox.firstChild.remove();
-      }
-    }
-
-    var elements = [];
-
-    for (let install of aInstallsList) {
-      if (!this.isManualUpdate(install)) {
-        continue;
-      }
-
-      let item = createItem(install.existingAddon);
-      item.setAttribute("upgrade", true);
-      item.addEventListener("IncludeUpdateChanged", () => {
-        this.maybeDisableUpdateSelected();
-      });
-      elements.push(item);
-    }
-
-    this.showEmptyNotice(elements.length == 0);
-    if (elements.length > 0) {
-      this._updateSelected.hidden = false;
-      sortElements(elements, ["updateDate"], false);
-      for (let element of elements) {
-        this._listBox.appendChild(element);
-      }
-    }
-
-    // ensure badge count is in sync
-    this._categoryItem.badgeCount = this._listBox.itemCount;
-
-    gViewController.notifyViewChanged();
-  },
-
-  showEmptyNotice(aShow) {
-    this._emptyNotice.hidden = !aShow;
-    this._listBox.hidden = aShow;
-  },
+  hide() {},
 
   isManualUpdate(aInstall, aOnlyAvailable) {
     var isManual =
       aInstall.existingAddon &&
       !AddonManager.shouldAutoUpdate(aInstall.existingAddon);
     if (isManual && aOnlyAvailable) {
       return isInState(aInstall, "available");
     }
     return isManual;
   },
 
   maybeRefresh() {
-    if (gViewController.currentViewId == "addons://updates/available") {
-      this._showAvailableUpdates(true);
-    }
     this.updateAvailableCount();
   },
 
   async updateAvailableCount(aInitializing) {
     if (aInitializing) {
       gPendingInitializations++;
     }
     let aInstallsList = await AddonManager.getAllInstalls();
@@ -4181,59 +1981,16 @@ var gUpdatesView = {
       gViewController.currentViewId != "addons://updates/available" &&
       count == 0;
     this._categoryItem.badgeCount = count;
     if (aInitializing) {
       notifyInitialized();
     }
   },
 
-  maybeDisableUpdateSelected() {
-    for (let item of this._listBox.childNodes) {
-      if (item.includeUpdate) {
-        this._updateSelected.disabled = false;
-        return;
-      }
-    }
-    this._updateSelected.disabled = true;
-  },
-
-  installSelected() {
-    for (let item of this._listBox.childNodes) {
-      if (item.includeUpdate) {
-        item.upgrade();
-      }
-    }
-
-    this._updateSelected.disabled = true;
-  },
-
-  getSelectedAddon() {
-    var item = this._listBox.selectedItem;
-    if (item) {
-      return item.mAddon;
-    }
-    return null;
-  },
-
-  getListItemForID(aId) {
-    var listitem = this._listBox.firstChild;
-    while (listitem) {
-      if (listitem.mAddon.id == aId) {
-        return listitem;
-      }
-      listitem = listitem.nextSibling;
-    }
-    return null;
-  },
-
-  onSortChanged(aSortBy, aAscending) {
-    sortList(this._listBox, aSortBy, aAscending);
-  },
-
   onNewInstall(aInstall) {
     if (!this.isManualUpdate(aInstall)) {
       return;
     }
     this.maybeRefresh();
   },
 
   onInstallStarted(aInstall) {
--- a/toolkit/mozapps/extensions/content/extensions.xml
+++ b/toolkit/mozapps/extensions/content/extensions.xml
@@ -13,202 +13,16 @@
 
 <bindings id="addonBindings"
           xmlns="http://www.mozilla.org/xbl"
           xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
           xmlns:xbl="http://www.mozilla.org/xbl"
           xmlns:html="http://www.w3.org/1999/xhtml">
 
 
-  <!-- Rating - displays current/average rating, allows setting user rating -->
-  <binding id="rating">
-    <content>
-      <xul:image class="star"
-                 onmouseover="document.getBindingParent(this)._hover(1);"
-                 onclick="document.getBindingParent(this).userRating = 1;"/>
-      <xul:image class="star"
-                 onmouseover="document.getBindingParent(this)._hover(2);"
-                 onclick="document.getBindingParent(this).userRating = 2;"/>
-      <xul:image class="star"
-                 onmouseover="document.getBindingParent(this)._hover(3);"
-                 onclick="document.getBindingParent(this).userRating = 3;"/>
-      <xul:image class="star"
-                 onmouseover="document.getBindingParent(this)._hover(4);"
-                 onclick="document.getBindingParent(this).userRating = 4;"/>
-      <xul:image class="star"
-                 onmouseover="document.getBindingParent(this)._hover(5);"
-                 onclick="document.getBindingParent(this).userRating = 5;"/>
-    </content>
-
-    <implementation>
-      <constructor><![CDATA[
-        this._updateStars();
-      ]]></constructor>
-
-      <property name="stars" readonly="true">
-        <getter><![CDATA[
-          return document.getAnonymousNodes(this);
-        ]]></getter>
-      </property>
-
-      <property name="averageRating">
-        <getter><![CDATA[
-          if (this.hasAttribute("averagerating"))
-            return this.getAttribute("averagerating");
-          return -1;
-        ]]></getter>
-        <setter><![CDATA[
-          this.setAttribute("averagerating", val);
-          if (this.showRating == "average")
-            this._updateStars();
-        ]]></setter>
-      </property>
-
-      <property name="userRating">
-        <getter><![CDATA[
-          if (this.hasAttribute("userrating"))
-            return this.getAttribute("userrating");
-          return -1;
-        ]]></getter>
-        <setter><![CDATA[
-          if (this.showRating != "user")
-            return;
-          this.setAttribute("userrating", val);
-          if (this.showRating == "user")
-            this._updateStars();
-        ]]></setter>
-      </property>
-
-      <property name="showRating">
-        <getter><![CDATA[
-          if (this.hasAttribute("showrating"))
-            return this.getAttribute("showrating");
-          return "average";
-        ]]></getter>
-        <setter><![CDATA[
-          if (val != "average" || val != "user")
-            throw Components.Exception("Invalid value", Cr.NS_ERROR_ILLEGAL_VALUE);
-          this.setAttribute("showrating", val);
-          this._updateStars();
-        ]]></setter>
-      </property>
-
-      <method name="_updateStars">
-        <body><![CDATA[
-          var stars = this.stars;
-          var rating = this[this.showRating + "Rating"];
-          // average ratings can be non-whole numbers, round them so they
-          // match to their closest star
-          rating = Math.round(rating);
-          for (let i = 0; i < stars.length; i++)
-            stars[i].setAttribute("on", rating > i);
-        ]]></body>
-      </method>
-
-      <method name="_hover">
-        <parameter name="aScore"/>
-        <body><![CDATA[
-          if (this.showRating != "user")
-            return;
-          var stars = this.stars;
-          for (let i = 0; i < stars.length; i++)
-            stars[i].setAttribute("on", i <= (aScore - 1));
-        ]]></body>
-      </method>
-
-    </implementation>
-
-    <handlers>
-      <handler event="mouseout">
-        this._updateStars();
-      </handler>
-    </handlers>
-  </binding>
-
-  <!-- Download progress - shows graphical progress of download and any
-       related status message. -->
-  <binding id="download-progress">
-    <content>
-      <xul:stack flex="1">
-        <xul:hbox flex="1">
-          <xul:hbox class="start-cap"/>
-          <html:progress anonid="progress" class="progress" max="100"/>
-          <xul:hbox class="end-cap"/>
-        </xul:hbox>
-        <xul:hbox class="status-container">
-          <xul:spacer flex="1"/>
-          <xul:label anonid="status" class="status"/>
-          <xul:spacer flex="1"/>
-          <xul:button anonid="cancel-btn" class="cancel"
-                      tooltiptext="&progress.cancel.tooltip;"
-                      oncommand="document.getBindingParent(this).cancel();"/>
-        </xul:hbox>
-      </xul:stack>
-    </content>
-
-    <implementation>
-      <constructor><![CDATA[
-        var progress = 0;
-        if (this.hasAttribute("progress"))
-          progress = parseInt(this.getAttribute("progress"));
-        this.progress = progress;
-      ]]></constructor>
-
-      <field name="_progress">
-        document.getAnonymousElementByAttribute(this, "anonid", "progress");
-      </field>
-      <field name="_cancel">
-        document.getAnonymousElementByAttribute(this, "anonid", "cancel-btn");
-      </field>
-      <field name="_status">
-        document.getAnonymousElementByAttribute(this, "anonid", "status");
-      </field>
-
-      <property name="progress">
-        <setter><![CDATA[
-          // This property is always updated after maxProgress.
-          if (this.getAttribute("mode") == "determined") {
-            this._progress.value = val;
-          }
-          if (val == this._progress.max)
-            this.setAttribute("complete", true);
-          else
-            this.removeAttribute("complete");
-        ]]></setter>
-      </property>
-
-      <property name="maxProgress">
-        <setter><![CDATA[
-          if (val == -1) {
-            this.setAttribute("mode", "undetermined");
-            this._progress.removeAttribute("value");
-          } else {
-            this.setAttribute("mode", "determined");
-            this._progress.setAttribute("max", val);
-          }
-        ]]></setter>
-      </property>
-
-      <property name="status">
-        <getter><![CDATA[
-          return this._status.value;
-        ]]></getter>
-        <setter><![CDATA[
-          this._status.value = val;
-        ]]></setter>
-      </property>
-
-      <method name="cancel">
-        <body><![CDATA[
-          this.mInstall.cancel();
-        ]]></body>
-      </method>
-    </implementation>
-  </binding>
-
   <!-- Category item - an item in the category list. -->
   <binding id="category"
            extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
     <content align="center">
       <xul:image anonid="icon" class="category-icon"/>
       <xul:label anonid="name" class="category-name" crop="end" flex="1" xbl:inherits="value=name"/>
       <xul:label anonid="badge" class="category-badge" xbl:inherits="value=count"/>
     </content>
@@ -230,1496 +44,9 @@
           this.setAttribute("count", val);
           var event = document.createEvent("Events");
           event.initEvent("CategoryBadgeUpdated", true, true);
           this.dispatchEvent(event);
         ]]></setter>
       </property>
     </implementation>
   </binding>
-
-
-  <!-- Creator link - Name of a user/developer, providing a link if relevant. -->
-  <binding id="creator-link">
-    <content>
-      <xul:label anonid="label" value="&addon.createdBy.label;"/>
-      <xul:label anonid="creator-link" class="creator-link" is="text-link"/>
-      <xul:label anonid="creator-name" class="creator-name"/>
-    </content>
-
-    <implementation>
-      <constructor><![CDATA[
-        if (this.hasAttribute("nameonly") &&
-            this.getAttribute("nameonly") == "true") {
-          this._label.hidden = true;
-        }
-      ]]></constructor>
-
-      <field name="_label">
-        document.getAnonymousElementByAttribute(this, "anonid", "label");
-      </field>
-      <field name="_creatorLink">
-        document.getAnonymousElementByAttribute(this, "anonid", "creator-link");
-      </field>
-      <field name="_creatorName">
-        document.getAnonymousElementByAttribute(this, "anonid", "creator-name");
-      </field>
-
-      <method name="setCreator">
-        <parameter name="aCreator"/>
-        <parameter name="aHomepageURL"/>
-        <body><![CDATA[
-          if (!aCreator) {
-            this.collapsed = true;
-            return;
-          }
-          this.collapsed = false;
-          var url = aCreator.url || aHomepageURL;
-          var showLink = !!url;
-          if (showLink) {
-            this._creatorLink.value = aCreator.name;
-            this._creatorLink.href = url;
-          } else {
-            this._creatorName.value = aCreator.name;
-          }
-          this._creatorLink.hidden = !showLink;
-          this._creatorName.hidden = showLink;
-        ]]></body>
-      </method>
-    </implementation>
-  </binding>
-
-
-  <!-- Install status - Displays the status of an install/upgrade. -->
-  <binding id="install-status">
-    <content>
-      <xul:label anonid="message"/>
-      <xul:box anonid="progress" class="download-progress"/>
-      <xul:button anonid="install-remote-btn" hidden="true"
-                  class="addon-control install" label="&addon.install.label;"
-                  tooltiptext="&addon.install.tooltip;"
-                  oncommand="document.getBindingParent(this).installRemote();"/>
-    </content>
-
-    <implementation>
-      <constructor><![CDATA[
-        if (this.mInstall)
-          this.initWithInstall(this.mInstall);
-        else if (this.mControl.mAddon.install)
-          this.initWithInstall(this.mControl.mAddon.install);
-        else
-          this.refreshState();
-      ]]></constructor>
-
-      <destructor><![CDATA[
-        if (this.mInstall)
-          this.mInstall.removeListener(this);
-      ]]></destructor>
-
-      <field name="_message">
-        document.getAnonymousElementByAttribute(this, "anonid", "message");
-      </field>
-      <field name="_progress">
-        document.getAnonymousElementByAttribute(this, "anonid", "progress");
-      </field>
-      <field name="_installRemote">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "install-remote-btn");
-      </field>
-      <field name="_undo">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "undo-btn");
-      </field>
-
-      <method name="initWithInstall">
-        <parameter name="aInstall"/>
-        <body><![CDATA[
-          if (this.mInstall) {
-            this.mInstall.removeListener(this);
-            this.mInstall = null;
-          }
-          this.mInstall = aInstall;
-          this._progress.mInstall = aInstall;
-          this.refreshState();
-          this.mInstall.addListener(this);
-        ]]></body>
-      </method>
-
-      <method name="refreshState">
-        <body><![CDATA[
-          var showInstallRemote = false;
-
-          if (this.mInstall) {
-            switch (this.mInstall.state) {
-              case AddonManager.STATE_AVAILABLE:
-                if (this.mControl.getAttribute("remote") != "true")
-                  break;
-
-                this._progress.hidden = true;
-                showInstallRemote = true;
-                break;
-              case AddonManager.STATE_DOWNLOADING:
-                this.showMessage("installDownloading");
-                break;
-              case AddonManager.STATE_CHECKING:
-                this.showMessage("installVerifying");
-                break;
-              case AddonManager.STATE_DOWNLOADED:
-                this.showMessage("installDownloaded");
-                break;
-              case AddonManager.STATE_DOWNLOAD_FAILED:
-                // XXXunf expose what error occured (bug 553487)
-                this.showMessage("installDownloadFailed", true);
-                break;
-              case AddonManager.STATE_INSTALLING:
-                this.showMessage("installInstalling");
-                break;
-              case AddonManager.STATE_INSTALL_FAILED:
-                // XXXunf expose what error occured (bug 553487)
-                this.showMessage("installFailed", true);
-                break;
-              case AddonManager.STATE_CANCELLED:
-                this.showMessage("installCancelled", true);
-                break;
-            }
-          }
-
-          this._installRemote.hidden = !showInstallRemote;
-
-          if ("refreshInfo" in this.mControl)
-            this.mControl.refreshInfo();
-        ]]></body>
-      </method>
-
-      <method name="showMessage">
-        <parameter name="aMsgId"/>
-        <parameter name="aHideProgress"/>
-        <body><![CDATA[
-          this._message.setAttribute("hidden", !aHideProgress);
-          this._progress.setAttribute("hidden", !!aHideProgress);
-
-          var msg = gStrings.ext.GetStringFromName(aMsgId);
-          if (aHideProgress)
-            this._message.value = msg;
-          else
-            this._progress.status = msg;
-        ]]></body>
-      </method>
-
-      <method name="installRemote">
-        <body><![CDATA[
-          if (this.mControl.getAttribute("remote") != "true")
-            return;
-
-          delete this.mControl.mAddon;
-          this.mControl.mInstall = this.mInstall;
-          this.mControl.setAttribute("status", "installing");
-          let prompt = Services.prefs.getBoolPref("extensions.webextPermissionPrompts", false);
-          if (prompt) {
-            this.mInstall.promptHandler = info => new Promise((resolve, reject) => {
-              // Skip prompts for non-webextensions
-              if (!info.addon.userPermissions) {
-                resolve();
-                return;
-              }
-              let subject = {
-                wrappedJSObject: {
-                  target: window.docShell.chromeEventHandler,
-                  info: {
-                    addon: info.addon,
-                    source: "AMO",
-                    icon: info.addon.iconURL,
-                    permissions: info.addon.userPermissions,
-                    resolve,
-                    reject,
-                  },
-                },
-              };
-              Services.obs.notifyObservers(subject, "webextension-permission-prompt");
-            });
-          }
-          this.mInstall.install();
-        ]]></body>
-      </method>
-
-      <method name="onDownloadStarted">
-        <body><![CDATA[
-          this.refreshState();
-        ]]></body>
-      </method>
-
-      <method name="onDownloadEnded">
-        <body><![CDATA[
-          this.refreshState();
-        ]]></body>
-      </method>
-
-      <method name="onDownloadFailed">
-        <body><![CDATA[
-          this.refreshState();
-        ]]></body>
-      </method>
-
-      <method name="onDownloadProgress">
-        <body><![CDATA[
-          this._progress.maxProgress = this.mInstall.maxProgress;
-          this._progress.progress = this.mInstall.progress;
-        ]]></body>
-      </method>
-
-      <method name="onInstallStarted">
-        <body><![CDATA[
-          this._progress.progress = 0;
-          this.refreshState();
-        ]]></body>
-      </method>
-
-      <method name="onInstallEnded">
-        <body><![CDATA[
-          this.refreshState();
-          if ("onInstallCompleted" in this.mControl)
-            this.mControl.onInstallCompleted();
-        ]]></body>
-      </method>
-
-      <method name="onInstallFailed">
-        <body><![CDATA[
-          this.refreshState();
-        ]]></body>
-      </method>
-    </implementation>
-  </binding>
-
-
-  <!-- Addon - base - parent binding of any item representing an addon. -->
-  <binding id="addon-base"
-           extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
-    <implementation>
-      <property name="isLegacy" readonly="true">
-        <getter><![CDATA[
-          if (this.mAddon.install) {
-            return false;
-          }
-          return isLegacyExtension(this.mAddon);
-        ]]></getter>
-      </property>
-
-      <method name="hasPermission">
-        <parameter name="aPerm"/>
-        <body><![CDATA[
-          var perm = AddonManager["PERM_CAN_" + aPerm.toUpperCase()];
-          return !!(this.mAddon.permissions & perm);
-        ]]></body>
-      </method>
-
-      <method name="isPending">
-        <parameter name="aAction"/>
-        <body><![CDATA[
-          var action = AddonManager["PENDING_" + aAction.toUpperCase()];
-          return !!(this.mAddon.pendingOperations & action);
-        ]]></body>
-      </method>
-
-      <method name="typeHasFlag">
-        <parameter name="aFlag"/>
-        <body><![CDATA[
-          let flag = AddonManager["TYPE_" + aFlag];
-          let type = AddonManager.addonTypes[this.mAddon.type];
-
-          return !!(type.flags & flag);
-        ]]></body>
-      </method>
-
-      <method name="onUninstalled">
-        <body><![CDATA[
-          this.remove();
-        ]]></body>
-      </method>
-    </implementation>
-  </binding>
-
-
-  <!-- Addon - generic - A normal addon item, or an update to one -->
-  <binding id="addon-generic"
-           extends="chrome://mozapps/content/extensions/extensions.xml#addon-base">
-    <content tooltiptext="&addon.details.tooltip;">
-      <xul:hbox anonid="warning-container"
-                class="warning">
-        <xul:image class="warning-icon"/>
-        <xul:label anonid="warning" flex="1"/>
-        <xul:label anonid="warning-link" is="text-link"/>
-        <xul:button anonid="warning-btn" class="button-link" hidden="true"/>
-        <xul:spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
-      </xul:hbox>
-      <xul:hbox anonid="error-container"
-                class="error">
-        <xul:image class="error-icon"/>
-        <xul:label anonid="error" flex="1"/>
-        <xul:label anonid="error-link" hidden="true" is="text-link"/>
-        <xul:spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
-      </xul:hbox>
-      <xul:hbox anonid="pending-container"
-                class="pending">
-        <xul:image class="pending-icon"/>
-        <xul:label anonid="pending" flex="1"/>
-        <xul:button anonid="undo-btn" class="button-link"
-                    label="&addon.undoAction.label;"
-                    tooltipText="&addon.undoAction.tooltip;"
-                    oncommand="document.getBindingParent(this).undo();"/>
-        <xul:spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
-      </xul:hbox>
-
-      <xul:image class="card-heading-image" anonid="theme-screenshot" xbl:inherits="src=previewURL"/>
-
-      <xul:hbox class="content-container">
-        <xul:vbox class="icon-container">
-          <xul:image anonid="icon" class="icon"/>
-        </xul:vbox>
-        <xul:vbox class="content-inner-container" flex="1">
-          <xul:hbox class="basicinfo-container">
-              <xul:hbox class="name-container">
-                <xul:label anonid="name" class="name" crop="end" flex="1"
-                           tooltip="addonitem-tooltip" xbl:inherits="xbl:text=name"/>
-                <xul:label anonid="legacy" class="legacy-warning" value="&addon.legacy.label;" is="text-link"/>
-                <xul:label class="disabled-postfix" value="&addon.disabled.postfix;"/>
-                <xul:label class="update-postfix" value="&addon.update.postfix;"/>
-                <xul:spacer flex="5000"/> <!-- Necessary to make the name crop -->
-              </xul:hbox>
-            <xul:label anonid="date-updated" class="date-updated"
-                       unknown="&addon.unknownDate;"/>
-          </xul:hbox>
-
-          <xul:hbox class="advancedinfo-container" flex="1">
-            <xul:vbox class="description-outer-container" flex="1">
-              <xul:hbox class="description-container">
-                <xul:label anonid="description" class="description" crop="end" flex="1"/>
-                <xul:spacer flex="5000"/> <!-- Necessary to make the description crop -->
-              </xul:hbox>
-              <xul:hbox class="relnotes-toggle-container">
-                <xul:button anonid="relnotes-toggle-btn" class="relnotes-toggle"
-                            hidden="true" label="&cmd.showReleaseNotes.label;"
-                            tooltiptext="&cmd.showReleaseNotes.tooltip;"
-                            showlabel="&cmd.showReleaseNotes.label;"
-                            showtooltip="&cmd.showReleaseNotes.tooltip;"
-                            hidelabel="&cmd.hideReleaseNotes.label;"
-                            hidetooltip="&cmd.hideReleaseNotes.tooltip;"
-                            oncommand="document.getBindingParent(this).toggleReleaseNotes();"/>
-              </xul:hbox>
-              <xul:vbox anonid="relnotes-container" class="relnotes-container">
-                <xul:label class="relnotes-header" value="&addon.releaseNotes.label;"/>
-                <xul:label anonid="relnotes-loading" value="&addon.loadingReleaseNotes.label;"/>
-                <xul:label anonid="relnotes-error" hidden="true"
-                           value="&addon.errorLoadingReleaseNotes.label;"/>
-                <xul:vbox anonid="relnotes" class="relnotes"/>
-              </xul:vbox>
-            </xul:vbox>
-          </xul:hbox>
-        </xul:vbox>
-        <xul:vbox class="status-control-wrapper">
-          <xul:hbox class="status-container">
-            <xul:hbox anonid="checking-update" hidden="true">
-              <xul:image class="spinner"/>
-              <xul:label value="&addon.checkingForUpdates.label;"/>
-            </xul:hbox>
-            <xul:vbox anonid="update-available" class="update-available"
-                      hidden="true">
-              <xul:checkbox anonid="include-update" class="include-update"
-                            label="&addon.includeUpdate.label;" checked="true"
-                            oncommand="document.getBindingParent(this).onIncludeUpdateChanged();"/>
-              <xul:hbox class="update-info-container">
-                <xul:label class="update-available-notice"
-                           value="&addon.updateAvailable.label;"/>
-                <xul:button anonid="update-btn" class="addon-control update"
-                            label="&addon.updateNow.label;"
-                            tooltiptext="&addon.updateNow.tooltip;"
-                            oncommand="document.getBindingParent(this).upgrade();"/>
-              </xul:hbox>
-            </xul:vbox>
-            <xul:hbox anonid="install-status" class="install-status"
-                      hidden="true"/>
-          </xul:hbox>
-          <xul:hbox anonid="control-container" class="control-container" flex="1">
-            <xul:button anonid="preferences-btn"
-                        class="addon-control preferences"
-#ifdef XP_WIN
-                        label="&cmd.showPreferencesWin.label;"
-                        tooltiptext="&cmd.showPreferencesWin.tooltip;"
-#else
-                        label="&cmd.showPreferencesUnix.label;"
-                        tooltiptext="&cmd.showPreferencesUnix.tooltip;"
-#endif
-                        oncommand="document.getBindingParent(this).showPreferences();"/>
-            <xul:button anonid="enable-btn"  class="addon-control enable"
-                        label="&cmd.enableAddon.label;"
-                        oncommand="document.getBindingParent(this).userDisabled = false;"/>
-            <xul:button anonid="disable-btn" class="addon-control disable"
-                        label="&cmd.disableAddon.label;"
-                        oncommand="document.getBindingParent(this).userDisabled = true;"/>
-            <xul:button anonid="replacement-btn" class="addon-control replacement"
-                        label="&cmd.findReplacement.label;"
-                        oncommand="document.getBindingParent(this).findReplacement();"/>
-            <xul:button anonid="remove-btn" class="addon-control remove"
-                        label="&cmd.uninstallAddon.label;"
-                        oncommand="document.getBindingParent(this).uninstall();"/>
-            <xul:menulist anonid="state-menulist"
-                          class="addon-control state"
-                          flex="1"
-                          tooltiptext="&cmd.stateMenu.tooltip;">
-              <xul:menupopup>
-                <xul:menuitem anonid="ask-to-activate-menuitem"
-                              class="addon-control"
-                              label="&cmd.askToActivate.label;"
-                              tooltiptext="&cmd.askToActivate.tooltip;"
-                              oncommand="document.getBindingParent(this).userDisabled = AddonManager.STATE_ASK_TO_ACTIVATE;"/>
-                <xul:menuitem anonid="always-activate-menuitem"
-                              class="addon-control"
-                              label="&cmd.alwaysActivate.label;"
-                              tooltiptext="&cmd.alwaysActivate.tooltip;"
-                              oncommand="document.getBindingParent(this).userDisabled = false;"/>
-                <xul:menuitem anonid="never-activate-menuitem"
-                              class="addon-control"
-                              label="&cmd.neverActivate.label;"
-                              tooltiptext="&cmd.neverActivate.tooltip;"
-                              oncommand="document.getBindingParent(this).userDisabled = true;"/>
-              </xul:menupopup>
-            </xul:menulist>
-          </xul:hbox>
-        </xul:vbox>
-      </xul:hbox>
-      <xul:hbox class="description-container privateBrowsing-notice-container">
-        <xul:label anonid="privateBrowsing" class="description privateBrowsing-notice" value="&addon.privateBrowsing.label;"/>
-      </xul:hbox>
-    </content>
-
-    <implementation>
-      <constructor><![CDATA[
-        window.customElements.upgrade(this._stateMenulist);
-        window.customElements.upgrade(this._enableBtn);
-        window.customElements.upgrade(this._disableBtn);
-        window.customElements.upgrade(this._askToActivateMenuitem);
-        window.customElements.upgrade(this._alwaysActivateMenuitem);
-        window.customElements.upgrade(this._neverActivateMenuitem);
-
-        this._installStatus = document.getAnonymousElementByAttribute(this, "anonid", "install-status");
-        this._installStatus.mControl = this;
-
-        this.setAttribute("contextmenu", "addonitem-popup");
-
-        this._showStatus("none");
-
-        this._initWithAddon(this.mAddon);
-
-        gEventManager.registerAddonListener(this, this.mAddon.id);
-      ]]></constructor>
-
-      <destructor><![CDATA[
-        gEventManager.unregisterAddonListener(this, this.mAddon.id);
-      ]]></destructor>
-
-      <field name="_warningContainer">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "warning-container");
-      </field>
-      <field name="_warning">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "warning");
-      </field>
-      <field name="_warningLink">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "warning-link");
-      </field>
-      <field name="_warningBtn">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "warning-btn");
-      </field>
-      <field name="_errorContainer">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "error-container");
-      </field>
-      <field name="_error">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "error");
-      </field>
-      <field name="_errorLink">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "error-link");
-      </field>
-      <field name="_pendingContainer">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "pending-container");
-      </field>
-      <field name="_pending">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "pending");
-      </field>
-      <field name="_infoContainer">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "info-container");
-      </field>
-      <field name="_info">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "info");
-      </field>
-      <field name="_icon">
-        document.getAnonymousElementByAttribute(this, "anonid", "icon");
-      </field>
-      <field name="_dateUpdated">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "date-updated");
-      </field>
-      <field name="_description">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "description");
-      </field>
-      <field name="_stateMenulist">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "state-menulist");
-      </field>
-      <field name="_askToActivateMenuitem">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "ask-to-activate-menuitem");
-      </field>
-      <field name="_alwaysActivateMenuitem">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "always-activate-menuitem");
-      </field>
-      <field name="_neverActivateMenuitem">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "never-activate-menuitem");
-      </field>
-      <field name="_preferencesBtn">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "preferences-btn");
-      </field>
-      <field name="_enableBtn">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "enable-btn");
-      </field>
-      <field name="_disableBtn">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "disable-btn");
-      </field>
-      <field name="_removeBtn">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "remove-btn");
-      </field>
-      <field name="_updateBtn">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "update-btn");
-      </field>
-      <field name="_controlContainer">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "control-container");
-      </field>
-      <field name="_installStatus">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "install-status");
-      </field>
-      <field name="_checkingUpdate">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "checking-update");
-      </field>
-      <field name="_updateAvailable">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "update-available");
-      </field>
-      <field name="_includeUpdate">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "include-update");
-      </field>
-      <field name="_relNotesLoaded">false</field>
-      <field name="_relNotesToggle">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "relnotes-toggle-btn");
-      </field>
-      <field name="_relNotesLoading">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "relnotes-loading");
-      </field>
-      <field name="_relNotesError">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "relnotes-error");
-      </field>
-      <field name="_relNotesContainer">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "relnotes-container");
-      </field>
-      <field name="_relNotes">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "relnotes");
-      </field>
-
-      <property name="userDisabled">
-        <getter><![CDATA[
-          return this.mAddon.userDisabled;
-        ]]></getter>
-        <setter><![CDATA[
-          if (val === true) {
-            gViewController.commands.cmd_disableItem.doCommand(this.mAddon);
-          } else if (val === false) {
-            gViewController.commands.cmd_enableItem.doCommand(this.mAddon);
-          } else {
-            this.mAddon.userDisabled = val;
-          }
-        ]]></setter>
-      </property>
-
-      <property name="includeUpdate">
-        <getter><![CDATA[
-          return this._includeUpdate.checked && !!this.mManualUpdate;
-        ]]></getter>
-        <setter><![CDATA[
-          // XXXunf Eventually, we'll want to persist this for individual
-          //        updates - see bug 594619.
-          this._includeUpdate.checked = !!val;
-        ]]></setter>
-      </property>
-
-      <method name="_initWithAddon">
-        <parameter name="aAddon"/>
-        <body><![CDATA[
-          this.mAddon = aAddon;
-
-          this._installStatus.mAddon = this.mAddon;
-          this._updateDates();
-          this._updateState();
-
-          this.setAttribute("name", aAddon.name);
-
-          var iconURL = AddonManager.getPreferredIconURL(aAddon, 24, window);
-          if (iconURL)
-            this._icon.src = iconURL;
-          else
-            this._icon.src = "";
-
-          if (this.mAddon.description)
-            this._description.value = this.mAddon.description;
-          else
-            this._description.hidden = true;
-
-          // Set a previewURL for themes if one exists.
-          let previewURL = this.mAddon.type == "theme" &&
-            this.mAddon.screenshots &&
-            this.mAddon.screenshots[0] &&
-            this.mAddon.screenshots[0].url;
-          this.setAttribute("previewURL", previewURL ? previewURL : "");
-          this.setAttribute("hasPreview", previewURL ? "true" : "fase");
-
-          let legacyWarning = legacyExtensionsEnabled && !this.mAddon.install &&
-            isLegacyExtension(this.mAddon);
-          this.setAttribute("legacy", legacyWarning);
-          document.getAnonymousElementByAttribute(this, "anonid", "legacy").href = SUPPORT_URL + "webextensions";
-
-          if (!allowPrivateBrowsingByDefault && this.mAddon.type === "extension") {
-            ExtensionPermissions.get(this.mAddon.id).then((perms) => {
-              let allowed = perms.permissions.includes("internal:privateBrowsingAllowed");
-              this.setAttribute("privateBrowsing", allowed);
-              if (!allowed && PrivateBrowsingUtils.isContentWindowPrivate(window)) {
-                // Hide the preferences button if the current window is
-                // private and the addon is not allowed to access it.
-                this._preferencesBtn.hidden = true;
-              }
-            });
-          }
-
-          if (!("applyBackgroundUpdates" in this.mAddon) ||
-              (this.mAddon.applyBackgroundUpdates == AddonManager.AUTOUPDATE_DISABLE ||
-               (this.mAddon.applyBackgroundUpdates == AddonManager.AUTOUPDATE_DEFAULT &&
-                !AddonManager.autoUpdateDefault))) {
-            AddonManager.getAllInstalls().then(aInstallsList => {
-              // This can return after the binding has been destroyed,
-              // so try to detect that and return early
-              if (!("onNewInstall" in this))
-                return;
-              for (let install of aInstallsList) {
-                if (install.existingAddon &&
-                    install.existingAddon.id == this.mAddon.id &&
-                    install.state == AddonManager.STATE_AVAILABLE) {
-                  this.onNewInstall(install);
-                  this.onIncludeUpdateChanged();
-                }
-              }
-            });
-          }
-        ]]></body>
-      </method>
-
-      <method name="_showStatus">
-        <parameter name="aType"/>
-        <body><![CDATA[
-          this._controlContainer.hidden = aType != "none" &&
-                                          !(aType == "update-available" && !this.hasAttribute("upgrade"));
-
-          this._installStatus.hidden = aType != "progress";
-          if (aType == "progress")
-            this._installStatus.refreshState();
-          this._checkingUpdate.hidden = aType != "checking-update";
-          this._updateAvailable.hidden = aType != "update-available";
-          this._relNotesToggle.hidden = !(this.mManualUpdate ?
-                                          this.mManualUpdate.releaseNotesURI :
-                                          this.mAddon.releaseNotesURI);
-        ]]></body>
-      </method>
-
-      <method name="_updateDates">
-        <body><![CDATA[
-          function formatDate(aDate) {
-            const dtOptions = { year: "numeric", month: "long", day: "numeric" };
-            return aDate.toLocaleDateString(undefined, dtOptions);
-          }
-
-          if (this.mAddon.updateDate)
-            this._dateUpdated.value = formatDate(this.mAddon.updateDate);
-          else
-            this._dateUpdated.value = this._dateUpdated.getAttribute("unknown");
-        ]]></body>
-      </method>
-
-      <method name="_updateState">
-        <body><![CDATA[
-          if (this.parentNode.selectedItem == this)
-            gViewController.updateCommands();
-
-          var pending = this.mAddon.pendingOperations;
-          if (pending & AddonManager.PENDING_UNINSTALL) {
-            this.removeAttribute("notification");
-
-            // We don't care about pending operations other than uninstall.
-            // They're transient, and cannot be undone.
-            this.setAttribute("pending", "uninstall");
-            this._pending.textContent = gStrings.ext.formatStringFromName(
-              "notification.restartless-uninstall",
-              [this.mAddon.name]);
-          } else {
-            this.removeAttribute("pending");
-
-            var isUpgrade = this.hasAttribute("upgrade");
-            var install = this._installStatus.mInstall;
-
-            if (install && install.state == AddonManager.STATE_DOWNLOAD_FAILED) {
-              this.setAttribute("notification", "warning");
-              this._warning.textContent = gStrings.ext.formatStringFromName(
-                "notification.downloadError",
-                [this.mAddon.name]
-              );
-              this._warningBtn.label = gStrings.ext.GetStringFromName("notification.downloadError.retry");
-              this._warningBtn.tooltipText = gStrings.ext.GetStringFromName("notification.downloadError.retry.tooltip");
-              this._warningBtn.setAttribute("oncommand", "document.getBindingParent(this).retryInstall();");
-              this._warningBtn.hidden = false;
-              this._warningLink.hidden = true;
-            } else if (install && install.state == AddonManager.STATE_INSTALL_FAILED) {
-              this.setAttribute("notification", "warning");
-              this._warning.textContent = gStrings.ext.formatStringFromName(
-                "notification.installError",
-                [this.mAddon.name]
-              );
-              this._warningBtn.label = gStrings.ext.GetStringFromName("notification.installError.retry");
-              this._warningBtn.tooltipText = gStrings.ext.GetStringFromName("notification.downloadError.retry.tooltip");
-              this._warningBtn.setAttribute("oncommand", "document.getBindingParent(this).retryInstall();");
-              this._warningBtn.hidden = false;
-              this._warningLink.hidden = true;
-            } else if (!isUpgrade && this.mAddon.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED) {
-              this.setAttribute("notification", "error");
-              this._error.textContent = gStrings.ext.formatStringFromName(
-                "notification.blocked",
-                [this.mAddon.name]
-              );
-              this._errorLink.value = gStrings.ext.GetStringFromName("notification.blocked.link");
-              this.mAddon.getBlocklistURL().then(url => {
-                this._errorLink.href = url;
-                this._errorLink.hidden = false;
-              });
-            } else if (!isUpgrade && isDisabledUnsigned(this.mAddon)) {
-              this.setAttribute("notification", "error");
-              this._error.textContent = gStrings.ext.formatStringFromName(
-                "notification.unsignedAndDisabled", [this.mAddon.name, gStrings.brandShortName]
-              );
-              this._errorLink.value = gStrings.ext.GetStringFromName("notification.unsigned.link");
-              this._errorLink.href = SUPPORT_URL + "unsigned-addons";
-              this._errorLink.hidden = false;
-            } else if ((!isUpgrade && !this.mAddon.isCompatible) && (AddonManager.checkCompatibility
-            || (this.mAddon.blocklistState != Ci.nsIBlocklistService.STATE_SOFTBLOCKED))) {
-              this.setAttribute("notification", "warning");
-              this._warning.textContent = gStrings.ext.formatStringFromName(
-                "notification.incompatible",
-                [this.mAddon.name, gStrings.brandShortName, gStrings.appVersion]
-              );
-              this._warningLink.hidden = true;
-              this._warningBtn.hidden = true;
-            } else if (!isUpgrade && !isCorrectlySigned(this.mAddon)) {
-              this.setAttribute("notification", "warning");
-              this._warning.textContent = gStrings.ext.formatStringFromName(
-                "notification.unsigned", [this.mAddon.name, gStrings.brandShortName]
-              );
-              this._warningLink.value = gStrings.ext.GetStringFromName("notification.unsigned.link");
-              this._warningLink.href = SUPPORT_URL + "unsigned-addons";
-              this._warningLink.hidden = false;
-            } else if (!isUpgrade && this.mAddon.blocklistState == Ci.nsIBlocklistService.STATE_SOFTBLOCKED) {
-              this.setAttribute("notification", "warning");
-              this._warning.textContent = gStrings.ext.formatStringFromName(
-                "notification.softblocked",
-                [this.mAddon.name]
-              );
-              this._warningLink.value = gStrings.ext.GetStringFromName("notification.softblocked.link");
-              this.mAddon.getBlocklistURL().then(url => {
-                this._warningLink.href = url;
-                this._warningLink.hidden = false;
-              });
-              this._warningBtn.hidden = true;
-            } else if (!isUpgrade && this.mAddon.blocklistState == Ci.nsIBlocklistService.STATE_OUTDATED) {
-              this.setAttribute("notification", "warning");
-              this._warning.textContent = gStrings.ext.formatStringFromName(
-                "notification.outdated",
-                [this.mAddon.name]
-              );
-              this._warningLink.value = gStrings.ext.GetStringFromName("notification.outdated.link");
-              this.mAddon.getBlocklistURL().then(url => {
-                this._warningLink.href = url;
-                this._warningLink.hidden = false;
-              });
-              this._warningBtn.hidden = true;
-            } else if (!isUpgrade && this.mAddon.blocklistState == Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE) {
-              this.setAttribute("notification", "error");
-              this._error.textContent = gStrings.ext.formatStringFromName(
-                "notification.vulnerableUpdatable",
-                [this.mAddon.name]
-              );
-              this._errorLink.value = gStrings.ext.GetStringFromName("notification.vulnerableUpdatable.link");
-              this.mAddon.getBlocklistURL().then(url => {
-                this._errorLink.href = url;
-                this._errorLink.hidden = false;
-              });
-            } else if (!isUpgrade && this.mAddon.blocklistState == Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE) {
-              this.setAttribute("notification", "error");
-              this._error.textContent = gStrings.ext.formatStringFromName(
-                "notification.vulnerableNoUpdate",
-                [this.mAddon.name]
-              );
-              this._errorLink.value = gStrings.ext.GetStringFromName("notification.vulnerableNoUpdate.link");
-              this.mAddon.getBlocklistURL().then(url => {
-                this._errorLink.href = url;
-                this._errorLink.hidden = false;
-              });
-            } else if (this.mAddon.isGMPlugin && !this.mAddon.isInstalled &&
-                       this.mAddon.isActive) {
-              this.setAttribute("notification", "warning");
-              this._warning.textContent =
-                gStrings.ext.formatStringFromName("notification.gmpPending",
-                                                  [this.mAddon.name]);
-            } else {
-              this.removeAttribute("notification");
-            }
-          }
-
-          this._preferencesBtn.hidden = !this.mAddon.optionsType && this.mAddon.type != "plugin";
-
-          if (this.typeHasFlag("SUPPORTS_ASK_TO_ACTIVATE")) {
-            this._enableBtn.disabled = true;
-            this._disableBtn.disabled = true;
-            this._askToActivateMenuitem.disabled = !this.hasPermission("ask_to_activate");
-            let alwaysActivateProp = this.mAddon.isFlashPlugin ? "hidden" : "disabled";
-            this._alwaysActivateMenuitem[alwaysActivateProp] = !this.hasPermission("enable");
-            this._neverActivateMenuitem.disabled = !this.hasPermission("disable");
-            if (!this.mAddon.isActive) {
-              this._stateMenulist.selectedItem = this._neverActivateMenuitem;
-            } else if (this.mAddon.userDisabled == AddonManager.STATE_ASK_TO_ACTIVATE) {
-              this._stateMenulist.selectedItem = this._askToActivateMenuitem;
-            } else {
-              this._stateMenulist.selectedItem = this._alwaysActivateMenuitem;
-            }
-            let hasActivatePermission =
-              ["ask_to_activate", "enable", "disable"].some(perm => this.hasPermission(perm));
-            this._stateMenulist.disabled = !hasActivatePermission;
-            this._stateMenulist.hidden = false;
-            this._askToActivateMenuitem.classList.add("no-auto-hide");
-            this._alwaysActivateMenuitem.classList.add("no-auto-hide");
-            this._neverActivateMenuitem.classList.add("no-auto-hide");
-            this._stateMenulist.classList.add("no-auto-hide");
-          } else {
-            this._stateMenulist.hidden = true;
-
-            let enableTooltip = gViewController.commands.cmd_enableItem
-                                               .getTooltip(this.mAddon);
-            this._enableBtn.setAttribute("tooltiptext", enableTooltip);
-            if (this.hasPermission("enable")) {
-              this._enableBtn.hidden = false;
-            } else {
-              this._enableBtn.hidden = true;
-            }
-
-            let disableTooltip = gViewController.commands.cmd_disableItem
-                                                .getTooltip(this.mAddon);
-            this._disableBtn.setAttribute("tooltiptext", disableTooltip);
-            if (this.hasPermission("disable")) {
-              this._disableBtn.hidden = false;
-            } else {
-              this._disableBtn.hidden = true;
-            }
-          }
-
-          let uninstallTooltip = gViewController.commands.cmd_uninstallItem
-                                                .getTooltip(this.mAddon);
-          this._removeBtn.setAttribute("tooltiptext", uninstallTooltip);
-          if (this.hasPermission("uninstall")) {
-            this._removeBtn.hidden = false;
-          } else {
-            this._removeBtn.hidden = true;
-          }
-
-          this.setAttribute("active", this.mAddon.isActive);
-
-          var showProgress = (this.mAddon.install &&
-                              this.mAddon.install.state != AddonManager.STATE_INSTALLED);
-          this._showStatus(showProgress ? "progress" : "none");
-        ]]></body>
-      </method>
-
-      <method name="_fetchReleaseNotes">
-        <parameter name="aURI"/>
-        <body><![CDATA[
-          let sendToggleEvent = () => {
-            var event = document.createEvent("Events");
-            event.initEvent("RelNotesToggle", true, true);
-            this.dispatchEvent(event);
-          };
-
-          if (!aURI || this._relNotesLoaded) {
-            sendToggleEvent();
-            return;
-          }
-
-          this._relNotesLoaded = true;
-          this._relNotesLoading.hidden = false;
-          this._relNotesError.hidden = true;
-
-          loadReleaseNotes(aURI).then(fragment => {
-            this._relNotesLoading.hidden = true;
-            this._relNotes.appendChild(fragment);
-            if (this.hasAttribute("show-relnotes")) {
-              var container = this._relNotesContainer;
-              container.style.height = container.scrollHeight + "px";
-            }
-            sendToggleEvent();
-          }, () => {
-            this._relNotesLoading.hidden = true;
-            this._relNotesError.hidden = false;
-            this._relNotesLoaded = false; // allow loading to be re-tried
-            sendToggleEvent();
-          });
-        ]]></body>
-      </method>
-
-      <method name="toggleReleaseNotes">
-        <body><![CDATA[
-          if (this.hasAttribute("show-relnotes")) {
-            this._relNotesContainer.style.height = "0px";
-            this.removeAttribute("show-relnotes");
-            this._relNotesToggle.setAttribute(
-              "label",
-              this._relNotesToggle.getAttribute("showlabel")
-            );
-            this._relNotesToggle.setAttribute(
-              "tooltiptext",
-              this._relNotesToggle.getAttribute("showtooltip")
-            );
-            let event = document.createEvent("Events");
-            event.initEvent("RelNotesToggle", true, true);
-            this.dispatchEvent(event);
-          } else {
-            this._relNotesContainer.style.height = this._relNotesContainer.scrollHeight +
-                                                   "px";
-            this.setAttribute("show-relnotes", true);
-            this._relNotesToggle.setAttribute(
-              "label",
-              this._relNotesToggle.getAttribute("hidelabel")
-            );
-            this._relNotesToggle.setAttribute(
-              "tooltiptext",
-              this._relNotesToggle.getAttribute("hidetooltip")
-            );
-            var uri = this.mManualUpdate ?
-                      this.mManualUpdate.releaseNotesURI :
-                      this.mAddon.releaseNotesURI;
-            this._fetchReleaseNotes(uri);
-
-            // Dispatch an event so extensions.js can record telemetry.
-            let event = document.createEvent("Events");
-            event.initEvent("RelNotesShow", true, true);
-            this.dispatchEvent(event);
-          }
-        ]]></body>
-      </method>
-
-      <method name="undo">
-        <body><![CDATA[
-          gViewController.commands.cmd_cancelOperation.doCommand(this.mAddon);
-        ]]></body>
-      </method>
-
-      <method name="uninstall">
-        <body><![CDATA[
-          // If the type doesn't support undoing of restartless uninstalls,
-          // then we fake it by just disabling it it, and doing the real
-          // uninstall later.
-          if (this.typeHasFlag("SUPPORTS_UNDO_RESTARTLESS_UNINSTALL")) {
-            this.mAddon.uninstall(true);
-          } else {
-            this.setAttribute("wasDisabled", this.mAddon.userDisabled);
-
-            // We must set userDisabled to true first, this will call
-            // _updateState which will clear any pending attribute set.
-            this.mAddon.disable().then(() => {
-              // This won't update any other add-on manager views (bug 582002)
-              this.setAttribute("pending", "uninstall");
-            });
-          }
-
-          // Dispatch an event so extensions.js can track telemetry.
-          var event = document.createEvent("Events");
-          event.initEvent("Uninstall", true, true);
-          this.dispatchEvent(event);
-        ]]></body>
-      </method>
-
-      <method name="showPreferences">
-        <body><![CDATA[
-          gViewController.doCommand("cmd_showItemPreferences", this.mAddon);
-        ]]></body>
-      </method>
-
-      <method name="upgrade">
-        <body><![CDATA[
-          var install = this.mManualUpdate;
-          delete this.mManualUpdate;
-          install.install();
-        ]]></body>
-      </method>
-
-      <method name="retryInstall">
-        <body><![CDATA[
-          var install = this._installStatus.mInstall;
-          if (!install)
-            return;
-          if (install.state != AddonManager.STATE_DOWNLOAD_FAILED &&
-              install.state != AddonManager.STATE_INSTALL_FAILED)
-            return;
-          install.install();
-        ]]></body>
-      </method>
-
-      <method name="showInDetailView">
-        <body><![CDATA[
-          gViewController.loadView("addons://detail/" +
-                                   encodeURIComponent(this.mAddon.id));
-        ]]></body>
-      </method>
-
-      <method name="findReplacement">
-        <body><![CDATA[
-          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);
-        ]]></body>
-      </method>
-
-      <method name="onEnabling">
-        <body><![CDATA[
-          this._updateState();
-        ]]></body>
-      </method>
-
-      <method name="onEnabled">
-        <body><![CDATA[
-          this._updateState();
-        ]]></body>
-      </method>
-
-      <method name="onDisabling">
-        <body><![CDATA[
-          this._updateState();
-        ]]></body>
-      </method>
-
-      <method name="onDisabled">
-        <body><![CDATA[
-          this._updateState();
-        ]]></body>
-      </method>
-
-      <method name="onUninstalling">
-        <body><![CDATA[
-          this._updateState();
-        ]]></body>
-      </method>
-
-      <method name="onOperationCancelled">
-        <body><![CDATA[
-          this._updateState();
-        ]]></body>
-      </method>
-
-      <method name="onPropertyChanged">
-        <parameter name="aProperties"/>
-        <body><![CDATA[
-          if (aProperties.includes("appDisabled") ||
-              aProperties.includes("signedState") ||
-              aProperties.includes("userDisabled"))
-            this._updateState();
-        ]]></body>
-      </method>
-
-      <method name="onUpdateAvailable">
-        <body><![CDATA[
-          this._showStatus("update-available");
-        ]]></body>
-      </method>
-
-      <method name="onNoUpdateAvailable">
-        <body><![CDATA[
-          this._showStatus("none");
-        ]]></body>
-      </method>
-
-      <method name="onCheckingUpdate">
-        <body><![CDATA[
-          this._showStatus("checking-update");
-        ]]></body>
-      </method>
-
-      <method name="onCompatibilityUpdateAvailable">
-        <body><![CDATA[
-          this._updateState();
-        ]]></body>
-      </method>
-
-      <method name="onExternalInstall">
-        <parameter name="aAddon"/>
-        <parameter name="aExistingAddon"/>
-        <body><![CDATA[
-          if (aExistingAddon.id != this.mAddon.id)
-            return;
-
-          this._initWithAddon(aAddon);
-        ]]></body>
-      </method>
-
-      <method name="onNewInstall">
-        <parameter name="aInstall"/>
-        <body><![CDATA[
-          if (this.mAddon.applyBackgroundUpdates == AddonManager.AUTOUPDATE_ENABLE)
-            return;
-          if (this.mAddon.applyBackgroundUpdates == AddonManager.AUTOUPDATE_DEFAULT &&
-              AddonManager.autoUpdateDefault)
-            return;
-
-          this.mManualUpdate = aInstall;
-          this._showStatus("update-available");
-        ]]></body>
-      </method>
-
-      <method name="onDownloadStarted">
-        <parameter name="aInstall"/>
-        <body><![CDATA[
-          this._updateState();
-          this._showStatus("progress");
-          this._installStatus.initWithInstall(aInstall);
-        ]]></body>
-      </method>
-
-      <method name="onInstallStarted">
-        <parameter name="aInstall"/>
-        <body><![CDATA[
-          this._updateState();
-          this._showStatus("progress");
-          this._installStatus.initWithInstall(aInstall);
-        ]]></body>
-      </method>
-
-      <method name="onInstallEnded">
-        <parameter name="aInstall"/>
-        <parameter name="aAddon"/>
-        <body><![CDATA[
-          this._initWithAddon(aAddon);
-        ]]></body>
-      </method>
-
-      <method name="onDownloadFailed">
-        <body><![CDATA[
-            this._updateState();
-        ]]></body>
-      </method>
-
-      <method name="onInstallFailed">
-        <body><![CDATA[
-            this._updateState();
-        ]]></body>
-      </method>
-
-      <method name="onInstallCancelled">
-        <body><![CDATA[
-            this._updateState();
-        ]]></body>
-      </method>
-    </implementation>
-
-    <handlers>
-      <handler event="click" button="0"><![CDATA[
-        if (!["button", "checkbox", "menulist", "menuitem"].includes(event.originalTarget.localName) &&
-            !event.originalTarget.classList.contains("text-link") &&
-            // Treat the relnotes container as embedded text instead of a click target.
-            !event.originalTarget.closest(".relnotes-container")) {
-          this.showInDetailView();
-        } else if (event.originalTarget.localName == "a" &&
-                   event.originalTarget.closest(".relnotes-container") &&
-                   event.originalTarget.href) {
-          event.preventDefault();
-          event.stopPropagation();
-          openURL(event.originalTarget.href);
-        }
-      ]]></handler>
-    </handlers>
-  </binding>
-
-
-  <!-- Addon - uninstalled - An uninstalled addon that can be re-installed. -->
-  <binding id="addon-uninstalled"
-           extends="chrome://mozapps/content/extensions/extensions.xml#addon-base">
-    <content>
-      <xul:hbox class="pending">
-        <xul:image class="pending-icon"/>
-        <xul:label anonid="notice" flex="1"/>
-        <xul:button anonid="undo-btn" class="button-link"
-                    label="&addon.undoRemove.label;"
-                    tooltiptext="&addon.undoRemove.tooltip;"
-                    oncommand="document.getBindingParent(this).cancelUninstall();"/>
-        <xul:spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
-      </xul:hbox>
-    </content>
-
-    <implementation>
-      <constructor><![CDATA[
-        this._notice.textContent = gStrings.ext.formatStringFromName("uninstallNotice",
-                                                                     [this.mAddon.name]);
-
-        gEventManager.registerAddonListener(this, this.mAddon.id);
-      ]]></constructor>
-
-      <destructor><![CDATA[
-        gEventManager.unregisterAddonListener(this, this.mAddon.id);
-      ]]></destructor>
-
-      <field name="_notice" readonly="true">
-        document.getAnonymousElementByAttribute(this, "anonid", "notice");
-      </field>
-
-      <method name="cancelUninstall">
-        <body><![CDATA[
-          // This assumes that disabling does not require a restart when
-          // uninstalling doesn't. Things will still work if not, the add-on
-          // will just still be active until finally getting uninstalled.
-
-          if (this.isPending("uninstall"))
-            this.mAddon.cancelUninstall();
-          else if (this.getAttribute("wasDisabled") != "true")
-            this.mAddon.enable();
-
-          // Dispatch an event so extensions.js can record telemetry.
-          var event = document.createEvent("Events");
-          event.initEvent("Undo", true, true);
-          this.dispatchEvent(event);
-
-          this.removeAttribute("pending");
-        ]]></body>
-      </method>
-
-      <method name="onExternalInstall">
-        <parameter name="aAddon"/>
-        <parameter name="aExistingAddon"/>
-        <body><![CDATA[
-          if (aExistingAddon.id != this.mAddon.id)
-            return;
-
-          // Make sure any newly installed add-on has the correct disabled state
-          if (this.hasAttribute("wasDisabled")) {
-            if (this.getAttribute("wasDisabled") == "true")
-              aAddon.disable();
-            else
-              aAddon.enable();
-          }
-
-          this.mAddon = aAddon;
-
-          this.removeAttribute("pending");
-        ]]></body>
-      </method>
-
-      <method name="onInstallStarted">
-        <parameter name="aInstall"/>
-        <body><![CDATA[
-          // Make sure any newly installed add-on has the correct disabled state
-          if (this.hasAttribute("wasDisabled")) {
-            if (this.getAttribute("wasDisabled") == "true")
-              aInstall.addon.disable();
-            else
-              aInstall.addon.enable();
-          }
-        ]]></body>
-      </method>
-
-      <method name="onInstallEnded">
-        <parameter name="aInstall"/>
-        <parameter name="aAddon"/>
-        <body><![CDATA[
-          this.mAddon = aAddon;
-
-          this.removeAttribute("pending");
-        ]]></body>
-      </method>
-    </implementation>
-  </binding>
-
-
-  <!-- Addon - installing - an addon item that is currently being installed -->
-  <binding id="addon-installing"
-           extends="chrome://mozapps/content/extensions/extensions.xml#addon-base">
-    <content>
-      <xul:hbox anonid="warning-container" class="warning">
-        <xul:image class="warning-icon"/>
-        <xul:label anonid="warning" flex="1"/>
-        <xul:button anonid="warning-link" class="button-link"
-                   oncommand="document.getBindingParent(this).retryInstall();"/>
-        <xul:spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
-      </xul:hbox>
-      <xul:hbox class="content-container">
-        <xul:vbox class="icon-outer-container">
-          <xul:vbox class="icon-container">
-            <xul:image anonid="icon" class="icon"/>
-          </xul:vbox>
-        </xul:vbox>
-        <xul:vbox class="fade name-outer-container" flex="1">
-          <xul:hbox class="name-container">
-            <xul:label anonid="name" class="name" crop="end" tooltip="addonitem-tooltip"/>
-          </xul:hbox>
-        </xul:vbox>
-        <xul:vbox class="install-status-container">
-          <xul:hbox anonid="install-status" class="install-status"/>
-        </xul:vbox>
-      </xul:hbox>
-    </content>
-
-    <implementation>
-      <constructor><![CDATA[
-        this._installStatus.mControl = this;
-        this._installStatus.mInstall = this.mInstall;
-        this.refreshInfo();
-      ]]></constructor>
-
-      <field name="_icon">
-        document.getAnonymousElementByAttribute(this, "anonid", "icon");
-      </field>
-      <field name="_name">
-        document.getAnonymousElementByAttribute(this, "anonid", "name");
-      </field>
-      <field name="_warning">
-        document.getAnonymousElementByAttribute(this, "anonid", "warning");
-      </field>
-      <field name="_warningLink">
-        document.getAnonymousElementByAttribute(this, "anonid", "warning-link");
-      </field>
-      <field name="_installStatus">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "install-status");
-      </field>
-
-      <method name="onInstallCompleted">
-        <body><![CDATA[
-          this.mAddon = this.mInstall.addon;
-          this.setAttribute("name", this.mAddon.name);
-          this.setAttribute("value", this.mAddon.id);
-          this.setAttribute("status", "installed");
-        ]]></body>
-      </method>
-
-      <method name="refreshInfo">
-        <body><![CDATA[
-          this.mAddon = this.mAddon || this.mInstall.addon;
-          if (this.mAddon) {
-            this._icon.src = this.mAddon.iconURL ||
-                             (this.mInstall ? this.mInstall.iconURL : "");
-            this._name.value = this.mAddon.name;
-          } else {
-            this._icon.src = this.mInstall.iconURL;
-            // AddonInstall.name isn't always available - fallback to filename
-            if (this.mInstall.name) {
-              this._name.value = this.mInstall.name;
-            } else if (this.mInstall.sourceURI) {
-              var url = Cc["@mozilla.org/network/standard-url-mutator;1"]
-                          .createInstance(Ci.nsIStandardURLMutator)
-                          .init(Ci.nsIStandardURL.URLTYPE_STANDARD,
-                                80, this.mInstall.sourceURI.spec,
-                                null, null)
-                          .finalize()
-                          .QueryInterface(Ci.nsIURL);
-              this._name.value = url.fileName;
-            }
-          }
-
-          if (this.mInstall.state == AddonManager.STATE_DOWNLOAD_FAILED) {
-            this.setAttribute("notification", "warning");
-            this._warning.textContent = gStrings.ext.formatStringFromName(
-              "notification.downloadError",
-              [this._name.value]
-            );
-            this._warningLink.label = gStrings.ext.GetStringFromName("notification.downloadError.retry");
-            this._warningLink.tooltipText = gStrings.ext.GetStringFromName("notification.downloadError.retry.tooltip");
-          } else if (this.mInstall.state == AddonManager.STATE_INSTALL_FAILED) {
-            this.setAttribute("notification", "warning");
-            this._warning.textContent = gStrings.ext.formatStringFromName(
-              "notification.installError",
-              [this._name.value]
-            );
-            this._warningLink.label = gStrings.ext.GetStringFromName("notification.installError.retry");
-            this._warningLink.tooltipText = gStrings.ext.GetStringFromName("notification.downloadError.retry.tooltip");
-          } else {
-            this.removeAttribute("notification");
-          }
-        ]]></body>
-      </method>
-
-      <method name="retryInstall">
-        <body><![CDATA[
-          this.mInstall.install();
-        ]]></body>
-      </method>
-    </implementation>
-  </binding>
-
-  <binding id="detail-row">
-    <content>
-      <xul:label class="detail-row-label" xbl:inherits="value=label"/>
-      <xul:label class="detail-row-value" xbl:inherits="value"/>
-    </content>
-
-    <implementation>
-      <property name="value">
-        <getter><![CDATA[
-          return this.getAttribute("value");
-        ]]></getter>
-        <setter><![CDATA[
-          if (!val)
-            this.removeAttribute("value");
-          else
-            this.setAttribute("value", val);
-        ]]></setter>
-      </property>
-    </implementation>
-  </binding>
-
 </bindings>
--- a/toolkit/mozapps/extensions/content/extensions.xul
+++ b/toolkit/mozapps/extensions/content/extensions.xul
@@ -31,42 +31,16 @@
   </linkset>
   
   <script src="chrome://global/content/contentAreaUtils.js"/>
   <script src="chrome://mozapps/content/extensions/aboutaddonsCommon.js"/>
   <script src="chrome://mozapps/content/extensions/extensions.js"/>
   <script src="chrome://mozapps/content/extensions/abuse-report-frame.js"/>
 
   <popupset>
-    <!-- menu for an addon item -->
-    <menupopup id="addonitem-popup">
-      <menuitem id="menuitem_showDetails" command="cmd_showItemDetails"
-                default="true" data-l10n-id="cmd-show-details"/>
-      <menuitem id="menuitem_enableItem" command="cmd_enableItem"
-                label="&cmd.enableAddon.label;"
-                accesskey="&cmd.enableAddon.accesskey;"/>
-      <menuitem id="menuitem_disableItem" command="cmd_disableItem"
-                label="&cmd.disableAddon.label;"
-                accesskey="&cmd.disableAddon.accesskey;"/>
-      <menuitem id="menuitem_enableTheme" command="cmd_enableItem"
-                data-l10n-id="cmd-enable-theme"/>
-      <menuitem id="menuitem_disableTheme" command="cmd_disableItem"
-                data-l10n-id="cmd-disable-theme"/>
-      <menuitem id="menuitem_installItem" command="cmd_installItem"
-                data-l10n-id="cmd-install-addon"/>
-      <menuitem id="menuitem_uninstallItem" command="cmd_uninstallItem"
-                label="&cmd.uninstallAddon.label;"
-                accesskey="&cmd.uninstallAddon.accesskey;"/>
-      <menuseparator id="addonitem-menuseparator" />
-      <menuitem id="menuitem_preferences" command="cmd_showItemPreferences"
-                data-l10n-id="cmd-preferences"/>
-      <menuitem id="menuitem_findUpdates" command="cmd_findItemUpdates"
-                data-l10n-id="cmd-find-updates"/>
-    </menupopup>
-
     <menulist popuponly="true" id="ContentSelectDropdown" hidden="true">
       <menupopup rolluponmousewheel="true"
                  activateontab="true" position="after_start"
                  level="parent"
 #ifdef XP_WIN
                  consumeoutsideclicks="false" ignorekeys="shortcuts"
 #endif
         />
@@ -75,85 +49,59 @@
     <panel is="autocomplete-richlistbox-popup"
            type="autocomplete-richlistbox"
            id="PopupAutoComplete"
            noautofocus="true"
            hidden="true"
            norolluponanchor="true"
            nomaxresults="true" />
 
-    <tooltip id="addonitem-tooltip"/>
-
     <menupopup id="contentAreaContextMenu"
                onpopupshowing="Cu.reportError('This dummy menupopup is not supposed to be shown');
                                return false">
       <!-- a dummy element used to forward the context menu related to the extension's
            options page XUL browsers to the context menu defined in the parent chrome window -->
     </menupopup>
   </popupset>
 
   <!-- global commands - these act on all addons, or affect the addons manager
        in some other way -->
   <commandset id="globalCommandSet">
     <!-- XXXsw remove useless oncommand attribute once bug 371900 is fixed -->
     <command id="cmd_focusSearch" oncommand=";"/>
     <command id="cmd_findAllUpdates"/>
-    <command id="cmd_restartApp"/>
     <command id="cmd_goToDiscoverPane"/>
     <command id="cmd_goToRecentUpdates"/>
     <command id="cmd_goToAvailableUpdates"/>
     <command id="cmd_installFromFile"/>
     <command id="cmd_debugAddons"/>
     <command id="cmd_back"/>
     <command id="cmd_forward"/>
     <command id="cmd_enableCheckCompatibility"/>
     <command id="cmd_enableUpdateSecurity"/>
     <command id="cmd_toggleAutoUpdateDefault"/>
     <command id="cmd_resetAddonAutoUpdate"/>
-    <command id="cmd_showUnsignedExtensions"/>
-    <command id="cmd_showAllExtensions"/>
     <command id="cmd_showShortcuts"/>
   </commandset>
 
-  <!-- view commands - these act on the selected addon -->
-  <commandset id="viewCommandSet"
-              events="richlistbox-select" commandupdater="true">
-    <command id="cmd_showItemDetails"/>
-    <command id="cmd_findItemUpdates"/>
-    <command id="cmd_showItemPreferences"/>
-    <command id="cmd_enableItem"/>
-    <command id="cmd_disableItem"/>
-    <command id="cmd_installItem"/>
-    <command id="cmd_uninstallItem"/>
-    <command id="cmd_cancelUninstallItem"/>
-    <command id="cmd_cancelOperation"/>
-    <command id="cmd_contribute"/>
-    <command id="cmd_askToActivateItem"/>
-    <command id="cmd_alwaysActivateItem"/>
-    <command id="cmd_neverActivateItem"/>
-  </commandset>
-
   <keyset>
     <key id="focusSearch" data-l10n-id="search-header-shortcut"
          modifiers="accel" command="cmd_focusSearch"/>
   </keyset>
 
   <stack id="main-page-stack" flex="1">
   <hbox id="main-page-content" flex="1">
     <vbox id="category-box">
       <!-- category list -->
       <richlistbox id="categories" flex="1">
         <richlistitem id="category-discover" value="addons://discover/"
                       class="category"
                       data-l10n-id="extensions-view-discopane"
                       data-l10n-attrs="name"
                       priority="1000"/>
-        <richlistitem id="category-legacy" value="addons://legacy/"
-                      class="category" priority="20000"
-                      hidden="true"/>
         <richlistitem id="category-availableUpdates" value="addons://updates/available"
                       class="category"
                       data-l10n-id="extensions-view-available-updates"
                       data-l10n-attrs="name"
                       hidden="true"/>
         <richlistitem id="category-recentUpdates" value="addons://updates/recent"
                       class="category"
                       data-l10n-id="extensions-view-recent-updates"
@@ -216,24 +164,17 @@
           <browser id="discover-browser" type="content" flex="1"
                    disablehistory="true"/>
         </deck>
 
         <!-- container for views with the search/tools header -->
         <vbox id="headered-views" flex="1">
           <!-- main header -->
           <hbox id="header">
-            <hbox id="header-inner" align="center">
-              <button id="show-all-extensions" hidden="true"
-                      data-l10n-id="show-all-extensions-button"
-                      command="cmd_showAllExtensions"/>
-              <spacer flex="1"/>
-              <button id="show-disabled-unsigned-extensions" hidden="true"
-                      class="warning" data-l10n-id="show-unsigned-extensions-button"
-                      command="cmd_showUnsignedExtensions"/>
+            <hbox id="header-inner" align="center" pack="end">
               <label id="search-label" control="header-search"/>
               <textbox id="header-search" is="search-textbox" searchbutton="true"
                        data-l10n-id="search-header"
                        data-l10n-attrs="searchbuttonlabel" maxlength="100"/>
             </hbox>
           </hbox>
 
           <hbox id="heading">
@@ -253,19 +194,16 @@
                         data-l10n-id="extensions-updates-manual-updates-found"
                         command="cmd_goToAvailableUpdates"/>
                 <label id="updates-progress" hidden="true"
                        data-l10n-id="extensions-updates-updating"/>
                 <label id="updates-installed" hidden="true"
                        data-l10n-id="extensions-updates-installed"/>
                 <label id="updates-downloaded" hidden="true"
                        data-l10n-id="extensions-updates-downloaded"/>
-                <button id="updates-restart-btn" class="button-link" hidden="true"
-                        data-l10n-id="extensions-updates-restart"
-                        command="cmd_restartApp"/>
               </hbox>
 
               <button id="header-utils-btn" type="menu" data-l10n-id="tools-menu">
                 <menupopup id="utils-menu">
                   <menuitem id="utils-updateNow"
                             data-l10n-id="extensions-updates-check-for-updates"
                             command="cmd_findAllUpdates"/>
                   <menuitem id="utils-viewUpdates"
@@ -294,389 +232,19 @@
                             data-l10n-id="manage-extensions-shortcuts"
                             command="cmd_showShortcuts"/>
                 </menupopup>
               </button>
             </hbox>
           </hbox>
 
           <deck id="headered-views-content" flex="1" selectedIndex="0">
-            <!-- list view -->
-            <vbox id="list-view" flex="1" class="view-pane" align="stretch">
-              <!-- info UI for add-ons that have been disabled for being unsigned -->
-              <vbox id="disabled-unsigned-addons-info" class="alert-container" hidden="true">
-                <label id="disabled-unsigned-addons-heading" data-l10n-id="disabled-unsigned-heading"/>
-                <description data-l10n-id="disabled-unsigned-description">
-                  <label class="plain" id="find-alternative-addons" data-l10n-name="find-addons" is="text-link"/>
-                </description>
-                <hbox pack="start"><label id="signing-learn-more" data-l10n-id="disabled-unsigned-learn-more" is="text-link"></label></hbox>
-                <description id="signing-dev-info" data-l10n-id="disabled-unsigned-devinfo">
-                  <label class="plain" id="signing-dev-manual-link" data-l10n-name="learn-more" is="text-link"/>
-                </description>
-              </vbox>
-              <vbox id="legacy-extensions-notice" class="alert-container" hidden="true">
-                <vbox class="alert">
-                  <description id="legacy-extensions-description">
-                    <label class="plain" id="legacy-extensions-learnmore-link" data-l10n-id="legacy-warning-show-legacy" is="text-link"/>
-                  </description>
-                </vbox>
-              </vbox>
-              <vbox id="private-browsing-notice" class="alert-container" hidden="true" align="start">
-                <hbox class="message-bar" align="start">
-                  <image class="message-bar-icon"/>
-                  <vbox class="message-container">
-                    <description class="message-bar-description" data-l10n-id="private-browsing-description2">
-                      <label class="plain" id="private-browsing-learnmore-link" data-l10n-name="private-browsing-learn-more" is="text-link"/>
-                    </description>
-                  </vbox>
-                </hbox>
-              </vbox>
-              <vbox id="plugindeprecation-notice" class="list-view-notice" align="start">
-                <hbox class="message-bar">
-                  <image class="message-bar-icon"/>
-                  <description class="message-bar-description" data-l10n-id="plugin-deprecation-description">
-                    <label class="plain" id="plugindeprecation-learnmore-link" data-l10n-name="learn-more" is="text-link"></label>
-                  </description>
-                </hbox>
-              </vbox>
-              <hbox class="view-header global-warning-container">
-                <!-- global warnings -->
-                <hbox class="global-warning" flex="1">
-                  <hbox class="global-warning-safemode" flex="1" align="center"
-                        data-l10n-id="extensions-warning-safe-mode-container">
-                    <image class="warning-icon"/>
-                    <label class="global-warning-text" flex="1" crop="end"
-                           data-l10n-id="extensions-warning-safe-mode-label"/>
-                  </hbox>
-                  <hbox class="global-warning-checkcompatibility" flex="1" align="center"
-                        data-l10n-id="extensions-warning-check-compatibility-container">
-                    <image class="warning-icon"/>
-                    <label class="global-warning-text" flex="1" crop="end"
-                           data-l10n-id="extensions-warning-check-compatibility-label"/>
-                  </hbox>
-                  <button class="button-link global-warning-checkcompatibility"
-                          data-l10n-id="extensions-warning-check-compatibility-enable"
-                          command="cmd_enableCheckCompatibility"/>
-                  <hbox class="global-warning-updatesecurity" flex="1" align="center"
-                        data-l10n-id="extensions-warning-update-security-container">
-                    <image class="warning-icon"/>
-                    <label class="global-warning-text" flex="1" crop="end"
-                          data-l10n-id="extensions-warning-update-security-label"/>
-                  </hbox>
-                  <button class="button-link global-warning-updatesecurity"
-                          data-l10n-id="extensions-warning-update-security-enable"
-                          command="cmd_enableUpdateSecurity"/>
-                  <spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
-                </hbox>
-              </hbox>
-              <vbox id="addon-list-empty" class="alert-container"
-                    flex="1" hidden="true">
-                <spacer class="alert-spacer-before"/>
-                <vbox class="alert">
-                  <label data-l10n-id="list-empty-installed"/>
-                  <button class="discover-button"
-                          id="discover-button-install"
-                          data-l10n-id="list-empty-button"
-                          command="cmd_goToDiscoverPane"/>
-                </vbox>
-                <spacer class="alert-spacer-after"/>
-              </vbox>
-              <richlistbox id="addon-list" class="list" flex="1"/>
-            </vbox>
-
             <!-- extension shortcuts view -->
             <browser id="shortcuts-view" type="content" flex="1" disablehistory="true"/>
 
-            <!-- legacy extensions view -->
-            <vbox id="legacy-view" flex="1" class="view-pane" align="stretch">
-              <vbox id="legacy-extensions-info">
-                <label id="legacy-extensions-heading" data-l10n-id="legacy-extensions"/>
-                <description data-l10n-id="legacy-extensions-description">
-                  <label class="plain" id="legacy-learnmore" data-l10n-name="legacy-learn-more" is="text-link"></label>
-                </description>
-              </vbox>
-              <richlistbox id="legacy-list" class="list" flex="1"/>
-            </vbox>
-
-            <!-- updates view -->
-            <vbox id="updates-view" flex="1" class="view-pane">
-              <hbox class="view-header global-warning-container" align="center">
-                <!-- global warnings -->
-                <hbox class="global-warning" flex="1">
-                  <hbox class="global-warning-safemode" flex="1" align="center"
-                        data-l10n-id="extensions-warning-safe-mode-container">
-                    <image class="warning-icon"/>
-                    <label class="global-warning-text" flex="1" crop="end"
-                           data-l10n-id="extensions-warning-safe-mode-label"/>
-                  </hbox>
-                  <hbox class="global-warning-checkcompatibility" flex="1" align="center"
-                        data-l10n-id="extensions-warning-check-compatibility-label">
-                    <image class="warning-icon"/>
-                    <label class="global-warning-text" flex="1" crop="end"
-                           data-l10n-id="extensions-warning-check-compatibility-label"/>
-                  </hbox>
-                  <button class="button-link global-warning-checkcompatibility"
-                          data-l10n-id="extensions-warning-check-compatibility-enable"
-                          command="cmd_enableCheckCompatibility"/>
-                  <hbox class="global-warning-updatesecurity" flex="1" align="center"
-                        data-l10n-id="extensions-warning-update-security-label">
-                    <image class="warning-icon"/>
-                    <label class="global-warning-text" flex="1" crop="end"
-                           data-l10n-id="extensions-warning-update-security-label"/>
-                  </hbox>
-                  <button class="button-link global-warning-updatesecurity"
-                          data-l10n-id="extensions-warning-update-security-enable"
-                          command="cmd_enableUpdateSecurity"/>
-                  <spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
-                </hbox>
-              </hbox>
-              <vbox id="updates-list-empty" class="alert-container"
-                    flex="1" hidden="true">
-                <spacer class="alert-spacer-before"/>
-                <vbox class="alert">
-                  <label id="empty-availableUpdates-msg" data-l10n-id="list-empty-available-updates"/>
-                  <label id="empty-recentUpdates-msg" data-l10n-id="list-empty-recent-updates"/>
-                  <button data-l10n-id="list-empty-find-updates"
-                          command="cmd_findAllUpdates"/>
-                </vbox>
-                <spacer class="alert-spacer-after"/>
-              </vbox>
-              <hbox id="update-actions" pack="center">
-                <button id="update-selected-btn" hidden="true"
-                        data-l10n-id="extensions-updates-update-selected"/>
-              </hbox>
-              <richlistbox id="updates-list" class="list" flex="1"/>
-            </vbox>
-
-            <!-- detail view -->
-            <scrollbox id="detail-view" class="view-pane addon-view" orient="vertical" tabindex="0"
-                       role="document">
-              <!-- global warnings -->
-              <hbox class="global-warning-container global-warning">
-                <hbox class="global-warning-safemode" flex="1" align="center"
-                        data-l10n-id="extensions-warning-safe-mode-container">
-                  <image class="warning-icon"/>
-                  <label class="global-warning-text" flex="1" crop="end"
-                        data-l10n-id="extensions-warning-safe-mode-label"/>
-                </hbox>
-                <hbox class="global-warning-checkcompatibility" flex="1" align="center"
-                      data-l10n-id="extensions-warning-check-compatibility-container">
-                  <image class="warning-icon"/>
-                  <label class="global-warning-text" flex="1" crop="end"
-                         data-l10n-id="extensions-warning-check-compatibility-label"/>
-                </hbox>
-                <button class="button-link global-warning-checkcompatibility"
-                        data-l10n-id="extensions-warning-check-compatibility-enable"
-                        command="cmd_enableCheckCompatibility"/>
-                <hbox class="global-warning-updatesecurity" flex="1" align="center"
-                      data-l10n-id="extensions-warning-update-security-container">
-                  <image class="warning-icon"/>
-                  <label class="global-warning-text" flex="1" crop="end"
-                         data-l10n-id="extensions-warning-update-security-label"/>
-                </hbox>
-                <button class="button-link global-warning-updatesecurity"
-                        data-l10n-id="extensions-warning-update-security-label"
-                        command="cmd_enableUpdateSecurity"/>
-                <spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
-              </hbox>
-              <hbox class="detail-view-wrapper">
-                <!-- "loading" splash screen -->
-                <vbox class="alert-container">
-                  <spacer class="alert-spacer-before"/>
-                  <hbox class="alert loading">
-                    <image/>
-                    <label data-l10n-id="loading-label"/>
-                  </hbox>
-                  <spacer class="alert-spacer-after"/>
-                </vbox>
-                <!-- actual detail view -->
-                <vbox class="detail-view-container" contextmenu="addonitem-popup">
-                  <vbox id="detail-notifications">
-                    <hbox id="warning-container" align="center" class="warning">
-                      <image class="warning-icon"/>
-                      <label id="detail-warning" flex="1"/>
-                      <label id="detail-warning-link" is="text-link"/>
-                      <spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
-                    </hbox>
-                    <hbox id="error-container" align="center" class="error">
-                      <image class="error-icon"/>
-                      <label id="detail-error" flex="1"/>
-                      <label id="detail-error-link" is="text-link"/>
-                      <spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
-                    </hbox>
-                    <hbox id="pending-container" align="center" class="pending">
-                      <image class="pending-icon"/>
-                      <label id="detail-pending" flex="1"/>
-                      <button id="detail-restart-btn" class="button-link"
-                              data-l10n-id="addon-restart-now"
-                              command="cmd_restartApp"/>
-                      <button id="detail-undo-btn" class="button-link"
-                              label="&addon.undoAction.label;"
-                              tooltipText="&addon.undoAction.tooltip;"
-                              command="cmd_cancelOperation"/>
-                      <spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
-                    </hbox>
-                  </vbox>
-                  <hbox class="card addon-detail" align="start">
-                    <vbox flex="1">
-                      <image class="card-heading-image theme-screenshot"/>
-                      <hbox align="start">
-                        <vbox id="detail-icon-container" align="end">
-                          <image id="detail-icon" class="icon"/>
-                        </vbox>
-                        <vbox id="detail-summary">
-                          <hbox id="detail-name-container" class="name-container"
-                                align="start">
-                            <label id="detail-name" flex="1"/>
-                            <label id="detail-legacy-warning" class="legacy-warning" value="&addon.legacy.label;" is="text-link"/>
-                            <label class="disabled-postfix" value="&addon.disabled.postfix;"/>
-                            <label class="update-postfix" value="&addon.update.postfix;"/>
-                            <spacer flex="5000"/> <!-- Necessary to allow the name to wrap -->
-                          </hbox>
-                          <label id="detail-creator" class="creator"/>
-                        </vbox>
-                      </hbox>
-                      <vbox id="detail-desc-container" align="start" flex="1">
-                        <description id="detail-desc"/>
-                        <description id="detail-fulldesc"/>
-                      </vbox>
-                      <vbox id="detail-contributions">
-                        <description id="detail-contrib-description" data-l10n-id="detail-contributions-description"/>
-                        <hbox align="center">
-                          <spacer flex="1"/>
-                          <button id="detail-contrib-btn"
-                                  data-l10n-id="cmd-contribute"
-                                  command="cmd_contribute"/>
-                        </hbox>
-                      </vbox>
-                      <grid id="detail-grid">
-                        <columns>
-                           <column flex="1"/>
-                           <column flex="2"/>
-                        </columns>
-                        <rows id="detail-rows">
-                          <row class="detail-row-complex detail-privateBrowsing" id="detail-privateBrowsing-row">
-                            <label class="detail-row-label" data-l10n-id="detail-private-browsing-label"/>
-                            <hbox align="center">
-                              <radiogroup id="detail-privateBrowsing" orient="horizontal">
-                                <radio data-l10n-id="detail-private-browsing-on"
-                                       value="1"/>
-                                <radio data-l10n-id="detail-private-browsing-off"
-                                       value="0"/>
-                              </radiogroup>
-                            </hbox>
-                          </row>
-                          <hbox class="detail-row-footer detail-privateBrowsing" id="detail-privateBrowsing-row-footer">
-                            <description class="indent preferences-description" data-l10n-id="detail-private-browsing-description2">
-                              <label class="learnMore private-learnmore" data-l10n-name="detail-private-browsing-learn-more" is="text-link"/>
-                            </description>
-                          </hbox>
-                          <row class="detail-row-complex detail-privateBrowsing" id="detail-privateBrowsing-required">
-                            <label class="detail-row-label" data-l10n-id="detail-private-required-label"/>
-                          </row>
-                          <hbox class="detail-row-footer detail-privateBrowsing" id="detail-privateBrowsing-required-footer">
-                            <description class="indent preferences-description" data-l10n-id="detail-private-required-description">
-                              <label class="learnMore private-learnmore" data-l10n-name="detail-private-browsing-learn-more" is="text-link"/>
-                            </description>
-                          </hbox>
-                          <row class="detail-row-complex detail-privateBrowsing" id="detail-privateBrowsing-disallowed">
-                            <label class="detail-row-label" data-l10n-id="detail-private-disallowed-label"/>
-                          </row>
-                          <hbox class="detail-row-footer detail-privateBrowsing" id="detail-privateBrowsing-disallowed-footer">
-                            <description class="indent preferences-description" data-l10n-id="detail-private-disallowed-description">
-                              <label class="learnMore private-learnmore" data-l10n-name="detail-private-browsing-learn-more" is="text-link"/>
-                            </description>
-                          </hbox>
-                          <row class="detail-row-complex" id="detail-updates-row">
-                            <label class="detail-row-label" data-l10n-id="detail-update-type"/>
-                            <hbox align="center">
-                              <radiogroup id="detail-autoUpdate" orient="horizontal">
-                                <!-- The values here need to match the values of
-                                     AddonManager.AUTOUPDATE_* -->
-                                <radio data-l10n-id="detail-update-default"
-                                       value="1"/>
-                                <radio data-l10n-id="detail-update-automatic"
-                                       value="2"/>
-                                <radio data-l10n-id="detail-update-manual"
-                                       value="0"/>
-                              </radiogroup>
-                              <button id="detail-findUpdates-btn" class="button-link"
-                                      data-l10n-id="detail-check-for-updates"
-                                      command="cmd_findItemUpdates"/>
-                            </hbox>
-                          </row>
-                          <row class="detail-row" id="detail-version" data-l10n-id="detail-version"/>
-                          <row class="detail-row" id="detail-dateUpdated" data-l10n-id="detail-last-updated"/>
-                          <row class="detail-row-complex" id="detail-homepage-row" data-l10n-id="detail-home">
-                            <label class="detail-row-label" data-l10n-id="detail-home-value"/>
-                            <label id="detail-homepage" class="detail-row-value" crop="end" is="text-link"/>
-                          </row>
-                          <row class="detail-row-complex" id="detail-repository-row" data-l10n-id="detail-repository">
-                            <label class="detail-row-label" data-l10n-id="detail-repository-value"/>
-                            <label id="detail-repository" class="detail-row-value" is="text-link"/>
-                          </row>
-                          <row class="detail-row-complex" id="detail-rating-row">
-                            <label class="detail-row-label" data-l10n-id="detail-rating"/>
-                            <hbox>
-                              <label id="detail-rating" class="meta-value meta-rating"
-                                     showrating="average"/>
-                              <label id="detail-reviews" is="text-link"/>
-                            </hbox>
-                          </row>
-                        </rows>
-                      </grid>
-                      <hbox id="detail-controls">
-                        <button id="detail-prefs-btn" class="addon-control preferences"
-                                data-l10n-id="detail-show-preferences"
-                                command="cmd_showItemPreferences"/>
-                        <spacer flex="1"/>
-                        <button id="detail-enable-btn" class="addon-control enable"
-                                label="&cmd.enableAddon.label;"
-                                accesskey="&cmd.enableAddon.accesskey;"
-                                command="cmd_enableItem"/>
-                        <button id="detail-disable-btn" class="addon-control disable"
-                                label="&cmd.disableAddon.label;"
-                                accesskey="&cmd.disableAddon.accesskey;"
-                                command="cmd_disableItem"/>
-                        <button id="detail-uninstall-btn" class="addon-control remove"
-                                label="&cmd.uninstallAddon.label;"
-                                accesskey="&cmd.uninstallAddon.accesskey;"
-                                command="cmd_uninstallItem"/>
-                        <button id="detail-install-btn" class="addon-control install"
-                                data-l10n-id="cmd-install-addon"
-                                command="cmd_installItem"/>
-                        <menulist id="detail-state-menulist"
-                                  crop="none" sizetopopup="always"
-                                  tooltiptext="&cmd.stateMenu.tooltip;">
-                          <menupopup>
-                            <menuitem id="detail-ask-to-activate-menuitem"
-                                      class="addon-control"
-                                      label="&cmd.askToActivate.label;"
-                                      tooltiptext="&cmd.askToActivate.tooltip;"
-                                      command="cmd_askToActivateItem"/>
-                            <menuitem id="detail-always-activate-menuitem"
-                                      class="addon-control"
-                                      label="&cmd.alwaysActivate.label;"
-                                      tooltiptext="&cmd.alwaysActivate.tooltip;"
-                                      command="cmd_alwaysActivateItem"/>
-                            <menuitem id="detail-never-activate-menuitem"
-                                      class="addon-control"
-                                      label="&cmd.neverActivate.label;"
-                                      tooltiptext="&cmd.neverActivate.tooltip;"
-                                      command="cmd_neverActivateItem"/>
-                          </menupopup>
-                        </menulist>
-                      </hbox>
-                    </vbox>
-                  </hbox>
-                </vbox>
-                <spacer flex="1"/>
-              </hbox>
-            </scrollbox>
-
             <vbox id="html-view" flex="1">
               <vbox class="alert-container html-alert-container" align="start">
                 <hbox class="global-warning-safemode message-bar"
                       data-l10n-id="extensions-warning-safe-mode-container"
                       align="start">
                   <image class="message-bar-icon"/>
                   <vbox class="message-container">
                     <description class="message-bar-description"
--- a/toolkit/mozapps/extensions/jar.mn
+++ b/toolkit/mozapps/extensions/jar.mn
@@ -6,17 +6,17 @@ toolkit.jar:
 % content mozapps %content/mozapps/
   content/mozapps/extensions/shortcuts.html                     (content/shortcuts.html)
   content/mozapps/extensions/shortcuts.css                      (content/shortcuts.css)
   content/mozapps/extensions/shortcuts.js                       (content/shortcuts.js)
 #ifndef MOZ_FENNEC
 * content/mozapps/extensions/extensions.xul                     (content/extensions.xul)
   content/mozapps/extensions/extensions.css                     (content/extensions.css)
   content/mozapps/extensions/extensions.js                      (content/extensions.js)
-* content/mozapps/extensions/extensions.xml                     (content/extensions.xml)
+  content/mozapps/extensions/extensions.xml                     (content/extensions.xml)
   content/mozapps/extensions/blocklist.xul                      (content/blocklist.xul)
   content/mozapps/extensions/blocklist.js                       (content/blocklist.js)
   content/mozapps/extensions/pluginPrefs.xul                    (content/pluginPrefs.xul)
   content/mozapps/extensions/pluginPrefs.js                     (content/pluginPrefs.js)
   content/mozapps/extensions/OpenH264-license.txt               (content/OpenH264-license.txt)
   content/mozapps/extensions/aboutaddons.html                   (content/aboutaddons.html)
   content/mozapps/extensions/aboutaddons.js                     (content/aboutaddons.js)
   content/mozapps/extensions/aboutaddonsCommon.js               (content/aboutaddonsCommon.js)
--- a/toolkit/themes/shared/in-content/common.inc.css
+++ b/toolkit/themes/shared/in-content/common.inc.css
@@ -75,17 +75,16 @@
   --grey-90-a60: rgba(12, 12, 13, 0.6);
   --green-50: #30e60b;
   --green-60: #12bc00;
   --green-70: #058b00;
   --green-80: #006504;
   --green-90: #003706;
   --orange-50: #ff9400;
   --purple-70: #6200a4;
-  --purple-70-a40: rgba(98, 0, 164, 0.4);
   --red-50: #ff0039;
   --red-50-a30: rgba(255, 0, 57, 0.3);
   --red-60: #d70022;
   --red-70: #a4000f;
   --red-80: #5a0002;
   --red-90: #3e0200;
   --yellow-50: #ffe900;
   --yellow-60: #d7b600;