Bug 1341029 - Turn on the ESLint no-undef rule for all of toolkit/. r?jaws draft
authorMark Banner <standard8@mozilla.com>
Mon, 20 Feb 2017 11:45:58 +0000
changeset 488597 b37eb98076f73440213005f203619d4e5f59f6eb
parent 488596 5b458008ea653d14010864b569e8df0b29a270b6
child 546794 09345d47c7607f23edb4eb28cbee1fa7aa2a1ffe
push id46597
push userbmo:standard8@mozilla.com
push dateThu, 23 Feb 2017 14:53:22 +0000
reviewersjaws
bugs1341029
milestone54.0a1
Bug 1341029 - Turn on the ESLint no-undef rule for all of toolkit/. r?jaws MozReview-Commit-ID: Ed9FfkskDos
.eslintignore
testing/mochitest/chrome.eslintrc.js
toolkit/.eslintrc.js
toolkit/components/.eslintrc.js
toolkit/components/aboutcheckerboard/content/aboutCheckerboard.js
toolkit/components/aboutmemory/tests/xpcshell/.eslintrc.js
toolkit/components/addoncompat/tests/addon/bootstrap.js
toolkit/components/alerts/test/test_image.html
toolkit/components/exthelper/extApplication.js
toolkit/components/formautofill/test/chrome/loader_parent.js
toolkit/components/gfx/content/gfxFrameScript.js
toolkit/components/lz4/lz4_internal.js
toolkit/components/microformats/.eslintrc.js
toolkit/components/microformats/update/update.js
toolkit/components/mozprotocol/tests/.eslintrc.js
toolkit/components/perfmonitoring/tests/browser/browser_webpagePerformanceAlerts.js
toolkit/components/printing/content/printUtils.js
toolkit/components/printing/tests/.eslintrc.js
toolkit/components/printing/tests/browser_page_change_print_original.js
toolkit/components/prompts/content/selectDialog.js
toolkit/components/prompts/content/tabprompts.xml
toolkit/components/satchel/test/parent_utils.js
toolkit/components/viewsource/content/viewSource.js
toolkit/components/windowcreator/test/.eslintrc.js
toolkit/components/windowwatcher/test/browser_new_content_window_chromeflags.js
toolkit/content/.eslintrc.js
toolkit/content/aboutSupport.js
toolkit/content/datepicker.xhtml
toolkit/content/finddialog.js
toolkit/content/macWindowMenu.js
toolkit/content/tests/browser/browser_mediaPlayback_suspended.js
toolkit/content/tests/browser/browser_saveImageURL.js
toolkit/content/tests/browser/browser_save_resend_postdata.js
toolkit/content/tests/chrome/RegisterUnregisterChrome.js
toolkit/content/tests/chrome/popup_trigger.js
toolkit/content/tests/chrome/test_autocomplete_with_composition_on_input.html
toolkit/content/tests/widgets/test_videocontrols.html
toolkit/content/tests/widgets/tree_shared.js
toolkit/content/tests/widgets/videocontrols_direction_test.js
toolkit/content/timepicker.xhtml
toolkit/content/widgets/colorpicker.xml
toolkit/content/widgets/datepicker.js
toolkit/content/widgets/datetimebox.xml
toolkit/content/widgets/datetimepicker.xml
toolkit/content/widgets/datetimepopup.xml
toolkit/content/widgets/listbox.xml
toolkit/content/widgets/popup.xml
toolkit/content/widgets/textbox.xml
toolkit/content/widgets/timepicker.js
toolkit/content/widgets/toolbar.xml
toolkit/content/widgets/tree.xml
toolkit/content/widgets/videocontrols.xml
--- a/.eslintignore
+++ b/.eslintignore
@@ -281,16 +281,17 @@ toolkit/components/workerloader/tests/mo
 # Tests old non-star function generators
 toolkit/modules/tests/xpcshell/test_task.js
 
 # Not yet updated
 toolkit/components/osfile/**
 
 # External code:
 toolkit/components/microformats/test/**
+toolkit/components/microformats/microformat-shiv.js
 toolkit/components/reader/Readability.js
 toolkit/components/reader/JSDOMParser.js
 
 # Uses preprocessing
 toolkit/content/widgets/wizard.xml
 toolkit/components/jsdownloads/src/DownloadIntegration.jsm
 toolkit/components/url-classifier/**
 toolkit/components/urlformatter/nsURLFormatter.js
--- a/testing/mochitest/chrome.eslintrc.js
+++ b/testing/mochitest/chrome.eslintrc.js
@@ -14,20 +14,23 @@ module.exports = {
   // All globals made available in the test environment.
   "globals": {
     // `$` is defined in SimpleTest.js
     "$": false,
     "add_task": false,
     "addLoadEvent": false,
     "Assert": false,
     "BrowserTestUtils": false,
+    "ContentTask": false,
     "EventUtils": false,
     "executeSoon": false,
     "export_assertions": false,
+    "extractJarToTmp": false,
     "finish": false,
+    "getJar": false,
     "getRootDirectory": false,
     "getTestFilePath": false,
     "gTestPath": false,
     "info": false,
     "is": false,
     "isnot": false,
     "ok": false,
     "privateNoteIntentionalCrash": false,
--- a/toolkit/.eslintrc.js
+++ b/toolkit/.eslintrc.js
@@ -246,19 +246,23 @@ module.exports = {
     "es6": true,
     "browser": true,
   },
   "globals": {
     "ChromeWorker": false,
     "ChromeUtils": false,
     "Components": false,
     "dump": true,
+    // Specific to Firefox
+    // https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/InternalError
+    "InternalError": true,
     "KeyEvent": false,
     "openDialog": false,
     "MenuBoxObject": false,
+    "SimpleGestureEvent": false,
     "sizeToContent": false,
     "SharedArrayBuffer": false,
     // Note: StopIteration will likely be removed as part of removing legacy
     // generators, see bug 968038.
     "StopIteration": false,
     // Specific to Firefox
     // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/uneval
     "uneval": false
deleted file mode 100644
--- a/toolkit/components/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
-  "rules": {
-    "no-undef": "off"
-  }
-};
--- a/toolkit/components/aboutcheckerboard/content/aboutCheckerboard.js
+++ b/toolkit/components/aboutcheckerboard/content/aboutCheckerboard.js
@@ -1,12 +1,15 @@
 /* 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/. */
 
+// Global in the DOM for privileged code only.
+/* global CheckerboardReportService */
+
 "use strict";
 
 var trace;
 var service;
 var reports;
 
 function onLoad() {
   trace = document.getElementById("trace");
new file mode 100644
--- /dev/null
+++ b/toolkit/components/aboutmemory/tests/xpcshell/.eslintrc.js
@@ -0,0 +1,7 @@
+"use strict";
+
+module.exports = {
+  "extends": [
+    "../../../../../testing/xpcshell/xpcshell.eslintrc.js"
+  ]
+};
--- a/toolkit/components/addoncompat/tests/addon/bootstrap.js
+++ b/toolkit/components/addoncompat/tests/addon/bootstrap.js
@@ -424,16 +424,18 @@ function testAboutModuleRegistration() {
    *
    * on failure.
    *
    * @param browser
    *        The browser to send the framescript to.
    */
   let testAboutModulesWork = (browser) => {
     let testConnection = () => {
+      // This section is loaded into a frame script.
+      /* global content:false */
       let request = new content.XMLHttpRequest();
       try {
         request.open("GET", "about:test1", false);
         request.send(null);
         if (request.status != 200) {
           throw (`about:test1 response had status ${request.status} - expected 200`);
         }
         if (request.responseText.indexOf("test1") == -1) {
--- a/toolkit/components/alerts/test/test_image.html
+++ b/toolkit/components/alerts/test/test_image.html
@@ -63,17 +63,17 @@ add_task(function* testContext() {
      "Should pass user data for missing image");
 });
 
 add_task(function* testTimeout() {
   var alert = makeAlert(null, imageServerURL + "?f=image.png&t=3");
   var [ready] = yield promiseImage(alert, 1000);
   ok(!ready, "Should cancel request if timeout fires");
 
-  [ready, request] = yield promiseImage(alert, 45000);
+  [ready] = yield promiseImage(alert, 45000);
   ok(ready, "Should load image if request finishes before timeout");
 });
 
 add_task(function* testAnimatedGIF() {
   var alert = makeAlert(null, imageServerURL + "?f=image.gif");
   var [ready, request] = yield promiseImage(alert);
   ok(ready, "Should load first animated GIF frame");
   is(request.mimeType, "image/gif", "Should report correct GIF MIME type");
--- a/toolkit/components/exthelper/extApplication.js
+++ b/toolkit/components/exthelper/extApplication.js
@@ -1,12 +1,15 @@
 /* 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/. */
 
+// This file expects these globals to be declared before it is included.
+/* global Ci, Cc */
+
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/AddonManager.jsm");
 
 // =================================================
 // Console constructor
 function Console() {
   this._console = Components.classes["@mozilla.org/consoleservice;1"]
                             .getService(Ci.nsIConsoleService);
--- a/toolkit/components/formautofill/test/chrome/loader_parent.js
+++ b/toolkit/components/formautofill/test/chrome/loader_parent.js
@@ -25,17 +25,17 @@ Cu.import("resource://gre/modules/Servic
 /* import-globals-from ../loader_common.js */
 var sharedUrl = "chrome://mochitests/content/chrome/" +
                 "toolkit/components/formautofill/test/chrome/loader_common.js";
 Services.scriptloader.loadSubScript(sharedUrl, this);
 
 // Define output functions so they look the same across all frameworks.  Since
 // we don't have an output function available here, we report as TEST-PASS.
 var Output = {
-  print: message => assert.ok(true, message),
+  print: message => assert.ok(false, message),
 };
 
 // Define assertion functions so they look the same across all frameworks.
 var Assert = {
   ok: assert.ok,
   equal: assert.equal,
 };
 
--- a/toolkit/components/gfx/content/gfxFrameScript.js
+++ b/toolkit/components/gfx/content/gfxFrameScript.js
@@ -1,11 +1,12 @@
 /* eslint-env mozilla/frame-script */
 
 var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 const gfxFrameScript = {
   domUtils: null,
 
   init() {
     let webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
     let webProgress =  docShell.QueryInterface(Ci.nsIInterfaceRequestor)
                        .getInterface(Ci.nsIWebProgress);
--- a/toolkit/components/lz4/lz4_internal.js
+++ b/toolkit/components/lz4/lz4_internal.js
@@ -15,16 +15,17 @@ if (typeof Components != "undefined") {
   Cu.import("resource://gre/modules/osfile/osfile_shared_allthreads.jsm", SharedAll);
 
   this.EXPORTED_SYMBOLS = [
     "Primitives"
   ];
   this.Primitives = Primitives;
   this.exports = {};
 } else if (typeof module != "undefined" && typeof require != "undefined") {
+  /* global require:false */
   SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
 } else {
   throw new Error("Please load this module with Component.utils.import or with require()");
 }
 
 var libxul = new SharedAll.Library("libxul", SharedAll.Constants.Path.libxul);
 var Type = SharedAll.Type;
 
@@ -51,16 +52,17 @@ libxul.declareLazyFFI(Primitives, "decom
 libxul.declareLazyFFI(Primitives, "maxCompressedSize",
   "workerlz4_maxCompressedSize",
   null,
   /* return*/ Type.size_t,
   /* inputSize*/ Type.size_t
 );
 
 if (typeof module != "undefined") {
+  /* global module:false */
   module.exports = {
     get compress() {
       return Primitives.compress;
     },
     get decompress() {
       return Primitives.decompress;
     },
     get maxCompressedSize() {
new file mode 100644
--- /dev/null
+++ b/toolkit/components/microformats/.eslintrc.js
@@ -0,0 +1,8 @@
+"use strict";
+
+module.exports = {
+  "env": {
+    "node": true,
+    "amd": true,
+  }
+};
--- a/toolkit/components/microformats/update/update.js
+++ b/toolkit/components/microformats/update/update.js
@@ -13,18 +13,18 @@
 	* test/standards-tests
 	* test/static
 
 	Copyright (C) 2015 Glenn Jones. All Rights Reserved.
 	MIT License: https://raw.github.com/glennjones/microformat-shiv/master/license.txt
 	*/
 
 // configuration
-var deployDir = "../"
-	exportedSymbol = 'try {\n    // mozilla jsm support\n    Components.utils.importGlobalProperties(["URL"]);\n} catch(e) {}\nthis.EXPORTED_SYMBOLS = [\'Microformats\'];';
+var deployDir = "../";
+var exportedSymbol = 'try {\n    // mozilla jsm support\n    Components.utils.importGlobalProperties(["URL"]);\n} catch(e) {}\nthis.EXPORTED_SYMBOLS = [\'Microformats\'];';
 
 
 
 var path			= require("path"),
 	request 		= require("request"),
 	fs 				= require("fs-extra"),
 	download 		= require("download-github-repo");
 
new file mode 100644
--- /dev/null
+++ b/toolkit/components/mozprotocol/tests/.eslintrc.js
@@ -0,0 +1,7 @@
+"use strict";
+
+module.exports = {
+  "extends": [
+    "../../../../testing/mochitest/chrome.eslintrc.js"
+  ],
+};
--- a/toolkit/components/perfmonitoring/tests/browser/browser_webpagePerformanceAlerts.js
+++ b/toolkit/components/perfmonitoring/tests/browser/browser_webpagePerformanceAlerts.js
@@ -66,18 +66,20 @@ add_task(function* test_open_window_then
   Assert.ok(universalListener.triggered, `1. The universal listener was triggered`);
   Assert.ok(!fakeListener.triggered, `1. The fake listener was not triggered`);
 
   if (realListener.result) {
     Assert.ok(realListener.result.highestJank >= 300, `1. jank is at least 300ms (${realListener.result.highestJank}ms)`);
   }
 
   info(`Attempting to remove a performance listener incorrectly, check that this does not hurt our real listener`);
-  Assert.throws(() => PerformanceWatcher.removePerformanceListener({addonId: addon.addonId}, () => {}));
-  Assert.throws(() => PerformanceWatcher.removePerformanceListener({addonId: addon.addonId + "-unbound-id-" + Math.random()}, realListener.listener));
+  Assert.throws(() => PerformanceWatcher.removePerformanceListener({windowId: burner.windowId}, () => {}),
+                /No listener for target/, "should throw an error for a different listener");
+  Assert.throws(() => PerformanceWatcher.removePerformanceListener({windowId: burner.windowId + "-unbound-id-" + Math.random()}, realListener.listener),
+                /No listener for target/, "should throw an error for a different window id");
 
   // Waiting a little – listeners are buffered.
   yield new Promise(resolve => setTimeout(resolve, 100));
   yield burner.run("promiseBurnContentCPU", 20, realListener);
   // Waiting a little – listeners are buffered.
   yield new Promise(resolve => setTimeout(resolve, 100));
 
   Assert.ok(realListener.triggered, `2. The real listener was triggered`);
--- a/toolkit/components/printing/content/printUtils.js
+++ b/toolkit/components/printing/content/printUtils.js
@@ -1,8 +1,11 @@
+// This file is loaded into the browser window scope.
+/* eslint mozilla/import-browserjs-globals:"warn" */
+
 // -*- tab-width: 2; 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/. */
 
 /**
  * PrintUtils is a utility for front-end code to trigger common print
new file mode 100644
--- /dev/null
+++ b/toolkit/components/printing/tests/.eslintrc.js
@@ -0,0 +1,7 @@
+"use strict";
+
+module.exports = {
+  "extends": [
+    "../../../../testing/mochitest/chrome.eslintrc.js"
+  ],
+};
--- a/toolkit/components/printing/tests/browser_page_change_print_original.js
+++ b/toolkit/components/printing/tests/browser_page_change_print_original.js
@@ -1,8 +1,11 @@
+// This file spawns content tasks.
+/* global content */
+
 /**
  * Verify that if the page contents change after print preview is initialized,
  * and we re-initialize print preview (e.g. by changing page orientation),
  * we still show (and will therefore print) the original contents.
  */
 add_task(function* pp_after_orientation_change() {
   const DATA_URI = `data:text/html,<script>window.onafterprint = function() { setTimeout("window.location = 'data:text/plain,REPLACED PAGE!'", 0); }</script><pre>INITIAL PAGE</pre>`;
   // Can only do something if we have a print preview UI:
--- a/toolkit/components/prompts/content/selectDialog.js
+++ b/toolkit/components/prompts/content/selectDialog.js
@@ -1,12 +1,15 @@
 /* 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/. */
 
+ // Defined in dialog.xml.
+ /* globals centerWindowOnScreen:false, moveToAlertPosition:false */
+
 var Ci = Components.interfaces;
 var Cr = Components.results;
 var Cc = Components.classes;
 var Cu = Components.utils;
 
 var gArgs, listBox;
 
 function dialogOnLoad() {
--- a/toolkit/components/prompts/content/tabprompts.xml
+++ b/toolkit/components/prompts/content/tabprompts.xml
@@ -1,13 +1,17 @@
 <?xml version="1.0"?>
 <!-- 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/. -->
 
+<!-- This file is imported into the browser window, and expects various variables,
+     e.g. Ci, Services, to be available. -->
+<!-- eslint mozilla/import-browserjs-globals:"warn" -->
+
 <!DOCTYPE bindings [
 <!ENTITY % commonDialogDTD  SYSTEM "chrome://global/locale/commonDialog.dtd">
 <!ENTITY % dialogOverlayDTD SYSTEM "chrome://global/locale/dialogOverlay.dtd">
 %commonDialogDTD;
 %dialogOverlayDTD;
 ]>
 
 <bindings id="tabPrompts"
--- a/toolkit/components/satchel/test/parent_utils.js
+++ b/toolkit/components/satchel/test/parent_utils.js
@@ -1,9 +1,11 @@
 /* eslint-env mozilla/frame-script */
+// assert is available to chrome scripts loaded via SpecialPowers.loadChromeScript.
+/* global assert */
 
 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
 Cu.import("resource://gre/modules/FormHistory.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://testing-common/ContentTaskUtils.jsm");
 
 var gAutocompletePopup = Services.ww.activeWindow.
--- a/toolkit/components/viewsource/content/viewSource.js
+++ b/toolkit/components/viewsource/content/viewSource.js
@@ -1,26 +1,32 @@
 // -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
 
+/* import-globals-from ../../../content/globalOverlay.js */
+/* import-globals-from ../../printing/content/printUtils.js */
+/* import-globals-from ../../../content/viewZoomOverlay.js */
+/* import-globals-from ../../../content/contentAreaUtils.js */
+
 /* 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/. */
 
 var { utils: Cu, interfaces: Ci, classes: Cc } = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/ViewSourceBrowser.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Services",
   "resource://gre/modules/Services.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "CharsetMenu",
   "resource://gre/modules/CharsetMenu.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Deprecated",
   "resource://gre/modules/Deprecated.jsm");
 
+/* global gBrowser, gViewSourceBundle, gContextMenu */
 [
   ["gBrowser",          "content"],
   ["gViewSourceBundle", "viewSourceBundle"],
   ["gContextMenu",      "viewSourceContextMenu"]
 ].forEach(function([name, id]) {
   window.__defineGetter__(name, function() {
     var element = document.getElementById(id);
     if (!element)
--- a/toolkit/components/windowcreator/test/.eslintrc.js
+++ b/toolkit/components/windowcreator/test/.eslintrc.js
@@ -1,7 +1,9 @@
 "use strict";
 
 module.exports = { // eslint-disable-line no-undef
   "extends": [
+    "../../../../testing/mochitest/browser.eslintrc.js",
+    "../../../../testing/mochitest/chrome.eslintrc.js",
     "../../../../testing/mochitest/mochitest.eslintrc.js",
   ]
 };
--- a/toolkit/components/windowwatcher/test/browser_new_content_window_chromeflags.js
+++ b/toolkit/components/windowwatcher/test/browser_new_content_window_chromeflags.js
@@ -233,16 +233,18 @@ add_task(function* test_new_remote_windo
                   Ci.nsIWebBrowserChrome.CHROME_REMOTE_WINDOW),
                 "Should not be remote by default");
     }
 
     // Confusingly, chromeFlags also exist in the content process
     // as part of the TabChild, so we have to check those too.
     let b = win.gBrowser.selectedBrowser;
     let contentChromeFlags = yield ContentTask.spawn(b, null, function*() {
+      // Content scripts provide docShell as a global.
+      /* global docShell */
       docShell.QueryInterface(Ci.nsIInterfaceRequestor);
       try {
         // This will throw if we're not a remote browser.
         return docShell.getInterface(Ci.nsITabChild)
                        .QueryInterface(Ci.nsIWebBrowserChrome)
                        .chromeFlags;
       } catch (e) {
         // This must be a non-remote browser...
--- a/toolkit/content/.eslintrc.js
+++ b/toolkit/content/.eslintrc.js
@@ -1,7 +1,7 @@
 "use strict";
 
 module.exports = {
   "rules": {
-    "no-undef": "off"
+    "mozilla/import-browserjs-globals": "warn",
   }
 };
--- a/toolkit/content/aboutSupport.js
+++ b/toolkit/content/aboutSupport.js
@@ -503,17 +503,17 @@ var snapshotFormatters = {
     }
 
     let crashGuards = data.crashGuards;
     delete data.crashGuards;
 
     if (crashGuards.length) {
       for (let guard of crashGuards) {
         let resetButton = $.new("button");
-        onClickReset = function() {
+        let onClickReset = function() {
           Services.prefs.setIntPref(guard.prefName, 0);
           resetButton.removeEventListener("click", onClickReset);
           resetButton.disabled = true;
         };
 
         resetButton.textContent = strings.GetStringFromName("resetOnNextRestart");
         resetButton.addEventListener("click", onClickReset);
 
--- a/toolkit/content/datepicker.xhtml
+++ b/toolkit/content/datepicker.xhtml
@@ -32,16 +32,17 @@
   <template id="spinner-template">
     <div class="spinner-container">
       <button class="up"/>
       <div class="spinner"></div>
       <button class="down"/>
     </div>
   </template>
   <script type="application/javascript">
+  /* import-globals-from widgets/datepicker.js */
   // We need to hide the scroll bar but maintain its scrolling
   // capability, so using |overflow: hidden| is not an option.
   // Instead, we are inserting a user agent stylesheet that is
   // capable of selecting scrollbars, and do |display: none|.
   var domWinUtls = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
                   getInterface(Components.interfaces.nsIDOMWindowUtils);
   domWinUtls.loadSheetUsingURIString('data:text/css,@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); scrollbar { display: none; }', domWinUtls.AGENT_SHEET);
   // Create a DatePicker instance and prepare to be
@@ -52,9 +53,9 @@
     monthYearView: root.querySelector(".month-year-view"),
     buttonLeft: root.querySelector(".left"),
     buttonRight: root.querySelector(".right"),
     weekHeader: root.querySelector(".week-header"),
     daysView: root.querySelector(".days-view")
   });
   </script>
 </body>
-</html>
\ No newline at end of file
+</html>
--- a/toolkit/content/finddialog.js
+++ b/toolkit/content/finddialog.js
@@ -1,14 +1,17 @@
 // -*- 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/. */
 
+// Defined in dialog.xml.
+/* globals moveToAlertPosition */
+
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/FormHistory.jsm");
 
 var dialog;     // Quick access to document/form elements.
 var gFindInst;   // nsIWebBrowserFind that we're going to use
 var gFindInstData; // use this to update the find inst data
 
 function initDialogObject() {
--- a/toolkit/content/macWindowMenu.js
+++ b/toolkit/content/macWindowMenu.js
@@ -17,17 +17,17 @@ function macWindowMenuDidShow() {
       sep.hidden = true;
     else if (win == window)
       sep.setAttribute("checked", "true");
   }
 }
 
 function toOpenWindow( aWindow ) {
   // deminiaturize the window, if it's in the Dock
-  if (aWindow.windowState == STATE_MINIMIZED)
+  if (aWindow.windowState == window.STATE_MINIMIZED)
     aWindow.restore();
   aWindow.document.commandDispatcher.focusedWindow.focus();
 }
 
 function ShowWindowFromResource( node ) {
   var windowManagerDS =
     Components.classes["@mozilla.org/rdf/datasource;1?name=window-mediator"]
               .getService(Components.interfaces.nsIWindowDataSource);
@@ -35,13 +35,13 @@ function ShowWindowFromResource( node ) 
   var desiredWindow = null;
   var url = node.getAttribute("id");
   desiredWindow = windowManagerDS.getWindowForResource( url );
   if (desiredWindow)
     toOpenWindow(desiredWindow);
 }
 
 function zoomWindow() {
-  if (window.windowState == STATE_NORMAL)
+  if (window.windowState == window.STATE_NORMAL)
     window.maximize();
   else
     window.restore();
 }
--- a/toolkit/content/tests/browser/browser_mediaPlayback_suspended.js
+++ b/toolkit/content/tests/browser/browser_mediaPlayback_suspended.js
@@ -18,17 +18,17 @@ function check_audio_onplay() {
   var list = content.document.getElementsByTagName("audio");
   if (list.length != 1) {
     ok(false, "There should be only one audio element in page!")
   }
 
   var audio = list[0];
   return new Promise((resolve, reject) => {
     audio.onplay = () => {
-      ok(needToReceiveOnPlay, "Should not receive play event!");
+      ok(false, "Should not receive play event!");
       this.onplay = null;
       reject();
     };
 
     audio.pause();
     audio.play();
 
     setTimeout(() => {
--- a/toolkit/content/tests/browser/browser_saveImageURL.js
+++ b/toolkit/content/tests/browser/browser_saveImageURL.js
@@ -1,13 +1,15 @@
 "use strict";
 
 const IMAGE_PAGE = "https://example.com/browser/toolkit/content/tests/browser/image_page.html";
 const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser";
 
+var MockFilePicker = SpecialPowers.MockFilePicker;
+
 MockFilePicker.init(window);
 MockFilePicker.returnValue = MockFilePicker.returnCancel;
 
 registerCleanupFunction(function() {
   MockFilePicker.cleanup();
 });
 
 function waitForFilePicker() {
--- a/toolkit/content/tests/browser/browser_save_resend_postdata.js
+++ b/toolkit/content/tests/browser/browser_save_resend_postdata.js
@@ -90,16 +90,17 @@ function test() {
     // Check if inner POST data is found (bug 485196).
     isnot(fileContents.indexOf("inputfield=inner"), -1,
           "The saved inner frame was generated using the correct POST data");
 
     finish();
   }
 }
 
+/* import-globals-from common/mockTransfer.js */
 Cc["@mozilla.org/moz/jssubscript-loader;1"]
   .getService(Ci.mozIJSSubScriptLoader)
   .loadSubScript("chrome://mochitests/content/browser/toolkit/content/tests/browser/common/mockTransfer.js",
                  this);
 
 function createTemporarySaveDirectory() {
   var saveDir = Cc["@mozilla.org/file/directory_service;1"]
                   .getService(Ci.nsIProperties)
--- a/toolkit/content/tests/chrome/RegisterUnregisterChrome.js
+++ b/toolkit/content/tests/chrome/RegisterUnregisterChrome.js
@@ -13,17 +13,17 @@ var gChromeReg = Cc["@mozilla.org/chrome
                     getService(Ci.nsIXULChromeRegistry);
 var gPrefs     = Cc["@mozilla.org/preferences-service;1"].
                     getService(Ci.nsIPrefBranch);
 
 // Create the temporary file in the profile, instead of in TmpD, because
 // we know the mochitest harness kills off the profile when it's done.
 function copyToTemporaryFile(f) {
   let tmpd = gDirSvc.get("ProfD", Ci.nsIFile);
-  tmpf = tmpd.clone();
+  let tmpf = tmpd.clone();
   tmpf.append("temp.manifest");
   tmpf.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600);
   tmpf.remove(false);
   f.copyTo(tmpd, tmpf.leafName);
   return tmpf;
 }
 
 function* dirIter(directory) {
@@ -63,17 +63,17 @@ function copyDirToTempProfile(path, subd
 
   let rootDir = getParent(path);
   if (rootDir == "") {
     return tmpdir;
   }
 
   // The SimpleTest directory is hidden
   var files = Array.from(dirIter("file://" + rootDir));
-  for (f in files) {
+  for (let f in files) {
     files[f].copyTo(tmpdir, "");
   }
   return tmpdir;
 
 }
 
 function convertChromeURI(chromeURI) {
   let uri = Cc["@mozilla.org/network/io-service;1"].
--- a/toolkit/content/tests/chrome/popup_trigger.js
+++ b/toolkit/content/tests/chrome/popup_trigger.js
@@ -1,8 +1,10 @@
+/* import-globals-from ../widgets/popup_shared.js */
+
 var gMenuPopup = null;
 var gTrigger = null;
 var gIsMenu = false;
 var gScreenX = -1, gScreenY = -1;
 var gCachedEvent = null;
 var gCachedEvent2 = null;
 
 function cacheEvent(modifiers) {
--- a/toolkit/content/tests/chrome/test_autocomplete_with_composition_on_input.html
+++ b/toolkit/content/tests/chrome/test_autocomplete_with_composition_on_input.html
@@ -14,16 +14,17 @@
   <iframe id="formTarget" name="formTarget"></iframe>
   <form action="data:text/html," target="formTarget">
     <input name="test" id="input"><input type="submit">
   </form>
 </div>
 
 <pre id="test">
 <script class="testbody" type="text/javascript">
+/* import-globals-from file_autocomplete_with_composition.js */
 
 SimpleTest.waitForExplicitFinish();
 
 function runTests() {
   var formFillController =
     SpecialPowers.getFormFillController()
                  .QueryInterface(Components.interfaces.nsIAutoCompleteInput);
   var originalFormFillTimeout = formFillController.timeout;
--- a/toolkit/content/tests/widgets/test_videocontrols.html
+++ b/toolkit/content/tests/widgets/test_videocontrols.html
@@ -253,17 +253,17 @@ function runTest(event) {
       is(event.type, "seeked", "checking event type");
       ok(true, "video position is at " + video.currentTime);
       // The scrubber currently just jumps towards the nearest pageIncrement point, not
       // precisely to the point clicked. So, expectedTime isn't (videoDuration / 4).
       // We should end up at 1.733, but sometimes we end up at 1.498. I guess
       // it's timing depending if the <scale> things it's click-and-hold, or a
       // single click. So, just make sure we end up less that the previous
       // position.
-      lastPosition = (videoDuration / 2) - 0.1;
+      var lastPosition = (videoDuration / 2) - 0.1;
       ok(video.currentTime < lastPosition, "checking expected playback position");
 
       // Set volume to 0.1 so one down arrow hit will decrease it to 0.
       video.volume = 0.1;
       break;
 
     // See bug 694696.
     case 16:
--- a/toolkit/content/tests/widgets/tree_shared.js
+++ b/toolkit/content/tests/widgets/tree_shared.js
@@ -1,8 +1,14 @@
+// This file expects the following globals to be defined at various times.
+/* globals getCustomTreeViewCellInfo */
+
+// This files relies on these specific Chrome/XBL globals
+/* globals TreeColumns, TreeColumn */
+
 var columns_simpletree =
 [
   { name: "name", label: "Name", key: true, properties: "one two" },
   { name: "address", label: "Address" }
 ];
 
 var columns_hiertree =
 [
--- a/toolkit/content/tests/widgets/videocontrols_direction_test.js
+++ b/toolkit/content/tests/widgets/videocontrols_direction_test.js
@@ -1,8 +1,11 @@
+// This file expects `tests` to have been declared in the global scope.
+/* global tests */
+
 var RemoteCanvas = function(url, id) {
   this.url = url;
   this.id = id;
   this.snapshot = null;
 };
 
 RemoteCanvas.CANVAS_WIDTH = 200;
 RemoteCanvas.CANVAS_HEIGHT = 200;
--- a/toolkit/content/timepicker.xhtml
+++ b/toolkit/content/timepicker.xhtml
@@ -16,21 +16,22 @@
   <template id="spinner-template">
     <div class="spinner-container">
       <button class="up"/>
       <div class="spinner"></div>
       <button class="down"/>
     </div>
   </template>
   <script type="application/javascript">
+  /* import-globals-from widgets/timepicker.js */
   // We need to hide the scroll bar but maintain its scrolling
   // capability, so using |overflow: hidden| is not an option.
   // Instead, we are inserting a user agent stylesheet that is
   // capable of selecting scrollbars, and do |display: none|.
   var domWinUtls = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
                   getInterface(Components.interfaces.nsIDOMWindowUtils);
   domWinUtls.loadSheetUsingURIString('data:text/css,@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); scrollbar { display: none; }', domWinUtls.AGENT_SHEET);
   // Create a TimePicker instance and prepare to be
   // initialized by the "TimePickerInit" event from timepicker.xml
   new TimePicker(document.getElementById("time-picker"));
   </script>
 </body>
-</html>
\ No newline at end of file
+</html>
--- a/toolkit/content/widgets/colorpicker.xml
+++ b/toolkit/content/widgets/colorpicker.xml
@@ -396,28 +396,28 @@
           this.selectCell(event.originalTarget);
           this.hoverCell(this.mSelectedCell);
         }
       ]]></handler>
 
 
       <handler event="focus" phase="capturing">
       <![CDATA[
-        if (!mIsPopup && this.getAttribute("focused") != "true") {
+        if (!this.mIsPopup && this.getAttribute("focused") != "true") {
           this.setAttribute("focused", "true");
           document.addEventListener("keydown", this, true);
           if (this.mSelectedCell)
             this.hoverCell(this.mSelectedCell);
         }
       ]]>
       </handler>
 
       <handler event="blur" phase="capturing">
       <![CDATA[
-        if (!mIsPopup && this.getAttribute("focused") == "true") {
+        if (!this.mIsPopup && this.getAttribute("focused") == "true") {
           document.removeEventListener("keydown", this, true);
           this.removeAttribute("focused");
           this.resetHover();
         }
       ]]>
       </handler>
     </handlers>
   </binding>
@@ -554,9 +554,8 @@
       ]]></handler>
     </handlers>
   </binding>
 
   <binding id="colorpickertile" role="xul:colorpickertile">
   </binding>
 
 </bindings>
-
--- a/toolkit/content/widgets/datepicker.js
+++ b/toolkit/content/widgets/datepicker.js
@@ -1,12 +1,16 @@
 /* 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/. */
 
+/* import-globals-from datekeeper.js */
+/* import-globals-from calendar.js */
+/* import-globals-from spinner.js */
+
 "use strict";
 
 function DatePicker(context) {
   this.context = context;
   this._attachEventListeners();
 }
 
 {
--- a/toolkit/content/widgets/datetimebox.xml
+++ b/toolkit/content/widgets/datetimebox.xml
@@ -1046,17 +1046,17 @@
 
       <destructor>
       <![CDATA[
         this.mInputElement = null;
 
         this.EVENTS.forEach((eventName) => {
           this.removeEventListener(eventName, this, { mozSystemGroup: true });
         });
-        this.removeEventListener("keypress", onKeyPress, {
+        this.removeEventListener("keypress", this, {
           capture: true,
           mozSystemGroup: true
         });
       ]]>
       </destructor>
 
       <property name="EVENTS" readonly="true">
         <getter>
--- a/toolkit/content/widgets/datetimepicker.xml
+++ b/toolkit/content/widgets/datetimepicker.xml
@@ -1113,20 +1113,16 @@
                   item.value = "";
                 }
 
                 date.setDate(date.getDate() + 1);
               }
             }
 
             this._fireEvent("monthchange", this);
-            if (this.hasAttribute("monthchange")) {
-              var fn = new Function("event", aTarget.getAttribute("onmonthchange"));
-              fn.call(aTarget, event);
-            }
           ]]>
         </body>
       </method>
       <method name="_increaseOrDecreaseDateFromEvent">
         <parameter name="aEvent"/>
         <parameter name="aDiff"/>
         <body>
           <![CDATA[
--- a/toolkit/content/widgets/datetimepopup.xml
+++ b/toolkit/content/widgets/datetimepopup.xml
@@ -21,18 +21,18 @@
       <field name="TIME_PICKER_WIDTH" readonly="true">"12em"</field>
       <field name="TIME_PICKER_HEIGHT" readonly="true">"21em"</field>
       <field name="DATE_PICKER_WIDTH" readonly="true">"23.1em"</field>
       <field name="DATE_PICKER_HEIGHT" readonly="true">"20.7em"</field>
       <constructor><![CDATA[
         this.l10n = {};
         const mozIntl = Components.classes["@mozilla.org/mozintl;1"]
                           .getService(Components.interfaces.mozIMozIntl);
-        mozIntl.addGetCalendarInfo(l10n);
-        mozIntl.addGetDisplayNames(l10n);
+        mozIntl.addGetCalendarInfo(this.l10n);
+        mozIntl.addGetDisplayNames(this.l10n);
       ]]></constructor>
       <method name="loadPicker">
         <parameter name="type"/>
         <parameter name="detail"/>
         <body><![CDATA[
           this.hidden = false;
           this.type = type;
           this.pickerState = {};
--- a/toolkit/content/widgets/listbox.xml
+++ b/toolkit/content/widgets/listbox.xml
@@ -1,14 +1,17 @@
 <?xml version="1.0"?>
 
 <!-- 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/. -->
 
+<!-- This files relies on these specific Chrome/XBL globals -->
+<!-- globals ChromeNodeList -->
+
 <bindings id="listboxBindings"
           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">
 
   <!--
     Interface binding that is base for bindings of xul:listbox and
     xul:richlistbox elements. This binding assumes that successors bindings
--- a/toolkit/content/widgets/popup.xml
+++ b/toolkit/content/widgets/popup.xml
@@ -1,13 +1,15 @@
 <?xml version="1.0"?>
 <!-- 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/. -->
 
+<!-- This files relies on these specific Chrome/XBL globals -->
+<!-- globals PopupBoxObject -->
 
 <bindings id="popupBindings"
    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">
 
   <binding id="popup-base">
     <resources>
--- a/toolkit/content/widgets/textbox.xml
+++ b/toolkit/content/widgets/textbox.xml
@@ -1,13 +1,16 @@
 <?xml version="1.0"?>
 <!-- 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/. -->
 
+<!-- This files relies on these specific Chrome/XBL globals -->
+<!-- globals ChromeWindow -->
+
 
 <!DOCTYPE bindings [
   <!ENTITY % textcontextDTD SYSTEM "chrome://global/locale/textcontext.dtd" >
   %textcontextDTD;
 ]>
 
 <bindings id="textboxBindings"
    xmlns="http://www.mozilla.org/xbl"
--- a/toolkit/content/widgets/timepicker.js
+++ b/toolkit/content/widgets/timepicker.js
@@ -1,12 +1,15 @@
 /* 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/. */
 
+ /* import-globals-from timekeeper.js */
+ /* import-globals-from spinner.js */
+
 "use strict";
 
 function TimePicker(context) {
   this.context = context;
   this._attachEventListeners();
 }
 
 {
--- a/toolkit/content/widgets/toolbar.xml
+++ b/toolkit/content/widgets/toolbar.xml
@@ -47,23 +47,23 @@
         ]]></setter>
       </property>
 
       <constructor>
         <![CDATA[
           // Look to see if there is a toolbarset.
           this.toolbarset = this.firstChild;
           while (this.toolbarset && this.toolbarset.localName != "toolbarset")
-            this.toolbarset = toolbarset.nextSibling;
+            this.toolbarset = this.toolbarset.nextSibling;
 
           if (this.toolbarset) {
             // Create each toolbar described by the toolbarset.
             var index = 0;
-            while (toolbarset.hasAttribute("toolbar" + (++index))) {
-              var toolbarInfo = toolbarset.getAttribute("toolbar" + index);
+            while (this.toolbarset.hasAttribute("toolbar" + (++index))) {
+              var toolbarInfo = this.toolbarset.getAttribute("toolbar" + index);
               var infoSplit = toolbarInfo.split(":");
               this.appendCustomToolbar(infoSplit[0], infoSplit[1]);
             }
           }
         ]]>
       </constructor>
 
       <method name="appendCustomToolbar">
@@ -582,9 +582,8 @@
       <xul:hbox class="toolbarpaletteitem-box" xbl:inherits="type,place">
         <children/>
       </xul:hbox>
       <xul:label xbl:inherits="value=title"/>
     </content>
   </binding>
 
 </bindings>
-
--- a/toolkit/content/widgets/tree.xml
+++ b/toolkit/content/widgets/tree.xml
@@ -896,94 +896,94 @@
             }
           }
         ]]>
       </handler>
       <handler event="keydown" keycode="VK_UP" modifiers="accel any">
         <![CDATA[
           if (this._editingColumn)
             return;
-          _moveByOffset(-1, 0, event);
+          this._moveByOffset(-1, 0, event);
         ]]>
       </handler>
       <handler event="keydown" keycode="VK_DOWN" modifiers="accel any">
         <![CDATA[
           if (this._editingColumn)
             return;
-          _moveByOffset(1, this.view.rowCount - 1, event);
+          this._moveByOffset(1, this.view.rowCount - 1, event);
         ]]>
       </handler>
       <handler event="keydown" keycode="VK_UP" modifiers="accel any, shift">
         <![CDATA[
           if (this._editingColumn)
             return;
-          _moveByOffsetShift(-1, 0, event);
+          this._moveByOffsetShift(-1, 0, event);
         ]]>
       </handler>
       <handler event="keydown" keycode="VK_DOWN" modifiers="accel any, shift">
         <![CDATA[
           if (this._editingColumn)
             return;
-          _moveByOffsetShift(1, this.view.rowCount - 1, event);
+          this._moveByOffsetShift(1, this.view.rowCount - 1, event);
         ]]>
       </handler>
       <handler event="keydown" keycode="VK_PAGE_UP" modifiers="accel any">
         <![CDATA[
           if (this._editingColumn)
             return;
-          _moveByPage(-1, 0, event);
+          this._moveByPage(-1, 0, event);
         ]]>
       </handler>
       <handler event="keydown" keycode="VK_PAGE_DOWN" modifiers="accel any">
         <![CDATA[
           if (this._editingColumn)
             return;
-          _moveByPage(1, this.view.rowCount - 1, event);
+          this._moveByPage(1, this.view.rowCount - 1, event);
         ]]>
       </handler>
       <handler event="keydown" keycode="VK_PAGE_UP" modifiers="accel any, shift">
         <![CDATA[
           if (this._editingColumn)
             return;
-          _moveByPageShift(-1, 0, event);
+          this._moveByPageShift(-1, 0, event);
         ]]>
       </handler>
       <handler event="keydown" keycode="VK_PAGE_DOWN" modifiers="accel any, shift">
         <![CDATA[
           if (this._editingColumn)
             return;
-          _moveByPageShift(1, this.view.rowCount - 1, event);
+          this._moveByPageShift(1, this.view.rowCount - 1, event);
         ]]>
       </handler>
       <handler event="keydown" keycode="VK_HOME" modifiers="accel any">
         <![CDATA[
           if (this._editingColumn)
             return;
-          _moveToEdge(0, event);
+          this._moveToEdge(0, event);
         ]]>
       </handler>
       <handler event="keydown" keycode="VK_END" modifiers="accel any">
         <![CDATA[
           if (this._editingColumn)
             return;
-          _moveToEdge(this.view.rowCount - 1, event);
+          this._moveToEdge(this.view.rowCount - 1, event);
         ]]>
       </handler>
       <handler event="keydown" keycode="VK_HOME" modifiers="accel any, shift">
         <![CDATA[
           if (this._editingColumn)
             return;
-          _moveToEdgeShift(0, event);
+          this._moveToEdgeShift(0, event);
         ]]>
       </handler>
       <handler event="keydown" keycode="VK_END" modifiers="accel any, shift">
         <![CDATA[
           if (this._editingColumn)
             return;
-          _moveToEdgeShift(this.view.rowCount - 1, event);
+          this._moveToEdgeShift(this.view.rowCount - 1, event);
         ]]>
       </handler>
       <handler event="keypress">
         <![CDATA[
          if (this._editingColumn)
            return;
 
          if (event.charCode == " ".charCodeAt(0)) {
--- a/toolkit/content/widgets/videocontrols.xml
+++ b/toolkit/content/widgets/videocontrols.xml
@@ -968,29 +968,29 @@
         this.bufferBar.max = duration;
         this.bufferBar.value = endTime;
       },
 
       _controlsHiddenByTimeout : false,
       _showControlsTimeout : 0,
       SHOW_CONTROLS_TIMEOUT_MS: 500,
       _showControlsFn() {
-        if (Utils.video.matches("video:hover")) {
-          Utils.startFadeIn(Utils.controlBar, false);
-          Utils._showControlsTimeout = 0;
-          Utils._controlsHiddenByTimeout = false;
+        if (this.Utils.video.matches("video:hover")) {
+          this.Utils.startFadeIn(this.Utils.controlBar, false);
+          this.Utils._showControlsTimeout = 0;
+          this.Utils._controlsHiddenByTimeout = false;
         }
       },
 
       _hideControlsTimeout : 0,
       _hideControlsFn() {
-        if (!Utils.scrubber.isDragging) {
-          Utils.startFade(Utils.controlBar, false);
-          Utils._hideControlsTimeout = 0;
-          Utils._controlsHiddenByTimeout = true;
+        if (!this.Utils.scrubber.isDragging) {
+          this.Utils.startFade(this.Utils.controlBar, false);
+          this.Utils._hideControlsTimeout = 0;
+          this.Utils._controlsHiddenByTimeout = true;
         }
       },
       HIDE_CONTROLS_TIMEOUT_MS : 2000,
       onMouseMove(event) {
         // Pause playing video when the mouse is dragging over the control bar.
         if (this.scrubber.startToDrag) {
           this.scrubber.isDragging = true;
           this.pauseVideoDuringDragging();
@@ -1065,17 +1065,17 @@
           // Keep the controls visible if the click-to-play is visible.
           if (!this.clickToPlay.hidden) {
             return;
           }
 
           this.startFadeOut(this.controlBar, false);
           this.textTrackList.setAttribute("hidden", "true");
           clearTimeout(this._showControlsTimeout);
-          Utils._controlsHiddenByTimeout = false;
+          this.Utils._controlsHiddenByTimeout = false;
         }
       },
 
       startFadeIn(element, immediate) {
         this.startFade(element, true, immediate);
       },
 
       startFadeOut(element, immediate) {
@@ -1206,17 +1206,17 @@
           this.fullscreenButton.setAttribute("fullscreened", "true");
         } else {
           this.fullscreenButton.removeAttribute("fullscreened");
         }
       },
 
       onFullscreenChange() {
         if (this.isVideoInFullScreen()) {
-          Utils._hideControlsTimeout = setTimeout(this._hideControlsFn, this.HIDE_CONTROLS_TIMEOUT_MS);
+          this.Utils._hideControlsTimeout = setTimeout(this._hideControlsFn, this.HIDE_CONTROLS_TIMEOUT_MS);
         }
         this.setFullscreenButtonState();
       },
 
       clickToPlayClickHandler(e) {
         if (e.button != 0) {
           return;
         }