Bug 1329014 - Enable the no-extra-bind rule and use eslint --fix to autofix the errors. r?standard8 draft
authorJared Wein <jwein@mozilla.com>
Thu, 05 Jan 2017 16:43:29 -0500
changeset 456534 ca5ec63cb5a0441ab05bf90fe55aa64bc697107f
parent 456533 35369b6ed68e3bf9ab59bfeece541642915926ec
child 456535 bd9954ac19da735c7e56bc7b42bfb790bb4383c2
push id40534
push userbmo:jaws@mozilla.com
push dateThu, 05 Jan 2017 22:11:21 +0000
reviewersstandard8
bugs1329014
milestone53.0a1
Bug 1329014 - Enable the no-extra-bind rule and use eslint --fix to autofix the errors. r?standard8 MozReview-Commit-ID: BwK94W2mHXS
browser/base/content/aboutNetError.xhtml
browser/components/migration/ChromeProfileMigrator.js
browser/components/migration/SafariProfileMigrator.js
browser/components/newtab/tests/browser/browser_newtab_overrides.js
browser/components/newtab/tests/browser/browser_newtabwebchannel.js
browser/components/newtab/tests/browser/browser_remotenewtab_pageloads.js
browser/components/nsBrowserGlue.js
browser/components/uitour/UITour.jsm
browser/modules/SocialService.jsm
toolkit/.eslintrc.js
toolkit/components/crashes/CrashManager.jsm
toolkit/components/jsdownloads/src/DownloadCore.jsm
toolkit/components/jsdownloads/test/unit/head.js
toolkit/components/places/Bookmarks.jsm
toolkit/components/places/PlacesTransactions.jsm
toolkit/components/places/PlacesUtils.jsm
toolkit/components/places/UnifiedComplete.js
toolkit/components/reader/AboutReader.jsm
toolkit/components/telemetry/TelemetrySession.jsm
toolkit/identity/IdentityProvider.jsm
toolkit/modules/ProfileAge.jsm
toolkit/modules/secondscreen/RokuApp.jsm
toolkit/modules/secondscreen/SimpleServiceDiscovery.jsm
toolkit/mozapps/extensions/content/extensions.js
--- a/browser/base/content/aboutNetError.xhtml
+++ b/browser/base/content/aboutNetError.xhtml
@@ -303,17 +303,17 @@
             // If it looks like an error that is user config based
             if (getErrorCode() == "nssFailure2" && hasPrefStyleError && options && options.changedCertPrefs) {
               showPrefChangeContainer();
             }
           }
           if (getErrorCode() == "weakCryptoUsed" || getErrorCode() == "sslv3Used") {
             setupAdvancedButton(getErrorCode() == "weakCryptoUsed");
           }
-        }.bind(this), true, true);
+        }, true, true);
 
         var event = new CustomEvent("AboutNetErrorLoad", {bubbles:true});
         document.dispatchEvent(event);
 
         if (err == "inadequateSecurityError") {
           // Remove the "Try again" button for HTTP/2 inadequate security as it
           // is useless.
           document.getElementById("errorTryAgain").style.display = "none";
--- a/browser/components/migration/ChromeProfileMigrator.js
+++ b/browser/components/migration/ChromeProfileMigrator.js
@@ -288,18 +288,18 @@ function GetBookmarksResource(aProfileFo
             parentGuid =
               yield MigrationUtils.createImportedBookmarksFolder("Chrome", parentGuid);
           }
           yield insertBookmarkItems(parentGuid, roots.other.children, errorGatherer);
         }
         if (gotErrors) {
           throw new Error("The migration included errors.");
         }
-      }.bind(this)).then(() => aCallback(true),
-                         () => aCallback(false));
+      }).then(() => aCallback(true),
+              () => aCallback(false));
     }
   };
 }
 
 function GetHistoryResource(aProfileFolder) {
   let historyFile = aProfileFolder.clone();
   historyFile.append("History");
   if (!historyFile.exists())
--- a/browser/components/migration/SafariProfileMigrator.js
+++ b/browser/components/migration/SafariProfileMigrator.js
@@ -323,17 +323,17 @@ SearchStrings.prototype = {
           if (recentSearchStrings && recentSearchStrings.length > 0) {
             let changes = recentSearchStrings.map((searchString) => (
               {op: "add",
                fieldname: "searchbar-history",
                value: searchString}));
             FormHistory.update(changes);
           }
         }
-      }.bind(this), aCallback));
+      }, aCallback));
   }
 };
 
 function SafariProfileMigrator() {
 }
 
 SafariProfileMigrator.prototype = Object.create(MigratorPrototype);
 
--- a/browser/components/newtab/tests/browser/browser_newtab_overrides.js
+++ b/browser/components/newtab/tests/browser/browser_newtab_overrides.js
@@ -130,10 +130,10 @@ add_task(function* override_blank_loads_
     yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
   }
 });
 
 function nextChangeNotificationPromise(aNewURL, testMessage) {
   return TestUtils.topicObserved("newtab-url-changed", function observer(aSubject, aData) {  // jshint unused:false
       Assert.equal(aData, aNewURL, testMessage);
       return true;
-  }.bind(this));
+  });
 }
--- a/browser/components/newtab/tests/browser/browser_newtabwebchannel.js
+++ b/browser/components/newtab/tests/browser/browser_newtabwebchannel.js
@@ -86,28 +86,28 @@ add_task(function* webchannel_broadcast(
   let countingMessagePromise = new Promise(resolve => {
     let count = 0;
     NewTabWebChannel.on("foo", function test_message(name, msg) {
       count += 1;
       if (count === 2) {
         NewTabWebChannel.off("foo", test_message);
         resolve(msg.target);
       }
-    }.bind(this));
+    });
   });
 
   let countingReplyPromise = new Promise(resolve => {
     let count = 0;
     NewTabWebChannel.on("reply", function test_message(name, msg) {
       count += 1;
       if (count === 2) {
         NewTabWebChannel.off("reply", test_message);
         resolve(msg.target);
       }
-    }.bind(this));
+    });
   });
 
   let countingUnloadPromise = new Promise(resolve => {
     let count = 0;
     NewTabWebChannel.on("targetUnload", function test_message() {
       count += 1;
       if (count === 2) {
         NewTabWebChannel.off("targetUnload", test_message);
@@ -142,17 +142,17 @@ add_task(function* webchannel_broadcast(
  */
 add_task(function* webchannel_switch() {
   setup();
 
   function newMessagePromise() {
     return new Promise(resolve => {
       NewTabWebChannel.once("foo", function(name, msg) {
         resolve(msg.target);
-      }.bind(this));
+      });
     });
   }
 
   let replyCount = 0;
   function newReplyPromise() {
     return new Promise(resolve => {
       NewTabWebChannel.on("reply", function() {
         replyCount += 1;
--- a/browser/components/newtab/tests/browser/browser_remotenewtab_pageloads.js
+++ b/browser/components/newtab/tests/browser/browser_remotenewtab_pageloads.js
@@ -43,10 +43,10 @@ add_task(function* open_newtab() {
   });
   yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
 });
 
 function nextChangeNotificationPromise(aNewURL, testMessage) {
   return TestUtils.topicObserved("newtab-url-changed", function observer(aSubject, aData) {  // jshint unused:false
       Assert.equal(aData, aNewURL, testMessage);
       return true;
-  }.bind(this));
+  });
 }
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1156,17 +1156,17 @@ BrowserGlue.prototype = {
                           .add(shouldCheck);
         Services.telemetry.getHistogramById("BROWSER_SET_DEFAULT_DIALOG_PROMPT_RAWCOUNT")
                           .add(promptCount);
       } catch (ex) { /* Don't break the default prompt if telemetry is broken. */ }
 
       if (willPrompt) {
         Services.tm.mainThread.dispatch(function() {
           DefaultBrowserCheck.prompt(RecentWindow.getMostRecentBrowserWindow());
-        }.bind(this), Ci.nsIThread.DISPATCH_NORMAL);
+        }, Ci.nsIThread.DISPATCH_NORMAL);
       }
     }
 
     E10SAccessibilityCheck.onWindowsRestored();
   },
 
   _createExtraDefaultProfile() {
     if (!AppConstants.MOZ_DEV_EDITION) {
--- a/browser/components/uitour/UITour.jsm
+++ b/browser/components/uitour/UITour.jsm
@@ -1313,17 +1313,17 @@ this.UITour = {
         maybeNotifyHeartbeat("Heartbeat:Voted", { score: rating });
 
         // Append the score data to the engagement URL.
         userEngaged(new Map([
           ["type", "stars"],
           ["score", rating],
           ["flowid", aOptions.flowId]
         ]));
-      }.bind(this));
+      });
 
       // Add it to the container.
       ratingContainer.appendChild(ratingElement);
     }
 
     frag.appendChild(ratingContainer);
 
     // Make sure the stars are not pushed to the right by the spacer.
--- a/browser/modules/SocialService.jsm
+++ b/browser/modules/SocialService.jsm
@@ -445,17 +445,17 @@ this.SocialService = {
     }.bind(this));
   },
 
   // Returns a single provider object with the specified origin.  The provider
   // must be "installed" (ie, in ActiveProviders)
   getProvider: function getProvider(origin, onDone) {
     schedule((function() {
       onDone(SocialServiceInternal.providers[origin] || null);
-    }).bind(this));
+    }));
   },
 
   // Returns an unordered array of installed providers
   getProviderList(onDone) {
     schedule(function() {
       onDone(SocialServiceInternal.providerArray);
     });
   },
--- a/toolkit/.eslintrc.js
+++ b/toolkit/.eslintrc.js
@@ -73,16 +73,19 @@ module.exports = {
     "no-dupe-args": "error",
 
     // No duplicate keys in object declarations
     "no-dupe-keys": "error",
 
     // No duplicate cases in switch statements
     "no-duplicate-case": "error",
 
+    // Disallow unnecessary calls to .bind()
+    "no-extra-bind": "error",
+
     // No labels
     "no-labels": "error",
 
     // Disallow unnecessary nested blocks
     "no-lone-blocks": "error",
 
     // If an if block ends with a return no need for an else block
     "no-else-return": "error",
--- a/toolkit/components/crashes/CrashManager.jsm
+++ b/toolkit/components/crashes/CrashManager.jsm
@@ -755,17 +755,17 @@ this.CrashManager.prototype = Object.fre
         });
       } finally {
         it.close();
       }
 
       entries.sort((a, b) => { return a.date - b.date; });
 
       return entries;
-    }.bind(this));
+    });
   },
 
   _getStore() {
     if (this._getStoreTask) {
       return this._getStoreTask;
     }
 
     return this._getStoreTask = Task.spawn(function* () {
--- a/toolkit/components/jsdownloads/src/DownloadCore.jsm
+++ b/toolkit/components/jsdownloads/src/DownloadCore.jsm
@@ -2092,36 +2092,36 @@ this.DownloadCopySaver.prototype = {
                                               keepPartialData);
               } else {
                 // Set the final target file, and delete it on failure.
                 backgroundFileSaver.setTarget(new FileUtils.File(targetPath),
                                               false);
               }
             }.bind(copySaver),
 
-            onStopRequest: function(aRequest, aContext, aStatusCode) {
+            onStopRequest(aRequest, aContext, aStatusCode) {
               try {
                 backgroundFileSaver.onStopRequest(aRequest, aContext,
                                                   aStatusCode);
               } finally {
                 // If the data transfer completed successfully, indicate to the
                 // background file saver that the operation can finish.  If the
                 // data transfer failed, the saver has been already stopped.
                 if (Components.isSuccessCode(aStatusCode)) {
                   backgroundFileSaver.finish(Cr.NS_OK);
                 }
               }
-            }.bind(copySaver),
+            },
 
-            onDataAvailable: function(aRequest, aContext, aInputStream,
+            onDataAvailable(aRequest, aContext, aInputStream,
                                       aOffset, aCount) {
               backgroundFileSaver.onDataAvailable(aRequest, aContext,
                                                   aInputStream, aOffset,
                                                   aCount);
-            }.bind(copySaver),
+            },
           });
 
           // We should check if we have been canceled in the meantime, after
           // all the previous asynchronous operations have been executed and
           // just before we set the _backgroundFileSaver property.
           if (this._canceled) {
             throw new DownloadError({ message: "Saver canceled." });
           }
--- a/toolkit/components/jsdownloads/test/unit/head.js
+++ b/toolkit/components/jsdownloads/test/unit/head.js
@@ -356,17 +356,17 @@ function promiseStartLegacyDownload(aSou
     // the Download object to be created and added to the public downloads.
     transfer.init(sourceURI, NetUtil.newURI(targetFile), null, mimeInfo, null,
                   null, persist, isPrivate);
     persist.progressListener = transfer;
 
     // Start the actual download process.
     persist.savePrivacyAwareURI(sourceURI, null, null, 0, null, null, targetFile,
                                 isPrivate);
-  }.bind(this)).then(null, do_report_unexpected_exception);
+  }).then(null, do_report_unexpected_exception);
 
   return deferred.promise;
 }
 
 /**
  * Starts a new download using the nsIHelperAppService interface, and controls
  * it using the legacy nsITransfer interface.  The source of the download will
  * be "interruptible_resumable.txt" and partially downloaded data will be kept.
@@ -424,17 +424,17 @@ function promiseStartExternalHelperAppSe
       },
 
       onDataAvailable(aRequest, aContext, aInputStream, aOffset,
                                 aCount) {
         this.contentListener.onDataAvailable(aRequest, aContext, aInputStream,
                                              aOffset, aCount);
       },
     });
-  }.bind(this)).then(null, do_report_unexpected_exception);
+  }).then(null, do_report_unexpected_exception);
 
   return deferred.promise;
 }
 
 /**
  * Waits for a download to reach half of its progress, in case it has not
  * reached the expected progress already.
  *
--- a/toolkit/components/places/Bookmarks.jsm
+++ b/toolkit/components/places/Bookmarks.jsm
@@ -1375,17 +1375,17 @@ function reorderChildren(parent, ordered
       yield db.executeCached(
         `DELETE FROM moz_items_annos
          WHERE anno_attribute_id = (SELECT id FROM moz_anno_attributes
                                     WHERE name = :orphanAnno) AND
                item_id IN (${possibleOrphanIds.join(", ")})`,
         { orphanAnno: PlacesSyncUtils.bookmarks.SYNC_PARENT_ANNO });
 
       return children;
-    }.bind(this))
+    })
   );
 }
 
 // Helpers.
 
 /**
  * Merges objects into a new object, included non-enumerable properties.
  *
--- a/toolkit/components/places/PlacesTransactions.jsm
+++ b/toolkit/components/places/PlacesTransactions.jsm
@@ -616,17 +616,17 @@ var TransactionsManager = {
       if (aUndoEntries && aRedoEntries)
         TransactionsHistory.clearAllEntries();
       else if (aUndoEntries)
         TransactionsHistory.clearUndoEntries();
       else if (aRedoEntries)
         TransactionsHistory.clearRedoEntries();
       else
         throw new Error("either aUndoEntries or aRedoEntries should be true");
-    }.bind(this));
+    });
 
     this._transactEnqueuer.alsoWaitFor(promise);
     return promise;
   },
 
   // Updates commands in the undo group of the active window commands.
   // Inactive windows commands will be updated on focus.
   _updateCommandsOnActiveWindow() {
--- a/toolkit/components/places/PlacesUtils.jsm
+++ b/toolkit/components/places/PlacesUtils.jsm
@@ -1833,17 +1833,17 @@ this.PlacesUtils = {
         case Ci.nsINavBookmarksService.TYPE_SEPARATOR:
           item.type = PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR;
           break;
         default:
           Cu.reportError("Unexpected bookmark type");
           break;
       }
       return item;
-    }.bind(this);
+    };
 
     const QUERY_STR =
       `/* do not warn (bug no): cannot use an index */
        WITH RECURSIVE
        descendants(fk, level, type, id, guid, parent, parentGuid, position,
                    title, dateAdded, lastModified) AS (
          SELECT b1.fk, 0, b1.type, b1.id, b1.guid, b1.parent,
                 (SELECT guid FROM moz_bookmarks WHERE id = b1.parent),
@@ -2268,17 +2268,17 @@ var Keywords = {
 
         yield PlacesSyncUtils.bookmarks.addSyncChangesForBookmarksWithURL(
           db, url, PlacesSyncUtils.bookmarks.determineSyncChangeDelta(source));
 
         cache.set(keyword, { keyword, url, postData });
 
         // In any case, notify about the new keyword.
         yield notifyKeywordChange(url.href, keyword, source);
-      }.bind(this))
+      })
     );
   },
 
   /**
    * Removes a keyword.
    *
    * @param keyword
    *        The keyword to remove.
@@ -2306,17 +2306,17 @@ var Keywords = {
       yield db.execute(`DELETE FROM moz_keywords WHERE keyword = :keyword`,
                        { keyword });
 
       yield PlacesSyncUtils.bookmarks.addSyncChangesForBookmarksWithURL(
         db, url, PlacesSyncUtils.bookmarks.determineSyncChangeDelta(source));
 
       // Notify bookmarks about the removal.
       yield notifyKeywordChange(url.href, "", source);
-    }.bind(this))) ;
+    }));
   }
 };
 
 // Set by the keywords API to distinguish notifications fired by the old API.
 // Once the old API will be gone, we can remove this and stop observing.
 var gIgnoreKeywordNotifications = false;
 
 XPCOMUtils.defineLazyGetter(this, "gKeywordsCachePromise", () =>
--- a/toolkit/components/places/UnifiedComplete.js
+++ b/toolkit/components/places/UnifiedComplete.js
@@ -1993,17 +1993,17 @@ UnifiedComplete.prototype = {
         // indices.  A larger cache helps reducing IO and improving performance.
         // The value used here is larger than the default Storage value defined
         // as MAX_CACHE_SIZE_BYTES in storage/mozStorageConnection.cpp.
         yield conn.execute("PRAGMA cache_size = -6144"); // 6MiB
 
         yield SwitchToTabStorage.initDatabase(conn);
 
         return conn;
-      }.bind(this)).then(null, ex => {
+      }).then(null, ex => {
  dump("Couldn't get database handle: " + ex + "\n");
                                        Cu.reportError(ex);
 });
     }
     return this._promiseDatabase;
   },
 
   // mozIPlacesAutoComplete
--- a/toolkit/components/reader/AboutReader.jsm
+++ b/toolkit/components/reader/AboutReader.jsm
@@ -906,17 +906,17 @@ AboutReader.prototype = {
 
         let items = segmentedButton.children;
         for (let j = items.length - 1; j >= 0; j--) {
           items[j].classList.remove("selected");
         }
 
         item.classList.add("selected");
         callback(option.value);
-      }.bind(this), true);
+      }, true);
 
       if (option.value === initialValue)
         item.classList.add("selected");
     }
   },
 
   _setupButton(id, callback, titleEntity, textEntity) {
     if (titleEntity) {
--- a/toolkit/components/telemetry/TelemetrySession.jsm
+++ b/toolkit/components/telemetry/TelemetrySession.jsm
@@ -1906,17 +1906,17 @@ var Impl = {
     case "idle-daily":
       // Enqueue to main-thread, otherwise components may be inited by the
       // idle-daily category and miss the gather-telemetry notification.
       Services.tm.mainThread.dispatch((function() {
         // Notify that data should be gathered now.
         // TODO: We are keeping this behaviour for now but it will be removed as soon as
         // bug 1127907 lands.
         Services.obs.notifyObservers(null, "gather-telemetry", null);
-      }).bind(this), Ci.nsIThread.DISPATCH_NORMAL);
+      }), Ci.nsIThread.DISPATCH_NORMAL);
       break;
 
     case "application-background":
       if (AppConstants.platform !== "android") {
         break;
       }
       // On Android, we can get killed without warning once we are in the background,
       // but we may also submit data and/or come back into the foreground without getting
--- a/toolkit/identity/IdentityProvider.jsm
+++ b/toolkit/identity/IdentityProvider.jsm
@@ -248,17 +248,17 @@ IdentityProviderService.prototype = {
       }
 
       provFlow.kp = kp;
 
       // Serialize the publicKey of the keypair and send it back to the
       // sandbox.
       log("genKeyPair: generated keypair for provisioning flow with id:", aProvId);
       provFlow.caller.doGenKeyPairCallback(provFlow.kp.serializedPublicKey);
-    }.bind(this));
+    });
   },
 
   /**
    * When navigator.id.registerCertificate is called from provisioning iframe
    * sandbox.
    *
    * Sets the certificate for the user for which a certificate was requested
    * via a preceding call to beginProvisioning (and genKeypair).
--- a/toolkit/modules/ProfileAge.jsm
+++ b/toolkit/modules/ProfileAge.jsm
@@ -46,17 +46,17 @@ this.ProfileAge.prototype = {
       }
       return onFailure.call(this, null, times);
     }
 
     function onFailure(err, times) {
       return this.computeAndPersistCreated(times)
                  .then(function onSuccess(created) {
                          return created;
-                       }.bind(this));
+                       });
     }
 
     return this.getTimes()
                .then(onSuccess.bind(this),
                      onFailure.bind(this));
   },
 
   /**
--- a/toolkit/modules/secondscreen/RokuApp.jsm
+++ b/toolkit/modules/secondscreen/RokuApp.jsm
@@ -55,17 +55,17 @@ RokuApp.prototype = {
         callback({ state: "unknown" });
       }
     }).bind(this), false);
 
     xhr.addEventListener("error", (function() {
       if (callback) {
         callback({ state: "unknown" });
       }
-    }).bind(this), false);
+    }), false);
 
     xhr.send(null);
   },
 
   start: function start(callback) {
     // We need to make sure we have cached the mediaAppID
     if (this.mediaAppID == -1) {
       this.status(function() {
@@ -86,46 +86,46 @@ RokuApp.prototype = {
     let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
     xhr.open("POST", url, true);
     xhr.overrideMimeType("text/plain");
 
     xhr.addEventListener("load", (function() {
       if (callback) {
         callback(xhr.status === 200);
       }
-    }).bind(this), false);
+    }), false);
 
     xhr.addEventListener("error", (function() {
       if (callback) {
         callback(false);
       }
-    }).bind(this), false);
+    }), false);
 
     xhr.send(null);
   },
 
   stop: function stop(callback) {
     // Roku doesn't seem to support stopping an app, so let's just go back to
     // the Home screen
     let url = this.resourceURL + "keypress/Home";
     let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
     xhr.open("POST", url, true);
     xhr.overrideMimeType("text/plain");
 
     xhr.addEventListener("load", (function() {
       if (callback) {
         callback(xhr.status === 200);
       }
-    }).bind(this), false);
+    }), false);
 
     xhr.addEventListener("error", (function() {
       if (callback) {
         callback(false);
       }
-    }).bind(this), false);
+    }), false);
 
     xhr.send(null);
   },
 
   remoteMedia: function remoteMedia(callback, listener) {
     if (this.mediaAppID != -1) {
       if (callback) {
         callback(new RemoteMedia(this.resourceURL, listener));
--- a/toolkit/modules/secondscreen/SimpleServiceDiscovery.jsm
+++ b/toolkit/modules/secondscreen/SimpleServiceDiscovery.jsm
@@ -75,17 +75,17 @@ var SimpleServiceDiscovery = {
     let service = {};
     response.forEach(function(row) {
       let name = row.toUpperCase();
       if (name.startsWith("LOCATION")) {
         service.location = row.substr(10).trim();
       } else if (name.startsWith("ST")) {
         service.target = row.substr(4).trim();
       }
-    }.bind(this));
+    });
 
     if (service.location && service.target) {
       service.location = this._forceTrailingSlash(service.location);
 
       // When we find a valid response, package up the service information
       // and pass it on.
       try {
         this._processService(service);
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -3502,17 +3502,17 @@ var gDetailView = {
               firstSetting = setting;
             }
           }
 
           finish(firstSetting);
 
           if (aCallback)
             aCallback();
-        }).bind(this);
+        });
         xhr.onerror = function(aEvent) {
           Cu.reportError("Error " + aEvent.target.status +
                          " occurred while receiving " + this._addon.optionsURL);
           if (aCallback)
             aCallback();
         };
         xhr.send();
       }