Backed out 2 changesets, 09209cd02343:8f2aaabd3130 (bug 1498967) for MozMill failures. a=backout
authorJorg K <jorgk@jorgk.com>
Tue, 23 Oct 2018 15:11:17 +0200
changeset 33545 e51fe5c93b88ba50efe167c4883e3394a1c0c4d3
parent 33544 02352ad526d3ae67e6f3254ff468b253c9ea353f
child 33546 af1295243bcf777e3d832bbc48d2ab4edf816db6
push id388
push userclokep@gmail.com
push dateMon, 28 Jan 2019 20:54:56 +0000
reviewersbackout
bugs1498967
backs out8f2aaabd3130c106bd569bd7ed4186d434f9f97e
09209cd0234390b24f1fe072ea9a5d0357a4ec84
Backed out 2 changesets, 09209cd02343:8f2aaabd3130 (bug 1498967) for MozMill failures. a=backout Backed out changeset 8f2aaabd3130 (bug 1498967) Backed out changeset 09209cd02343 (bug 1498967)
common/src/extensionSupport.jsm
mail/base/content/aboutAddonsExtra.js
mail/base/content/extensions.xml
mail/base/content/messenger.xul
mail/base/modules/ExtensionsUI.jsm
mail/components/extensions/parent/ext-legacy.js
mail/locales/en-US/chrome/messenger/addons.properties
mail/locales/en-US/chrome/messenger/extensionsOverlay.properties
--- a/common/src/extensionSupport.jsm
+++ b/common/src/extensionSupport.jsm
@@ -1,78 +1,31 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
- * Helper functions for use by extensions that should ease them plug
+ * Helper functions for use by entensions that should ease them plug
  * into the application.
  */
 
 this.EXPORTED_SYMBOLS = ["ExtensionSupport"];
 
-ChromeUtils.import("resource://gre/modules/AddonManager.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 // ChromeUtils.import("resource://gre/modules/Deprecated.jsm") - needed for warning.
 ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
 
 var { fixIterator } = ChromeUtils.import("resource:///modules/iteratorUtils.jsm", null);
 ChromeUtils.import("resource:///modules/IOUtils.js");
 
 var extensionHooks = new Map();
-var legacyExtensions = new Map();
 var openWindowList;
 
 var ExtensionSupport = {
-  /**
-   * A Map-like object which tracks legacy extension status. The "has" method
-   * returns only active extensions for compatibility with existing code.
-   */
-  loadedLegacyExtensions: {
-    set(id, state) {
-      legacyExtensions.set(id, state);
-    },
-    get(id) {
-      return legacyExtensions.get(id);
-    },
-    has(id) {
-      if (!legacyExtensions.has(id))
-        return false;
-
-      let state = legacyExtensions.get(id);
-      return !["install", "enable"].includes(state.pendingOperation);
-    },
-    hasAnyState(id) {
-      return legacyExtensions.has(id);
-    },
-    _maybeDelete(id, newPendingOperation) {
-      if (!legacyExtensions.has(id))
-        return;
-
-      let state = legacyExtensions.get(id);
-      if (state.pendingOperation == "enable" && newPendingOperation == "disable") {
-        legacyExtensions.delete(id);
-        this.notifyObservers(state);
-      } else if (state.pendingOperation == "install" && newPendingOperation == "uninstall") {
-        legacyExtensions.delete(id);
-        this.notifyObservers(state);
-      }
-    },
-    notifyObservers(state) {
-      let wrappedState = { wrappedJSObject: state };
-      Services.obs.notifyObservers(wrappedState, "legacy-addon-status-changed");
-    },
-    // AddonListener
-    onDisabled(ev) {
-      this._maybeDelete(ev.id, "disable");
-    },
-    onUninstalled(ev) {
-      this._maybeDelete(ev.id, "uninstall");
-    },
-  },
+  loadedLegacyExtensions: new Set(),
 
   loadAddonPrefs(addonFile) {
     function setPref(preferDefault, name, value) {
       let branch = preferDefault ? Services.prefs.getDefaultBranch("") : Services.prefs.getBranch("");
 
       if (typeof value == "boolean") {
         branch.setBoolPref(name, value);
       } else if (typeof value == "string") {
@@ -349,10 +302,8 @@ var ExtensionSupport = {
       }
     }
   },
 
   get registeredWindowListenerCount() {
     return extensionHooks.size;
   },
 };
-
-AddonManager.addAddonListener(ExtensionSupport.loadedLegacyExtensions);
--- a/mail/base/content/aboutAddonsExtra.js
+++ b/mail/base/content/aboutAddonsExtra.js
@@ -121,132 +121,60 @@ window.sortElements = function(aElements
 if (window.gViewController.currentViewObj == window.gListView) {
   window.sortList(window.gListView._listBox, ["uiState", "name"], true);
 }
 
 gDetailView._oldDetailUpdateState = gDetailView.updateState;
 gDetailView.updateState = function() {
   this._oldDetailUpdateState();
 
+  let pending = this._addon.pendingOperations;
+
+  let warningContainer = document.getElementById("warning-container");
+  let warning = document.getElementById("detail-warning");
+  let warningLink = document.getElementById("detail-warning-link");
   let restartButton = document.getElementById("restart-btn");
   let undoButton = document.getElementById("undo-btn");
 
   if (ExtensionSupport.loadedLegacyExtensions.has(this._addon.id)) {
     this.node.setAttribute("active", "true");
+    this.node.removeAttribute("pending");
   }
 
-  if (ExtensionSupport.loadedLegacyExtensions.hasAnyState(this._addon.id, true)) {
-    let { stringName, undoCommand, version } = getTrueState(this._addon, "gDetailView._addon");
-
-    if (stringName) {
-      this.node.setAttribute("notification", "warning");
-      this.node.removeAttribute("pending");
+  if (ExtensionSupport.loadedLegacyExtensions.has(this._addon.id) &&
+      (this._addon.userDisabled || pending & AddonManager.PENDING_UNINSTALL)) {
+    this.node.setAttribute("notification", "warning");
 
-      let warningContainer = document.getElementById("warning-container");
-      let warning = document.getElementById("detail-warning");
-      document.getElementById("detail-warning-link").hidden = true;
-      warning.textContent = gStrings.mailExt.formatStringFromName(
-        stringName, [this._addon.name, gStrings.brandShortName], 2
-      );
+    let stringName = this._addon.userDisabled ? "warnLegacyDisable" : "warnLegacyUninstall";
+    warning.textContent = gStrings.mailExt.formatStringFromName(
+      stringName, [this._addon.name, gStrings.brandShortName], 2
+    );
 
-      if (version) {
-        document.getElementById("detail-version").value = version;
-      }
+    warningLink.hidden = true;
 
-      if (!restartButton) {
-        restartButton = document.createElement("button");
-        restartButton.id = "restart-btn";
-        restartButton.className = "button-link restart-btn";
-        restartButton.setAttribute(
-          "label", gStrings.mailExt.GetStringFromName("warnLegacyRestartButton")
-        );
-        restartButton.setAttribute("oncommand", "BrowserUtils.restartApplication()");
-        warningContainer.insertBefore(restartButton, warningContainer.lastElementChild);
-      }
-      restartButton.hidden = false;
-      if (undoCommand) {
-        if (!undoButton) {
-          undoButton = document.createElement("button");
-          undoButton.className = "button-link undo-btn";
-          undoButton.setAttribute(
-            "label", gStrings.mailExt.GetStringFromName("warnLegacyUndoButton")
-          );
-          // We shouldn't really attach non-anonymous content to anonymous content, but we can.
-          warningContainer.insertBefore(undoButton, warningContainer.lastElementChild);
-        }
-        undoButton.setAttribute("oncommand", undoCommand);
-        undoButton.hidden = false;
-      } else if (undoButton) {
-        undoButton.hidden = true;
-      }
-      return;
+    if (!restartButton) {
+      restartButton = document.createElement("button");
+      restartButton.id = "restart-btn";
+      restartButton.className = "button-link restart-btn";
+      restartButton.setAttribute("label", gStrings.mailExt.GetStringFromName("warnLegacyRestartButton"));
+      restartButton.setAttribute("oncommand", "BrowserUtils.restartApplication()");
+      warningContainer.insertBefore(restartButton, warningContainer.lastElementChild);
     }
-  }
+    restartButton.hidden = false;
 
-  if (restartButton) {
+    if (!undoButton) {
+      undoButton = document.createElement("button");
+      undoButton.id = "undo-btn";
+      undoButton.className = "button-link undo-btn";
+      undoButton.setAttribute("label", gStrings.mailExt.GetStringFromName("warnLegacyUndoButton"));
+      warningContainer.insertBefore(undoButton, warningContainer.lastElementChild);
+    }
+    if (this._addon.userDisabled) {
+      undoButton.setAttribute("oncommand", "gDetailView._addon.enable()");
+    } else {
+      undoButton.setAttribute("oncommand", "gDetailView._addon.cancelUninstall()");
+    }
+    undoButton.hidden = false;
+  } else if (restartButton) { // If one exists, so does the other.
     restartButton.hidden = true;
-  }
-  if (undoButton) {
     undoButton.hidden = true;
   }
 };
-
-/**
- * Update the UI when things change.
- */
-function statusChangedObserver(subject, topic, data) {
-  let { id } = subject.wrappedJSObject;
-
-  if (gViewController.currentViewObj == gListView) {
-    let listItem = gListView.getListItemForID(id);
-    if (listItem) {
-      setTimeout(() => listItem._updateState());
-    }
-  } else if (gViewController.currentViewObj == gDetailView) {
-    setTimeout(() => gDetailView.updateState());
-  }
-}
-Services.obs.addObserver(statusChangedObserver, "legacy-addon-status-changed");
-window.addEventListener("unload", () => {
-  Services.obs.removeObserver(statusChangedObserver, "legacy-addon-status-changed");
-});
-
-/**
- * The true status of legacy extensions, which AddonManager doesn't know
- * about because it thinks all extensions are restartless.
- *
- * @return An object of three properties:
- *         stringName: a string to display to the user, from extensionsOverlay.properties.
- *         undoCommand: code to run, should the user want to return to the previous state.
- *         version: the current version of the extension.
- */
-function getTrueState(addon, addonRef) {
-  let state = ExtensionSupport.loadedLegacyExtensions.get(addon.id);
-  let returnObject = {};
-
-  if (addon.pendingOperations & AddonManager.PENDING_UNINSTALL &&
-      ExtensionSupport.loadedLegacyExtensions.has(addon.id)) {
-    returnObject.stringName = "warnLegacyUninstall";
-    returnObject.undoCommand = `${addonRef}.cancelUninstall()`;
-
-  } else if (state.pendingOperation == "install") {
-    returnObject.stringName = "warnLegacyInstall";
-    returnObject.undoCommand = `${addonRef}.uninstall()`;
-
-  } else if (addon.userDisabled) {
-    returnObject.stringName = "warnLegacyDisable";
-    returnObject.undoCommand = `${addonRef}.enable()`;
-
-  } else if (state.pendingOperation == "enable") {
-    returnObject.stringName = "warnLegacyEnable";
-    returnObject.undoCommand = `${addonRef}.disable()`;
-
-  } else if (state.pendingOperation == "upgrade") {
-    returnObject.stringName = "warnLegacyUpgrade";
-    returnObject.version = state.version;
-
-  } else if (state.pendingOperation == "downgrade") {
-    returnObject.stringName = "warnLegacyDowngrade";
-    returnObject.version = state.version;
-  }
-
-  return returnObject;
-}
--- a/mail/base/content/extensions.xml
+++ b/mail/base/content/extensions.xml
@@ -18,65 +18,51 @@
       ]]></constructor>
       <destructor><![CDATA[
         ExtensionParent.apiManager.off("startup", this._updateState);
         ExtensionParent.apiManager.off("shutdown", this._updateState);
       ]]></destructor>
       <method name="_updateState">
         <body><![CDATA[
           this.__proto__.__proto__._updateState.call(this);
+          let pending = this.mAddon.pendingOperations;
           let undoButton = this._warningContainer.querySelector("button.undo-btn");
 
           if (ExtensionSupport.loadedLegacyExtensions.has(this.mAddon.id)) {
             this.setAttribute("active", "true");
+            this.removeAttribute("pending");
           }
 
-          if (ExtensionSupport.loadedLegacyExtensions.hasAnyState(this.mAddon.id, true)) {
-            let {
-              stringName,
-              undoCommand,
-            } = getTrueState(this.mAddon, "document.getBindingParent(this).mAddon");
-
-            if (stringName) {
-              this.setAttribute("notification", "warning");
-              this.removeAttribute("pending");
+          if (
+            ExtensionSupport.loadedLegacyExtensions.has(this.mAddon.id) &&
+            (this.mAddon.userDisabled || pending & AddonManager.PENDING_UNINSTALL)
+          ) {
+            this.setAttribute("notification", "warning");
+            let stringName = this.mAddon.userDisabled ? "warnLegacyDisable" : "warnLegacyUninstall";
+            this._warning.textContent = gStrings.mailExt.formatStringFromName(stringName, [this.mAddon.name, gStrings.brandShortName], 2);
 
-              this._warningLink.hidden = true;
-              this._warning.textContent = gStrings.mailExt.formatStringFromName(
-                stringName, [this.mAddon.name, gStrings.brandShortName], 2
-              );
+            this._warningLink.hidden = true;
 
-              this._warningBtn.label = gStrings.mailExt.GetStringFromName(
-                "warnLegacyRestartButton"
-              );
-              this._warningBtn.setAttribute("oncommand", "BrowserUtils.restartApplication()");
-              this._warningBtn.hidden = false;
+            this._warningBtn.label = gStrings.mailExt.GetStringFromName("warnLegacyRestartButton");
+            this._warningBtn.setAttribute("oncommand", "BrowserUtils.restartApplication()");
+            this._warningBtn.hidden = false;
 
-              if (undoCommand) {
-                if (!undoButton) {
-                  undoButton = document.createElement("button");
-                  undoButton.className = "button-link undo-btn";
-                  undoButton.setAttribute(
-                    "label", gStrings.mailExt.GetStringFromName("warnLegacyUndoButton")
-                  );
-                  // We shouldn't really attach non-anonymous content to anonymous content,
-                  // but we can.
-                  this._warningContainer.insertBefore(
-                    undoButton, this._warningContainer.lastElementChild
-                  );
-                }
-                undoButton.setAttribute("oncommand", undoCommand);
-                undoButton.hidden = false;
-              } else if (undoButton) {
-                undoButton.hidden = true;
-              }
-              return;
+            if (!undoButton) {
+              undoButton = document.createElement("button");
+              undoButton.className = "button-link undo-btn";
+              undoButton.setAttribute("label", gStrings.mailExt.GetStringFromName("warnLegacyUndoButton"));
+              // We shouldn't really attach non-anonymous content to anonymous content, but we can.
+              this._warningContainer.insertBefore(undoButton, this._warningContainer.lastElementChild);
             }
-          }
-
-          if (undoButton) {
+            if (this.mAddon.userDisabled) {
+              undoButton.setAttribute("oncommand", "document.getBindingParent(this).mAddon.enable()");
+            } else {
+              undoButton.setAttribute("oncommand", "document.getBindingParent(this).mAddon.cancelUninstall()");
+            }
+            undoButton.hidden = false;
+          } else if (undoButton) {
             undoButton.hidden = true;
           }
         ]]></body>
       </method>
     </implementation>
   </binding>
 </bindings>
--- a/mail/base/content/messenger.xul
+++ b/mail/base/content/messenger.xul
@@ -328,19 +328,17 @@
     <popupnotificationcontent class="addon-webext-perm-notification-content" orient="vertical">
       <description id="addon-webext-perm-text" class="addon-webext-perm-text"/>
       <label id="addon-webext-perm-intro" class="addon-webext-perm-text"/>
       <html:ul id="addon-webext-perm-list" class="addon-webext-perm-list"/>
     </popupnotificationcontent>
   </popupnotification>
 
   <popupnotification id="addon-installed-notification" hidden="true">
-    <popupnotificationcontent class="addon-installed-notification-content" orient="vertical">
-      <description id="addon-installed-restart-text" class="addon-installed-restart-text"/>
-    </popupnotificationcontent>
+    <popupnotificationcontent class="addon-installed-notification-content" orient="vertical"/>
   </popupnotification>
 
 #include editContactPanel.inc
 #include ../../components/im/content/chat-menu.inc
 </popupset>
 #ifdef XP_MACOSX
 <popupset>
   <menupopup id="menu_mac_dockmenu">
--- a/mail/base/modules/ExtensionsUI.jsm
+++ b/mail/base/modules/ExtensionsUI.jsm
@@ -260,75 +260,51 @@ var gXPInstallObserver = {
                        "addons-notification-icon", action, secondaryActions, popupOptions);
     });
 
     this.pendingNotifications.set(window, promise);
     promise.finally(() => this.pendingNotifications.delete(window));
     return promise;
   },
 
-  async showInstallNotification(browser, addon) {
-    let document = browser.ownerDocument;
+  showInstallNotification(browser, addon) {
     let window = browser.ownerGlobal;
 
     let brandBundle = window.document.getElementById("bundle_brand");
     let appName = brandBundle.getString("brandShortName");
 
     let message = addonsBundle.getFormattedString("addonPostInstall.message1",
                                                   ["<>", appName]);
-
-    let restartRequired = false;
-    let icon = DEFAULT_EXTENSION_ICON;
-    if (addon.isWebExtension) {
-      let uri = addon.getResourceURI().spec;
-      let data = new ExtensionData(Services.io.newURI(`jar:${uri}!/`));
-      await data.loadManifest();
-      restartRequired = data.manifest.legacy;
-      icon = AddonManager.getPreferredIconURL(addon, 32, window) || icon;
-    }
-
-    let action;
-    let secondaryActions = null;
-    let textEl = document.getElementById("addon-installed-restart-text");
-    if (restartRequired) {
-      action = {
-        label: addonsBundle.getString("addonPostInstall.restart.label"),
-        accessKey: addonsBundle.getString("addonPostInstall.restart.key"),
-        callback: () => {
-          ChromeUtils.import("resource://gre/modules/BrowserUtils.jsm");
-          BrowserUtils.restartApplication();
-        },
-      };
-      secondaryActions = [{
-        label: addonsBundle.getString("addonPostInstall.noRestart.label"),
-        accessKey: addonsBundle.getString("addonPostInstall.noRestart.key"),
-        callback: () => {},
-      }];
-      textEl.textContent = addonsBundle.getFormattedString(
-        "addonPostInstall.restartRequired.message", [appName]
-      );
-      textEl.hidden = false;
-    } else {
-      action = {
+    return new Promise(resolve => {
+      let action = {
         label: addonsBundle.getString("addonPostInstall.okay.label"),
         accessKey: addonsBundle.getString("addonPostInstall.okay.key"),
-        callback: () => {},
+        callback: resolve,
       };
-      textEl.hidden = true;
-    }
+
+      let icon = DEFAULT_EXTENSION_ICON;
+      if (addon.isWebExtension) {
+        icon = AddonManager.getPreferredIconURL(addon, 32, window) || icon;
+      }
 
-    let options = {
-      hideClose: true,
-      timeout: Date.now() + 30000,
-      popupIconURL: icon,
-      name: addon.name,
-    };
+      let options = {
+        hideClose: true,
+        timeout: Date.now() + 30000,
+        popupIconURL: icon,
+        eventCallback(topic) {
+          if (topic == "dismissed") {
+            resolve();
+          }
+        },
+        name: addon.name,
+      };
 
-    showNotification(browser, "addon-installed", message, "addons-notification-icon",
-                     action, secondaryActions, options);
+      showNotification(browser, "addon-installed", message, "addons-notification-icon",
+                       action, null, options);
+    });
   },
 
   /* eslint-disable complexity */
   observe(subject, topic, data) {
     let installInfo = subject.wrappedJSObject;
     let browser = installInfo.browser || installInfo.target;
     let window = browser.ownerGlobal;
 
@@ -541,17 +517,17 @@ var gXPInstallObserver = {
         showNotification();
         break;
       }
       case "addon-install-complete": {
         this.showInstallNotification(browser, installInfo.installs[0].addon);
         break;
       }
       case "webextension-permission-prompt": {
-        let { info } = subject.wrappedJSObject;
+        let {info} = subject.wrappedJSObject;
 
         // Dismiss the progress notification.  Note that this is bad if
         // there are multiple simultaneous installs happening, see
         // bug 1329884 for a longer explanation.
         let progressNotification = getNotification("addon-progress", browser);
         if (progressNotification) {
           progressNotification.remove();
         }
@@ -577,17 +553,17 @@ var gXPInstallObserver = {
             info.resolve();
           } else {
             info.reject();
           }
         });
         break;
       }
       case "webextension-update-permissions": {
-        let { info } = subject.wrappedJSObject;
+        let {info} = subject.wrappedJSObject;
         info.type = "update";
         let strings = this._buildStrings(info);
 
         // If we don't prompt for any new permissions, just apply it.
         if (strings.msgs.length == 0) {
           info.resolve();
         }
 
@@ -596,25 +572,29 @@ var gXPInstallObserver = {
             info.resolve();
           } else {
             info.reject();
           }
         });
         break;
       }
       case "webextension-install-notify": {
-        let { addon } = subject.wrappedJSObject;
-        this.showInstallNotification(browser, addon);
+        let {addon, callback} = subject.wrappedJSObject;
+        this.showInstallNotification(browser, addon).then(() => {
+          if (callback) {
+            callback();
+          }
+        });
         break;
       }
       case "webextension-optional-permission-prompt": {
-        let { name, icon, permissions, resolve } = subject.wrappedJSObject;
+        let {name, icon, permissions, resolve} = subject.wrappedJSObject;
         let strings = this._buildStrings({
           type: "optional",
-          addon: { name },
+          addon: {name},
           permissions,
         });
 
         // If we don't have any promptable permissions, just proceed
         if (strings.msgs.length == 0) {
           resolve(true);
           return;
         }
@@ -625,17 +605,17 @@ var gXPInstallObserver = {
   },
   /* eslint-enable complexity */
 
   // Create a set of formatted strings for a permission prompt
   _buildStrings(info) {
     // This bundle isn't the same as addonsBundle.
     let bundle = Services.strings.createBundle(ADDONS_PROPERTIES);
     let appName = brandBundle.getString("brandShortName");
-    let info2 = Object.assign({ appName }, info);
+    let info2 = Object.assign({appName}, info);
 
     let strings = ExtensionData.formatPermissionStrings(info2, bundle);
     strings.addonName = info.addon.name;
     return strings;
   },
 
   _removeProgressNotification(browser) {
     let notification = getNotification("addon-progress", browser);
--- a/mail/components/extensions/parent/ext-legacy.js
+++ b/mail/components/extensions/parent/ext-legacy.js
@@ -15,42 +15,22 @@ this.legacy = class extends ExtensionAPI
     if (this.extension.manifest.legacy) {
       await this.register();
     }
   }
 
   async register() {
     this.extension.legacyLoaded = true;
 
-    let state = {
-      id: this.extension.id,
-      pendingOperation: null,
-      version: this.extension.version,
-    };
     if (ExtensionSupport.loadedLegacyExtensions.has(this.extension.id)) {
-      state = ExtensionSupport.loadedLegacyExtensions.get(this.extension.id);
-      let versionComparison = Services.vc.compare(this.extension.version, state.version);
-      if (versionComparison > 0) {
-        state.pendingOperation = "upgrade";
-        ExtensionSupport.loadedLegacyExtensions.notifyObservers(state);
-      } else if (versionComparison < 0) {
-        state.pendingOperation = "downgrade";
-        ExtensionSupport.loadedLegacyExtensions.notifyObservers(state);
-      }
-      console.log(`Legacy WebExtension ${this.extension.id} has already been loaded in this run, refusing to do so again. Please restart.`);
+      console.log(`Legacy WebExtension ${this.extension.id} has already been loaded in this run, refusing to do so again. Please restart`);
       return;
     }
+    ExtensionSupport.loadedLegacyExtensions.add(this.extension.id);
 
-    ExtensionSupport.loadedLegacyExtensions.set(this.extension.id, state);
-    if (["ADDON_INSTALL", "ADDON_ENABLE"].includes(this.extension.startupReason)) {
-      state.pendingOperation = this.extension.startupReason.substring(6).toLowerCase();
-      console.log(`Legacy WebExtension ${this.extension.id} loading for other reason than startup (${this.extension.startupReason}), refusing to load immediately.`);
-      ExtensionSupport.loadedLegacyExtensions.notifyObservers(state);
-      return;
-    }
 
     let extensionRoot;
     if (this.extension.rootURI instanceof Ci.nsIJARURI) {
       extensionRoot = this.extension.rootURI.JARFile.QueryInterface(Ci.nsIFileURL).file;
       console.log("Loading packed extension from", extensionRoot.path);
     } else {
       extensionRoot = this.extension.rootURI.QueryInterface(Ci.nsIFileURL).file;
       console.log("Loading unpacked extension from", extensionRoot.path);
--- a/mail/locales/en-US/chrome/messenger/addons.properties
+++ b/mail/locales/en-US/chrome/messenger/addons.properties
@@ -14,24 +14,16 @@ xpinstallDisabledButton.accesskey=n
 # LOCALIZATION NOTE (addonPostInstall.message1)
 # %1$S is replaced with the localized named of the extension that was
 # just installed.
 # %2$S is replaced with the localized name of the application.
 addonPostInstall.message1=%1$S has been added to %2$S.
 addonPostInstall.okay.label=OK
 addonPostInstall.okay.key=O
 
-# LOCALIZATION NOTE (addonPostInstall.restartRequired.message)
-# %S is the application name
-addonPostInstall.restartRequired.message=%S must be restarted to complete the installation.
-addonPostInstall.restart.label=Restart now
-addonPostInstall.restart.key=R
-addonPostInstall.noRestart.label=Not now
-addonPostInstall.noRestart.key=N
-
 # LOCALIZATION NOTE (addonDownloadingAndVerifying):
 # Semicolon-separated list of plural forms. See:
 # http://developer.mozilla.org/en/docs/Localization_and_Plurals
 # Also see https://bugzilla.mozilla.org/show_bug.cgi?id=570012 for mockups
 addonDownloadingAndVerifying=Downloading and verifying add-on…;Downloading and verifying #1 add-ons…
 addonDownloadVerifying=Verifying
 
 addonInstall.unsigned=(Unverified)
--- a/mail/locales/en-US/chrome/messenger/extensionsOverlay.properties
+++ b/mail/locales/en-US/chrome/messenger/extensionsOverlay.properties
@@ -5,18 +5,14 @@
 cmdBackTooltip=Go back one page
 cmdForwardTooltip=Go forward one page
 
 # LOCALIZATION NOTE (legacyInfo):
 # #1 is the application name, #2 is the application version
 legacyInfo=Legacy extensions must be updated to be compatible with #1 #2.
 legacyLearnMore=Learn more…
 
-# LOCALIZATION NOTE (warnLegacyUpgrade, warnLegacyDowngrade, warnLegacyEnable, warnLegacyDisable, warnLegacyInstall, warnLegacyUninstall)
-# %1$S is the add-on name, %2$S is brand name
-warnLegacyUpgrade=%1$S will be upgraded after you restart %2$S.
-warnLegacyDowngrade=%1$S will be downgraded after you restart %2$S.
-warnLegacyEnable=%1$S will be enabled after you restart %2$S.
+#LOCALIZATION NOTE (notification.disable) %1$S is the add-on name, %2$S is brand name
 warnLegacyDisable=%1$S will be disabled after you restart %2$S.
-warnLegacyInstall=%1$S will be installed after you restart %2$S.
+#LOCALIZATION NOTE (notification.uninstall) %1$S is the add-on name, %2$S is brand name
 warnLegacyUninstall=%1$S will be uninstalled after you restart %2$S.
 warnLegacyRestartButton=Restart
 warnLegacyUndoButton=Undo