Bug 1451659 - Enable ESLint for devtools/client/{canvasdebugger,framework,scratchpad,shadereditor}/. r=jdescottes
authorMark Banner <standard8@mozilla.com>
Wed, 04 Apr 2018 23:24:04 +0100
changeset 468015 a45a86e9a6e30917511555c9a2672109e19f5068
parent 468014 61316c057950e0762d90ec687e045658d41b85b6
child 468016 e20559cdf1c479180fe049e5302309cedbc2eb87
push id1728
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:12:27 +0000
treeherdermozilla-release@c296fde26f5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdescottes
bugs1451659
milestone61.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 1451659 - Enable ESLint for devtools/client/{canvasdebugger,framework,scratchpad,shadereditor}/. r=jdescottes Disable rules with many failures for now, in a way that mentored bugs can easily pick them up. Fix other minor issues raised by various rules. MozReview-Commit-ID: 71OQI7jLihe
.eslintignore
devtools/.eslintrc.js
devtools/client/canvasdebugger/callslist.js
devtools/client/canvasdebugger/snapshotslist.js
devtools/client/canvasdebugger/test/browser_profiling-webgl.js
devtools/client/framework/sidebar.js
devtools/client/framework/test/browser_browser_toolbox_debugger.js
devtools/client/framework/test/browser_toolbox_options_disable_js.html
devtools/client/framework/test/browser_toolbox_options_disable_js_iframe.html
devtools/client/framework/test/browser_toolbox_transport_events.js
devtools/client/framework/test/browser_toolbox_window_shortcuts.js
devtools/client/scratchpad/scratchpad-commands.js
devtools/client/scratchpad/scratchpad-panel.js
devtools/client/scratchpad/scratchpad.js
devtools/client/scratchpad/test/browser_scratchpad_open.js
devtools/client/scratchpad/test/browser_scratchpad_recent_files.js
devtools/client/scratchpad/test/browser_scratchpad_remember_view_options.js
devtools/client/scratchpad/test/browser_scratchpad_revert_to_saved.js
devtools/client/scratchpad/test/head.js
devtools/client/shadereditor/panel.js
devtools/client/shadereditor/shadereditor.js
devtools/client/shadereditor/test/head.js
--- a/.eslintignore
+++ b/.eslintignore
@@ -96,33 +96,21 @@ browser/extensions/activity-stream/vendo
 # The only file in browser/locales/ is pre-processed.
 browser/locales/**
 # imported from chromium
 browser/extensions/mortar/**
 # Generated data files
 browser/extensions/formautofill/phonenumberutils/PhoneNumberMetaData.jsm
 
 # devtools/ exclusions
-devtools/client/canvasdebugger/**
-devtools/client/commandline/**
-devtools/client/debugger/**
-devtools/client/framework/**
-!devtools/client/framework/devtools.js
-!devtools/client/framework/devtools-browser.js
-!devtools/client/framework/selection.js
-!devtools/client/framework/target*
-!devtools/client/framework/toolbox*
 devtools/client/inspector/markup/test/doc_markup_events_*.html
 devtools/client/inspector/rules/test/doc_media_queries.html
 devtools/client/memory/test/chrome/*.html
 devtools/client/performance/components/test/test_jit_optimizations_01.html
-devtools/client/projecteditor/**
 devtools/client/responsive.html/test/browser/touch.html
-devtools/client/scratchpad/**
-devtools/client/shadereditor/**
 devtools/client/shared/*.jsm
 devtools/client/shared/components/reps/reps.js
 devtools/client/shared/components/reps/test/mochitest/*.html
 !devtools/client/shared/components/reps/test/mochitest/test_reps_infinity.html
 !devtools/client/shared/components/reps/test/mochitest/test_reps_nan.html
 !devtools/client/shared/components/reps/test/mochitest/test_reps_promise.html
 !devtools/client/shared/components/reps/test/mochitest/test_reps_symbol.html
 !devtools/client/shared/components/reps/test/mochitest/test_reps_text-node.html
@@ -149,50 +137,54 @@ devtools/server/tests/browser/storage-*.
 !devtools/server/tests/browser/storage-unsecured-iframe.html
 devtools/server/tests/browser/stylesheets-nested-iframes.html
 devtools/server/tests/unit/xpcshell_debugging_script.js
 devtools/client/shared/webpack/shims/test/test_clipboard.html
 devtools/shared/qrcode/tests/mochitest/test_decode.html
 devtools/shared/tests/mochitest/*.html
 devtools/shared/webconsole/test/test_*.html
 
+# Soon to be removed
+devtools/client/commandline/**
+# Soon to be removed, the new/ directory is explicitly excluded below due to
+# also being an imported repository.
+devtools/client/debugger/**
+
+# Ignore devtools imported repositories
+devtools/client/debugger/new/**
+
 # Ignore devtools preferences files
 devtools/client/preferences/**
 devtools/startup/devtools-startup-prefs.js
 
 # Ignore devtools third-party libs
 devtools/shared/jsbeautify/*
 devtools/shared/acorn/*
 devtools/shared/gcli/source/*
 devtools/shared/node-properties/*
 devtools/shared/pretty-fast/*
 devtools/shared/sourcemap/*
 devtools/shared/sprintfjs/*
 devtools/shared/qrcode/decoder/*
 devtools/shared/qrcode/encoder/*
+devtools/client/inspector/markup/test/lib_*
+devtools/client/jsonview/lib/require.js
 devtools/client/shared/demangle.js
 devtools/client/shared/source-map/*
 devtools/client/shared/vendor/*
 devtools/client/sourceeditor/codemirror/*.js
 devtools/client/sourceeditor/codemirror/**/*.js
 devtools/client/sourceeditor/tern/*
 devtools/client/sourceeditor/test/cm_mode_ruby.js
 devtools/client/sourceeditor/test/codemirror/*
-devtools/client/inspector/markup/test/lib_*
-devtools/client/jsonview/lib/require.js
 devtools/server/actors/utils/automation-timeline.js
 
 # Ignore devtools files testing sourcemaps / code style
-devtools/client/debugger/test/mochitest/code_binary_search.js
-devtools/client/debugger/test/mochitest/code_binary_search_absolute.js
-devtools/client/debugger/test/mochitest/code_math.min.js
-devtools/client/debugger/test/mochitest/code_math_bogus_map.js
-devtools/client/debugger/test/mochitest/code_ugly*
-devtools/client/debugger/test/mochitest/code_worker-source-map.js
-devtools/client/framework/test/code_ugly*
+devtools/client/debugger/test/mochitest/code_*.js
+devtools/client/framework/test/code_*
 devtools/client/inspector/markup/test/events_bundle.js
 devtools/client/netmonitor/test/xhr_bundle.js
 devtools/client/webconsole/new-console-output/test/mochitest/code_bundle_nosource.js
 devtools/client/webconsole/new-console-output/test/mochitest/code_bundle_invalidmap.js
 devtools/server/tests/unit/babel_and_browserify_script_with_source_map.js
 devtools/server/tests/unit/setBreakpoint*
 devtools/server/tests/unit/sourcemapped.js
 
--- a/devtools/.eslintrc.js
+++ b/devtools/.eslintrc.js
@@ -11,22 +11,132 @@ module.exports = {
     "module": true,
     "reportError": true,
     "require": true,
   },
   "overrides": [{
     // XXX Bug 1230193. We're still working on enabling no-undef for these test
     // directories.
     "files": [
+      "client/framework/test/**",
+      "client/scratchpad/**",
       "server/tests/mochitest/**",
       "shared/tests/unit/**",
     ],
     "rules": {
       "no-undef": "off",
     }
+  }, {
+    "files": [
+      "client/framework/**",
+    ],
+    "rules": {
+      "no-return-assign": "off",
+      "no-unused-vars": "off",
+    }
+  }, {
+    "files": [
+      "client/scratchpad/scratchpad-manager.jsm",
+      "client/scratchpad/scratchpad.js",
+    ],
+    "rules": {
+      "camelcase": "off",
+    }
+  }, {
+    "files": [
+      "client/framework/**",
+      "client/scratchpad/**",
+    ],
+    "rules": {
+      "consistent-return": "off",
+    }
+  }, {
+    "files": [
+      "client/framework/**",
+      "client/scratchpad/**",
+    ],
+    "rules": {
+      "max-nested-callbacks": "off",
+    }
+  }, {
+    "files": [
+      "client/framework/**",
+      "client/scratchpad/**",
+    ],
+    "rules": {
+      "max-len": "off",
+    }
+  }, {
+    "files": [
+      "client/scratchpad/test/browser_scratchpad_inspect.js",
+      "client/scratchpad/test/browser_scratchpad_inspect_primitives.js",
+    ],
+    "rules": {
+      "no-labels": "off",
+    }
+  }, {
+    "files": [
+      "client/framework/**",
+      "client/scratchpad/**",
+    ],
+    "rules": {
+      "mozilla/no-aArgs": "off",
+    }
+  }, {
+    "files": [
+      "client/framework/test/**",
+      "client/scratchpad/**",
+    ],
+    "rules": {
+      "mozilla/var-only-at-top-level": "off",
+    }
+  }, {
+    "files": [
+      "client/framework/**",
+      "client/scratchpad/**",
+    ],
+    "rules": {
+      "no-shadow": "off",
+    }
+  }, {
+    "files": [
+      "client/framework/**",
+      "client/scratchpad/**",
+    ],
+    "rules": {
+      "strict": "off",
+    }
+  }, {
+    "files": [
+      // Note: Bug 1403938 may be removing canvasdebugger, check before
+      // doing more work on enabling these rules.
+      "client/canvasdebugger/**",
+      // Note: Bug 1342237 may be removing shadereditor, check before
+      // doing more work on enabling these rules.
+      "client/shadereditor/**",
+    ],
+    "rules": {
+      "consistent-return": "off",
+      "max-len": "off",
+      "mozilla/no-aArgs": "off",
+      "mozilla/var-only-at-top-level": "off",
+      "no-return-assign": "off",
+      "no-shadow": "off",
+      "no-undef": "off",
+      "no-unused-vars": "off",
+      "strict": "off",
+    }
+  }, {
+    // For all head*.js files, turn off no-unused-vars at a global level
+    "files": [
+      "**/head*.js",
+    ],
+    "rules": {
+      "no-unused-vars": ["error", {"args": "none", "vars": "local"}],
+    }
   }],
   "rules": {
     // These are the rules that have been configured so far to match the
     // devtools coding style.
 
     // Rules from the mozilla plugin
     "mozilla/no-aArgs": "error",
     "mozilla/no-single-arg-cu-import": "error",
--- a/devtools/client/canvasdebugger/callslist.js
+++ b/devtools/client/canvasdebugger/callslist.js
@@ -362,19 +362,18 @@ var CallsListView = extend(WidgetMethods
       window.emit(EVENTS.CALL_STACK_DISPLAYED);
     };
 
     // If this animation snapshot is loaded from disk, there are no corresponding
     // backend actors available and the data is immediately available.
     let functionCall = callItem.attachment.actor;
     if (functionCall.isLoadedFromDisk) {
       display(functionCall.stack);
-    }
-    // ..otherwise we need to request the function call stack from the backend.
-    else {
+    } else {
+      // ..otherwise we need to request the function call stack from the backend.
       callItem.attachment.actor.getDetails().then(fn => display(fn.stack));
     }
   },
 
   /**
    * The click listener for a location link in the call stack.
    *
    * @param string file
--- a/devtools/client/canvasdebugger/snapshotslist.js
+++ b/devtools/client/canvasdebugger/snapshotslist.js
@@ -301,22 +301,21 @@ var SnapshotsListView = extend(WidgetMet
    * or if a recording times out.
    */
   async _stopRecordingAnimation() {
     clearNamedTimeout("canvas-actor-recording");
     let actorCanStop = await gTarget.actorHasMethod("canvas", "stopRecordingAnimationFrame");
 
     if (actorCanStop) {
       await gFront.stopRecordingAnimationFrame();
-    }
-    // If actor does not have the method to stop recording (Fx39+),
-    // manually call the record failure method. This will call a connection failure
-    // on disconnect as a result of `gFront.recordAnimationFrame()` never resolving,
-    // but this is better than it hanging when there is no requestAnimationFrame anyway.
-    else {
+    } else {
+      // If actor does not have the method to stop recording (Fx39+),
+      // manually call the record failure method. This will call a connection failure
+      // on disconnect as a result of `gFront.recordAnimationFrame()` never resolving,
+      // but this is better than it hanging when there is no requestAnimationFrame anyway.
       this._onRecordFailure();
     }
 
     this._recording = false;
     $("#record-snapshot").removeAttribute("checked");
     this._enableRecordButton();
   },
 
@@ -366,19 +365,20 @@ var SnapshotsListView = extend(WidgetMet
         uri: NetUtil.newURI(fp.file), loadUsingSystemPrincipal: true});
       channel.contentType = "text/plain";
 
       NetUtil.asyncFetch(channel, (inputStream, status) => {
         if (!Components.isSuccessCode(status)) {
           console.error("Could not import recorded animation frame snapshot file.");
           return;
         }
+        var data;
         try {
           let string = NetUtil.readInputStreamToString(inputStream, inputStream.available());
-          var data = JSON.parse(string);
+          data = JSON.parse(string);
         } catch (e) {
           console.error("Could not read animation frame snapshot file.");
           return;
         }
         if (data.fileType != CALLS_LIST_SERIALIZER_IDENTIFIER) {
           console.error("Unrecognized animation frame snapshot file.");
           return;
         }
--- a/devtools/client/canvasdebugger/test/browser_profiling-webgl.js
+++ b/devtools/client/canvasdebugger/test/browser_profiling-webgl.js
@@ -37,17 +37,19 @@ async function ifTestingSupported() {
   is(animationOverview.primitive.tris, 5, "The count of triangles is correct.");
   is(animationOverview.primitive.vertices, 26, "The count of vertices is correct.");
   is(animationOverview.primitive.points, 4, "The count of points is correct.");
   is(animationOverview.primitive.lines, 8, "The count of lines is correct.");
 
   await removeTab(target.tab);
 
   info("Start to estimate WebGL drawElements function.");
-  var { target, front } = await initCanvasDebuggerBackend(WEBGL_DRAW_ELEMENTS);
+  let result = await initCanvasDebuggerBackend(WEBGL_DRAW_ELEMENTS);
+  target = result.target;
+  front = result.front;
 
   navigated = once(target, "navigate");
 
   await front.setup({ reload: true });
   ok(true, "The front was setup up successfully.");
 
   await navigated;
   ok(true, "Target automatically navigated when the front was set up.");
--- a/devtools/client/framework/sidebar.js
+++ b/devtools/client/framework/sidebar.js
@@ -63,19 +63,20 @@ function ToolSidebar(tabbox, panel, uid,
   this._uid = uid;
   this._panelDoc = this._tabbox.ownerDocument;
   this._toolPanel = panel;
   this._options = options;
 
   this._onTabBoxOverflow = this._onTabBoxOverflow.bind(this);
   this._onTabBoxUnderflow = this._onTabBoxUnderflow.bind(this);
 
-  try {
-    this._width = Services.prefs.getIntPref("devtools.toolsidebar-width." + this._uid);
-  } catch (e) {}
+  let width = Services.prefs.getIntPref("devtools.toolsidebar-width." + this._uid, undefined);
+  if (width) {
+    this._width = width;
+  }
 
   if (!options.disableTelemetry) {
     this._telemetry = new Telemetry();
   }
 
   this._tabbox.tabpanels.addEventListener("select", this, true);
 
   this._tabs = new Map();
--- a/devtools/client/framework/test/browser_browser_toolbox_debugger.js
+++ b/devtools/client/framework/test/browser_browser_toolbox_debugger.js
@@ -103,16 +103,18 @@ add_task(async function runTest() {
     // test_browser_toolbox_debugger.js uses waitForPaused, which relies on waitUntil
     // which is normally provided by shared-head.js
     const { setTimeout } = ChromeUtils.import("resource://gre/modules/Timer.jsm", {});
     function waitUntil(predicate, interval = 10) {
       if (predicate()) {
         return Promise.resolve(true);
       }
       return new Promise(resolve => {
+        // TODO: fixme.
+        // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
         setTimeout(function() {
           waitUntil(predicate, interval).then(() => resolve(true));
         }, interval);
       });
     }
   }).toSource().replace(/^\(function \(\) \{|\}\)$/g, "");
   // Stringify testHead's function and remove `(function {` prefix and `})` suffix
   // to ensure inner symbols gets exposed to next pieces of code
--- a/devtools/client/framework/test/browser_toolbox_options_disable_js.html
+++ b/devtools/client/framework/test/browser_toolbox_options_disable_js.html
@@ -19,16 +19,17 @@
       h1 {
         font-size: 20px
       }
     </style>
     <script type="application/javascript">
       function log(msg) {
         let output = document.getElementById("output");
 
+        // eslint-disable-next-line no-unsanitized/property
         output.innerHTML = msg;
       }
     </script>
   </head>
   <body>
     <h1>Test in page</h1>
     <input id="logJSEnabled"
            type="button"
--- a/devtools/client/framework/test/browser_toolbox_options_disable_js_iframe.html
+++ b/devtools/client/framework/test/browser_toolbox_options_disable_js_iframe.html
@@ -9,16 +9,17 @@
         border: 1px solid #000;
         margin-top: 10px;
       }
     </style>
     <script type="application/javascript">
       function log(msg) {
         let output = document.getElementById("output");
 
+        // eslint-disable-next-line no-unsanitized/property
         output.innerHTML = msg;
       }
     </script>
   </head>
   <body>
     <input id="logJSEnabled"
            type="button"
            value="Log JS Enabled"
--- a/devtools/client/framework/test/browser_toolbox_transport_events.js
+++ b/devtools/client/framework/test/browser_toolbox_transport_events.js
@@ -25,16 +25,18 @@ function testResults(toolbox) {
   cleanUp(toolbox);
 }
 
 function cleanUp(toolbox) {
   gDevTools.off("toolbox-created", onToolboxCreated);
   off(DebuggerClient, "connect", onDebuggerClientConnect);
 
   toolbox.destroy().then(function() {
+    // TODO: fixme.
+    // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
     setTimeout(() => {
       gBrowser.removeCurrentTab();
       executeSoon(function() {
         finish();
       });
     }, 1000);
   });
 }
--- a/devtools/client/framework/test/browser_toolbox_window_shortcuts.js
+++ b/devtools/client/framework/test/browser_toolbox_window_shortcuts.js
@@ -18,22 +18,18 @@ function test() {
       let shortcut = Startup.KeyShortcuts.filter(s => s.toolId == id)[0];
       if (!shortcut) {
         continue;
       }
       toolIDs.push(id);
       toolShortcuts.push(shortcut);
 
       // Enable disabled tools
-      let pref = definition.visibilityswitch, prefValue;
-      try {
-        prefValue = Services.prefs.getBoolPref(pref);
-      } catch (e) {
-        continue;
-      }
+      let pref = definition.visibilityswitch;
+      let prefValue = Services.prefs.getBoolPref(pref, false);
       if (!prefValue) {
         modifiedPrefs.push(pref);
         Services.prefs.setBoolPref(pref, true);
       }
     }
     let target = TargetFactory.forTab(gBrowser.selectedTab);
     idIndex = 0;
     gDevTools.showToolbox(target, toolIDs[0], Toolbox.HostType.WINDOW)
--- a/devtools/client/scratchpad/scratchpad-commands.js
+++ b/devtools/client/scratchpad/scratchpad-commands.js
@@ -1,16 +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/. */
 
 "use strict";
 
 const l10n = require("gcli/l10n");
-const {Cu} = require("chrome");
 
 exports.items = [{
   item: "command",
   runAt: "client",
   name: "scratchpad",
   buttonId: "command-button-scratchpad",
   buttonClass: "command-button",
   tooltipText: l10n.lookup("scratchpadOpenTooltip"),
--- a/devtools/client/scratchpad/scratchpad-panel.js
+++ b/devtools/client/scratchpad/scratchpad-panel.js
@@ -1,16 +1,15 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ft=javascript 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/. */
 "use strict";
 
-const {Cu} = require("chrome");
 const EventEmitter = require("devtools/shared/event-emitter");
 const promise = require("promise");
 const defer = require("devtools/shared/defer");
 
 function ScratchpadPanel(iframeWindow, toolbox) {
   let { Scratchpad } = iframeWindow;
   this._toolbox = toolbox;
   this.panelWin = iframeWindow;
--- a/devtools/client/scratchpad/scratchpad.js
+++ b/devtools/client/scratchpad/scratchpad.js
@@ -51,22 +51,22 @@ const promise = require("promise");
 const defer = require("devtools/shared/defer");
 const Services = require("Services");
 const {gDevTools} = require("devtools/client/framework/devtools");
 const { extend } = require("devtools/shared/extend");
 
 const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm");
 const {NetUtil} = require("resource://gre/modules/NetUtil.jsm");
 const {ScratchpadManager} = require("resource://devtools/client/scratchpad/scratchpad-manager.jsm");
-const {addDebuggerToGlobal} = require("resource://gre/modules/jsdebugger.jsm");
 const {OS} = require("resource://gre/modules/osfile.jsm");
 const {Reflect} = require("resource://gre/modules/reflect.jsm");
 
 // Use privileged promise in panel documents to prevent having them to freeze
 // during toolbox destruction. See bug 1402779.
+// eslint-disable-next-line no-unused-vars
 const Promise = require("Promise");
 
 XPCOMUtils.defineConstant(this, "SCRATCHPAD_CONTEXT_CONTENT", SCRATCHPAD_CONTEXT_CONTENT);
 XPCOMUtils.defineConstant(this, "SCRATCHPAD_CONTEXT_BROWSER", SCRATCHPAD_CONTEXT_BROWSER);
 XPCOMUtils.defineConstant(this, "BUTTON_POSITION_SAVE", BUTTON_POSITION_SAVE);
 XPCOMUtils.defineConstant(this, "BUTTON_POSITION_CANCEL", BUTTON_POSITION_CANCEL);
 XPCOMUtils.defineConstant(this, "BUTTON_POSITION_DONT_SAVE", BUTTON_POSITION_DONT_SAVE);
 XPCOMUtils.defineConstant(this, "BUTTON_POSITION_REVERT", BUTTON_POSITION_REVERT);
@@ -1074,32 +1074,32 @@ var Scratchpad = {
    * Get content converted to unicode, using a list of input charset to try.
    *
    * @param string aContent
    * @param array of string aCharsetArray
    * @return string
    */
   _getUnicodeContent: function SP__getUnicodeContent(aContent, aCharsetArray) {
     let content = null,
-      converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter),
-      success = aCharsetArray.some(charset => {
-        try {
-          converter.charset = charset;
-          content = converter.ConvertToUnicode(aContent);
-          return true;
-        } catch (e) {
-          this.notificationBox.appendNotification(
-              this.strings.formatStringFromName("importFromFile.convert.failed",
-                                                [ charset ], 1),
-              "file-import-convert-failed",
-              null,
-              this.notificationBox.PRIORITY_WARNING_HIGH,
-              null);
-        }
-      });
+      converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
+    aCharsetArray.some(charset => {
+      try {
+        converter.charset = charset;
+        content = converter.ConvertToUnicode(aContent);
+        return true;
+      } catch (e) {
+        this.notificationBox.appendNotification(
+            this.strings.formatStringFromName("importFromFile.convert.failed",
+                                              [ charset ], 1),
+            "file-import-convert-failed",
+            null,
+            this.notificationBox.PRIORITY_WARNING_HIGH,
+            null);
+      }
+    });
     return content;
   },
 
   /**
    * Read the content of a file and put it into the textbox.
    *
    * @param nsIFile aFile
    *        The file you want to save the textbox content into.
@@ -1276,20 +1276,19 @@ var Scratchpad = {
         // same file has been opened in two or more windows.
         this.populateRecentFilesMenu();
         return;
       }
 
       // It is not the most recent file. Remove it from the list, we add it as
       // the most recent farther down.
       filePaths.splice(pathIndex, 1);
-    }
-    // If we are not storing the file and the 'recent files'-list is full,
-    // remove the oldest file from the list.
-    else if (filesCount === maxRecent) {
+    } else if (filesCount === maxRecent) {
+      // If we are not storing the file and the 'recent files'-list is full,
+      // remove the oldest file from the list.
       filePaths.shift();
     }
 
     filePaths.push(aFile.path);
 
     Services.prefs.getBranch("devtools.scratchpad.")
             .setStringPref("recentFilePaths", JSON.stringify(filePaths));
   },
--- a/devtools/client/scratchpad/test/browser_scratchpad_open.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_open.js
@@ -66,17 +66,17 @@ function testOpenWithState() {
 
 function testOpenInvalidState() {
   let win = openScratchpad(null, {state: 7});
   ok(!win, "no scratchpad opened if state is not an object");
   done();
 }
 
 function testOpenTestFile() {
-  let win = openScratchpad(function(win) {
+  openScratchpad(function(win) {
     ok(win, "scratchpad opened for file open");
     try {
       win.Scratchpad.importFromFile(
         "http://example.com/browser/devtools/client/scratchpad/test/NS_ERROR_ILLEGAL_INPUT.txt",
         "silent",
         function(aStatus, content) {
           let nb = win.document.querySelector("#scratchpad-notificationbox");
           is(nb.querySelectorAll("notification").length, 1, "There is just one notification");
--- a/devtools/client/scratchpad/test/browser_scratchpad_recent_files.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_recent_files.js
@@ -22,17 +22,16 @@ var lists = {
 
 // Temporary file names.
 var gFileName01 = "file01_ForBug651942.tmp";
 var gFileName02 = "☕"; // See bug 783858 for more information
 var gFileName03 = "file03_ForBug651942.tmp";
 var gFileName04 = "file04_ForBug651942.tmp";
 
 // Content for the temporary files.
-var gFileContent;
 var gFileContent01 = "hello.world.01('bug651942');";
 var gFileContent02 = "hello.world.02('bug651942');";
 var gFileContent03 = "hello.world.03('bug651942');";
 var gFileContent04 = "hello.world.04('bug651942');";
 
 function startTest() {
   gScratchpad = gScratchpadWindow.Scratchpad;
 
--- a/devtools/client/scratchpad/test/browser_scratchpad_remember_view_options.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_remember_view_options.js
@@ -16,17 +16,16 @@ function test() {
     openScratchpad(runTests);
   });
 
   gBrowser.loadURI("data:text/html,<title>Bug 1140839</title>" +
                    "<p>test Scratchpad should remember View options");
 }
 
 function runTests() {
-  let sp = gScratchpadWindow.Scratchpad;
   let doc = gScratchpadWindow.document;
 
   let testData = [
     {itemMenuId: "sp-menu-line-numbers", prefId: "devtools.scratchpad.lineNumbers", expectedVal: false},
     {itemMenuId: "sp-menu-word-wrap", prefId: "devtools.scratchpad.wrapText", expectedVal: true},
     {itemMenuId: "sp-menu-highlight-trailing-space", prefId: "devtools.scratchpad.showTrailingSpace", expectedVal: true},
     {itemMenuId: "sp-menu-larger-font", prefId: "devtools.scratchpad.editorFontSize", expectedVal: 13},
     {itemMenuId: "sp-menu-normal-size-font", prefId: "devtools.scratchpad.editorFontSize", expectedVal: 12},
--- a/devtools/client/scratchpad/test/browser_scratchpad_revert_to_saved.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_revert_to_saved.js
@@ -10,17 +10,16 @@ var gScratchpad;
 var gFile;
 
 // Temporary file name.
 var gFileName = "testFileForBug751744.tmp";
 
 // Content for the temporary file.
 var gFileContent = "/* this file is already saved */\n" +
                    "function foo() { alert('bar') }";
-var gLength = gFileContent.length;
 
 // Reference to the menu entry.
 var menu;
 
 function startTest() {
   gScratchpad = gScratchpadWindow.Scratchpad;
   menu = gScratchpadWindow.document.getElementById("sp-cmd-revert");
   createAndLoadTemporaryFile();
--- a/devtools/client/scratchpad/test/head.js
+++ b/devtools/client/scratchpad/test/head.js
@@ -81,16 +81,17 @@ function openScratchpad(aReadyCallback, 
  *        to the options supported by openScratchpad, the following options
  *        are supported:
  *        - tabContent
  *          A string providing the html content of the tab.
  * @return Promise
  */
 function openTabAndScratchpad(aOptions = {}) {
   waitForExplicitFinish();
+  // eslint-disable-next-line new-cap
   return new promise(resolve => {
     gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
     let {selectedBrowser} = gBrowser;
     BrowserTestUtils.browserLoaded(selectedBrowser).then(function() {
       openScratchpad((win, sp) => resolve([win, sp]), aOptions);
     });
     gBrowser.loadURI("data:text/html;charset=utf8," + (aOptions.tabContent || ""));
   });
--- a/devtools/client/shadereditor/panel.js
+++ b/devtools/client/shadereditor/panel.js
@@ -1,16 +1,15 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ft=javascript 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/. */
 "use strict";
 
-const { Cc, Ci, Cu, Cr } = require("chrome");
 const promise = require("promise");
 const EventEmitter = require("devtools/shared/event-emitter");
 const { WebGLFront } = require("devtools/shared/fronts/webgl");
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
 
 function ShaderEditorPanel(iframeWindow, toolbox) {
   this.panelWin = iframeWindow;
   this._toolbox = toolbox;
@@ -62,15 +61,15 @@ ShaderEditorPanel.prototype = {
   },
 
   destroy: function() {
     // Make sure this panel is not already destroyed.
     if (this._destroyer) {
       return this._destroyer;
     }
 
-    return this._destroyer = this.panelWin.shutdownShaderEditor().then(() => {
+    return (this._destroyer = this.panelWin.shutdownShaderEditor().then(() => {
       // Destroy front to ensure packet handler is removed from client
       this.panelWin.gFront.destroy();
       this.emit("destroyed");
-    });
+    }));
   }
 };
--- a/devtools/client/shadereditor/shadereditor.js
+++ b/devtools/client/shadereditor/shadereditor.js
@@ -1,30 +1,32 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
+/* exported startupShaderEditor, shutdownShaderEditor */
+
 const {require} = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
 const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm");
 const {SideMenuWidget} = require("resource://devtools/client/shared/widgets/SideMenuWidget.jsm");
 const promise = require("promise");
 const defer = require("devtools/shared/defer");
 const {Task} = require("devtools/shared/task");
-const Services = require("Services");
 const EventEmitter = require("devtools/shared/event-emitter");
 const Tooltip = require("devtools/client/shared/widgets/tooltip/Tooltip");
 const Editor = require("devtools/client/sourceeditor/editor");
 const {LocalizationHelper} = require("devtools/shared/l10n");
 const {extend} = require("devtools/shared/extend");
 const {WidgetMethods, setNamedTimeout} =
   require("devtools/client/shared/widgets/view-helpers");
 
 // Use privileged promise in panel documents to prevent having them to freeze
 // during toolbox destruction. See bug 1402779.
+// eslint-disable-next-line no-unused-vars
 const Promise = require("Promise");
 
 // The panel's window global is an EventEmitter firing the following events:
 const EVENTS = {
   // When new programs are received from the server.
   NEW_PROGRAM: "ShaderEditor:NewProgram",
   PROGRAMS_ADDED: "ShaderEditor:ProgramsAdded",
 
--- a/devtools/client/shadereditor/test/head.js
+++ b/devtools/client/shadereditor/test/head.js
@@ -68,17 +68,17 @@ function ifWebGLUnsupported() {
   finish();
 }
 
 async function test() {
   let generator = isWebGLSupported(document) ? ifWebGLSupported : ifWebGLUnsupported;
   try {
     await generator();
   } catch (e) {
-    handlError(e);
+    handleError(e);
   }
 }
 
 function createCanvas() {
   return document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
 }
 
 function observe(aNotificationName, aOwnsWeak = false) {
@@ -110,17 +110,18 @@ function ensurePixelIs(aFront, aPosition
     let pixel = await aFront.getPixel({ selector: aSelector, position: aPosition });
     if (isApproxColor(pixel, aColor)) {
       ok(true, "Expected pixel is shown at: " + aPosition.toSource());
       return;
     }
 
     if (aWaitFlag) {
       await aFront.waitForFrame();
-      return ensurePixelIs(aFront, aPosition, aColor, aWaitFlag, aSelector);
+      await ensurePixelIs(aFront, aPosition, aColor, aWaitFlag, aSelector);
+      return;
     }
 
     ok(false, "Expected pixel was not already shown at: " + aPosition.toSource());
     throw new Error("Expected pixel was not already shown at: " + aPosition.toSource());
   })();
 }
 
 function navigateInHistory(aTarget, aDirection, aWaitForTargetEvent = "navigate") {