Bug 1264206 - Enable ESLint for browser/components/downloads and fix the existing issues. r=Standard8
authorYiren Wang <yiren.wang@student.ecp.fr>
Mon, 03 Apr 2017 10:25:05 +0100
changeset 399089 ba78fb79365f3bcff0575568846fde62f0e0b8a0
parent 399088 922e2f268ab3f18834a38c41fe55b10ed1fc6250
child 399090 55d087f9121432218382dfcefba5a88ce8d4e93a
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersStandard8
bugs1264206
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1264206 - Enable ESLint for browser/components/downloads and fix the existing issues. r=Standard8 MozReview-Commit-ID: HDjTxdFCnRp
.eslintignore
browser/components/downloads/DownloadsCommon.jsm
browser/components/downloads/DownloadsTaskbar.jsm
browser/components/downloads/DownloadsViewUI.jsm
browser/components/downloads/content/allDownloadsViewOverlay.js
browser/components/downloads/content/contentAreaDownloadsView.js
browser/components/downloads/content/downloads.js
browser/components/downloads/content/indicator.js
browser/components/downloads/test/browser/browser_basic_functionality.js
browser/components/downloads/test/browser/browser_downloads_panel_block.js
browser/components/downloads/test/browser/browser_downloads_panel_footer.js
browser/components/downloads/test/browser/browser_first_download_panel.js
browser/components/downloads/test/browser/browser_iframe_gone_mid_download.js
browser/components/downloads/test/browser/browser_indicatorDrop.js
browser/components/downloads/test/browser/browser_libraryDrop.js
browser/components/downloads/test/browser/head.js
browser/components/downloads/test/unit/head.js
browser/components/downloads/test/unit/test_DownloadsCommon.js
--- a/.eslintignore
+++ b/.eslintignore
@@ -53,17 +53,16 @@ b2g/graphene/graphene.js
 b2g/locales/en-US/b2g-l10n.js
 
 # browser/ exclusions
 browser/app/**
 browser/branding/**/firefox-branding.js
 browser/base/content/test/general/file_csp_block_all_mixedcontent.html
 browser/base/content/test/urlbar/file_blank_but_not_blank.html
 browser/base/content/newtab/**
-browser/components/downloads/**
 # Test files that are really json not js, and don't need to be linted.
 browser/components/sessionstore/test/unit/data/sessionstore_valid.js
 browser/components/sessionstore/test/unit/data/sessionstore_invalid.js
 browser/components/tabview/**
 # generated & special files in cld2
 browser/components/translation/cld2/**
 browser/extensions/pdfjs/content/build**
 browser/extensions/pdfjs/content/web**
--- a/browser/components/downloads/DownloadsCommon.jsm
+++ b/browser/components/downloads/DownloadsCommon.jsm
@@ -25,18 +25,17 @@ this.EXPORTED_SYMBOLS = [
  * to build a consistent view of the available data.
  *
  * DownloadsIndicatorData
  * This object registers itself with DownloadsData as a view, and transforms the
  * notifications it receives into overall status data, that is then broadcast to
  * the registered download status indicators.
  */
 
-////////////////////////////////////////////////////////////////////////////////
-//// Globals
+// Globals
 
 const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
                                   "resource://gre/modules/NetUtil.jsm");
@@ -106,40 +105,39 @@ var PrefObserver = {
           return kPrefBranch.getBoolPref(name);
       }
     } catch (ex) { }
     return this.prefs[name];
   },
   observe(aSubject, aTopic, aData) {
     if (this.prefs.hasOwnProperty(aData)) {
       delete this[aData];
-      return this[aData] = this.getPref(aData);
+      this[aData] = this.getPref(aData);
     }
   },
   register(prefs) {
     this.prefs = prefs;
     kPrefBranch.addObserver("", this, true);
     for (let key in prefs) {
       let name = key;
-      XPCOMUtils.defineLazyGetter(this, name, function () {
+      XPCOMUtils.defineLazyGetter(this, name, function() {
         return PrefObserver.getPref(name);
       });
     }
   },
 };
 
 PrefObserver.register({
   // prefName: defaultValue
   animateNotifications: true,
   showPanelDropmarker: true,
 });
 
 
-////////////////////////////////////////////////////////////////////////////////
-//// DownloadsCommon
+// DownloadsCommon
 
 /**
  * This object is exposed directly to the consumers of this JavaScript module,
  * and provides shared methods for all the instances of the user interface.
  */
 this.DownloadsCommon = {
   ATTENTION_NONE: "",
   ATTENTION_SUCCESS: "success",
@@ -161,24 +159,24 @@ this.DownloadsCommon = {
   get strings() {
     let strings = {};
     let sb = Services.strings.createBundle(kDownloadsStringBundleUrl);
     let enumerator = sb.getSimpleEnumeration();
     while (enumerator.hasMoreElements()) {
       let string = enumerator.getNext().QueryInterface(Ci.nsIPropertyElement);
       let stringName = string.key;
       if (stringName in kDownloadsStringsRequiringFormatting) {
-        strings[stringName] = function () {
+        strings[stringName] = function() {
           // Convert "arguments" to a real array before calling into XPCOM.
           return sb.formatStringFromName(stringName,
                                          Array.slice(arguments, 0),
                                          arguments.length);
         };
       } else if (stringName in kDownloadsStringsRequiringPluralForm) {
-        strings[stringName] = function (aCount) {
+        strings[stringName] = function(aCount) {
           // Convert "arguments" to a real array before calling into XPCOM.
           let formattedString = sb.formatStringFromName(stringName,
                                          Array.slice(arguments, 0),
                                          arguments.length);
           return PluralForm.get(aCount, formattedString);
         };
       } else {
         strings[stringName] = string.value;
@@ -238,19 +236,18 @@ this.DownloadsCommon = {
    * depending on the privacy status of the window in question.
    *
    * @param aWindow
    *        The browser window which owns the download button.
    */
   getData(aWindow) {
     if (PrivateBrowsingUtils.isContentWindowPrivate(aWindow)) {
       return PrivateDownloadsData;
-    } else {
-      return DownloadsData;
     }
+    return DownloadsData;
   },
 
   /**
    * Initializes the Downloads back-end and starts receiving events for both the
    * private and non-private downloads data objects.
    */
   initializeAllDataLinks() {
     DownloadsData.initializeDataLink();
@@ -260,19 +257,18 @@ this.DownloadsCommon = {
   /**
    * Get access to one of the DownloadsIndicatorData or
    * PrivateDownloadsIndicatorData objects, depending on the privacy status of
    * the window in question.
    */
   getIndicatorData(aWindow) {
     if (PrivateBrowsingUtils.isContentWindowPrivate(aWindow)) {
       return PrivateDownloadsIndicatorData;
-    } else {
-      return DownloadsIndicatorData;
     }
+    return DownloadsIndicatorData;
   },
 
   /**
    * Returns a reference to the DownloadsSummaryData singleton - creating one
    * in the process if one hasn't been instantiated yet.
    *
    * @param aWindow
    *        The browser window which owns the download button.
@@ -281,22 +277,21 @@ this.DownloadsCommon = {
    *        from the summary.
    */
   getSummary(aWindow, aNumToExclude) {
     if (PrivateBrowsingUtils.isContentWindowPrivate(aWindow)) {
       if (this._privateSummary) {
         return this._privateSummary;
       }
       return this._privateSummary = new DownloadsSummaryData(true, aNumToExclude);
-    } else {
-      if (this._summary) {
-        return this._summary;
-      }
-      return this._summary = new DownloadsSummaryData(false, aNumToExclude);
     }
+    if (this._summary) {
+      return this._summary;
+    }
+    return this._summary = new DownloadsSummaryData(false, aNumToExclude);
   },
   _summary: null,
   _privateSummary: null,
 
   /**
    * Returns the legacy state integer value for the provided Download object.
    */
   stateOfDownload(download) {
@@ -661,27 +656,26 @@ XPCOMUtils.defineLazyGetter(this.Downloa
 });
 XPCOMUtils.defineLazyGetter(this.DownloadsCommon, "error", () => {
   return DownloadsLogger.error.bind(DownloadsLogger);
 });
 
 /**
  * Returns true if we are executing on Windows Vista or a later version.
  */
-XPCOMUtils.defineLazyGetter(DownloadsCommon, "isWinVistaOrHigher", function () {
+XPCOMUtils.defineLazyGetter(DownloadsCommon, "isWinVistaOrHigher", function() {
   let os = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS;
   if (os != "WINNT") {
     return false;
   }
   let sysInfo = Cc["@mozilla.org/system-info;1"].getService(Ci.nsIPropertyBag2);
   return parseFloat(sysInfo.getProperty("version")) >= 6;
 });
 
-////////////////////////////////////////////////////////////////////////////////
-//// DownloadsData
+// DownloadsData
 
 /**
  * Retrieves the list of past and completed downloads from the underlying
  * Download Manager data, and provides asynchronous notifications allowing to
  * build a consistent view of the available data.
  *
  * This object responds to real-time changes in the underlying Download Manager
  * data.  For example, the deletion of one or more downloads is notified through
@@ -751,18 +745,17 @@ DownloadsDataCtor.prototype = {
                                                         : Downloads.PUBLIC);
     promiseList.then(list => list.removeFinished())
                .then(null, Cu.reportError);
     let indicatorData = this._isPrivate ? PrivateDownloadsIndicatorData
                                         : DownloadsIndicatorData;
     indicatorData.attention = DownloadsCommon.ATTENTION_NONE;
   },
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// Integration with the asynchronous Downloads back-end
+  // Integration with the asynchronous Downloads back-end
 
   onDownloadAdded(download) {
     // Download objects do not store the end time of downloads, as the Downloads
     // API does not need to persist this information for all platforms. Once a
     // download terminates on a Desktop browser, it becomes a history download,
     // for which the end time is stored differently, as a Places annotation.
     download.endTime = Date.now();
 
@@ -842,18 +835,17 @@ DownloadsDataCtor.prototype = {
   onDownloadRemoved(download) {
     this.oldDownloadStates.delete(download);
 
     for (let view of this._views) {
       view.onDownloadRemoved(download);
     }
   },
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// Registration of views
+  // Registration of views
 
   /**
    * Adds an object to be notified when the available download data changes.
    * The specified object is initialized with the currently available downloads.
    *
    * @param aView
    *        DownloadsView object to be added.  This reference must be passed to
    *        removeView before termination.
@@ -891,18 +883,17 @@ DownloadsDataCtor.prototype = {
     let downloadsArray = [...this.downloads];
     downloadsArray.sort((a, b) => b.startTime - a.startTime);
     downloadsArray.forEach(download => aView.onDownloadAdded(download, false));
 
     // Notify the view that all data is available.
     aView.onDataLoadCompleted();
   },
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// Notifications sent to the most recent browser window only
+  // Notifications sent to the most recent browser window only
 
   /**
    * Set to true after the first download causes the downloads panel to be
    * displayed.
    */
   get panelHasShownBefore() {
     try {
       return Services.prefs.getBoolPref("browser.download.panel.shown");
@@ -947,26 +938,24 @@ DownloadsDataCtor.prototype = {
 XPCOMUtils.defineLazyGetter(this, "PrivateDownloadsData", function() {
   return new DownloadsDataCtor(true);
 });
 
 XPCOMUtils.defineLazyGetter(this, "DownloadsData", function() {
   return new DownloadsDataCtor(false);
 });
 
-////////////////////////////////////////////////////////////////////////////////
-//// DownloadsViewPrototype
+// DownloadsViewPrototype
 
 /**
  * A prototype for an object that registers itself with DownloadsData as soon
  * as a view is registered with it.
  */
 const DownloadsViewPrototype = {
-  //////////////////////////////////////////////////////////////////////////////
-  //// Registration of views
+  // Registration of views
 
   /**
    * Array of view objects that should be notified when the available status
    * data changes.
    *
    * SUBCLASSES MUST OVERRIDE THIS PROPERTY.
    */
   _views: null,
@@ -1031,18 +1020,17 @@ const DownloadsViewPrototype = {
       if (this._isPrivate) {
         PrivateDownloadsData.removeView(this);
       } else {
         DownloadsData.removeView(this);
       }
     }
   },
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// Callback functions from DownloadsData
+  // Callback functions from DownloadsData
 
   /**
    * Indicates whether we are still loading downloads data asynchronously.
    */
   _loading: false,
 
   /**
    * Called before multiple downloads are about to be loaded.
@@ -1131,18 +1119,17 @@ const DownloadsViewPrototype = {
    *
    * @note Subclasses should override this.
    */
   _updateView() {
     throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
   },
 };
 
-////////////////////////////////////////////////////////////////////////////////
-//// DownloadsIndicatorData
+// DownloadsIndicatorData
 
 /**
  * This object registers itself with DownloadsData as a view, and transforms the
  * notifications it receives into overall status data, that is then broadcast to
  * the registered download status indicators.
  *
  * Note that using this object does not automatically start the Download Manager
  * service.  Consumers will see an empty list of downloads until the service is
@@ -1165,18 +1152,17 @@ DownloadsIndicatorDataCtor.prototype = {
   removeView(aView) {
     DownloadsViewPrototype.removeView.call(this, aView);
 
     if (this._views.length == 0) {
       this._itemCount = 0;
     }
   },
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// Callback functions from DownloadsData
+  // Callback functions from DownloadsData
 
   onDataLoadCompleted() {
     DownloadsViewPrototype.onDataLoadCompleted.call(this);
     this._updateViews();
   },
 
   onDownloadAdded(download, newest) {
     this._itemCount++;
@@ -1223,18 +1209,17 @@ DownloadsIndicatorDataCtor.prototype = {
     this._updateViews();
   },
 
   onDownloadRemoved(download) {
     this._itemCount--;
     this._updateViews();
   },
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// Propagation of properties to our views
+  // Propagation of properties to our views
 
   // The following properties are updated by _refreshProperties and are then
   // propagated to the views.  See _refreshProperties for details.
   _hasDownloads: false,
   _counter: "",
   _percentComplete: -1,
   _paused: false,
 
@@ -1283,18 +1268,17 @@ DownloadsIndicatorDataCtor.prototype = {
     aView.hasDownloads = this._hasDownloads;
     aView.counter = this._counter;
     aView.percentComplete = this._percentComplete;
     aView.paused = this._paused;
     aView.attention = this._attentionSuppressed ? DownloadsCommon.ATTENTION_NONE
                                                 : this._attention;
   },
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// Property updating based on current download status
+  // Property updating based on current download status
 
   /**
    * Number of download items that are available to be displayed.
    */
   _itemCount: 0,
 
   /**
    * Floating point value indicating the last number of seconds estimated until
@@ -1365,18 +1349,17 @@ DownloadsIndicatorDataCtor.prototype = {
 XPCOMUtils.defineLazyGetter(this, "PrivateDownloadsIndicatorData", function() {
   return new DownloadsIndicatorDataCtor(true);
 });
 
 XPCOMUtils.defineLazyGetter(this, "DownloadsIndicatorData", function() {
   return new DownloadsIndicatorDataCtor(false);
 });
 
-////////////////////////////////////////////////////////////////////////////////
-//// DownloadsSummaryData
+// DownloadsSummaryData
 
 /**
  * DownloadsSummaryData is a view for DownloadsData that produces a summary
  * of all downloads after a certain exclusion point aNumToExclude. For example,
  * if there were 5 downloads in progress, and a DownloadsSummaryData was
  * constructed with aNumToExclude equal to 3, then that DownloadsSummaryData
  * would produce a summary of the last 2 downloads.
  *
@@ -1434,20 +1417,19 @@ DownloadsSummaryData.prototype = {
 
     if (this._views.length == 0) {
       // Clear out our collection of Download objects. If we ever have
       // another view registered with us, this will get re-populated.
       this._downloads = [];
     }
   },
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// Callback functions from DownloadsData - see the documentation in
-  //// DownloadsViewPrototype for more information on what these functions
-  //// are used for.
+  // Callback functions from DownloadsData - see the documentation in
+  // DownloadsViewPrototype for more information on what these functions
+  // are used for.
 
   onDataLoadCompleted() {
     DownloadsViewPrototype.onDataLoadCompleted.call(this);
     this._updateViews();
   },
 
   onDownloadAdded(download, newest) {
     if (newest) {
@@ -1470,18 +1452,17 @@ DownloadsSummaryData.prototype = {
   },
 
   onDownloadRemoved(download) {
     let itemIndex = this._downloads.indexOf(download);
     this._downloads.splice(itemIndex, 1);
     this._updateViews();
   },
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// Propagation of properties to our views
+  // Propagation of properties to our views
 
   /**
    * Computes aggregate values and propagates the changes to our views.
    */
   _updateViews() {
     // Do not update the status indicators during batch loads of download items.
     if (this._loading) {
       return;
@@ -1499,18 +1480,17 @@ DownloadsSummaryData.prototype = {
    */
   _updateView(aView) {
     aView.showingProgress = this._showingProgress;
     aView.percentComplete = this._percentComplete;
     aView.description = this._description;
     aView.details = this._details;
   },
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// Property updating based on current download status
+  // Property updating based on current download status
 
   /**
    * A generator function for the Download objects this summary is currently
    * interested in. This generator is passed off to summarizeDownloads in order
    * to generate statistics about the downloads we care about - in this case,
    * it's the downloads in this._downloads after the first few to exclude,
    * which was set when constructing this DownloadsSummaryData instance.
    */
--- a/browser/components/downloads/DownloadsTaskbar.jsm
+++ b/browser/components/downloads/DownloadsTaskbar.jsm
@@ -9,50 +9,48 @@
  */
 
 "use strict";
 
 this.EXPORTED_SYMBOLS = [
   "DownloadsTaskbar",
 ];
 
-////////////////////////////////////////////////////////////////////////////////
-//// Globals
+// Globals
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const Cr = Components.results;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
                                   "resource://gre/modules/Downloads.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow",
                                   "resource:///modules/RecentWindow.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Services",
                                   "resource://gre/modules/Services.jsm");
 
-XPCOMUtils.defineLazyGetter(this, "gWinTaskbar", function () {
+XPCOMUtils.defineLazyGetter(this, "gWinTaskbar", function() {
   if (!("@mozilla.org/windows-taskbar;1" in Cc)) {
     return null;
   }
   let winTaskbar = Cc["@mozilla.org/windows-taskbar;1"]
                      .getService(Ci.nsIWinTaskbar);
   return winTaskbar.available && winTaskbar;
 });
 
-XPCOMUtils.defineLazyGetter(this, "gMacTaskbarProgress", function () {
+XPCOMUtils.defineLazyGetter(this, "gMacTaskbarProgress", function() {
   return ("@mozilla.org/widget/macdocksupport;1" in Cc) &&
          Cc["@mozilla.org/widget/macdocksupport;1"]
            .getService(Ci.nsITaskbarProgress);
 });
 
-////////////////////////////////////////////////////////////////////////////////
-//// DownloadsTaskbar
+// DownloadsTaskbar
 
 /**
  * Handles the download progress indicator in the taskbar.
  */
 this.DownloadsTaskbar = {
   /**
    * Underlying DownloadSummary providing the aggregate download information, or
    * null if the indicator has never been initialized.
@@ -106,17 +104,16 @@ this.DownloadsTaskbar = {
     if (!this._summary) {
       Downloads.getSummary(Downloads.ALL).then(summary => {
         // In case the method is re-entered, we simply ignore redundant
         // invocations of the callback, instead of keeping separate state.
         if (this._summary) {
           return;
         }
         this._summary = summary;
-        return this._summary.addView(this);
       }).then(null, Cu.reportError);
     }
   },
 
   /**
    * On Windows, attaches the taskbar indicator to the specified browser window.
    */
   _attachIndicator(aWindow) {
@@ -145,18 +142,17 @@ this.DownloadsTaskbar = {
         // The last browser window has been closed.  We remove the reference to
         // the taskbar progress object so that the indicator will be registered
         // again on the next browser window that is opened.
         this._taskbarProgress = null;
       }
     });
   },
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// DownloadSummary view
+  // DownloadSummary view
 
   onSummaryChanged() {
     // If the last browser window has been closed, we have no indicator any more.
     if (!this._taskbarProgress) {
       return;
     }
 
     if (this._summary.allHaveStopped || this._summary.progressTotalBytes == 0) {
--- a/browser/components/downloads/DownloadsViewUI.jsm
+++ b/browser/components/downloads/DownloadsViewUI.jsm
@@ -44,17 +44,17 @@ this.DownloadsViewUI = {
  * from the JavaScript API for downloads, and commands are executed using a
  * combination of Download methods and DownloadsCommon.jsm helper functions.
  *
  * Specialized versions of this shell must be defined, and they are required to
  * implement the "download" property or getter. Currently these objects are the
  * HistoryDownloadElementShell and the DownloadsViewItem for the panel. The
  * history view may use a HistoryDownload object in place of a Download object.
  */
-this.DownloadsViewUI.DownloadElementShell = function () {}
+this.DownloadsViewUI.DownloadElementShell = function() {}
 
 this.DownloadsViewUI.DownloadElementShell.prototype = {
   /**
    * The richlistitem for the download, initialized by the derived object.
    */
   element: null,
 
   /**
@@ -237,20 +237,20 @@ this.DownloadsViewUI.DownloadElementShel
         stateLabel = s.stateBlockedParentalControls;
       } else if (this.download.error.becauseBlockedByReputationCheck) {
         stateLabel = this.rawBlockedTitleAndDetails[0];
       } else {
         stateLabel = s.stateFailed;
       }
 
       let referrer = this.download.source.referrer || this.download.source.url;
-      let [displayHost, fullHost] = DownloadUtils.getURIHost(referrer);
+      let [displayHost /* ,fullHost */] = DownloadUtils.getURIHost(referrer);
 
       let date = new Date(this.download.endTime);
-      let [displayDate, fullDate] = DownloadUtils.getReadableDates(date);
+      let [displayDate /* ,fullDate */] = DownloadUtils.getReadableDates(date);
 
       let firstPart = s.statusSeparator(stateLabel, displayHost);
       fullStatus = s.statusSeparator(firstPart, displayDate);
       status = status || stateLabel;
     }
 
     return {
       status,
@@ -274,18 +274,16 @@ this.DownloadsViewUI.DownloadElementShel
       case Downloads.Error.BLOCK_VERDICT_POTENTIALLY_UNWANTED:
         return [s.blockedPotentiallyUnwanted,
                 [s.unblockTypePotentiallyUnwanted2, s.unblockTip2]];
       case Downloads.Error.BLOCK_VERDICT_MALWARE:
         return [s.blockedMalware, [s.unblockTypeMalware, s.unblockTip2]];
     }
     throw new Error("Unexpected reputationCheckVerdict: " +
                     this.download.error.reputationCheckVerdict);
-    // return anyway to avoid a JS strict warning.
-    return [null, null];
   },
 
   /**
    * Shows the appropriate unblock dialog based on the verdict, and executes the
    * action selected by the user in the dialog, which may involve unblocking,
    * opening or removing the file.
    *
    * @param window
@@ -301,16 +299,17 @@ this.DownloadsViewUI.DownloadElementShel
     }).then(action => {
       if (action == "open") {
         return this.unblockAndOpenDownload();
       } else if (action == "unblock") {
         return this.download.unblock();
       } else if (action == "confirmBlock") {
         return this.download.confirmBlock();
       }
+      return Promise.resolve();
     }).catch(Cu.reportError);
   },
 
   /**
    * Unblocks the downloaded file and opens it.
    *
    * @return A promise that's resolved after the file has been opened.
    */
--- a/browser/components/downloads/content/allDownloadsViewOverlay.js
+++ b/browser/components/downloads/content/allDownloadsViewOverlay.js
@@ -1,11 +1,12 @@
 /* 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/. */
+/* eslint-env mozilla/browser-window */
 
 var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "DownloadUtils",
                                   "resource://gre/modules/DownloadUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon",
@@ -938,19 +939,17 @@ DownloadsPlacesView.prototype = {
       delete this._resultNode;
       delete this._result;
     }
 
     return val;
   },
 
   get selectedNodes() {
-    return [for (element of this._richlistbox.selectedItems)
-            if (element._placesNode)
-            element._placesNode];
+      return this._richlistbox.selectedItems.filter(element => element._placesNode);
   },
 
   get selectedNode() {
     let selectedNodes = this.selectedNodes;
     return selectedNodes.length == 1 ? selectedNodes[0] : null;
   },
 
   get hasSelection() {
@@ -1173,18 +1172,17 @@ DownloadsPlacesView.prototype = {
       if (download.stopped && !(download.canceled && download.hasPartialData)) {
         return true;
       }
     }
     return false;
   },
 
   _copySelectedDownloadsToClipboard() {
-    let urls = [for (element of this._richlistbox.selectedItems)
-                element._shell.download.source.url];
+    let urls = this._richlistbox.selectedItems.map(element => element._shell.download.source.url);
 
     Cc["@mozilla.org/widget/clipboardhelper;1"]
       .getService(Ci.nsIClipboardHelper)
       .copyString(urls.join("\n"));
   },
 
   _getURLFromClipboardData() {
     let trans = Cc["@mozilla.org/widget/transferable;1"].
@@ -1206,17 +1204,17 @@ DownloadsPlacesView.prototype = {
         return [NetUtil.newURI(url).spec, name];
       }
     } catch (ex) {}
 
     return ["", ""];
   },
 
   _canDownloadClipboardURL() {
-    let [url, name] = this._getURLFromClipboardData();
+    let [url /* ,name */] = this._getURLFromClipboardData();
     return url != "";
   },
 
   _downloadURLFromClipboard() {
     let [url, name] = this._getURLFromClipboardData();
     let browserWin = RecentWindow.getMostRecentBrowserWindow();
     let initiatingDoc = browserWin ? browserWin.document : document;
     DownloadURL(url, name, initiatingDoc);
@@ -1303,18 +1301,17 @@ DownloadsPlacesView.prototype = {
       // supported when a single item is selected. To be consistent, do the
       // same here.
       if (selectedElements.length == 1) {
         let element = selectedElements[0];
         if (element._shell) {
           element._shell.doDefaultCommand();
         }
       }
-    }
-    else if (aEvent.charCode == " ".charCodeAt(0)) {
+    } else if (aEvent.charCode == " ".charCodeAt(0)) {
       // Pause/Resume every selected download
       for (let element of selectedElements) {
         if (element._shell.isCommandEnabled("downloadsCmd_pauseResume")) {
           element._shell.doCommand("downloadsCmd_pauseResume");
         }
       }
     }
   },
@@ -1404,17 +1401,17 @@ DownloadsPlacesView.prototype = {
       if (link.url.startsWith("about:"))
         continue;
       DownloadURL(link.url, link.name, initiatingDoc);
     }
   },
 };
 
 for (let methodName of ["load", "applyFilter", "selectNode", "selectItems"]) {
-  DownloadsPlacesView.prototype[methodName] = function () {
+  DownloadsPlacesView.prototype[methodName] = function() {
     throw new Error("|" + methodName +
                     "| is not implemented by the downloads view.");
   }
 }
 
 function goUpdateDownloadCommands() {
   function updateCommandsForObject(object) {
     for (let name in object) {
--- a/browser/components/downloads/content/contentAreaDownloadsView.js
+++ b/browser/components/downloads/content/contentAreaDownloadsView.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/. */
 
+/* import-globals-from allDownloadsViewOverlay.js */
+
 Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
 
 var ContentAreaDownloadsView = {
   init() {
     let view = new DownloadsPlacesView(document.getElementById("downloadsRichListBox"));
     // Do not display the Places downloads in private windows
     if (!PrivateBrowsingUtils.isContentWindowPrivate(window)) {
       view.place = "place:transition=7&sort=4";
--- a/browser/components/downloads/content/downloads.js
+++ b/browser/components/downloads/content/downloads.js
@@ -1,13 +1,14 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* 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/. */
+/* eslint-env mozilla/browser-window */
 
 /**
  * Handles the Downloads panel user interface for each browser window.
  *
  * This file includes the following constructors and global objects:
  *
  * DownloadsPanel
  * Main entry point for the downloads panel interface.
@@ -73,25 +74,23 @@ XPCOMUtils.defineLazyModuleGetter(this, 
                                   "resource://gre/modules/FileUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
                                   "resource://gre/modules/NetUtil.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
                                   "resource://gre/modules/PlacesUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Services",
                                   "resource://gre/modules/Services.jsm");
 
-////////////////////////////////////////////////////////////////////////////////
-//// DownloadsPanel
+// DownloadsPanel
 
 /**
  * Main entry point for the downloads panel interface.
  */
 const DownloadsPanel = {
-  //////////////////////////////////////////////////////////////////////////////
-  //// Initialization and termination
+  // Initialization and termination
 
   /**
    * Internal state of the downloads panel, based on one of the kState
    * constants.  This is not the same state as the XUL panel element.
    */
   _state: 0,
 
   /** The panel is not linked to downloads data yet. */
@@ -187,18 +186,17 @@ const DownloadsPanel = {
     this._unattachEventListeners();
 
     this._state = this.kStateUninitialized;
 
     DownloadsSummary.active = false;
     DownloadsCommon.log("DownloadsPanel terminated.");
   },
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// Panel interface
+  // Panel interface
 
   /**
    * Main panel element in the browser window, or null if the panel overlay
    * hasn't been loaded yet.
    */
   get panel() {
     // If the downloads panel overlay hasn't loaded yet, just return null
     // without resetting this.panel.
@@ -303,19 +301,21 @@ const DownloadsPanel = {
    * visualization.
    */
   handleEvent(aEvent) {
     switch (aEvent.type) {
       case "mousemove":
         this.keyFocusing = false;
         break;
       case "keydown":
-        return this._onKeyDown(aEvent);
+        this._onKeyDown(aEvent);
+        break;
       case "keypress":
-        return this._onKeyPress(aEvent);
+        this._onKeyPress(aEvent);
+        break;
       case "popupshown":
         if (this.setHeightToFitOnShow) {
           this.setHeightToFitOnShow = false;
           this.setHeightToFit();
         }
         break;
     }
   },
@@ -323,28 +323,26 @@ const DownloadsPanel = {
   setHeightToFit() {
     if (this._state == this.kStateShown) {
       DownloadsBlockedSubview.view.setHeightToFit();
     } else {
       this.setHeightToFitOnShow = true;
     }
   },
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// Callback functions from DownloadsView
+  // Callback functions from DownloadsView
 
   /**
    * Called after data loading finished.
    */
   onViewLoadCompleted() {
     this._openPopupIfDataReady();
   },
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// User interface event functions
+  // User interface event functions
 
   onWindowUnload() {
     // This function is registered as an event listener, we can't use "this".
     DownloadsPanel.terminate();
   },
 
   onPopupShown(aEvent) {
     // Ignore events raised by nested popups.
@@ -402,18 +400,17 @@ const DownloadsPanel = {
       .setAttribute("showingdropdown", true);
   },
 
   onFooterPopupHidden(aEvent) {
     document.getElementById("downloadsFooter")
       .removeAttribute("showingdropdown");
   },
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// Related operations
+  // Related operations
 
   /**
    * Shows or focuses the user interface dedicated to downloads history.
    */
   showDownloadsHistory() {
     DownloadsCommon.log("Showing download history.");
     // Hide the panel before showing another window, otherwise focus will return
     // to the browser window when the panel closes automatically.
@@ -424,18 +421,17 @@ const DownloadsPanel = {
 
   openDownloadsFolder() {
     Downloads.getPreferredDownloadsDirectory().then(downloadsPath => {
       DownloadsCommon.showDirectory(new FileUtils.File(downloadsPath));
     }).catch(Cu.reportError);
     this.hidePanel();
   },
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// Internal functions
+  // Internal functions
 
   /**
    * Attach event listeners to a panel element. These listeners should be
    * removed in _unattachEventListeners. This is called automatically after the
    * panel has successfully loaded.
    */
   _attachEventListeners() {
     // Handle keydown to support accel-V.
@@ -620,18 +616,17 @@ const DownloadsPanel = {
       DownloadsCommon.log("Opening downloads panel popup.");
       this.panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, null);
     });
   },
 };
 
 XPCOMUtils.defineConstant(this, "DownloadsPanel", DownloadsPanel);
 
-////////////////////////////////////////////////////////////////////////////////
-//// DownloadsOverlayLoader
+// DownloadsOverlayLoader
 
 /**
  * Allows loading the downloads panel and the status indicator interfaces on
  * demand, to improve startup performance.
  */
 const DownloadsOverlayLoader = {
   /**
    * We cannot load two overlays at the same time, thus we use a queue of
@@ -700,27 +695,25 @@ const DownloadsOverlayLoader = {
       // for the associated overlay to load.
       this.ensureOverlayLoaded(request.overlay, request.callback);
     }
   },
 };
 
 XPCOMUtils.defineConstant(this, "DownloadsOverlayLoader", DownloadsOverlayLoader);
 
-////////////////////////////////////////////////////////////////////////////////
-//// DownloadsView
+// DownloadsView
 
 /**
  * Builds and updates the downloads list widget, responding to changes in the
  * download state and real-time data.  In addition, handles part of the user
  * interaction events raised by the downloads list widget.
  */
 const DownloadsView = {
-  //////////////////////////////////////////////////////////////////////////////
-  //// Functions handling download items in the list
+  // Functions handling download items in the list
 
   /**
    * Maximum number of items shown by the list at any given time.
    */
   kItemCountLimit: 5,
 
   /**
    * Indicates whether there is an open contextMenu for a download item.
@@ -786,18 +779,17 @@ const DownloadsView = {
   /**
    * Element corresponding to the button for showing more downloads.
    */
   get downloadsHistory() {
     delete this.downloadsHistory;
     return this.downloadsHistory = document.getElementById("downloadsHistory");
   },
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// Callback functions from DownloadsData
+  // Callback functions from DownloadsData
 
   /**
    * Called before multiple downloads are about to be loaded.
    */
   onDataLoadStarting() {
     DownloadsCommon.log("onDataLoadStarting called for DownloadsView.");
     this.loading = true;
   },
@@ -913,18 +905,17 @@ const DownloadsView = {
   itemForElement(element) {
     return this._itemsForElements.get(element);
   },
 
   /**
    * Creates a new view item associated with the specified data item, and adds
    * it to the top or the bottom of the list.
    */
-  _addViewItem(download, aNewest)
-  {
+  _addViewItem(download, aNewest) {
     DownloadsCommon.log("Adding a new DownloadsViewItem to the downloads list.",
                         "aNewest =", aNewest);
 
     let element = document.createElement("richlistitem");
     let viewItem = new DownloadsViewItem(download, element);
     this._visibleViewItems.set(download, viewItem);
     this._itemsForElements.set(element, viewItem);
     if (aNewest) {
@@ -945,18 +936,17 @@ const DownloadsView = {
     if (previousSelectedIndex != -1) {
       this.richListBox.selectedIndex = Math.min(previousSelectedIndex,
                                                 this.richListBox.itemCount - 1);
     }
     this._visibleViewItems.delete(download);
     this._itemsForElements.delete(element);
   },
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// User interface event functions
+  // User interface event functions
 
   /**
    * Helper function to do commands on a specific download item.
    *
    * @param aEvent
    *        Event object for the event being handled.  If the event target is
    *        not a richlistitem that represents a download, this function will
    *        walk up the parent nodes until it finds a DOM node that is.
@@ -1113,18 +1103,17 @@ const DownloadsView = {
     dataTransfer.addElement(element);
 
     aEvent.stopPropagation();
   },
 }
 
 XPCOMUtils.defineConstant(this, "DownloadsView", DownloadsView);
 
-////////////////////////////////////////////////////////////////////////////////
-//// DownloadsViewItem
+// DownloadsViewItem
 
 /**
  * Builds and updates a single item in the downloads list widget, responding to
  * changes in the download state and real-time data, and handles the user
  * interaction events related to a single item in the downloads list widgets.
  *
  * @param download
  *        Download object to be associated with the view item.
@@ -1194,18 +1183,17 @@ DownloadsViewItem.prototype = {
   },
 
   doCommand(aCommand) {
     if (this.isCommandEnabled(aCommand)) {
       this[aCommand]();
     }
   },
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// Item commands
+  // Item commands
 
   cmd_delete() {
     DownloadsCommon.removeAndFinalizeDownload(this.download);
     PlacesUtils.history.remove(this.download.source.url).catch(Cu.reportError);
   },
 
   downloadsCmd_unblock() {
     DownloadsPanel.hidePanel();
@@ -1263,38 +1251,35 @@ DownloadsViewItem.prototype = {
   downloadsCmd_doDefault() {
     let defaultCommand = this.currentDefaultCommandName;
     if (defaultCommand && this.isCommandEnabled(defaultCommand)) {
       this.doCommand(defaultCommand);
     }
   },
 };
 
-////////////////////////////////////////////////////////////////////////////////
-//// DownloadsViewController
+// DownloadsViewController
 
 /**
  * Handles part of the user interaction events raised by the downloads list
  * widget, in particular the "commands" that apply to multiple items, and
  * dispatches the commands that apply to individual items.
  */
 const DownloadsViewController = {
-  //////////////////////////////////////////////////////////////////////////////
-  //// Initialization and termination
+  // Initialization and termination
 
   initialize() {
     window.controllers.insertControllerAt(0, this);
   },
 
   terminate() {
     window.controllers.removeController(this);
   },
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// nsIController
+  // nsIController
 
   supportsCommand(aCommand) {
     if (aCommand === "downloadsCmd_clearList") {
       return true;
     }
     // Firstly, determine if this is a command that we can handle.
     if (!DownloadsViewUI.isCommandName(aCommand)) {
       return false;
@@ -1347,43 +1332,40 @@ const DownloadsViewController = {
     if (element) {
       // The doCommand function also checks if the command is enabled.
       DownloadsView.itemForElement(element).doCommand(aCommand);
     }
   },
 
   onEvent() {},
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// Other functions
+  // Other functions
 
   updateCommands() {
     function updateCommandsForObject(object) {
       for (let name in object) {
         if (DownloadsViewUI.isCommandName(name)) {
           goUpdateCommand(name);
         }
       }
     }
     updateCommandsForObject(this);
     updateCommandsForObject(DownloadsViewItem.prototype);
   },
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// Selection-independent commands
+  // Selection-independent commands
 
   downloadsCmd_clearList() {
     DownloadsCommon.getData(window).removeFinished();
   },
 };
 
 XPCOMUtils.defineConstant(this, "DownloadsViewController", DownloadsViewController);
 
-////////////////////////////////////////////////////////////////////////////////
-//// DownloadsSummary
+// DownloadsSummary
 
 /**
  * Manages the summary at the bottom of the downloads panel list if the number
  * of items in the list exceeds the panels limit.
  */
 const DownloadsSummary = {
 
   /**
@@ -1557,18 +1539,17 @@ const DownloadsSummary = {
     }
     delete this._detailsNode;
     return this._detailsNode = node;
   }
 };
 
 XPCOMUtils.defineConstant(this, "DownloadsSummary", DownloadsSummary);
 
-////////////////////////////////////////////////////////////////////////////////
-//// DownloadsFooter
+// DownloadsFooter
 
 /**
  * Manages events sent to to the footer vbox, which contains both the
  * DownloadsSummary as well as the "Show All Downloads" button.
  */
 const DownloadsFooter = {
 
   /**
@@ -1617,18 +1598,17 @@ const DownloadsFooter = {
     delete this._footerNode;
     return this._footerNode = node;
   }
 };
 
 XPCOMUtils.defineConstant(this, "DownloadsFooter", DownloadsFooter);
 
 
-////////////////////////////////////////////////////////////////////////////////
-//// DownloadsBlockedSubview
+// DownloadsBlockedSubview
 
 /**
  * Manages the blocked subview that slides in when you click a blocked download.
  */
 const DownloadsBlockedSubview = {
 
   get subview() {
     let subview = document.getElementById("downloadsPanel-blockedSubview");
--- a/browser/components/downloads/content/indicator.js
+++ b/browser/components/downloads/content/indicator.js
@@ -1,13 +1,14 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* 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/. */
+/* eslint-env mozilla/browser-window */
 
 /**
  * Handles the indicator that displays the progress of ongoing downloads, which
  * is also used as the anchor for the downloads panel.
  *
  * This module includes the following constructors and global objects:
  *
  * DownloadsButton
@@ -21,18 +22,17 @@
  * Builds and updates the actual downloads status widget, responding to changes
  * in the global status data, or provides a neutral view if the indicator is
  * removed from the toolbars and only used as a temporary anchor.  In addition,
  * handles the user interaction events raised by the widget.
  */
 
 "use strict";
 
-////////////////////////////////////////////////////////////////////////////////
-//// DownloadsButton
+// DownloadsButton
 
 /**
  * Main entry point for the downloads indicator.  Depending on how the toolbars
  * have been customized, this object determines if we should show a fully
  * functional indicator, a placeholder used during customization and in the
  * customization palette, or a neutral view as a temporary anchor for the
  * downloads panel.
  */
@@ -182,18 +182,17 @@ const DownloadsButton = {
 };
 
 Object.defineProperty(this, "DownloadsButton", {
   value: DownloadsButton,
   enumerable: true,
   writable: false
 });
 
-////////////////////////////////////////////////////////////////////////////////
-//// DownloadsIndicatorView
+// DownloadsIndicatorView
 
 /**
  * Builds and updates the actual downloads status widget, responding to changes
  * in the global status data, or provides a neutral view if the indicator is
  * removed from the toolbars and only used as a temporary anchor.  In addition,
  * handles the user interaction events raised by the widget.
  */
 const DownloadsIndicatorView = {
@@ -282,18 +281,17 @@ const DownloadsIndicatorView = {
         }
 
         if (aCallback) {
           aCallback();
         }
       });
   },
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// Direct control functions
+  // Direct control functions
 
   /**
    * Set while we are waiting for a notification to fade out.
    */
   _notificationTimeout: null,
 
   /**
    * Check if the panel containing aNode is open.
@@ -352,39 +350,38 @@ const DownloadsIndicatorView = {
     }
 
     // The notification element is positioned to show in the same location as
     // the downloads button. It's not in the downloads button itself in order to
     // be able to anchor the notification elsewhere if required, and to ensure
     // the notification isn't clipped by overflow properties of the anchor's
     // container.
     let notifier = this.notifier;
-    if (notifier.style.transform == '') {
+    if (notifier.style.transform == "") {
       let anchorRect = anchor.getBoundingClientRect();
       let notifierRect = notifier.getBoundingClientRect();
       let topDiff = anchorRect.top - notifierRect.top;
       let leftDiff = anchorRect.left - notifierRect.left;
       let heightDiff = anchorRect.height - notifierRect.height;
       let widthDiff = anchorRect.width - notifierRect.width;
       let translateX = (leftDiff + .5 * widthDiff) + "px";
       let translateY = (topDiff + .5 * heightDiff) + "px";
-      notifier.style.transform = "translate(" +  translateX + ", " + translateY + ")";
+      notifier.style.transform = "translate(" + translateX + ", " + translateY + ")";
     }
     notifier.setAttribute("notification", aType);
     anchor.setAttribute("notification", aType);
     this._notificationTimeout = setTimeout(() => {
       anchor.removeAttribute("notification");
       notifier.removeAttribute("notification");
-      notifier.style.transform = '';
+      notifier.style.transform = "";
       // This value is determined by the overall duration of animation in CSS.
     }, 2000);
   },
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// Callback functions from DownloadsIndicatorData
+  // Callback functions from DownloadsIndicatorData
 
   /**
    * Indicates whether the indicator should be shown because there are some
    * downloads to be displayed.
    */
   set hasDownloads(aValue) {
     if (this._hasDownloads != aValue || (!this._operational && aValue)) {
       this._hasDownloads = aValue;
@@ -519,18 +516,17 @@ const DownloadsIndicatorView = {
         let badgeClass = "download-" + this._attention;
         gMenuButtonBadgeManager.addBadge(
                           gMenuButtonBadgeManager.BADGEID_DOWNLOAD, badgeClass);
       }
     }
   },
   _attention: DownloadsCommon.ATTENTION_NONE,
 
-  //////////////////////////////////////////////////////////////////////////////
-  //// User interface event functions
+  // User interface event functions
 
   onWindowUnload() {
     // This function is registered as an event listener, we can't use "this".
     DownloadsIndicatorView.ensureTerminated();
   },
 
   onCommand(aEvent) {
     // If the downloads button is in the menu panel, open the Library
--- a/browser/components/downloads/test/browser/browser_basic_functionality.js
+++ b/browser/components/downloads/test/browser/browser_basic_functionality.js
@@ -25,17 +25,17 @@ add_task(function* test_basic_functional
   yield promiseFocus();
 
   // Ensure that state is reset in case previous tests didn't finish.
   yield task_resetState();
 
   // For testing purposes, show all the download items at once.
   var originalCountLimit = DownloadsView.kItemCountLimit;
   DownloadsView.kItemCountLimit = DownloadData.length;
-  registerCleanupFunction(function () {
+  registerCleanupFunction(function() {
     DownloadsView.kItemCountLimit = originalCountLimit;
   });
 
   // Populate the downloads database with the data required by this test.
   yield task_addDownloads(DownloadData);
 
   // Open the user interface and wait for data to be fully loaded.
   yield task_openPanel();
--- a/browser/components/downloads/test/browser/browser_downloads_panel_block.js
+++ b/browser/components/downloads/test/browser/browser_downloads_panel_block.js
@@ -103,30 +103,28 @@ function* openPanel() {
     let interval = setInterval(() => {
       if (DownloadsPanel.panel && DownloadsPanel.panel.state == "open") {
         if (verifyCount > 0) {
           verifyCount--;
         } else {
           clearInterval(interval);
           resolve();
         }
-      } else {
-        if (iBackoff < backoff) {
+      } else if (iBackoff < backoff) {
           // Keep backing off before trying again.
           iBackoff++;
-        } else {
+      } else {
           // Try (or retry) opening the panel.
           verifyCount = 5;
           backoff = Math.max(1, 2 * backoff);
           iBackoff = 0;
           if (DownloadsPanel._state != DownloadsPanel.kStateUninitialized) {
-            DownloadsPanel._state = DownloadsPanel.kStateHidden;
+              DownloadsPanel._state = DownloadsPanel.kStateHidden;
           }
           DownloadsPanel.showPanel();
-        }
       }
     }, 100);
   });
 }
 
 function promisePanelHidden() {
   return new Promise(resolve => {
     if (!DownloadsPanel.panel || DownloadsPanel.panel.state == "closed") {
@@ -157,17 +155,16 @@ function promiseSubviewShown(shown) {
   // More terribleness, but I'm tired of fighting intermittent timeouts on try.
   // Just poll for the subview and wait a second before resolving the promise.
   return new Promise(resolve => {
     let interval = setInterval(() => {
       if (shown == DownloadsBlockedSubview.view.showingSubView &&
           !DownloadsBlockedSubview.view._transitioning) {
         clearInterval(interval);
         setTimeout(resolve, 1000);
-        return;
       }
     }, 0);
   });
 }
 
 function promiseUnblockAndOpenDownloadCalled(item) {
   return new Promise(resolve => {
     let realFn = item._shell.unblockAndOpenDownload;
--- a/browser/components/downloads/test/browser/browser_downloads_panel_footer.js
+++ b/browser/components/downloads/test/browser/browser_downloads_panel_footer.js
@@ -36,27 +36,27 @@ add_task(function* test_clearList() {
     downloads: [
       { state: nsIDM.DOWNLOAD_NOTSTARTED },
       { state: nsIDM.DOWNLOAD_FINISHED },
       { state: nsIDM.DOWNLOAD_FAILED },
       { state: nsIDM.DOWNLOAD_CANCELED },
     ],
     expectClearListShown: true,
     expectedItemNumber: 0,
-  },{
+  }, {
     downloads: [
       { state: nsIDM.DOWNLOAD_NOTSTARTED },
       { state: nsIDM.DOWNLOAD_FINISHED },
       { state: nsIDM.DOWNLOAD_FAILED },
       { state: nsIDM.DOWNLOAD_PAUSED },
       { state: nsIDM.DOWNLOAD_CANCELED },
     ],
     expectClearListShown: true,
     expectedItemNumber: 1,
-  },{
+  }, {
     downloads: [
       { state: nsIDM.DOWNLOAD_PAUSED },
     ],
     expectClearListShown: false,
     expectedItemNumber: 1,
   }];
 
   for (let testCase of kTestCases) {
--- a/browser/components/downloads/test/browser/browser_first_download_panel.js
+++ b/browser/components/downloads/test/browser/browser_first_download_panel.js
@@ -39,17 +39,17 @@ add_task(function* test_first_download_p
   DownloadsPanel.hidePanel();
 
   ok(DownloadsCommon.getData(window).panelHasShownBefore,
      "Should have recorded that the panel was opened on a download.")
 
   // Next, make sure that if we start another download, we don't open the
   // panel automatically.
   let originalOnPopupShown = DownloadsPanel.onPopupShown;
-  DownloadsPanel.onPopupShown = function () {
+  DownloadsPanel.onPopupShown = function() {
     originalOnPopupShown.apply(this, arguments);
     ok(false, "Should not have opened the downloads panel.");
   };
 
   DownloadsCommon.getData(window)._notifyDownloadEvent("start");
 
   // Wait 2 seconds to ensure that the panel does not open.
   yield new Promise(resolve => setTimeout(resolve, 2000));
--- a/browser/components/downloads/test/browser/browser_iframe_gone_mid_download.js
+++ b/browser/components/downloads/test/browser/browser_iframe_gone_mid_download.js
@@ -1,11 +1,11 @@
 const SAVE_PER_SITE_PREF = "browser.download.lastDir.savePerSite";
 
-function test_deleted_iframe(perSitePref, windowOptions={}) {
+function test_deleted_iframe(perSitePref, windowOptions = {}) {
   return function*() {
     Services.prefs.setBoolPref(SAVE_PER_SITE_PREF, perSitePref);
     let {DownloadLastDir} = Cu.import("resource://gre/modules/DownloadLastDir.jsm", {});
 
     let win = yield promiseOpenAndLoadWindow(windowOptions);
     let tab = win.gBrowser.addTab();
     yield promiseTabLoadEvent(tab, "about:mozilla");
 
--- a/browser/components/downloads/test/browser/browser_indicatorDrop.js
+++ b/browser/components/downloads/test/browser/browser_indicatorDrop.js
@@ -24,20 +24,20 @@ add_task(function* test_indicatorDrop() 
     let dragData = [[{type: "text/plain", data: urls.join("\n")}]];
 
     let list = yield Downloads.getList(Downloads.ALL);
 
     let added = new Set();
     let succeeded = new Set();
     yield new Promise(function(resolve) {
       let view = {
-        onDownloadAdded: function(download) {
+        onDownloadAdded(download) {
           added.add(download.source.url);
         },
-        onDownloadChanged: function(download) {
+        onDownloadChanged(download) {
           if (!added.has(download.source.url))
             return;
           if (!download.succeeded)
             return;
           succeeded.add(download.source.url);
           if (succeeded.size == urls.length) {
             list.removeView(view).then(resolve);
           }
--- a/browser/components/downloads/test/browser/browser_libraryDrop.js
+++ b/browser/components/downloads/test/browser/browser_libraryDrop.js
@@ -24,20 +24,20 @@ add_task(function* test_indicatorDrop() 
     ok(listBox, "download list box present");
 
     let list = await Downloads.getList(Downloads.ALL);
 
     let added = new Set();
     let succeeded = new Set();
     await new Promise(resolve => {
       let view = {
-        onDownloadAdded: function(download) {
+        onDownloadAdded(download) {
           added.add(download.source.url);
         },
-        onDownloadChanged: function(download) {
+        onDownloadChanged(download) {
           if (!added.has(download.source.url))
             return;
           if (!download.succeeded)
             return;
           succeeded.add(download.source.url);
           if (succeeded.size == urls.length) {
             list.removeView(view).then(resolve);
           }
--- a/browser/components/downloads/test/browser/head.js
+++ b/browser/components/downloads/test/browser/head.js
@@ -2,53 +2,54 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Provides infrastructure for automated download components tests.
  */
 
-////////////////////////////////////////////////////////////////////////////////
-//// Globals
+// Globals
 
 XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
                                   "resource://gre/modules/Downloads.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon",
                                   "resource:///modules/DownloadsCommon.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
                                   "resource://gre/modules/FileUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Promise",
                                   "resource://gre/modules/Promise.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Task",
                                   "resource://gre/modules/Task.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
                                   "resource://gre/modules/PlacesUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "HttpServer",
+    "resource://testing-common/httpd.js");
+
 const nsIDM = Ci.nsIDownloadManager;
 
 var gTestTargetFile = FileUtils.getFile("TmpD", ["dm-ui-test.file"]);
 gTestTargetFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
 
 // Load mocking/stubbing library, sinon
 // docs: http://sinonjs.org/docs/
+/* global sinon:false */
 Services.scriptloader.loadSubScript("resource://testing-common/sinon-1.16.1.js");
 
-registerCleanupFunction(function () {
+registerCleanupFunction(function() {
   gTestTargetFile.remove(false);
 
   delete window.sinon;
   delete window.setImmediate;
   delete window.clearImmediate;
 });
 
-////////////////////////////////////////////////////////////////////////////////
-//// Asynchronous support subroutines
+// Asynchronous support subroutines
 
-function promiseOpenAndLoadWindow(aOptions)
-{
+function promiseOpenAndLoadWindow(aOptions) {
   return new Promise((resolve, reject) => {
     let win = OpenBrowserWindow(aOptions);
     win.addEventListener("load", function() {
       resolve(win);
     }, {once: true});
   });
 }
 
@@ -61,18 +62,17 @@ function promiseOpenAndLoadWindow(aOptio
  * @param [optional] url
  *        The url to load, or the current url.
  * @param [optional] event
  *        The load event type to wait for.  Defaults to "load".
  * @return {Promise} resolved when the event is handled.
  * @resolves to the received event
  * @rejects if a valid load event is not received within a meaningful interval
  */
-function promiseTabLoadEvent(tab, url, eventType="load")
-{
+function promiseTabLoadEvent(tab, url, eventType = "load") {
   let deferred = Promise.defer();
   info("Wait tab event: " + eventType);
 
   function handle(event) {
     if (event.originalTarget != tab.linkedBrowser.contentDocument ||
         event.target.location.href == "about:blank" ||
         (url && event.target.location.href != url)) {
       info("Skipping spurious '" + eventType + "'' event" +
@@ -91,77 +91,72 @@ function promiseTabLoadEvent(tab, url, e
   registerCleanupFunction(() => realCleanup());
 
   tab.linkedBrowser.addEventListener(eventType, handle, true, true);
   if (url)
     tab.linkedBrowser.loadURI(url);
   return deferred.promise;
 }
 
-function promiseWindowClosed(win)
-{
+function promiseWindowClosed(win) {
   let promise = new Promise((resolve, reject) => {
     Services.obs.addObserver(function obs(subject, topic) {
       if (subject == win) {
         Services.obs.removeObserver(obs, topic);
         resolve();
       }
     }, "domwindowclosed", false);
   });
   win.close();
   return promise;
 }
 
 
-function promiseFocus()
-{
+function promiseFocus() {
   let deferred = Promise.defer();
   waitForFocus(deferred.resolve);
   return deferred.promise;
 }
 
-function promisePanelOpened()
-{
+function promisePanelOpened() {
   let deferred = Promise.defer();
 
   if (DownloadsPanel.panel && DownloadsPanel.panel.state == "open") {
     return deferred.resolve();
   }
 
   // Hook to wait until the panel is shown.
   let originalOnPopupShown = DownloadsPanel.onPopupShown;
-  DownloadsPanel.onPopupShown = function () {
+  DownloadsPanel.onPopupShown = function() {
     DownloadsPanel.onPopupShown = originalOnPopupShown;
     originalOnPopupShown.apply(this, arguments);
 
     // Defer to the next tick of the event loop so that we don't continue
     // processing during the DOM event handler itself.
     setTimeout(deferred.resolve, 0);
   };
 
   return deferred.promise;
 }
 
-function* task_resetState()
-{
+function* task_resetState() {
   // Remove all downloads.
   let publicList = yield Downloads.getList(Downloads.PUBLIC);
   let downloads = yield publicList.getAll();
   for (let download of downloads) {
     publicList.remove(download);
     yield download.finalize(true);
   }
 
   DownloadsPanel.hidePanel();
 
   yield promiseFocus();
 }
 
-function* task_addDownloads(aItems)
-{
+function* task_addDownloads(aItems) {
   let startTimeMs = Date.now();
 
   let publicList = yield Downloads.getList(Downloads.PUBLIC);
   for (let item of aItems) {
     let download = {
       source: {
         url: "http://www.example.com/test-download.txt",
       },
@@ -179,31 +174,30 @@ function* task_addDownloads(aItems)
     // `"errorObj" in download` must be false when there's no error.
     if (item.errorObj) {
       download.errorObj = item.errorObj;
     }
     yield publicList.add(yield Downloads.createDownload(download));
   }
 }
 
-function* task_openPanel()
-{
+function* task_openPanel() {
   yield promiseFocus();
 
   let promise = promisePanelOpened();
   DownloadsPanel.showPanel();
   yield promise;
 }
 
 function* setDownloadDir() {
   let tmpDir = Services.dirsvc.get("TmpD", Ci.nsIFile);
   tmpDir.append("testsavedir");
   if (!tmpDir.exists()) {
     tmpDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
-    registerCleanupFunction(function () {
+    registerCleanupFunction(function() {
       try {
         tmpDir.remove(true);
       } catch (e) {
         // On Windows debug build this may fail.
       }
     });
   }
 
--- a/browser/components/downloads/test/unit/head.js
+++ b/browser/components/downloads/test/unit/head.js
@@ -2,17 +2,16 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Provides infrastructure for automated download components tests.
  */
 
-////////////////////////////////////////////////////////////////////////////////
-//// Globals
+// Globals
 
 var Cc = Components.classes;
 var Ci = Components.interfaces;
 var Cu = Components.utils;
 var Cr = Components.results;
 
 Cu.import("resource:///modules/DownloadsCommon.jsm");
--- a/browser/components/downloads/test/unit/test_DownloadsCommon.js
+++ b/browser/components/downloads/test/unit/test_DownloadsCommon.js
@@ -2,36 +2,34 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Tests for the functions located directly in the "DownloadsCommon" object.
  */
 
-function testFormatTimeLeft(aSeconds, aExpectedValue, aExpectedUnitString)
-{
+function testFormatTimeLeft(aSeconds, aExpectedValue, aExpectedUnitString) {
   let expected = "";
   if (aExpectedValue) {
     // Format the expected result based on the current language.
     expected = DownloadsCommon.strings[aExpectedUnitString](aExpectedValue);
   }
   do_check_eq(DownloadsCommon.formatTimeLeft(aSeconds), expected);
 }
 
-function run_test()
-{
-  testFormatTimeLeft(      0,   "", "");
-  testFormatTimeLeft(      1,  "1", "shortTimeLeftSeconds");
-  testFormatTimeLeft(     29, "29", "shortTimeLeftSeconds");
-  testFormatTimeLeft(     30, "30", "shortTimeLeftSeconds");
-  testFormatTimeLeft(     31,  "1", "shortTimeLeftMinutes");
-  testFormatTimeLeft(     60,  "1", "shortTimeLeftMinutes");
-  testFormatTimeLeft(     89,  "1", "shortTimeLeftMinutes");
-  testFormatTimeLeft(     90,  "2", "shortTimeLeftMinutes");
-  testFormatTimeLeft(     91,  "2", "shortTimeLeftMinutes");
-  testFormatTimeLeft(   3600,  "1", "shortTimeLeftHours");
-  testFormatTimeLeft(  86400, "24", "shortTimeLeftHours");
-  testFormatTimeLeft( 169200, "47", "shortTimeLeftHours");
-  testFormatTimeLeft( 172800,  "2", "shortTimeLeftDays");
+function run_test() {
+  testFormatTimeLeft(0, "", "");
+  testFormatTimeLeft(1, "1", "shortTimeLeftSeconds");
+  testFormatTimeLeft(29, "29", "shortTimeLeftSeconds");
+  testFormatTimeLeft(30, "30", "shortTimeLeftSeconds");
+  testFormatTimeLeft(31, "1", "shortTimeLeftMinutes");
+  testFormatTimeLeft(60, "1", "shortTimeLeftMinutes");
+  testFormatTimeLeft(89, "1", "shortTimeLeftMinutes");
+  testFormatTimeLeft(90, "2", "shortTimeLeftMinutes");
+  testFormatTimeLeft(91, "2", "shortTimeLeftMinutes");
+  testFormatTimeLeft(3600, "1", "shortTimeLeftHours");
+  testFormatTimeLeft(86400, "24", "shortTimeLeftHours");
+  testFormatTimeLeft(169200, "47", "shortTimeLeftHours");
+  testFormatTimeLeft(172800, "2", "shortTimeLeftDays");
   testFormatTimeLeft(8553600, "99", "shortTimeLeftDays");
   testFormatTimeLeft(8640000, "99", "shortTimeLeftDays");
 }