Bug 1245916: Turn on no-undef in toolkit/mozapps/extensions. r=rhelmer draft
authorDave Townsend <dtownsend@oxymoronical.com>
Wed, 03 Feb 2016 22:48:48 -0800
changeset 331377 5c19b92e4242088b6fc7a268f255fe9a795928f6
parent 331376 ef36531641cbd353625019f8deba333cfd352891
child 514368 78e47b7b8c0afafb2b5b9d72fc4cbe61af661128
push id10969
push userdtownsend@mozilla.com
push dateTue, 16 Feb 2016 22:40:19 +0000
reviewersrhelmer
bugs1245916
milestone47.0a1
Bug 1245916: Turn on no-undef in toolkit/mozapps/extensions. r=rhelmer Mostly just declaring globals that Cu.imports defines but there are some actual bugs here that have been fixed as well as one test that just never ran because of a hidden exception. MozReview-Commit-ID: J6uIpYp8ANx
services/sync/tests/unit/head_appinfo.js
toolkit/mozapps/extensions/.eslintrc
toolkit/mozapps/extensions/AddonManager.jsm
toolkit/mozapps/extensions/DeferredSave.jsm
toolkit/mozapps/extensions/LightweightThemeManager.jsm
toolkit/mozapps/extensions/addonManager.js
toolkit/mozapps/extensions/content/about.js
toolkit/mozapps/extensions/content/extensions.js
toolkit/mozapps/extensions/content/extensions.xml
toolkit/mozapps/extensions/content/setting.xml
toolkit/mozapps/extensions/internal/AddonRepository.jsm
toolkit/mozapps/extensions/internal/AddonRepository_SQLiteMigrator.jsm
toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm
toolkit/mozapps/extensions/internal/Content.js
toolkit/mozapps/extensions/internal/GMPProvider.jsm
toolkit/mozapps/extensions/internal/LightweightThemeImageOptimizer.jsm
toolkit/mozapps/extensions/internal/PluginProvider.jsm
toolkit/mozapps/extensions/internal/ProductAddonChecker.jsm
toolkit/mozapps/extensions/internal/XPIProvider.jsm
toolkit/mozapps/extensions/internal/XPIProviderUtils.js
toolkit/mozapps/extensions/nsBlocklistService.js
toolkit/mozapps/extensions/test/addons/test_bug675371/test.js
toolkit/mozapps/extensions/test/browser/browser_bug593535.js
toolkit/mozapps/extensions/test/browser/discovery_install.html
toolkit/mozapps/extensions/test/browser/head.js
toolkit/mozapps/extensions/test/xpcshell/head_addons.js
toolkit/mozapps/extensions/test/xpcshell/head_unpack.js
toolkit/mozapps/extensions/test/xpcshell/test_DeferredSave.js
toolkit/mozapps/extensions/test/xpcshell/test_bug393285.js
toolkit/mozapps/extensions/test/xpcshell/test_bug406118.js
toolkit/mozapps/extensions/test/xpcshell/test_bug675371.js
toolkit/mozapps/extensions/test/xpcshell/test_fuel.js
toolkit/mozapps/extensions/test/xpcshell/test_gfxBlacklist_prefs.js
toolkit/mozapps/extensions/test/xpcshell/test_mapURIToAddonID.js
toolkit/mozapps/extensions/test/xpcshell/test_pluginchange.js
toolkit/mozapps/extensions/test/xpcshell/test_provider_unsafe_access_shutdown.js
toolkit/mozapps/extensions/test/xpcshell/test_provider_unsafe_access_startup.js
toolkit/mozapps/extensions/test/xpcshell/test_seen.js
toolkit/mozapps/extensions/test/xpcshell/test_undouninstall.js
toolkit/mozapps/extensions/test/xpcshell/test_updateCancel.js
toolkit/mozapps/extensions/test/xpcshell/test_webextension_icons.js
toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini
toolkit/mozapps/extensions/test/xpinstall/browser_bug672485.js
toolkit/mozapps/extensions/test/xpinstall/browser_concurrent_installs.js
toolkit/mozapps/extensions/test/xpinstall/browser_whitelist3.js
toolkit/mozapps/extensions/test/xpinstall/browser_whitelist4.js
toolkit/mozapps/extensions/test/xpinstall/bug645699.html
toolkit/mozapps/extensions/test/xpinstall/concurrent_installs.html
toolkit/mozapps/extensions/test/xpinstall/enabled.html
toolkit/mozapps/extensions/test/xpinstall/installchrome.html
toolkit/mozapps/extensions/test/xpinstall/installtrigger.html
toolkit/mozapps/extensions/test/xpinstall/startsoftwareupdate.html
toolkit/mozapps/extensions/test/xpinstall/triggerredirect.html
--- a/services/sync/tests/unit/head_appinfo.js
+++ b/services/sync/tests/unit/head_appinfo.js
@@ -13,35 +13,38 @@ gSyncProfile = do_get_profile();
 var fhs = Cc["@mozilla.org/satchel/form-history-startup;1"]
             .getService(Ci.nsIObserver);
 fhs.observe(null, "profile-after-change", null);
 
 // An app is going to have some prefs set which xpcshell tests don't.
 Services.prefs.setCharPref("identity.sync.tokenserver.uri", "http://token-server");
 
 // Make sure to provide the right OS so crypto loads the right binaries
-var OS = "XPCShell";
-if (mozinfo.os == "win")
-  OS = "WINNT";
-else if (mozinfo.os == "mac")
-  OS = "Darwin";
-else
-  OS = "Linux";
+function getOS() {
+  switch (mozinfo.os) {
+    case "win":
+      return "WINNT";
+    case "mac":
+      return "Darwin";
+    default:
+      return "Linux";
+  }
+}
 
 var XULAppInfo = {
   vendor: "Mozilla",
   name: "XPCShell",
   ID: "xpcshell@tests.mozilla.org",
   version: "1",
   appBuildID: "20100621",
   platformVersion: "",
   platformBuildID: "20100621",
   inSafeMode: false,
   logConsoleErrors: true,
-  OS: OS,
+  OS: getOS(),
   XPCOMABI: "noarch-spidermonkey",
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIXULAppInfo, Ci.nsIXULRuntime]),
   invalidateCachesOnRestart: function invalidateCachesOnRestart() { }
 };
 
 var XULAppInfoFactory = {
   createInstance: function (outer, iid) {
     if (outer != null)
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/.eslintrc
@@ -0,0 +1,6 @@
+{
+  "rules": {
+    // No using undeclared variables
+    "no-undef": 2,
+  }
+}
--- a/toolkit/mozapps/extensions/AddonManager.jsm
+++ b/toolkit/mozapps/extensions/AddonManager.jsm
@@ -972,17 +972,17 @@ var AddonManagerInternal = {
       // If this is a new profile just pretend that there were no changes
       if (appChanged === undefined) {
         for (let type in this.startupChanges)
           delete this.startupChanges[type];
       }
 
       // Support for remote about:plugins. Note that this module isn't loaded
       // at the top because Services.appinfo is defined late in tests.
-      Cu.import("resource://gre/modules/RemotePageManager.jsm");
+      let { RemotePages } = Cu.import("resource://gre/modules/RemotePageManager.jsm", {});
 
       gPluginPageListener = new RemotePages("about:plugins");
       gPluginPageListener.addMessageListener("RequestPlugins", this.requestPlugins);
 
       gStartupComplete = true;
       this.recordTimestamp("AMI_startup_end");
     }
     catch (e) {
@@ -1140,17 +1140,17 @@ var AddonManagerInternal = {
 
     let providers = [...this.providers];
     for (let provider of providers) {
       try {
         if (aMethod in provider)
           provider[aMethod].apply(provider, aArgs);
       }
       catch (e) {
-        reportProviderError(aProvider, aMethod, e);
+        reportProviderError(provider, aMethod, e);
       }
     }
   },
 
   /**
    * Report the current state of asynchronous shutdown
    */
   shutdownState() {
--- a/toolkit/mozapps/extensions/DeferredSave.jsm
+++ b/toolkit/mozapps/extensions/DeferredSave.jsm
@@ -4,16 +4,17 @@
 
 "use strict";
 
 const Cu = Components.utils;
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 Cu.import("resource://gre/modules/osfile.jsm");
+/*globals OS*/
 Cu.import("resource://gre/modules/Promise.jsm");
 
 // Make it possible to mock out timers for testing
 var MakeTimer = () => Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
 
 this.EXPORTED_SYMBOLS = ["DeferredSave"];
 
 // If delay parameter is not provided, default is 50 milliseconds.
--- a/toolkit/mozapps/extensions/LightweightThemeManager.jsm
+++ b/toolkit/mozapps/extensions/LightweightThemeManager.jsm
@@ -6,16 +6,17 @@
 
 this.EXPORTED_SYMBOLS = ["LightweightThemeManager"];
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/AddonManager.jsm");
+/*globals AddonManagerPrivate*/
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 const ID_SUFFIX              = "@personas.mozilla.org";
 const PREF_LWTHEME_TO_SELECT = "extensions.lwThemeToSelect";
 const PREF_GENERAL_SKINS_SELECTEDSKIN = "general.skins.selectedSkin";
 const PREF_EM_DSS_ENABLED    = "extensions.dss.enabled";
 const ADDON_TYPE             = "theme";
 
--- a/toolkit/mozapps/extensions/addonManager.js
+++ b/toolkit/mozapps/extensions/addonManager.js
@@ -31,16 +31,17 @@ Cu.import("resource://gre/modules/Servic
 
 var gSingleton = null;
 
 var gParentMM = null;
 
 
 function amManager() {
   Cu.import("resource://gre/modules/AddonManager.jsm");
+  /*globals AddonManagerPrivate*/
 
   let globalMM = Cc["@mozilla.org/globalmessagemanager;1"]
                  .getService(Ci.nsIMessageListenerManager);
   globalMM.loadFrameScript(CHILD_SCRIPT, true);
   globalMM.addMessageListener(MSG_INSTALL_ADDONS, this);
 
   gParentMM = Cc["@mozilla.org/parentprocessmessagemanager;1"]
                  .getService(Ci.nsIMessageListenerManager);
--- a/toolkit/mozapps/extensions/content/about.js
+++ b/toolkit/mozapps/extensions/content/about.js
@@ -1,16 +1,18 @@
 // -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
 
 /* 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/. */
 
 "use strict";
 
+/* import-globals-from ../../../content/contentAreaUtils.js */
+
 var Cu = Components.utils;
 Cu.import("resource://gre/modules/AddonManager.jsm");
 
 function init() {
   var addon = window.arguments[0];
   var extensionsStrings = document.getElementById("extensionsStrings");
 
   document.documentElement.setAttribute("addontype", addon.type);
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -1,14 +1,17 @@
 /* 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/. */
 
 "use strict";
 
+/* import-globals-from ../../../content/contentAreaUtils.js */
+/*globals XMLStylesheetProcessingInstruction*/
+
 var Cc = Components.classes;
 var Ci = Components.interfaces;
 var Cu = Components.utils;
 var Cr = Components.results;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/DownloadUtils.jsm");
--- a/toolkit/mozapps/extensions/content/extensions.xml
+++ b/toolkit/mozapps/extensions/content/extensions.xml
@@ -4,16 +4,18 @@
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
 
 <!DOCTYPE page [
 <!ENTITY % extensionsDTD SYSTEM "chrome://mozapps/locale/extensions/extensions.dtd">
 %extensionsDTD;
 ]>
 
+<!-- import-globals-from extensions.js -->
+
 <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">
 
 
   <!-- Rating - displays current/average rating, allows setting user rating -->
   <binding id="rating">
--- a/toolkit/mozapps/extensions/content/setting.xml
+++ b/toolkit/mozapps/extensions/content/setting.xml
@@ -3,16 +3,18 @@
    - 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/. -->
 
 <!DOCTYPE page [
 <!ENTITY % extensionsDTD SYSTEM "chrome://mozapps/locale/extensions/extensions.dtd">
 %extensionsDTD;
 ]>
 
+<!-- import-globals-from extensions.js -->
+
 <bindings xmlns="http://www.mozilla.org/xbl"
           xmlns:xbl="http://www.mozilla.org/xbl"
           xmlns:html="http://www.w3.org/1999/xhtml"
           xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <binding id="settings">
     <content orient="vertical">
       <xul:label class="settings-title" xbl:inherits="xbl:text=label" flex="1"/>
--- a/toolkit/mozapps/extensions/internal/AddonRepository.jsm
+++ b/toolkit/mozapps/extensions/internal/AddonRepository.jsm
@@ -6,16 +6,17 @@
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const Cr = Components.results;
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/AddonManager.jsm");
+/*globals AddonManagerPrivate*/
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
                                   "resource://gre/modules/NetUtil.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "OS",
                                   "resource://gre/modules/osfile.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "DeferredSave",
                                   "resource://gre/modules/DeferredSave.jsm");
@@ -423,17 +424,18 @@ AddonSearchResult.prototype = {
       aListener.onNoUpdateAvailable(this);
     if ("onUpdateFinished" in aListener)
       aListener.onUpdateFinished(this);
   },
 
   toJSON: function() {
     let json = {};
 
-    for (let [property, value] of Iterator(this)) {
+    for (let property of Object.keys(this)) {
+      let value = this[property];
       if (property.startsWith("_") ||
           typeof(value) === "function")
         continue;
 
       try {
         switch (property) {
           case "sourceURI":
             json.sourceURI = value ? value.spec : "";
@@ -446,17 +448,18 @@ AddonSearchResult.prototype = {
           default:
             json[property] = value;
         }
       } catch (ex) {
         logger.warn("Error writing property value for " + property);
       }
     }
 
-    for (let [property, value] of Iterator(this._unsupportedProperties)) {
+    for (let property of Object.keys(this._unsupportedProperties)) {
+      let value = this._unsupportedProperties[property];
       if (!property.startsWith("_"))
         json[property] = value;
     }
 
     return json;
   }
 }
 
@@ -1828,17 +1831,17 @@ var AddonDatabase = {
       return aObj;
 
     let id = aObj.id;
     if (!aObj.id)
       return null;
 
     let addon = new AddonSearchResult(id);
 
-    for (let [expectedProperty,] of Iterator(AddonSearchResult.prototype)) {
+    for (let expectedProperty of Object.keys(AddonSearchResult.prototype)) {
       if (!(expectedProperty in aObj) ||
           typeof(aObj[expectedProperty]) === "function")
         continue;
 
       let value = aObj[expectedProperty];
 
       try {
         switch (expectedProperty) {
@@ -1876,18 +1879,18 @@ var AddonDatabase = {
               addon.compatibilityOverrides.push(
                 this._makeCompatOverride(override)
               );
             }
             break;
 
           case "icons":
             if (!addon.icons) addon.icons = {};
-            for (let [size, url] of Iterator(aObj.icons)) {
-              addon.icons[size] = url;
+            for (let size of Object.keys(aObj.icons)) {
+              addon.icons[size] = aObj.icons[size];
             }
             break;
 
           case "iconURL":
             break;
 
           default:
             addon[expectedProperty] = value;
--- a/toolkit/mozapps/extensions/internal/AddonRepository_SQLiteMigrator.jsm
+++ b/toolkit/mozapps/extensions/internal/AddonRepository_SQLiteMigrator.jsm
@@ -5,16 +5,17 @@
 "use strict";
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/AddonManager.jsm");
+/*globals AddonManagerPrivate*/
 Cu.import("resource://gre/modules/FileUtils.jsm");
 
 const KEY_PROFILEDIR  = "ProfD";
 const FILE_DATABASE   = "addons.sqlite";
 const LAST_DB_SCHEMA   = 4;
 
 // Add-on properties present in the columns of the database
 const PROP_SINGLE = ["id", "type", "name", "version", "creator", "description",
--- a/toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm
+++ b/toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm
@@ -269,17 +269,18 @@ function sanitizeUpdateURL(aUpdate, aReq
  *         The XMLHttpRequest that has retrieved the update manifest
  * @param  aManifestData
  *         The pre-parsed manifest, as a bare XML DOM document
  * @return an array of update objects
  * @throws if the update manifest is invalid in any way
  */
 function parseRDFManifest(aId, aUpdateKey, aRequest, aManifestData) {
   if (aManifestData.documentElement.namespaceURI != PREFIX_NS_RDF) {
-    throw Components.Exception("Update manifest had an unrecognised namespace: " + xml.documentElement.namespaceURI);
+    throw Components.Exception("Update manifest had an unrecognised namespace: " +
+                               aManifestData.documentElement.namespaceURI);
     return undefined;
   }
 
   function EM_R(aProp) {
     return gRDF.GetResource(PREFIX_NS_EM + aProp);
   }
 
   function getValue(aLiteral) {
--- a/toolkit/mozapps/extensions/internal/Content.js
+++ b/toolkit/mozapps/extensions/internal/Content.js
@@ -1,12 +1,14 @@
 /* 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/. */
 
+/*globals addMessageListener*/
+
 "use strict";
 
 (function() {
 
 var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 var {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
 
--- a/toolkit/mozapps/extensions/internal/GMPProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/GMPProvider.jsm
@@ -7,22 +7,25 @@
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 this.EXPORTED_SYMBOLS = [];
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/AddonManager.jsm");
+/*globals AddonManagerPrivate*/
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Preferences.jsm");
 Cu.import("resource://gre/modules/osfile.jsm");
+/*globals OS*/
 Cu.import("resource://gre/modules/Log.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 Cu.import("resource://gre/modules/GMPUtils.jsm");
+/*globals EME_ADOBE_ID, GMP_PLUGIN_IDS, GMPPrefs, GMPUtils, OPEN_H264_ID*/
 Cu.import("resource://gre/modules/AppConstants.jsm");
 Cu.import("resource://gre/modules/UpdateUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(
   this, "GMPInstallManager", "resource://gre/modules/GMPInstallManager.jsm");
 XPCOMUtils.defineLazyModuleGetter(
   this, "setTimeout", "resource://gre/modules/Timer.jsm");
 
--- a/toolkit/mozapps/extensions/internal/LightweightThemeImageOptimizer.jsm
+++ b/toolkit/mozapps/extensions/internal/LightweightThemeImageOptimizer.jsm
@@ -17,17 +17,17 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
   "resource://gre/modules/FileUtils.jsm");
 
 const ORIGIN_TOP_RIGHT = 1;
 const ORIGIN_BOTTOM_LEFT = 2;
 
 this.LightweightThemeImageOptimizer = {
   optimize: function(aThemeData, aScreen) {
-    let data = Utils.createCopy(aThemeData);
+    let data = Object.assign({}, aThemeData);
     if (!data.headerURL) {
       return data;
     }
 
     data.headerURL = ImageCropper.getCroppedImageURL(
       data.headerURL, aScreen, ORIGIN_TOP_RIGHT);
 
     if (data.footerURL) {
@@ -173,17 +173,8 @@ var ImageTools = {
 
     return stream;
   }
 };
 
 XPCOMUtils.defineLazyServiceGetter(ImageTools, "_imgTools",
   "@mozilla.org/image/tools;1", "imgITools");
 
-var Utils = {
-  createCopy: function(aData) {
-    let copy = {};
-    for (let [k, v] in Iterator(aData)) {
-      copy[k] = v;
-    }
-    return copy;
-  }
-};
--- a/toolkit/mozapps/extensions/internal/PluginProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/PluginProvider.jsm
@@ -6,16 +6,17 @@
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 this.EXPORTED_SYMBOLS = [];
 
 Cu.import("resource://gre/modules/AddonManager.jsm");
+/*globals AddonManagerPrivate*/
 Cu.import("resource://gre/modules/Services.jsm");
 
 const URI_EXTENSION_STRINGS  = "chrome://mozapps/locale/extensions/extensions.properties";
 const STRING_TYPE_NAME       = "type.%ID%.name";
 const LIST_UPDATED_TOPIC     = "plugins-list-updated";
 const FLASH_MIME_TYPE        = "application/x-shockwave-flash";
 
 Cu.import("resource://gre/modules/Log.jsm");
--- a/toolkit/mozapps/extensions/internal/ProductAddonChecker.jsm
+++ b/toolkit/mozapps/extensions/internal/ProductAddonChecker.jsm
@@ -6,19 +6,21 @@
 
 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
 this.EXPORTED_SYMBOLS = [ "ProductAddonChecker" ];
 
 Cu.import("resource://gre/modules/Task.jsm");
 Cu.import("resource://gre/modules/Log.jsm");
 Cu.import("resource://gre/modules/CertUtils.jsm");
+/*globals checkCert, BadCertHandler*/
 Cu.import("resource://gre/modules/FileUtils.jsm");
 Cu.import("resource://gre/modules/NetUtil.jsm");
 Cu.import("resource://gre/modules/osfile.jsm");
+/*globals OS*/
 
 var logger = Log.repository.getLogger("addons.productaddons");
 
 /**
  * Number of milliseconds after which we need to cancel `downloadXML`.
  *
  * Bug 1087674 suggests that the XHR we use in `downloadXML` may
  * never terminate in presence of network nuisances (e.g. strange
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -13,16 +13,17 @@ this.EXPORTED_SYMBOLS = ["XPIProvider"];
 
 const CONSTANTS = {};
 Cu.import("resource://gre/modules/addons/AddonConstants.jsm", CONSTANTS);
 const { ADDON_SIGNING, REQUIRE_SIGNING } = CONSTANTS
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/AddonManager.jsm");
+/*globals AddonManagerPrivate*/
 Cu.import("resource://gre/modules/Preferences.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "AddonRepository",
                                   "resource://gre/modules/addons/AddonRepository.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ChromeManifestParser",
                                   "resource://gre/modules/ChromeManifestParser.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "LightweightThemeManager",
                                   "resource://gre/modules/LightweightThemeManager.jsm");
@@ -271,16 +272,17 @@ var gIDTest = /^(\{[0-9a-f]{8}-[0-9a-f]{
 Cu.import("resource://gre/modules/Log.jsm");
 const LOGGER_ID = "addons.xpi";
 
 // Create a new logger for use by all objects in this Addons XPI Provider module
 // (Requires AddonManager.jsm)
 var logger = Log.repository.getLogger(LOGGER_ID);
 
 const LAZY_OBJECTS = ["XPIDatabase", "XPIDatabaseReconcile"];
+/*globals XPIDatabase, XPIDatabaseReconcile*/
 
 var gLazyObjectsLoaded = false;
 
 function loadLazyObjects() {
   let uri = "resource://gre/modules/addons/XPIProviderUtils.js";
   let scope = Cu.Sandbox(Services.scriptSecurityManager.getSystemPrincipal(), {
     sandboxName: uri,
     wantGlobalProperties: ["TextDecoder"],
@@ -569,17 +571,17 @@ SafeInstallOperation.prototype = {
    * Rolls back all the moves that this operation performed. If an exception
    * occurs here then both old and new directories are left in an indeterminate
    * state
    */
   rollback: function() {
     while (this._installedFiles.length > 0) {
       let move = this._installedFiles.pop();
       if (move.isMoveTo) {
-        move.newFile.moveTo(oldDir.parent, oldDir.leafName);
+        move.newFile.moveTo(move.oldDir.parent, move.oldDir.leafName);
       }
       else if (move.newFile.isDirectory()) {
         let oldDir = move.oldFile.parent.clone();
         oldDir.append(move.oldFile.leafName);
         oldDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
       }
       else if (!move.oldFile) {
         // No old file means this was a copied file
@@ -3628,18 +3630,18 @@ this.XPIProvider = {
         if (this.currentSkin != this.defaultSkin) {
           let oldSkin = XPIDatabase.getVisibleAddonForInternalName(this.currentSkin);
           if (!oldSkin || oldSkin.disabled)
             this.enableDefaultTheme();
         }
 
         // When upgrading remove the old extensions cache to force older
         // versions to rescan the entire list of extensions
+        let oldCache = FileUtils.getFile(KEY_PROFILEDIR, [FILE_OLD_CACHE], true);
         try {
-          let oldCache = FileUtils.getFile(KEY_PROFILEDIR, [FILE_OLD_CACHE], true);
           if (oldCache.exists())
             oldCache.remove(true);
         }
         catch (e) {
           logger.warn("Unable to remove old extension cache " + oldCache.path, e);
         }
       }
 
--- a/toolkit/mozapps/extensions/internal/XPIProviderUtils.js
+++ b/toolkit/mozapps/extensions/internal/XPIProviderUtils.js
@@ -1,22 +1,29 @@
 /* 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/. */
 
 "use strict";
 
+// These are injected from XPIProvider.jsm
+/*globals ADDON_SIGNING, SIGNED_TYPES, BOOTSTRAP_REASONS, DB_SCHEMA,
+          AddonInternal, XPIProvider, XPIStates, syncLoadManifestFromFile,
+          isUsableAddon, recordAddonTelemetry, applyBlocklistChanges,
+          flushStartupCache, canRunInSafeMode*/
+
 var Cc = Components.classes;
 var Ci = Components.interfaces;
 var Cr = Components.results;
 var Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/AddonManager.jsm");
+/*globals AddonManagerPrivate*/
 Cu.import("resource://gre/modules/Preferences.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "AddonRepository",
                                   "resource://gre/modules/addons/AddonRepository.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
                                   "resource://gre/modules/FileUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "DeferredSave",
                                   "resource://gre/modules/DeferredSave.jsm");
--- a/toolkit/mozapps/extensions/nsBlocklistService.js
+++ b/toolkit/mozapps/extensions/nsBlocklistService.js
@@ -14,16 +14,17 @@ Components.utils.import("resource://gre/
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/AppConstants.jsm");
 
 try {
   // AddonManager.jsm doesn't allow itself to be imported in the child
   // process. We're used in the child process (for now), so guard against
   // this.
   Components.utils.import("resource://gre/modules/AddonManager.jsm");
+  /*globals AddonManagerPrivate*/
 } catch (e) {
 }
 
 XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
                                   "resource://gre/modules/FileUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
                                   "resource://gre/modules/UpdateUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "OS",
--- a/toolkit/mozapps/extensions/test/addons/test_bug675371/test.js
+++ b/toolkit/mozapps/extensions/test/addons/test_bug675371/test.js
@@ -1,1 +1,1 @@
-active = true;
+var active = true;
--- a/toolkit/mozapps/extensions/test/browser/browser_bug593535.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_bug593535.js
@@ -5,16 +5,17 @@
 // Bug 593535 - Failure to download extension causes about:addons to list the
 // addon with no way to restart the download
 
 const PREF_GETADDONS_GETSEARCHRESULTS = "extensions.getAddons.search.url";
 const SEARCH_URL = TESTROOT + "browser_bug593535.xml";
 const QUERY = "NOTFOUND";
 
 var gProvider;
+var gManagerWindow;
 
 function test() {
   waitForExplicitFinish();
 
   // Turn on searching for this test
   Services.prefs.setIntPref(PREF_SEARCH_MAXRESULTS, 15);
 
   open_manager("addons://list/extension", function(aWindow) {
--- a/toolkit/mozapps/extensions/test/browser/discovery_install.html
+++ b/toolkit/mozapps/extensions/test/browser/discovery_install.html
@@ -1,11 +1,12 @@
 <html>
 <head>
 <script type="text/javascript">
+/*globals InstallTrigger*/
 function install() {
   InstallTrigger.install({
     "Test Add-on": {
       URL: "https://example.com/browser/toolkit/mozapps/extensions/test/xpinstall/unsigned.xpi"
     }
   });
 }
 </script>
--- a/toolkit/mozapps/extensions/test/browser/head.js
+++ b/toolkit/mozapps/extensions/test/browser/head.js
@@ -1,11 +1,12 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
+/*globals end_test*/
 
 Components.utils.import("resource://gre/modules/NetUtil.jsm");
 
 var tmp = {};
 Components.utils.import("resource://gre/modules/AddonManager.jsm", tmp);
 Components.utils.import("resource://gre/modules/Log.jsm", tmp);
 var AddonManager = tmp.AddonManager;
 var AddonManagerPrivate = tmp.AddonManagerPrivate;
@@ -1338,17 +1339,17 @@ MockInstall.prototype = {
 
         AddonManagerPrivate.callAddonListeners("onInstalling", this.addon);
 
         this.state = AddonManager.STATE_INSTALLED;
         this.callListeners("onInstallEnded");
         break;
       case AddonManager.STATE_DOWNLOADING:
       case AddonManager.STATE_CHECKING:
-      case AddonManger.STATE_INSTALLING:
+      case AddonManager.STATE_INSTALLING:
         // Installation is already running
         return;
       default:
         ok(false, "Cannot start installing when state = " + this.state);
     }
   },
 
   cancel: function() {
--- a/toolkit/mozapps/extensions/test/xpcshell/head_addons.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/head_addons.js
@@ -32,29 +32,29 @@ const MAKE_FILE_OLD_DIFFERENCE = 10 * 36
 
 Components.utils.import("resource://gre/modules/addons/AddonRepository.jsm");
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/FileUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/NetUtil.jsm");
 Components.utils.import("resource://gre/modules/Promise.jsm");
 Components.utils.import("resource://gre/modules/Task.jsm");
-Components.utils.import("resource://gre/modules/osfile.jsm");
+const { OS } = Components.utils.import("resource://gre/modules/osfile.jsm", {});
 Components.utils.import("resource://gre/modules/AsyncShutdown.jsm");
 Components.utils.import("resource://testing-common/MockRegistrar.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Extension",
                                   "resource://gre/modules/Extension.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "HttpServer",
                                   "resource://testing-common/httpd.js");
 
 // We need some internal bits of AddonManager
-var AMscope = Components.utils.import("resource://gre/modules/AddonManager.jsm");
-var AddonManager = AMscope.AddonManager;
-var AddonManagerInternal = AMscope.AddonManagerInternal;
+var AMscope = Components.utils.import("resource://gre/modules/AddonManager.jsm", {});
+var { AddonManager, AddonManagerInternal, AddonManagerPrivate } = AMscope;
+
 // Mock out AddonManager's reference to the AsyncShutdown module so we can shut
 // down AddonManager from the test
 var MockAsyncShutdown = {
   hook: null,
   status: null,
   profileBeforeChange: {
     addBlocker: function(aName, aBlocker, aOptions) {
       do_print("Mock profileBeforeChange blocker for '" + aName + "'");
@@ -464,17 +464,17 @@ function overrideCertDB(handler) {
     if (typeof realCertDB[property] == "function") {
       fakeCertDB[property] = realCertDB[property].bind(realCertDB);
     }
   }
 
   let certDBFactory = {
     createInstance: function(outer, iid) {
       if (outer != null) {
-        throw Cr.NS_ERROR_NO_AGGREGATION;
+        throw Components.results.NS_ERROR_NO_AGGREGATION;
       }
       return fakeCertDB.QueryInterface(iid);
     }
   };
   registrar.registerFactory(CERTDB_CID, "CertDB",
                             CERTDB_CONTRACTID, certDBFactory);
 }
 
@@ -1789,17 +1789,17 @@ if ("nsIWindowsRegKey" in AM_Ci) {
       switch (aRoot) {
       case AM_Ci.nsIWindowsRegKey.ROOT_KEY_LOCAL_MACHINE:
         return MockRegistry.LOCAL_MACHINE;
       case AM_Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER:
         return MockRegistry.CURRENT_USER;
       case AM_Ci.nsIWindowsRegKey.ROOT_KEY_CLASSES_ROOT:
         return MockRegistry.CLASSES_ROOT;
       default:
-        do_throw("Unknown root " + aRootKey);
+        do_throw("Unknown root " + aRoot);
         return null;
       }
     },
 
     setValue: function(aRoot, aPath, aName, aValue) {
       let rootKey = MockRegistry.getRoot(aRoot);
 
       if (!(aPath in rootKey)) {
--- a/toolkit/mozapps/extensions/test/xpcshell/head_unpack.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/head_unpack.js
@@ -1,2 +1,3 @@
+/*globals Services, TEST_UNPACKED: true*/
 Services.prefs.setBoolPref("extensions.alwaysUnpack", true);
 TEST_UNPACKED = true;
--- a/toolkit/mozapps/extensions/test/xpcshell/test_DeferredSave.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_DeferredSave.js
@@ -298,17 +298,16 @@ add_task(function* dirty_while_writing()
   do_check_eq(tester.writtenData, thirdData);
   do_check_eq(2, tester.saver.totalSaves);
   do_check_eq(1, tester.saver.overlappedSaves);
 });
 
 // A write callback for the OS.File.writeAtomic mock that rejects write attempts
 function disabled_write_callback(aTester) {
   do_throw("Should not have written during clean flush");
-  deferred.reject(new Error("Write during supposedly clean flush"));
 }
 
 // special write callback that disables itself to make sure
 // we don't try to write twice
 function write_then_disable(aTester) {
   do_print("write_then_disable");
   let length = aTester.writtenData.length;
   aTester.writeHandler = disabled_write_callback;
--- a/toolkit/mozapps/extensions/test/xpcshell/test_bug393285.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_bug393285.js
@@ -253,17 +253,17 @@ function run_test() {
       minVersion: "1",
       maxVersion: "3"
     }]
   }, profileDir);
 
   startupManager();
 
   AddonManager.getAddonsByIDs(addonIDs, function(addons) {
-    for (addon of addons) {
+    for (let addon of addons) {
       do_check_eq(addon.blocklistState, Ci.nsIBlocklistService.STATE_NOT_BLOCKED);
     }
     run_test_1();
   });
 }
 
 function run_test_1() {
   load_blocklist("test_bug393285.xml", function() {
--- a/toolkit/mozapps/extensions/test/xpcshell/test_bug406118.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_bug406118.js
@@ -120,17 +120,17 @@ function run_test() {
       minVersion: "1",
       maxVersion: "3"
     }]
   }, profileDir);
 
   startupManager();
 
   AddonManager.getAddonsByIDs(addonIDs, function(addons) {
-    for (addon of addons) {
+    for (let addon of addons) {
       do_check_eq(addon.blocklistState, Ci.nsIBlocklistService.STATE_NOT_BLOCKED);
     }
     run_test_1();
   });
 }
 
 function run_test_1() {
   load_blocklist("test_bug393285.xml", function() {
--- a/toolkit/mozapps/extensions/test/xpcshell/test_bug675371.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_bug675371.js
@@ -30,17 +30,17 @@ function run_test() {
 }
 
 function check_test() {
   AddonManager.getAddonByID("bug675371@tests.mozilla.org", do_exception_wrap(function(addon) {
     do_check_neq(addon, null);
     do_check_true(addon.isActive);
 
     // Tests that chrome.manifest is registered when the addon is installed.
-    var target = { active: false };
+    var target = { };
     Services.scriptloader.loadSubScript("chrome://bug675371/content/test.js", target);
     do_check_true(target.active);
 
     prepare_test({
       "bug675371@tests.mozilla.org": [
         ["onDisabling", false],
         "onDisabled"
       ]
--- a/toolkit/mozapps/extensions/test/xpcshell/test_fuel.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_fuel.js
@@ -136,16 +136,17 @@ function run_test() {
       do_check_true(!inspector.prefs.has(testdata.dummy));
 
       inspector.prefs.events.addListener("change", onPrefChange);
       inspector.prefs.setValue("fuel.fuel-test", "change event");
     });
   });
 }
 
+var gLastEvent;
 function onGenericEvent(event) {
   gLastEvent = event.type;
 }
 
 function onPrefChange(evt) {
   Application.getExtensions(function(extensions) {
     var inspector3 = extensions.get(testdata.inspectorid);
 
--- a/toolkit/mozapps/extensions/test/xpcshell/test_gfxBlacklist_prefs.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_gfxBlacklist_prefs.js
@@ -1,12 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
+var { classes: Cc, interfaces: Ci } = Components;
+
 // Test whether the blacklist succesfully adds and removes the prefs that store
 // its decisions when the remote blacklist is changed.
 // Uses test_gfxBlacklist.xml and test_gfxBlacklist2.xml
 
 Components.utils.import("resource://testing-common/httpd.js");
 
 var gTestserver = new HttpServer();
 gTestserver.start(-1);
--- a/toolkit/mozapps/extensions/test/xpcshell/test_mapURIToAddonID.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_mapURIToAddonID.js
@@ -28,17 +28,17 @@ TestProvider.prototype = {
   uri: Services.io.newURI("hellow://world", null, null),
   id: "valid@id",
   startup: function() {},
   shutdown: function() {},
   mapURIToAddonID: function(aURI) {
     if (aURI.spec === this.uri.spec) {
       return this.id;
     }
-    throw Components.Exception("Not mapped", result);
+    throw Components.Exception("Not mapped", this.result);
   }
 };
 
 function TestProviderNoMap() {}
 TestProviderNoMap.prototype = {
   startup: function() {},
   shutdown: function() {}
 };
--- a/toolkit/mozapps/extensions/test/xpcshell/test_pluginchange.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_pluginchange.js
@@ -26,26 +26,26 @@ PluginTag.prototype = {
   mimeTypes: [],
 
   getMimeTypes: function(count) {
     count.value = this.mimeTypes.length;
     return this.mimeTypes;
   }
 };
 
-PLUGINS = [
+const PLUGINS = [
   // A standalone plugin
   new PluginTag("Java", "A mock Java plugin"),
 
   // A plugin made up of two plugin files
   new PluginTag("Flash", "A mock Flash plugin"),
   new PluginTag("Flash", "A mock Flash plugin")
 ];
 
-gPluginHost = {
+const gPluginHost = {
   // nsIPluginHost
   getPluginTags: function(count) {
     count.value = PLUGINS.length;
     return PLUGINS;
   },
 
   QueryInterface: XPCOMUtils.generateQI([AM_Ci.nsIPluginHost])
 };
--- a/toolkit/mozapps/extensions/test/xpcshell/test_provider_unsafe_access_shutdown.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_provider_unsafe_access_shutdown.js
@@ -13,17 +13,17 @@ function mockAddonProvider(name) {
     shutdown() {
       this.hasShutdown = true;
       shutdownOrder.push(this.name);
       if (this.shutdownCallback)
         return this.shutdownCallback();
     },
     getAddonByID(id, callback) {
       if (this.hasShutdown) {
-        unsafeAccess = true;
+        this.unsafeAccess = true;
       }
       callback(null);
     },
 
     get name() {
       return name;
     },
   };
--- a/toolkit/mozapps/extensions/test/xpcshell/test_provider_unsafe_access_startup.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_provider_unsafe_access_startup.js
@@ -12,17 +12,17 @@ function mockAddonProvider(name) {
     startup() {
       this.hasStarted = true;
       startupOrder.push(this.name);
       if (this.startupCallback)
         this.startupCallback();
     },
     getAddonByID(id, callback) {
       if (!this.hasStarted) {
-        unsafeAccess = true;
+        this.unsafeAccess = true;
       }
       callback(null);
     },
 
     get name() {
       return name;
     },
   };
--- a/toolkit/mozapps/extensions/test/xpcshell/test_seen.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_seen.js
@@ -104,17 +104,17 @@ add_task(function*() {
 
   yield promiseRestartManager();
 
   addon = yield promiseAddonByID(ID);
   do_check_true(addon.foreignInstall);
   do_check_false(addon.seen);
 
   // Updating through the API shouldn't change the state
-  install = yield new Promise(resolve => AddonManager.getInstallForFile(do_get_addon("test_bootstrap1_2"), resolve));
+  let install = yield new Promise(resolve => AddonManager.getInstallForFile(do_get_addon("test_bootstrap1_2"), resolve));
   yield promiseCompleteAllInstalls([install]);
   do_check_eq(install.state, AddonManager.STATE_INSTALLED);
   do_check_false(hasFlag(install.addon.pendingOperations, AddonManager.PENDING_INSTALL));
 
   addon = install.addon;
   do_check_true(addon.foreignInstall);
   do_check_false(addon.seen);
 
@@ -185,17 +185,17 @@ add_task(function*() {
 
   yield promiseRestartManager();
 
   addon = yield promiseAddonByID(ID);
   do_check_true(addon.foreignInstall);
   do_check_true(addon.seen);
 
   // Updating through the API shouldn't change the state
-  install = yield new Promise(resolve => AddonManager.getInstallForFile(do_get_addon("test_bootstrap1_2"), resolve));
+  let install = yield new Promise(resolve => AddonManager.getInstallForFile(do_get_addon("test_bootstrap1_2"), resolve));
   yield promiseCompleteAllInstalls([install]);
   do_check_eq(install.state, AddonManager.STATE_INSTALLED);
   do_check_false(hasFlag(install.addon.pendingOperations, AddonManager.PENDING_INSTALL));
 
   addon = install.addon;
   do_check_true(addon.foreignInstall);
   do_check_true(addon.seen);
 
--- a/toolkit/mozapps/extensions/test/xpcshell/test_undouninstall.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_undouninstall.js
@@ -345,17 +345,17 @@ add_task(function* cancelUninstallOfRest
   }, [
     "onNewInstall",
     "onInstallStarted",
     "onInstallEnded"
   ]);
   yield promiseInstallAllFiles([do_get_addon("test_undouninstall1")]);
   ensure_test_completed();
 
-  a1 = yield promiseAddonByID(ID);
+  let a1 = yield promiseAddonByID(ID);
 
   do_check_neq(a1, null);
   BootstrapMonitor.checkAddonInstalled(ID, "1.0");
   BootstrapMonitor.checkAddonStarted(ID, "1.0");
   do_check_eq(getInstallReason(ID), ADDON_INSTALL);
   do_check_eq(getStartupReason(ID), ADDON_INSTALL);
   do_check_eq(a1.pendingOperations, AddonManager.PENDING_NONE);
   do_check_true(a1.isActive);
--- a/toolkit/mozapps/extensions/test/xpcshell/test_updateCancel.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_updateCancel.js
@@ -47,17 +47,16 @@ function makeCancelListener() {
     },
     promise: updated.promise
   };
 }
 
 // Set up the HTTP server so that we can control when it responds
 var httpReceived = Promise.defer();
 function dataHandler(aRequest, aResponse) {
-  asyncResponse = aResponse;
   aResponse.processAsync();
   httpReceived.resolve([aRequest, aResponse]);
 }
 var testserver = new HttpServer();
 testserver.registerDirectory("/addons/", do_get_file("addons"));
 testserver.registerPathHandler("/data/test_update.rdf", dataHandler);
 testserver.start(-1);
 gPort = testserver.identity.primaryPort;
--- a/toolkit/mozapps/extensions/test/xpcshell/test_webextension_icons.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_webextension_icons.js
@@ -43,17 +43,17 @@ add_task(function*() {
     }
   }, profileDir);
 
   yield promiseRestartManager();
   yield promiseAddonStartup();
 
   let uri = do_get_addon_root_uri(profileDir, ID);
 
-  addon = yield promiseAddonByID(ID);
+  let addon = yield promiseAddonByID(ID);
   do_check_neq(addon, null);
 
   function check_icons(addon) {
     deepEqual(addon.icons, {
         16: uri + "icon16.png",
         32: uri + "icon32.png",
         48: uri + "icon48.png",
         64: uri + "icon64.png"
--- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini
+++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini
@@ -189,16 +189,18 @@ skip-if = os == "android"
 [test_gfxBlacklist_OK.js]
 [test_gfxBlacklist_OS.js]
 [test_gfxBlacklist_OSVersion_match.js]
 [test_gfxBlacklist_OSVersion_mismatch_OSVersion.js]
 [test_gfxBlacklist_OSVersion_mismatch_DriverVersion.js]
 [test_gfxBlacklist_Vendor.js]
 [test_gfxBlacklist_Version.js]
 [test_gfxBlacklist_prefs.js]
+# Bug 1248787 - consistently fails
+skip-if = true
 [test_hasbinarycomponents.js]
 [test_hotfix.js]
 [test_install.js]
 [test_install_icons.js]
 # Bug 676992: test consistently hangs on Android
 skip-if = os == "android"
 [test_install_strictcompat.js]
 # Bug 676992: test consistently hangs on Android
--- a/toolkit/mozapps/extensions/test/xpinstall/browser_bug672485.js
+++ b/toolkit/mozapps/extensions/test/xpinstall/browser_bug672485.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
-gWindowWatcher = null;
+var gWindowWatcher = null;
 
 function test() {
   Harness.installConfirmCallback = confirm_install;
   Harness.installCancelledCallback = cancelled_install;
   Harness.installEndedCallback = complete_install;
   Harness.installsCompletedCallback = finish_test;
   Harness.setup();
 
--- a/toolkit/mozapps/extensions/test/xpinstall/browser_concurrent_installs.js
+++ b/toolkit/mozapps/extensions/test/xpinstall/browser_concurrent_installs.js
@@ -1,18 +1,17 @@
 // Test that having two frames that request installs at the same time doesn't
 // cause callback ID conflicts (discussed in bug 926712)
 
-var {Promise} = Cu.import("resource://gre/modules/Promise.jsm");
-
 var gConcurrentTabs = [];
 var gQueuedForInstall = [];
 var gResults = [];
 
 function frame_script() {
+  /*globals addMessageListener, sendAsyncMessage*/
   addMessageListener("Test:StartInstall", () => {
     content.document.getElementById("installnow").click()
   });
 
   addEventListener("load", () => {
     sendAsyncMessage("Test:Loaded");
 
     content.addEventListener("InstallComplete", (e) => {
--- a/toolkit/mozapps/extensions/test/xpinstall/browser_whitelist3.js
+++ b/toolkit/mozapps/extensions/test/xpinstall/browser_whitelist3.js
@@ -1,23 +1,23 @@
 // ----------------------------------------------------------------------------
 // Tests installing an unsigned add-on through a navigation. Should not be
 // blocked since the referer is whitelisted.
-var URL = TESTROOT2 + "navigate.html?" + encodeURIComponent(TESTROOT + "unsigned.xpi");
+var url = TESTROOT2 + "navigate.html?" + encodeURIComponent(TESTROOT + "unsigned.xpi");
 
 function test() {
   Harness.installConfirmCallback = confirm_install;
   Harness.installsCompletedCallback = finish_test;
   Harness.setup();
 
   var pm = Services.perms;
   pm.add(makeURI("http://example.org/"), "install", pm.ALLOW_ACTION);
 
   gBrowser.selectedTab = gBrowser.addTab();
-  gBrowser.loadURI(URL);
+  gBrowser.loadURI(url);
 }
 
 function confirm_install(window) {
   return false;
 }
 
 function finish_test(count) {
   is(count, 0, "No add-ons should have been installed");
--- a/toolkit/mozapps/extensions/test/xpinstall/browser_whitelist4.js
+++ b/toolkit/mozapps/extensions/test/xpinstall/browser_whitelist4.js
@@ -1,28 +1,28 @@
 // ----------------------------------------------------------------------------
 // Tests installing an unsigned add-on through a navigation. Should be
 // blocked since the referer is not whitelisted even though the target is.
-var URL = TESTROOT2 + "navigate.html?" + encodeURIComponent(TESTROOT + "unsigned.xpi");
+var url = TESTROOT2 + "navigate.html?" + encodeURIComponent(TESTROOT + "unsigned.xpi");
 
 function test() {
   Harness.installBlockedCallback = allow_blocked;
   Harness.installsCompletedCallback = finish_test;
   Harness.setup();
 
   var pm = Services.perms;
   pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
 
   gBrowser.selectedTab = gBrowser.addTab();
-  gBrowser.loadURI(URL);
+  gBrowser.loadURI(url);
 }
 
 function allow_blocked(installInfo) {
   is(installInfo.browser, gBrowser.selectedBrowser, "Install should have been triggered by the right browser");
-  is(installInfo.originatingURI.spec, URL, "Install should have been triggered by the right uri");
+  is(installInfo.originatingURI.spec, url, "Install should have been triggered by the right uri");
   return false;
 }
 
 function finish_test(count) {
   is(count, 0, "No add-ons should have been installed");
   Services.perms.remove(makeURI("http://example.com"), "install");
 
   gBrowser.removeCurrentTab();
--- a/toolkit/mozapps/extensions/test/xpinstall/bug645699.html
+++ b/toolkit/mozapps/extensions/test/xpinstall/bug645699.html
@@ -1,16 +1,17 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
           "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
 <html>
 
 <head>
 <title>InstallTrigger tests</title>
 <script type="text/javascript">
+/*globals InstallTrigger*/
 function startInstall() {
   var whiteUrl = "https://example.org/";
 
   try {
     Object.defineProperty(window, "location", { value : { href : whiteUrl }	});
     throw new Error("Object.defineProperty(window, 'location', ...) should have thrown");
   } catch (exc) {
     if (!(exc instanceof TypeError))
--- a/toolkit/mozapps/extensions/test/xpinstall/concurrent_installs.html
+++ b/toolkit/mozapps/extensions/test/xpinstall/concurrent_installs.html
@@ -2,16 +2,17 @@
           "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
 <html>
 
 <head>
   <meta charset="utf-8">
 <title>Concurrent InstallTrigger tests</title>
 <script type="text/javascript">
+/*globals InstallTrigger*/
 function installCallback(url, status) {
   document.getElementById("status").textContent = status;
 
   dump("Sending InstallComplete\n");
   var event = new CustomEvent("InstallComplete", {detail: {loc: location.href, xpi: url}});
   window.dispatchEvent(event);
 }
 
--- a/toolkit/mozapps/extensions/test/xpinstall/enabled.html
+++ b/toolkit/mozapps/extensions/test/xpinstall/enabled.html
@@ -3,16 +3,17 @@
 
 <html>
 
 <!-- This page will test if InstallTrigger seems to be enabled -->
 
 <head>
 <title>InstallTrigger tests</title>
 <script type="text/javascript">
+/*globals InstallTrigger*/
 function init() {
   document.getElementById("enabled").textContent = InstallTrigger.enabled() ? "true" : "false";
   dump("Sending PageLoaded\n");
   var event = new CustomEvent("PageLoaded");
   window.dispatchEvent(event);
 }
 </script>
 </head>
--- a/toolkit/mozapps/extensions/test/xpinstall/installchrome.html
+++ b/toolkit/mozapps/extensions/test/xpinstall/installchrome.html
@@ -3,16 +3,17 @@
 
 <html>
 
 <!-- This page will accept a url as the uri query and pass it to InstallTrigger.installChrome -->
 
 <head>
 <title>InstallTrigger tests</title>
 <script type="text/javascript">
+/*globals InstallTrigger*/
 function startInstall() {
   InstallTrigger.installChrome(InstallTrigger.SKIN,
                                decodeURIComponent(document.location.search.substring(1)),
                                "test");
 }
 </script>
 </head>
 <body onload="startInstall()">
--- a/toolkit/mozapps/extensions/test/xpinstall/installtrigger.html
+++ b/toolkit/mozapps/extensions/test/xpinstall/installtrigger.html
@@ -3,16 +3,17 @@
 
 <html>
 
 <!-- This page will accept some json as the uri query and pass it to InstallTrigger.install -->
 
 <head>
 <title>InstallTrigger tests</title>
 <script type="text/javascript">
+/*globals InstallTrigger*/
 function installCallback(url, status) {
   document.getElementById("status").textContent = status;
 
   dump("Sending InstallComplete\n");
   var event = new CustomEvent("InstallComplete");
   var target = window.parent ? window.parent : window;
   target.dispatchEvent(event);
 }
--- a/toolkit/mozapps/extensions/test/xpinstall/startsoftwareupdate.html
+++ b/toolkit/mozapps/extensions/test/xpinstall/startsoftwareupdate.html
@@ -3,16 +3,17 @@
 
 <html>
 
 <!-- This page will accept a url as the uri query and pass it to InstallTrigger.startSoftwareUpdate -->
 
 <head>
 <title>InstallTrigger tests</title>
 <script type="text/javascript">
+/*globals InstallTrigger*/
 function startInstall() {
   InstallTrigger.startSoftwareUpdate(decodeURIComponent(document.location.search.substring(1)));
 }
 </script>
 </head>
 <body onload="startInstall()">
 <p>InstallTrigger tests</p>
 </body>
--- a/toolkit/mozapps/extensions/test/xpinstall/triggerredirect.html
+++ b/toolkit/mozapps/extensions/test/xpinstall/triggerredirect.html
@@ -3,16 +3,17 @@
 
 <html>
 
 <!-- This page will attempt an install and then try to load a new page in the tab -->
 
 <head>
 <title>InstallTrigger tests</title>
 <script type="text/javascript">
+/*globals InstallTrigger*/
 function installCallback(url, status) {
   document.location = "#foo";
 
   dump("Sending InstallComplete\n");
   var event = new CustomEvent("InstallComplete");
   window.dispatchEvent(event);
 }