Bug 670023 - Use ES5's strict mode in Add-ons Manager frontend and backend code. r=dtownsend
authorBlair McBride <bmcbride@mozilla.com>
Tue, 19 Jul 2011 13:16:35 -0700
changeset 74443 5f37764372988cd1d010c0c8846580c7caf668ee
parent 74442 d5c5b7841f212233c720ed67a6ce79824ae6e045
child 74444 a8bbb17fd043d21756fd3272f48040e5c85ee06d
child 74519 0d0395cb99ff140ae2e2386aaf0f4e0384096cbb
push id235
push userbzbarsky@mozilla.com
push dateTue, 27 Sep 2011 17:13:04 +0000
treeherdermozilla-beta@2d1e082d176a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdtownsend
bugs670023
milestone8.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 670023 - Use ES5's strict mode in Add-ons Manager frontend and backend code. r=dtownsend
toolkit/mozapps/extensions/AddonLogging.jsm
toolkit/mozapps/extensions/AddonManager.jsm
toolkit/mozapps/extensions/AddonRepository.jsm
toolkit/mozapps/extensions/AddonUpdateChecker.jsm
toolkit/mozapps/extensions/LightweightThemeManager.jsm
toolkit/mozapps/extensions/PluginProvider.jsm
toolkit/mozapps/extensions/XPIProvider.jsm
toolkit/mozapps/extensions/addonManager.js
toolkit/mozapps/extensions/amContentHandler.js
toolkit/mozapps/extensions/amWebInstallListener.js
toolkit/mozapps/extensions/content/about.js
toolkit/mozapps/extensions/content/blocklist.js
toolkit/mozapps/extensions/content/eula.js
toolkit/mozapps/extensions/content/extensions-content.js
toolkit/mozapps/extensions/content/extensions.js
toolkit/mozapps/extensions/content/list.js
toolkit/mozapps/extensions/content/update.js
toolkit/mozapps/extensions/nsBlocklistService.js
--- a/toolkit/mozapps/extensions/AddonLogging.jsm
+++ b/toolkit/mozapps/extensions/AddonLogging.jsm
@@ -32,24 +32,28 @@
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 */
 
+"use strict";
+
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cr = Components.results;
 
 const KEY_PROFILEDIR                  = "ProfD";
 const FILE_EXTENSIONS_LOG             = "extensions.log";
 const PREF_LOGGING_ENABLED            = "extensions.logging.enabled";
 
+const LOGGER_FILE_PERM                = parseInt("666", 8);
+
 const NS_PREFBRANCH_PREFCHANGE_TOPIC_ID = "nsPref:changed";
 
 Components.utils.import("resource://gre/modules/FileUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 var EXPORTED_SYMBOLS = [ "LogManager" ];
 
 var gDebugLogEnabled = false;
@@ -114,17 +118,17 @@ AddonLogger.prototype = {
     if (gDebugLogEnabled)
       dump("*** " + message + "\n");
 
     try {
       var tstamp = new Date();
       var logfile = FileUtils.getFile(KEY_PROFILEDIR, [FILE_EXTENSIONS_LOG]);
       var stream = Cc["@mozilla.org/network/file-output-stream;1"].
                    createInstance(Ci.nsIFileOutputStream);
-      stream.init(logfile, 0x02 | 0x08 | 0x10, 0666, 0); // write, create, append
+      stream.init(logfile, 0x02 | 0x08 | 0x10, LOGGER_FILE_PERM, 0); // write, create, append
       var writer = Cc["@mozilla.org/intl/converter-output-stream;1"].
                    createInstance(Ci.nsIConverterOutputStream);
       writer.init(stream, "UTF-8", 0, 0x0000);
       writer.writeString(tstamp.toLocaleFormat("%Y-%m-%d %H:%M:%S ") +
                          message + " at " + stack.sourceName + ":" +
                          stack.lineNumber + "\n");
       writer.close();
     }
--- a/toolkit/mozapps/extensions/AddonManager.jsm
+++ b/toolkit/mozapps/extensions/AddonManager.jsm
@@ -32,16 +32,18 @@
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 */
 
+"use strict";
+
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cr = Components.results;
 
 const PREF_BLOCKLIST_PINGCOUNTVERSION = "extensions.blocklist.pingCountVersion";
 const PREF_EM_UPDATE_ENABLED          = "extensions.update.enabled";
 const PREF_EM_LAST_APP_VERSION        = "extensions.lastAppVersion";
 const PREF_EM_LAST_PLATFORM_VERSION   = "extensions.lastPlatformVersion";
--- a/toolkit/mozapps/extensions/AddonRepository.jsm
+++ b/toolkit/mozapps/extensions/AddonRepository.jsm
@@ -32,16 +32,18 @@
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 */
 
+"use strict";
+
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Components.utils.import("resource://gre/modules/FileUtils.jsm");
 Components.utils.import("resource://gre/modules/NetUtil.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/AddonManager.jsm");
@@ -1505,17 +1507,17 @@ var AddonDatabase = {
         handleCompletion: function(aReason) {
           if (aReason != Ci.mozIStorageStatementCallback.REASON_FINISHED) {
             ERROR("Error retrieving screenshots from database. Returning empty results");
             aCallback({});
             return;
           }
 
           let returnedAddons = {};
-          for each (addon in addons)
+          for each (let addon in addons)
             returnedAddons[addon.id] = addon;
           aCallback(returnedAddons);
         }
       });
     }
 
     // Begin asynchronous process
     getAllAddons();
--- a/toolkit/mozapps/extensions/AddonUpdateChecker.jsm
+++ b/toolkit/mozapps/extensions/AddonUpdateChecker.jsm
@@ -37,16 +37,18 @@
 # ***** END LICENSE BLOCK *****
 */
 
 /**
  * The AddonUpdateChecker is responsible for retrieving the update information
  * from an add-on's remote update manifest.
  */
 
+"use strict";
+
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 var EXPORTED_SYMBOLS = [ "AddonUpdateChecker" ];
 
 const TIMEOUT               = 2 * 60 * 1000;
 const PREFIX_NS_RDF         = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
 const PREFIX_NS_EM          = "http://www.mozilla.org/2004/em-rdf#";
--- a/toolkit/mozapps/extensions/LightweightThemeManager.jsm
+++ b/toolkit/mozapps/extensions/LightweightThemeManager.jsm
@@ -30,16 +30,18 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+"use strict";
+
 var EXPORTED_SYMBOLS = ["LightweightThemeManager"];
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 Components.utils.import("resource://gre/modules/AddonManager.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 
--- a/toolkit/mozapps/extensions/PluginProvider.jsm
+++ b/toolkit/mozapps/extensions/PluginProvider.jsm
@@ -32,16 +32,18 @@
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 */
 
+"use strict";
+
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 var EXPORTED_SYMBOLS = [];
 
 Components.utils.import("resource://gre/modules/AddonManager.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 
--- a/toolkit/mozapps/extensions/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/XPIProvider.jsm
@@ -32,16 +32,18 @@
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 */
 
+"use strict";
+
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cr = Components.results;
 
 var EXPORTED_SYMBOLS = [];
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/AddonManager.jsm");
@@ -385,17 +387,17 @@ function findClosestLocale(aLocales) {
   /* If the current locale is English then it will find a match if there is
      a valid match for en-US so no point searching that locale too. */
   if (matchLocales[0].substring(0, 3) != "en-")
     matchLocales.push("en-us");
 
   for each (var locale in matchLocales) {
     var lparts = locale.split("-");
     for each (var localized in aLocales) {
-      for each (found in localized.locales) {
+      for each (let found in localized.locales) {
         found = found.toLowerCase();
         // Exact match is returned immediately
         if (locale == found)
           return localized;
 
         var fparts = found.split("-");
         /* If we have found a possible match and this one isn't any longer
            then we dont need to check further. */
@@ -1895,18 +1897,18 @@ var XPIProvider = {
           LOG("Error removing XPI staging dir " + stagedXPIDir.path, e);
         }
       }
 
       if (!stagingDir || !stagingDir.exists() || !stagingDir.isDirectory())
         return;
 
       let seenFiles = [];
-      entries = stagingDir.directoryEntries
-                          .QueryInterface(Ci.nsIDirectoryEnumerator);
+      let entries = stagingDir.directoryEntries
+                              .QueryInterface(Ci.nsIDirectoryEnumerator);
       while (entries.hasMoreElements()) {
         let stageDirEntry = entries.getNext().QueryInterface(Ci.nsILocalFile);
 
         let id = stageDirEntry.leafName;
         if (!stageDirEntry.isDirectory()) {
           if (id.substring(id.length - 4).toLowerCase() == ".xpi") {
             id = id.substring(0, id.length - 4);
           }
@@ -2773,17 +2775,17 @@ var XPIProvider = {
     knownLocations.forEach(function(aLocation) {
       let addons = XPIDatabase.getAddonsInLocation(aLocation);
       addons.forEach(function(aOldAddon) {
         changed = removeMetadata(aLocation, aOldAddon) || changed;
       }, this);
     }, this);
 
     // Cache the new install location states
-    cache = JSON.stringify(this.getInstallLocationStates());
+    let cache = JSON.stringify(this.getInstallLocationStates());
     Services.prefs.setCharPref(PREF_INSTALL_CACHE, cache);
 
     return changed;
   },
 
   /**
    * Imports the xpinstall permissions from preferences into the permissions
    * manager for the user to change later.
@@ -3686,16 +3688,60 @@ var XPIProvider = {
     // If the add-on is not visible then there is no need to notify listeners.
     if (!aAddon.visible)
       return;
 
     let wrapper = createWrapper(aAddon);
     AddonManagerPrivate.callAddonListeners("onUninstalling", wrapper,
                                            requiresRestart);
 
+    // Reveal the highest priority add-on with the same ID
+    function revealAddon(aAddon) {
+      XPIDatabase.makeAddonVisible(aAddon);
+
+      let wrappedAddon = createWrapper(aAddon);
+      AddonManagerPrivate.callAddonListeners("onInstalling", wrappedAddon, false);
+
+      if (!isAddonDisabled(aAddon) && !XPIProvider.enableRequiresRestart(aAddon)) {
+        aAddon.active = true;
+        XPIDatabase.updateAddonActive(aAddon);
+      }
+
+      if (aAddon.bootstrap) {
+        let file = aAddon._installLocation.getLocationForID(aAddon.id);
+        XPIProvider.callBootstrapMethod(aAddon.id, aAddon.version, file,
+                                        "install", BOOTSTRAP_REASONS.ADDON_INSTALL);
+
+        if (aAddon.active) {
+          XPIProvider.callBootstrapMethod(aAddon.id, aAddon.version, file,
+                                          "startup", BOOTSTRAP_REASONS.ADDON_INSTALL);
+        }
+        else {
+          XPIProvider.unloadBootstrapScope(aAddon.id);
+        }
+      }
+
+      // We always send onInstalled even if a restart is required to enable
+      // the revealed add-on
+      AddonManagerPrivate.callAddonListeners("onInstalled", wrappedAddon);
+    }
+
+    function checkInstallLocation(aPos) {
+      if (aPos < 0)
+        return;
+
+      let location = XPIProvider.installLocations[aPos];
+      XPIDatabase.getAddonInLocation(aAddon.id, location.name, function(aNewAddon) {
+        if (aNewAddon)
+          revealAddon(aNewAddon);
+        else
+          checkInstallLocation(aPos - 1);
+      })
+    }
+
     if (!requiresRestart) {
       if (aAddon.bootstrap) {
         let file = aAddon._installLocation.getLocationForID(aAddon.id);
         if (aAddon.active) {
           this.callBootstrapMethod(aAddon.id, aAddon.version, file, "shutdown",
                                    BOOTSTRAP_REASONS.ADDON_UNINSTALL);
         }
 
@@ -3703,60 +3749,16 @@ var XPIProvider = {
                                  BOOTSTRAP_REASONS.ADDON_UNINSTALL);
         this.unloadBootstrapScope(aAddon.id);
         flushStartupCache();
       }
       aAddon._installLocation.uninstallAddon(aAddon.id);
       XPIDatabase.removeAddonMetadata(aAddon);
       AddonManagerPrivate.callAddonListeners("onUninstalled", wrapper);
 
-      // Reveal the highest priority add-on with the same ID
-      function revealAddon(aAddon) {
-        XPIDatabase.makeAddonVisible(aAddon);
-
-        let wrappedAddon = createWrapper(aAddon);
-        AddonManagerPrivate.callAddonListeners("onInstalling", wrappedAddon, false);
-
-        if (!isAddonDisabled(aAddon) && !XPIProvider.enableRequiresRestart(aAddon)) {
-          aAddon.active = true;
-          XPIDatabase.updateAddonActive(aAddon);
-        }
-
-        if (aAddon.bootstrap) {
-          let file = aAddon._installLocation.getLocationForID(aAddon.id);
-          XPIProvider.callBootstrapMethod(aAddon.id, aAddon.version, file,
-                                          "install", BOOTSTRAP_REASONS.ADDON_INSTALL);
-
-          if (aAddon.active) {
-            XPIProvider.callBootstrapMethod(aAddon.id, aAddon.version, file,
-                                            "startup", BOOTSTRAP_REASONS.ADDON_INSTALL);
-          }
-          else {
-            XPIProvider.unloadBootstrapScope(aAddon.id);
-          }
-        }
-
-        // We always send onInstalled even if a restart is required to enable
-        // the revealed add-on
-        AddonManagerPrivate.callAddonListeners("onInstalled", wrappedAddon);
-      }
-
-      function checkInstallLocation(aPos) {
-        if (aPos < 0)
-          return;
-
-        let location = XPIProvider.installLocations[aPos];
-        XPIDatabase.getAddonInLocation(aAddon.id, location.name, function(aNewAddon) {
-          if (aNewAddon)
-            revealAddon(aNewAddon);
-          else
-            checkInstallLocation(aPos - 1);
-        })
-      }
-
       checkInstallLocation(this.installLocations.length - 1);
     }
 
     // Notify any other providers that a new theme has been enabled
     if (aAddon.type == "theme" && aAddon.active)
       AddonManagerPrivate.notifyAddonChanged(null, aAddon.type, requiresRestart);
   },
 
@@ -5027,36 +5029,38 @@ var XPIDatabase = {
    * @param  aAddon
    *         AddonInternal to add
    * @param  aDescriptor
    *         The file descriptor of the add-on
    */
   addAddonMetadata: function XPIDB_addAddonMetadata(aAddon, aDescriptor) {
     this.beginTransaction();
 
+    var self = this;
+    function insertLocale(aLocale) {
+      let localestmt = self.getStatement("addAddonMetadata_locale");
+      let stringstmt = self.getStatement("addAddonMetadata_strings");
+
+      copyProperties(aLocale, PROP_LOCALE_SINGLE, localestmt.params);
+      executeStatement(localestmt);
+      let row = XPIDatabase.connection.lastInsertRowID;
+
+      PROP_LOCALE_MULTI.forEach(function(aProp) {
+        aLocale[aProp].forEach(function(aStr) {
+          stringstmt.params.locale = row;
+          stringstmt.params.type = aProp;
+          stringstmt.params.value = aStr;
+          executeStatement(stringstmt);
+        });
+      });
+      return row;
+    }
+
     // Any errors in here should rollback the transaction
     try {
-      let localestmt = this.getStatement("addAddonMetadata_locale");
-      let stringstmt = this.getStatement("addAddonMetadata_strings");
-
-      function insertLocale(aLocale) {
-        copyProperties(aLocale, PROP_LOCALE_SINGLE, localestmt.params);
-        executeStatement(localestmt);
-        let row = XPIDatabase.connection.lastInsertRowID;
-
-        PROP_LOCALE_MULTI.forEach(function(aProp) {
-          aLocale[aProp].forEach(function(aStr) {
-            stringstmt.params.locale = row;
-            stringstmt.params.type = aProp;
-            stringstmt.params.value = aStr;
-            executeStatement(stringstmt);
-          });
-        });
-        return row;
-      }
 
       if (aAddon.visible) {
         let stmt = this.getStatement("clearVisibleAddons");
         stmt.params.id = aAddon.id;
         executeStatement(stmt);
       }
 
       let stmt = this.getStatement("addAddonMetadata_addon");
@@ -7507,17 +7511,17 @@ DirectoryInstallLocation.prototype = {
 
       if (!gIDTest.test(id)) {
         LOG("Ignoring file entry whose name is not a valid add-on ID: " +
              entry.path);
         continue;
       }
 
       if (entry.isFile() && !directLoad) {
-        newEntry = this._readDirectoryFromFile(entry);
+        let newEntry = this._readDirectoryFromFile(entry);
         if (!newEntry) {
           LOG("Deleting stale pointer file " + entry.path);
           entry.remove(true);
           continue;
         }
 
         entry = newEntry;
         this._linkedAddons.push(id);
--- a/toolkit/mozapps/extensions/addonManager.js
+++ b/toolkit/mozapps/extensions/addonManager.js
@@ -38,16 +38,18 @@
 */
 
 /**
  * This component serves as integration between the platform and AddonManager.
  * It is responsible for initializing and shutting down the AddonManager as well
  * as passing new installs from webpages to the AddonManager.
  */
 
+"use strict";
+
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cr = Components.results;
 
 const PREF_EM_UPDATE_INTERVAL = "extensions.update.interval";
 
 // The old XPInstall error codes
 const EXECUTION_ERROR   = -203;
@@ -134,28 +136,28 @@ amManager.prototype = {
     let installs = [];
     function buildNextInstall() {
       if (aUris.length == 0) {
         AddonManager.installAddonsFromWebpage(aMimetype, aWindow, aReferer, installs);
         return;
       }
       let uri = aUris.shift();
       AddonManager.getInstallForURL(uri, function(aInstall) {
+        function callCallback(aUri, aStatus) {
+          try {
+            aCallback.onInstallEnded(aUri, aStatus);
+          }
+          catch (e) {
+            Components.utils.reportError(e);
+          }
+        }
+
         if (aInstall) {
           installs.push(aInstall);
           if (aCallback) {
-            function callCallback(aUri, aStatus) {
-              try {
-                aCallback.onInstallEnded(aUri, aStatus);
-              }
-              catch (e) {
-                Components.utils.reportError(e);
-              }
-            }
-
             aInstall.addListener({
               onDownloadCancelled: function(aInstall) {
                 callCallback(uri, USER_CANCELLED);
               },
 
               onDownloadFailed: function(aInstall) {
                 if (aInstall.error == AddonManager.ERROR_CORRUPT_FILE)
                   callCallback(uri, CANT_READ_ARCHIVE);
--- a/toolkit/mozapps/extensions/amContentHandler.js
+++ b/toolkit/mozapps/extensions/amContentHandler.js
@@ -32,16 +32,18 @@
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 */
 
+"use strict";
+
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cr = Components.results;
 
 const XPI_CONTENT_TYPE = "application/x-xpinstall";
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
--- a/toolkit/mozapps/extensions/amWebInstallListener.js
+++ b/toolkit/mozapps/extensions/amWebInstallListener.js
@@ -39,16 +39,18 @@
 
 /**
  * This is a default implementation of amIWebInstallListener that should work
  * for most applications but can be overriden. It notifies the observer service
  * about blocked installs. For normal installs it pops up an install
  * confirmation when all the add-ons have been downloaded.
  */
 
+"use strict";
+
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cr = Components.results;
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/AddonManager.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 
--- a/toolkit/mozapps/extensions/content/about.js
+++ b/toolkit/mozapps/extensions/content/about.js
@@ -31,16 +31,18 @@
 # use your version of this file under the terms of the MPL, indicate your
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 # 
 # ***** END LICENSE BLOCK *****
 
+"use strict";
+
 function init() {
   var addon = window.arguments[0];
   var extensionsStrings = document.getElementById("extensionsStrings");
 
   document.documentElement.setAttribute("addontype", addon.type);
 
   if (addon.iconURL) {
     var extensionIcon = document.getElementById("extensionIcon");
--- a/toolkit/mozapps/extensions/content/blocklist.js
+++ b/toolkit/mozapps/extensions/content/blocklist.js
@@ -30,16 +30,18 @@
 # use your version of this file under the terms of the MPL, indicate your
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
+"use strict";
+
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 var gArgs;
 
 function init() {
   var hasHardBlocks = false;
   var hasSoftBlocks = false;
   gArgs = window.arguments[0].wrappedJSObject;
--- a/toolkit/mozapps/extensions/content/eula.js
+++ b/toolkit/mozapps/extensions/content/eula.js
@@ -30,16 +30,18 @@
 # use your version of this file under the terms of the MPL, indicate your
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
+"use strict";
+
 function Startup() {
   var bundle = document.getElementById("extensionsStrings");
   var addon = window.arguments[0].addon;
 
   document.documentElement.setAttribute("addontype", addon.type);
 
   if (addon.iconURL)
     document.getElementById("icon").src = addon.iconURL;
--- a/toolkit/mozapps/extensions/content/extensions-content.js
+++ b/toolkit/mozapps/extensions/content/extensions-content.js
@@ -32,16 +32,18 @@
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 */
 
+"use strict";
+
 (function(){
 
 let Cc = Components.classes;
 let Ci = Components.interfaces;
 let Cu = Components.utils;
 
 const MSG_INSTALL_ENABLED  = "WebInstallerIsInstallEnabled";
 const MSG_INSTALL_ADDONS   = "WebInstallerInstallAddonsFromWebpage";
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -30,16 +30,18 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+"use strict";
+
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/PluralForm.jsm");
@@ -220,23 +222,24 @@ var HTML5History = {
     window.history.pushState(aState, document.title);
   },
 
   replaceState: function(aState) {
     window.history.replaceState(aState, document.title);
   },
 
   popState: function() {
-    window.addEventListener("popstate", function(event) {
-      window.removeEventListener("popstate", arguments.callee, true);
+    function onStatePopped(aEvent) {
+      window.removeEventListener("popstate", onStatePopped, true);
       // TODO To ensure we can't go forward again we put an additional entry
       // for the current state into the history. Ideally we would just strip
       // the history but there doesn't seem to be a way to do that. Bug 590661
-      window.history.pushState(event.state, document.title);
-    }, true);
+      window.history.pushState(aEvent.state, document.title);
+    }
+    window.addEventListener("popstate", onStatePopped, true);
     window.history.back();
     gViewController.updateCommand("cmd_back");
     gViewController.updateCommand("cmd_forward");
   }
 };
 
 /**
  * A wrapper around a fake history service
--- a/toolkit/mozapps/extensions/content/list.js
+++ b/toolkit/mozapps/extensions/content/list.js
@@ -70,16 +70,18 @@ const kDialog = "dialog";
  *            focused: true },
  *  cancel: { label: "A Label for the Cancel button" },
  *  ...
  * },
  *
  * result:  The dlgtype of button that was used to dismiss the dialog. 
  */
 
+"use strict";
+
 var gButtons = { };
 
 function init() {
   var de = document.documentElement;
   var items = [];
   if (window.arguments[0] instanceof Components.interfaces.nsIDialogParamBlock) {
     // This is a warning about a blocklisted item the user is trying to install
     var args = window.arguments[0];
--- a/toolkit/mozapps/extensions/content/update.js
+++ b/toolkit/mozapps/extensions/content/update.js
@@ -33,16 +33,18 @@
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 // This UI is only opened from the Extension Manager when the app is upgraded.
 
+"use strict";
+
 const PREF_UPDATE_EXTENSIONS_ENABLED            = "extensions.update.enabled";
 const PREF_XPINSTALL_ENABLED                    = "xpinstall.enabled";
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/AddonManager.jsm");
 
 var gUpdateWizard = {
   // When synchronizing app compatibility info this contains all installed
--- a/toolkit/mozapps/extensions/nsBlocklistService.js
+++ b/toolkit/mozapps/extensions/nsBlocklistService.js
@@ -35,16 +35,18 @@
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 */
 
+"use strict";
+
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cr = Components.results;
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/FileUtils.jsm");
 Components.utils.import("resource://gre/modules/AddonManager.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
@@ -1031,30 +1033,31 @@ Blocklist.prototype = {
           else
             addonList[i].item.softDisabled = true;
         }
 
         if (args.restart)
           restartApp();
 
         Services.obs.notifyObservers(self, "blocklist-updated", "");
-        Services.obs.removeObserver(arguments.callee, "addon-blocklist-closed");
+        Services.obs.removeObserver(applyBlocklistChanges, "addon-blocklist-closed");
       }
 
       Services.obs.addObserver(applyBlocklistChanges, "addon-blocklist-closed", false)
 
+      function blocklistUnloadHandler(event) {
+        if (event.target.location == URI_BLOCKLIST_DIALOG) {
+          applyBlocklistChanges();
+          blocklistWindow.removeEventListener("unload", blocklistUnloadHandler);
+        }
+      }
+
       let blocklistWindow = Services.ww.openWindow(null, URI_BLOCKLIST_DIALOG, "",
                               "chrome,centerscreen,dialog,titlebar", args);
-
-      blocklistWindow.addEventListener("unload", function(event) {
-        if(event.target.location == URI_BLOCKLIST_DIALOG) {
-          applyBlocklistChanges();
-          blocklistWindow.removeEventListener("unload", arguments.callee);
-        }
-      },false)
+      blocklistWindow.addEventListener("unload", blocklistUnloadHandler, false);
     });
   },
 
   classID: Components.ID("{66354bc9-7ed1-4692-ae1d-8da97d6b205e}"),
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
                                          Ci.nsIBlocklistService,
                                          Ci.nsITimerCallback]),
 };