[tor-commits] [torbutton] branch main updated: Bug 40012: Linted torbutton

gitolite role git at cupani.torproject.org
Thu Aug 25 16:29:56 UTC 2022


This is an automated email from the git hooks/post-receive script.

pierov pushed a commit to branch main
in repository torbutton.

The following commit(s) were added to refs/heads/main by this push:
     new 9f2e434a Bug 40012: Linted torbutton
9f2e434a is described below

commit 9f2e434a7f09d2f53c529e7293bf715c4a6b71e6
Author: Pier Angelo Vendrame <pierov at torproject.org>
AuthorDate: Wed Aug 24 16:28:30 2022 +0200

    Bug 40012: Linted torbutton
---
 chrome/content/aboutTor/aboutTor-content.js |   64 +-
 chrome/content/preferences-mobile.js        |   49 +-
 chrome/content/tor-circuit-display.js       |  907 +++++++++-------
 chrome/content/torbutton.js                 | 1561 ++++++++++++++-------------
 components/domain-isolator.js               |   98 +-
 components/dragDropFilter.js                |   39 +-
 components/external-app-blocker.js          |   75 +-
 components/startup-observer.js              |  270 ++---
 components/torCheckService.js               |  119 +-
 components/torbutton-logger.js              |  201 ++--
 modules/tor-control-port.js                 |  457 ++++----
 modules/utils.js                            |  238 ++--
 12 files changed, 2217 insertions(+), 1861 deletions(-)

diff --git a/chrome/content/aboutTor/aboutTor-content.js b/chrome/content/aboutTor/aboutTor-content.js
index 601b817c..55bf4413 100644
--- a/chrome/content/aboutTor/aboutTor-content.js
+++ b/chrome/content/aboutTor/aboutTor-content.js
@@ -14,9 +14,14 @@
  *   AboutTor:ChromeData      privileged data        chrome -> content
  */
 
+/* globals content, addMessageListener, sendAsyncMessage,
+   removeMessageListener */
+
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
-let { bindPrefAndInit, show_torbrowser_manual } = ChromeUtils.import("resource://torbutton/modules/utils.js", {});
+const { bindPrefAndInit, show_torbrowser_manual } = ChromeUtils.import(
+  "resource://torbutton/modules/utils.js"
+);
 
 var AboutTorListener = {
   kAboutTorLoadedMessage: "AboutTor:Loaded",
@@ -26,13 +31,14 @@ var AboutTorListener = {
     return content.document.documentURI.toLowerCase() == "about:tor";
   },
 
-  init: function(aChromeGlobal) {
+  init(aChromeGlobal) {
     aChromeGlobal.addEventListener("AboutTorLoad", this, false, true);
   },
 
-  handleEvent: function(aEvent) {
-    if (!this.isAboutTor)
+  handleEvent(aEvent) {
+    if (!this.isAboutTor) {
       return;
+    }
 
     switch (aEvent.type) {
       case "AboutTorLoad":
@@ -44,9 +50,10 @@ var AboutTorListener = {
     }
   },
 
-  receiveMessage: function(aMessage) {
-    if (!this.isAboutTor)
+  receiveMessage(aMessage) {
+    if (!this.isAboutTor) {
       return;
+    }
 
     switch (aMessage.name) {
       case this.kAboutTorChromeDataMessage:
@@ -55,7 +62,7 @@ var AboutTorListener = {
     }
   },
 
-  onPageLoad: function() {
+  onPageLoad() {
     // Arrange to update localized text and links.
     bindPrefAndInit("intl.locale.requested", () => {
       const aNewVal = Services.locale.requestedLocale;
@@ -72,48 +79,53 @@ var AboutTorListener = {
     sendAsyncMessage(this.kAboutTorLoadedMessage);
   },
 
-  onPageHide: function() {
+  onPageHide() {
     removeEventListener("resize", this, false);
     removeEventListener("pagehide", this, false);
     removeMessageListener(this.kAboutTorChromeDataMessage, this);
   },
 
-  onChromeDataUpdate: function(aData) {
+  onChromeDataUpdate(aData) {
     let body = content.document.body;
 
     // Update status: tor on/off, Tor Browser manual shown.
-    if (aData.torOn)
+    if (aData.torOn) {
       body.setAttribute("toron", "yes");
-    else
+    } else {
       body.removeAttribute("toron");
+    }
 
-    if (show_torbrowser_manual())
+    if (show_torbrowser_manual()) {
       body.setAttribute("showmanual", "yes");
-    else
+    } else {
       body.removeAttribute("showmanual");
+    }
 
-    if (aData.updateChannel)
+    if (aData.updateChannel) {
       body.setAttribute("updatechannel", aData.updateChannel);
-    else
+    } else {
       body.removeAttribute("updatechannel");
+    }
 
     if (aData.hasBeenUpdated) {
       body.setAttribute("hasbeenupdated", "yes");
-      content.document.getElementById("update-infolink").setAttribute("href",
-                                                      aData.updateMoreInfoURL);
+      content.document
+        .getElementById("update-infolink")
+        .setAttribute("href", aData.updateMoreInfoURL);
     }
 
-    if (aData.mobile)
+    if (aData.mobile) {
       body.setAttribute("mobile", "yes");
+    }
 
     // Setting body.initialized="yes" displays the body.
     body.setAttribute("initialized", "yes");
   },
 
-  onLocaleChange: function(aLocale) {
+  onLocaleChange(aLocale) {
     // Set localized "Get Involved" link.
     content.document.getElementById("getInvolvedLink").href =
-                            "https://community.torproject.org/" + aLocale;
+      "https://community.torproject.org/" + aLocale;
 
     // Display the Tor Browser product name and version.
     try {
@@ -123,12 +135,14 @@ var AboutTorListener = {
       let tbbVersion = Services.prefs.getCharPref("torbrowser.version");
       let elem = content.document.getElementById("torbrowser-version");
 
-      while (elem.firstChild)
-        elem.removeChild(elem.firstChild);
-      elem.appendChild(content.document.createTextNode(productName + ' '
-                       + tbbVersion));
+      while (elem.firstChild) {
+        elem.firstChild.remove();
+      }
+      elem.appendChild(
+        content.document.createTextNode(productName + " " + tbbVersion)
+      );
     } catch (e) {}
-  }
+  },
 };
 
 AboutTorListener.init(this);
diff --git a/chrome/content/preferences-mobile.js b/chrome/content/preferences-mobile.js
index fa79dce8..92564e90 100644
--- a/chrome/content/preferences-mobile.js
+++ b/chrome/content/preferences-mobile.js
@@ -2,26 +2,30 @@
 
 // Utilities
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const { getBoolPref, getIntPref, setBoolPref, setIntPref, getCharPref }
-  = Services.prefs;
+const {
+  getBoolPref,
+  getIntPref,
+  setBoolPref,
+  setIntPref,
+  getCharPref,
+} = Services.prefs;
 
-let { getLocale, show_torbrowser_manual } =
-    ChromeUtils.import("resource://torbutton/modules/utils.js", {});
+let { getLocale, show_torbrowser_manual } = ChromeUtils.import(
+  "resource://torbutton/modules/utils.js"
+);
 
 // Description elements have the follow names.
-const descNames =
-      [, "desc_standard", "desc_safer", "desc_safest"];
+const descNames = ["", "desc_standard", "desc_safer", "desc_safest"];
 // "Learn-more"-elements have the follow names.
-const linkNames =
-      [, "link_standard", "link_safer", "link_safest"];
+const linkNames = ["", "link_standard", "link_safer", "link_safest"];
 // A single `state` object that reflects the user settings in this UI.
 
-let state = { slider : 0, custom : false};
+let state = { slider: 0, custom: false };
 
 // Utility functions to convert between the legacy 4-value pref index
 // and the 3-valued security slider.
-let sliderPositionToPrefSetting = pos => [, 4, 2, 1][pos];
-let prefSettingToSliderPosition = pref => [, 3, 2, 2, 1][pref];
+let sliderPositionToPrefSetting = pos => [0, 4, 2, 1][pos];
+let prefSettingToSliderPosition = pref => [0, 3, 2, 2, 1][pref];
 
 // Set the desired slider value and update UI.
 function torbutton_set_slider(sliderValue) {
@@ -31,9 +35,9 @@ function torbutton_set_slider(sliderValue) {
   let descs = descNames.map(name => document.getElementById(name));
   descs.forEach((desc, i) => {
     if (state.slider !== i) {
-      desc.style.display = 'none';
+      desc.style.display = "none";
     } else {
-      desc.style.display = 'block';
+      desc.style.display = "block";
     }
   });
   torbutton_save_security_settings();
@@ -42,15 +46,20 @@ function torbutton_set_slider(sliderValue) {
 // Read prefs 'extensions.torbutton.security_slider' and
 // 'extensions.torbutton.security_custom', and initialize the UI.
 function torbutton_init_security_ui() {
-  torbutton_set_slider(prefSettingToSliderPosition(
-    getIntPref("extensions.torbutton.security_slider")));
+  torbutton_set_slider(
+    prefSettingToSliderPosition(
+      getIntPref("extensions.torbutton.security_slider")
+    )
+  );
   torbutton_set_learn_more_links();
 }
 
 // Write the two prefs from the current settings.
 function torbutton_save_security_settings() {
-  setIntPref("extensions.torbutton.security_slider",
-             sliderPositionToPrefSetting(state.slider));
+  setIntPref(
+    "extensions.torbutton.security_slider",
+    sliderPositionToPrefSetting(state.slider)
+  );
   setBoolPref("extensions.torbutton.security_custom", state.custom);
 }
 
@@ -59,15 +68,15 @@ function torbutton_save_security_settings() {
 // let's show the "Learn more"-link, otherwise hide it.
 function torbutton_set_learn_more_links() {
   let show_manual = show_torbrowser_manual();
-  let locale = ""
+  let locale = "";
   if (show_manual) {
     locale = getLocale();
   }
   let links = linkNames.map(name => document.getElementById(name));
   links.forEach(link => {
     if (show_manual && locale != "") {
-      link.href= "https:/tb-manual.torproject.org/" + locale +
-        "/security-slider.html";
+      link.href =
+        "https:/tb-manual.torproject.org/" + locale + "/security-slider.html";
       link.hidden = false;
     } else {
       link.hidden = true;
diff --git a/chrome/content/tor-circuit-display.js b/chrome/content/tor-circuit-display.js
index 14e3da5b..e4b5ceea 100644
--- a/chrome/content/tor-circuit-display.js
+++ b/chrome/content/tor-circuit-display.js
@@ -21,28 +21,38 @@
 // a previous call to configureControlPortModule(), and binds to a named
 // bool pref whose value determines whether the circuit display is enabled
 // or disabled.
-let createTorCircuitDisplay = (function () {
-
-"use strict";
-
-// Mozilla utilities
-const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-// Import the controller code.
-let { wait_for_controller } = ChromeUtils.import("resource://torbutton/modules/tor-control-port.js", {});
-
-// Utility functions
-let { bindPrefAndInit, observe, getLocale, getDomainForBrowser, torbutton_get_property_string } = ChromeUtils.import("resource://torbutton/modules/utils.js", {});
-
-// Make the TorButton logger available.
-let logger = Cc["@torproject.org/torbutton-logger;1"]
-               .getService(Ci.nsISupports).wrappedJSObject;
-
-// ## Circuit/stream credentials and node monitoring
-
-// A mutable map that stores the current nodes for each
-// SOCKS username/password pair.
-let credentialsToNodeDataMap = new Map(),
+let createTorCircuitDisplay = (function() {
+  "use strict";
+
+  // Mozilla utilities
+  const { Services } = ChromeUtils.import(
+    "resource://gre/modules/Services.jsm"
+  );
+
+  // Import the controller code.
+  const { wait_for_controller } = ChromeUtils.import(
+    "resource://torbutton/modules/tor-control-port.js"
+  );
+
+  // Utility functions
+  let {
+    bindPrefAndInit,
+    observe,
+    getLocale,
+    getDomainForBrowser,
+    torbutton_get_property_string,
+  } = ChromeUtils.import("resource://torbutton/modules/utils.js");
+
+  // Make the TorButton logger available.
+  let logger = Cc["@torproject.org/torbutton-logger;1"].getService(
+    Ci.nsISupports
+  ).wrappedJSObject;
+
+  // ## Circuit/stream credentials and node monitoring
+
+  // A mutable map that stores the current nodes for each
+  // SOCKS username/password pair.
+  let credentialsToNodeDataMap = new Map(),
     // A mutable map that reports `true` for IDs of "mature" circuits
     // (those that have conveyed a stream).
     knownCircuitIDs = new Map(),
@@ -50,424 +60,477 @@ let credentialsToNodeDataMap = new Map(),
     // latest channels for each browser + domain.
     browserToCredentialsMap = new Map();
 
-// __trimQuotes(s)__.
-// Removes quotation marks around a quoted string.
-let trimQuotes = s => s ? s.match(/^"(.*)"$/)[1] : undefined;
-
-// __getBridge(id)__.
-// Gets the bridge parameters for a given node ID. If the node
-// is not currently used as a bridge, returns null.
-let getBridge = async function (controller, id) {
-  let bridges = await controller.getConf("bridge");
-  if (bridges) {
-    for (let bridge of bridges) {
-      if (bridge.ID && bridge.ID.toUpperCase() === id.toUpperCase()) {
-        return bridge;
+  // __trimQuotes(s)__.
+  // Removes quotation marks around a quoted string.
+  let trimQuotes = s => (s ? s.match(/^"(.*)"$/)[1] : undefined);
+
+  // __getBridge(id)__.
+  // Gets the bridge parameters for a given node ID. If the node
+  // is not currently used as a bridge, returns null.
+  let getBridge = async function(controller, id) {
+    let bridges = await controller.getConf("bridge");
+    if (bridges) {
+      for (let bridge of bridges) {
+        if (bridge.ID && bridge.ID.toUpperCase() === id.toUpperCase()) {
+          return bridge;
+        }
       }
     }
-  }
-  return null;
-};
-
-// nodeDataForID(controller, id)__.
-// Returns the type, IP addresses and country code of a node with given ID.
-// Example: `nodeDataForID(controller, "20BC91DC525C3DC9974B29FBEAB51230DE024C44")`
-// => `{ type: "default", ipAddrs: ["12.23.34.45", "2001:db8::"], countryCode: "fr" }`
-let nodeDataForID = async function (controller, id) {
-  let result = {ipAddrs: []};
-  const bridge = await getBridge(controller, id); // type, ip, countryCode;
-  const addrRe = /^\[?([^\]]+)\]?:\d+$/
-  if (bridge) {
-    result.type = "bridge";
-    result.bridgeType = bridge.type;
-    // Attempt to get an IP address from bridge address string.
-    try {
-      const ip = bridge.address.match(addrRe)[1];
-      if (!ip.startsWith("0.")) {
-        result.ipAddrs = [ip];
-      }
-    } catch (e) {
-    }
-  } else {
-    // either dealing with a relay, or a bridge whose fingerprint is not saved in torrc
-    try {
-      const statusMap = await controller.getInfo("ns/id/" + id);
-      result.type = "default";
-      if (!statusMap.IP.startsWith("0.")) {
-        result.ipAddrs.push(statusMap.IP);
-      }
+    return null;
+  };
+
+  // nodeDataForID(controller, id)__.
+  // Returns the type, IP addresses and country code of a node with given ID.
+  // Example: `nodeDataForID(controller, "20BC91DC525C3DC9974B29FBEAB51230DE024C44")`
+  // => `{ type: "default", ipAddrs: ["12.23.34.45", "2001:db8::"], countryCode: "fr" }`
+  let nodeDataForID = async function(controller, id) {
+    let result = { ipAddrs: [] };
+    const bridge = await getBridge(controller, id); // type, ip, countryCode;
+    const addrRe = /^\[?([^\]]+)\]?:\d+$/;
+    if (bridge) {
+      result.type = "bridge";
+      result.bridgeType = bridge.type;
+      // Attempt to get an IP address from bridge address string.
+      try {
+        const ip = bridge.address.match(addrRe)[1];
+        if (!ip.startsWith("0.")) {
+          result.ipAddrs = [ip];
+        }
+      } catch (e) {}
+    } else {
+      // either dealing with a relay, or a bridge whose fingerprint is not saved in torrc
       try {
-        result.ipAddrs.push(statusMap.IPv6.match(addrRe)[1]);
+        const statusMap = await controller.getInfo("ns/id/" + id);
+        result.type = "default";
+        if (!statusMap.IP.startsWith("0.")) {
+          result.ipAddrs.push(statusMap.IP);
+        }
+        try {
+          result.ipAddrs.push(statusMap.IPv6.match(addrRe)[1]);
+        } catch (e) {}
       } catch (e) {
+        // getInfo will throw if the given id is not a relay
+        // this probably means we are dealing with a user-provided bridge with no fingerprint
+        result.type = "bridge";
+        // we don't know the ip/ipv6 or type, so leave blank
+        result.ipAddrs = [];
+        result.bridgeType = "";
       }
-    } catch (e) {
-      // getInfo will throw if the given id is not a relay
-      // this probably means we are dealing with a user-provided bridge with no fingerprint
-      result.type = "bridge";
-      // we don't know the ip/ipv6 or type, so leave blank
-      result.ipAddrs = [];
-      result.bridgeType = "";
     }
-  }
-  if (result.ipAddrs.length > 0) {
-    // Get the country code for the node's IP address.
-    try {
-      const countryCode = await controller.getInfo("ip-to-country/" + result.ipAddrs[0]);
-      result.countryCode = countryCode === "??" ? null : countryCode;
-    } catch (e) { }
-  }
-  return result;
-};
-
-// __nodeDataForCircuit(controller, circuitEvent)__.
-// Gets the information for a circuit.
-let nodeDataForCircuit = async function (controller, circuitEvent) {
-  let rawIDs = circuitEvent.circuit.map(circ => circ[0]),
+    if (result.ipAddrs.length) {
+      // Get the country code for the node's IP address.
+      try {
+        const countryCode = await controller.getInfo(
+          "ip-to-country/" + result.ipAddrs[0]
+        );
+        result.countryCode = countryCode === "??" ? null : countryCode;
+      } catch (e) {}
+    }
+    return result;
+  };
+
+  // __nodeDataForCircuit(controller, circuitEvent)__.
+  // Gets the information for a circuit.
+  let nodeDataForCircuit = async function(controller, circuitEvent) {
+    let rawIDs = circuitEvent.circuit.map(circ => circ[0]),
       // Remove the leading '$' if present.
-      ids = rawIDs.map(id => id[0] === "$" ? id.substring(1) : id);
-  // Get the node data for all IDs in circuit.
-  return Promise.all(ids.map(id => nodeDataForID(controller, id)));
-};
-
-// __getCircuitStatusByID(aController, circuitID)__
-// Returns the circuit status for the circuit with the given ID.
-let getCircuitStatusByID = async function (aController, circuitID) {
-  let circuitStatuses = await aController.getInfo("circuit-status");
-  if (circuitStatuses) {
-    for (let circuitStatus of circuitStatuses) {
-      if (circuitStatus.id === circuitID) {
-        return circuitStatus;
+      ids = rawIDs.map(id => (id[0] === "$" ? id.substring(1) : id));
+    // Get the node data for all IDs in circuit.
+    return Promise.all(ids.map(id => nodeDataForID(controller, id)));
+  };
+
+  // __getCircuitStatusByID(aController, circuitID)__
+  // Returns the circuit status for the circuit with the given ID.
+  let getCircuitStatusByID = async function(aController, circuitID) {
+    let circuitStatuses = await aController.getInfo("circuit-status");
+    if (circuitStatuses) {
+      for (let circuitStatus of circuitStatuses) {
+        if (circuitStatus.id === circuitID) {
+          return circuitStatus;
+        }
       }
     }
-  }
-  return null;
-};
-
-// __collectIsolationData(aController, updateUI)__.
-// Watches for STREAM SENTCONNECT events. When a SENTCONNECT event occurs, then
-// we assume isolation settings (SOCKS username+password) are now fixed for the
-// corresponding circuit. Whenever the first stream on a new circuit is seen,
-// looks up u+p and records the node data in the credentialsToNodeDataMap.
-// We need to update the circuit display immediately after any new node data
-// is received. So the `updateUI` callback will be called at that point.
-// See https://trac.torproject.org/projects/tor/ticket/15493
-let collectIsolationData = function (aController, updateUI) {
-  return aController.watchEvent(
-    "STREAM",
-    streamEvent => streamEvent.StreamStatus === "SENTCONNECT",
-    async (streamEvent) => {
-      if (!knownCircuitIDs.get(streamEvent.CircuitID)) {
-        logger.eclog(3, "streamEvent.CircuitID: " + streamEvent.CircuitID);
-        knownCircuitIDs.set(streamEvent.CircuitID, true);
-        let circuitStatus = await getCircuitStatusByID(aController, streamEvent.CircuitID),
-            credentials = circuitStatus ?
-                            (trimQuotes(circuitStatus.SOCKS_USERNAME) + "|" +
-                             trimQuotes(circuitStatus.SOCKS_PASSWORD)) :
-                            null;
-        if (credentials) {
-          let nodeData = await nodeDataForCircuit(aController, circuitStatus);
-          credentialsToNodeDataMap.set(credentials, nodeData);
-          updateUI();
+    return null;
+  };
+
+  // __collectIsolationData(aController, updateUI)__.
+  // Watches for STREAM SENTCONNECT events. When a SENTCONNECT event occurs, then
+  // we assume isolation settings (SOCKS username+password) are now fixed for the
+  // corresponding circuit. Whenever the first stream on a new circuit is seen,
+  // looks up u+p and records the node data in the credentialsToNodeDataMap.
+  // We need to update the circuit display immediately after any new node data
+  // is received. So the `updateUI` callback will be called at that point.
+  // See https://trac.torproject.org/projects/tor/ticket/15493
+  let collectIsolationData = function(aController, updateUI) {
+    return aController.watchEvent(
+      "STREAM",
+      streamEvent => streamEvent.StreamStatus === "SENTCONNECT",
+      async streamEvent => {
+        if (!knownCircuitIDs.get(streamEvent.CircuitID)) {
+          logger.eclog(3, "streamEvent.CircuitID: " + streamEvent.CircuitID);
+          knownCircuitIDs.set(streamEvent.CircuitID, true);
+          let circuitStatus = await getCircuitStatusByID(
+              aController,
+              streamEvent.CircuitID
+            ),
+            credentials = circuitStatus
+              ? trimQuotes(circuitStatus.SOCKS_USERNAME) +
+                "|" +
+                trimQuotes(circuitStatus.SOCKS_PASSWORD)
+              : null;
+          if (credentials) {
+            let nodeData = await nodeDataForCircuit(aController, circuitStatus);
+            credentialsToNodeDataMap.set(credentials, nodeData);
+            updateUI();
+          }
         }
       }
-    });
-};
-
-// __browserForChannel(channel)__.
-// Returns the browser that loaded a given channel.
-let browserForChannel = function (channel) {
-  if (!channel) return null;
-  let chan = channel.QueryInterface(Ci.nsIChannel);
-  let callbacks = chan.notificationCallbacks;
-  if (!callbacks) return null;
-  let loadContext;
-  try {
-    loadContext = callbacks.getInterface(Ci.nsILoadContext);
-  } catch (e) {
-    // Ignore
-    return null;
-  }
-  if (!loadContext) return null;
-  return loadContext.topFrameElement;
-};
-
-// __collectBrowserCredentials()__.
-// Starts observing http channels. Each channel's proxyInfo
-// username and password is recorded for the channel's browser.
-let collectBrowserCredentials = function () {
-  return observe("http-on-modify-request", chan => {
+    );
+  };
+
+  // __browserForChannel(channel)__.
+  // Returns the browser that loaded a given channel.
+  let browserForChannel = function(channel) {
+    if (!channel) {
+      return null;
+    }
+    let chan = channel.QueryInterface(Ci.nsIChannel);
+    let callbacks = chan.notificationCallbacks;
+    if (!callbacks) {
+      return null;
+    }
+    let loadContext;
     try {
-      let proxyInfo = chan.QueryInterface(Ci.nsIProxiedChannel).proxyInfo;
-      let browser = browserForChannel(chan);
-      if (browser && proxyInfo) {
-        if (!browserToCredentialsMap.has(browser)) {
-          browserToCredentialsMap.set(browser, new Map());
+      loadContext = callbacks.getInterface(Ci.nsILoadContext);
+    } catch (e) {
+      // Ignore
+      return null;
+    }
+    if (!loadContext) {
+      return null;
+    }
+    return loadContext.topFrameElement;
+  };
+
+  // __collectBrowserCredentials()__.
+  // Starts observing http channels. Each channel's proxyInfo
+  // username and password is recorded for the channel's browser.
+  let collectBrowserCredentials = function() {
+    return observe("http-on-modify-request", chan => {
+      try {
+        let proxyInfo = chan.QueryInterface(Ci.nsIProxiedChannel).proxyInfo;
+        let browser = browserForChannel(chan);
+        if (browser && proxyInfo) {
+          if (!browserToCredentialsMap.has(browser)) {
+            browserToCredentialsMap.set(browser, new Map());
+          }
+          let domainMap = browserToCredentialsMap.get(browser);
+          domainMap.set(proxyInfo.username, [
+            proxyInfo.username,
+            proxyInfo.password,
+          ]);
         }
-        let domainMap = browserToCredentialsMap.get(browser);
-        domainMap.set(proxyInfo.username, [proxyInfo.username,
-                                          proxyInfo.password]);
+      } catch (e) {
+        logger.eclog(
+          3,
+          `Error collecting browser credentials: ${e.message}, ${chan.URI.spec}`
+        );
       }
+    });
+  };
+
+  // ## User interface
+
+  // __uiString__.
+  // Read the localized strings for this UI.
+  let uiString = function(shortName) {
+    return torbutton_get_property_string(
+      "torbutton.circuit_display." + shortName
+    );
+  };
+
+  // __localizedCountryNameFromCode(countryCode)__.
+  // Convert a country code to a localized country name.
+  // Example: `'de'` -> `'Deutschland'` in German locale.
+  let localizedCountryNameFromCode = function(countryCode) {
+    if (!countryCode) {
+      return uiString("unknown_country");
+    }
+    try {
+      return Services.intl.getRegionDisplayNames(undefined, [countryCode])[0];
     } catch (e) {
-      logger.eclog(3, `Error collecting browser credentials: ${e.message}, ${chan.URI.spec}`);
+      return countryCode.toUpperCase();
     }
-  });
-};
-
-// ## User interface
-
-// __uiString__.
-// Read the localized strings for this UI.
-let uiString = function (shortName) {
-  return torbutton_get_property_string("torbutton.circuit_display." + shortName);
-};
-
-// __localizedCountryNameFromCode(countryCode)__.
-// Convert a country code to a localized country name.
-// Example: `'de'` -> `'Deutschland'` in German locale.
-let localizedCountryNameFromCode = function (countryCode) {
-  if (!countryCode) return uiString("unknown_country");
-  try {
-    return Services.intl.getRegionDisplayNames(undefined, [countryCode])[0];
-  } catch (e) {
-    return countryCode.toUpperCase();
-  }
-};
-
-// __showCircuitDisplay(show)__.
-// If show === true, makes the circuit display visible.
-let showCircuitDisplay = function (show) {
-  document.getElementById("circuit-display-container").style.display = show ?
-							    'block' : 'none';
-};
-
-// __xmlTree(ns, data)__.
-// Takes an xml namespace, ns, and a
-// data structure representing xml elements like
-// [tag, { attr-key: attr-value }, ...xml-children]
-// and returns nested xml element objects.
-let xmlTree = function xmlTree (ns, data) {
-  let [type, attrs, ...children] = data;
-  let element = type.startsWith("html:")
-    ? document.createXULElement(type)
-    : document.createElementNS(ns, type);
-  for (let [key, val] of Object.entries(attrs)) {
-    element.setAttribute(key, val);
-  }
-  for (let child of children) {
-    if (child !== null && child !== undefined) {
-      element.append(typeof child === "string" ? child : xmlTree(ns, child));
+  };
+
+  // __showCircuitDisplay(show)__.
+  // If show === true, makes the circuit display visible.
+  let showCircuitDisplay = function(show) {
+    document.getElementById("circuit-display-container").style.display = show
+      ? "block"
+      : "none";
+  };
+
+  // __xmlTree(ns, data)__.
+  // Takes an xml namespace, ns, and a
+  // data structure representing xml elements like
+  // [tag, { attr-key: attr-value }, ...xml-children]
+  // and returns nested xml element objects.
+  let xmlTree = function xmlTree(ns, data) {
+    let [type, attrs, ...children] = data;
+    let element = type.startsWith("html:")
+      ? document.createXULElement(type)
+      : document.createElementNS(ns, type);
+    for (let [key, val] of Object.entries(attrs)) {
+      element.setAttribute(key, val);
     }
-  }
-  return element;
-};
-
-// __htmlTree(data)__.
-// Takes a data structure representing html elements like
-// [tag, { attr-key: attr-value }, ...html-children]
-// and returns nested html element objects.
-let htmlTree = data => xmlTree("http://www.w3.org/1999/xhtml", data);
-
-// __appendHtml(parent, data)__.
-// Takes a data structure representing html elements like
-// [tag, { attr-key: attr-value }, ...html-children]
-// and appends nested html element objects to the parent element.
-let appendHtml = (parent, data) => parent.appendChild(htmlTree(data));
-
-// __circuitCircuitData()__.
-// Obtains the circuit used by the given browser.
-let currentCircuitData = function (browser) {
-  if (browser) {
-    let firstPartyDomain = getDomainForBrowser(browser);
-    let domain = firstPartyDomain || "--unknown--";
-    let domainMap = browserToCredentialsMap.get(browser);
-    let credentials = domainMap && domainMap.get(domain);
-    if (credentials) {
-      let [SOCKS_username, SOCKS_password] = credentials;
-      let nodeData = credentialsToNodeDataMap.get(`${SOCKS_username}|${SOCKS_password}`);
-      let domain = SOCKS_username;
-      if (browser.documentURI.host.endsWith(".tor.onion")) {
-        const service = Cc["@torproject.org/onion-alias-service;1"].getService(
-          Ci.IOnionAliasService
-        );
-        domain = service.getOnionAlias(browser.documentURI.host);
+    for (let child of children) {
+      if (child !== null && child !== undefined) {
+        element.append(typeof child === "string" ? child : xmlTree(ns, child));
       }
-      return { domain, nodeData };
     }
-  }
-  return { domain: null, nodeData: null };
-};
-
-// __updateCircuitDisplay()__.
-// Updates the Tor circuit display, showing the current domain
-// and the relay nodes for that domain.
-let updateCircuitDisplay = function () {
-  let { domain, nodeData } = currentCircuitData(gBrowser.selectedBrowser);
-  if (domain && nodeData) {
-    // Update the displayed information for the relay nodes.
-    let nodeHtmlList = document.getElementById("circuit-display-nodes");
-    let li = (...data) => appendHtml(nodeHtmlList, ["li", {}, ...data]);
-    nodeHtmlList.innerHTML = "";
-    li(uiString("this_browser"));
-    for (let i = 0; i < nodeData.length; ++i) {
-      let relayText;
-      if (nodeData[i].type === "bridge") {
-        relayText = uiString("tor_bridge");
-        let bridgeType = nodeData[i].bridgeType;
-        if (bridgeType === "meek_lite") {
-          relayText += ": meek";
-        }
-        else if (bridgeType !== "vanilla" && bridgeType !== "") {
-          relayText += ": " + bridgeType;
+    return element;
+  };
+
+  // __htmlTree(data)__.
+  // Takes a data structure representing html elements like
+  // [tag, { attr-key: attr-value }, ...html-children]
+  // and returns nested html element objects.
+  let htmlTree = data => xmlTree("http://www.w3.org/1999/xhtml", data);
+
+  // __appendHtml(parent, data)__.
+  // Takes a data structure representing html elements like
+  // [tag, { attr-key: attr-value }, ...html-children]
+  // and appends nested html element objects to the parent element.
+  let appendHtml = (parent, data) => parent.appendChild(htmlTree(data));
+
+  // __circuitCircuitData()__.
+  // Obtains the circuit used by the given browser.
+  let currentCircuitData = function(browser) {
+    if (browser) {
+      let firstPartyDomain = getDomainForBrowser(browser);
+      let domain = firstPartyDomain || "--unknown--";
+      let domainMap = browserToCredentialsMap.get(browser);
+      let credentials = domainMap && domainMap.get(domain);
+      if (credentials) {
+        let [SOCKS_username, SOCKS_password] = credentials;
+        let nodeData = credentialsToNodeDataMap.get(
+          `${SOCKS_username}|${SOCKS_password}`
+        );
+        let domain = SOCKS_username;
+        if (browser.documentURI.host.endsWith(".tor.onion")) {
+          const service = Cc[
+            "@torproject.org/onion-alias-service;1"
+          ].getService(Ci.IOnionAliasService);
+          domain = service.getOnionAlias(browser.documentURI.host);
         }
-      } else if (nodeData[i].type == "default") {
-        relayText = localizedCountryNameFromCode(nodeData[i].countryCode);
+        return { domain, nodeData };
       }
-      const ipAddrs = nodeData[i].ipAddrs.join(", ");
-      li(relayText, " ", ["span", { class: "circuit-ip-address" }, ipAddrs], " ",
-         (i === 0 && nodeData[0].type !== "bridge") ?
-           ["span", { class: "circuit-guard-info" }, uiString("guard")] : null);
     }
+    return { domain: null, nodeData: null };
+  };
 
-    let domainParts = [];
-    if (domain.endsWith(".onion")) {
-      for (let i = 0; i < 3; ++i) {
-        li(uiString("relay"));
+  // __updateCircuitDisplay()__.
+  // Updates the Tor circuit display, showing the current domain
+  // and the relay nodes for that domain.
+  let updateCircuitDisplay = function() {
+    let { domain, nodeData } = currentCircuitData(gBrowser.selectedBrowser);
+    if (domain && nodeData) {
+      // Update the displayed information for the relay nodes.
+      let nodeHtmlList = document.getElementById("circuit-display-nodes");
+      let li = (...data) => appendHtml(nodeHtmlList, ["li", {}, ...data]);
+      nodeHtmlList.innerHTML = "";
+      li(uiString("this_browser"));
+      for (let i = 0; i < nodeData.length; ++i) {
+        let relayText;
+        if (nodeData[i].type === "bridge") {
+          relayText = uiString("tor_bridge");
+          let bridgeType = nodeData[i].bridgeType;
+          if (bridgeType === "meek_lite") {
+            relayText += ": meek";
+          } else if (bridgeType !== "vanilla" && bridgeType !== "") {
+            relayText += ": " + bridgeType;
+          }
+        } else if (nodeData[i].type == "default") {
+          relayText = localizedCountryNameFromCode(nodeData[i].countryCode);
+        }
+        const ipAddrs = nodeData[i].ipAddrs.join(", ");
+        li(
+          relayText,
+          " ",
+          ["span", { class: "circuit-ip-address" }, ipAddrs],
+          " ",
+          i === 0 && nodeData[0].type !== "bridge"
+            ? ["span", { class: "circuit-guard-info" }, uiString("guard")]
+            : null
+        );
       }
-      if (domain.length > 22) {
-        domainParts.push(domain.slice(0, 7), "…", domain.slice(-12));
+
+      let domainParts = [];
+      if (domain.endsWith(".onion")) {
+        for (let i = 0; i < 3; ++i) {
+          li(uiString("relay"));
+        }
+        if (domain.length > 22) {
+          domainParts.push(domain.slice(0, 7), "…", domain.slice(-12));
+        } else {
+          domainParts.push(domain);
+        }
       } else {
         domainParts.push(domain);
       }
-    } else {
-      domainParts.push(domain);
-    }
 
-    // We use a XUL html:span element so that the tooltiptext is displayed.
-    li([
-      "html:span",
-      {
-        class: "circuit-onion",
-        onclick: `
+      // We use a XUL html:span element so that the tooltiptext is displayed.
+      li([
+        "html:span",
+        {
+          class: "circuit-onion",
+          onclick: `
           this.classList.add("circuit-onion-copied");
           Cc[
             "@mozilla.org/widget/clipboardhelper;1"
           ].getService(Ci.nsIClipboardHelper).copyString(this.getAttribute("data-onion"))
         `,
-        "data-onion": domain,
-        "data-text-clicktocopy": torbutton_get_property_string("torbutton.circuit_display.click_to_copy"),
-        "data-text-copied": torbutton_get_property_string("torbutton.circuit_display.copied"),
-        tooltiptext: domain,
-      },
-      ...domainParts,
-    ]);
-
-    // Hide the note about guards if we are using a bridge.
-    document.getElementById("circuit-guard-note-container").style.display =
-      (nodeData[0].type === "bridge") ? "none" : "block";
-  } else {
-    // Only show the Tor circuit if we have credentials and node data.
-    logger.eclog(4, "no SOCKS credentials found for current document.");
-  }
-  showCircuitDisplay(domain && nodeData);
-};
-
-// __syncDisplayWithSelectedTab(syncOn)__.
-// Whenever the user starts to open the popup menu, make sure the display
-// is the correct one for this tab. It's also possible that a new site
-// can be loaded while the popup menu is open.
-// Update the display if this happens.
-let syncDisplayWithSelectedTab = (function() {
-  let listener = { onLocationChange : function (aBrowser) {
-                      if (aBrowser === gBrowser.selectedBrowser) {
-                        updateCircuitDisplay();
-                      }
-                    } };
-  return function (syncOn) {
-    let popupMenu = document.getElementById("identity-popup");
-    if (syncOn) {
-      // Update the circuit display just before the popup menu is shown.
-      popupMenu.addEventListener("popupshowing", updateCircuitDisplay);
-      // If the currently selected tab has been sent to a new location,
-      // update the circuit to reflect that.
-      gBrowser.addTabsProgressListener(listener);
+          "data-onion": domain,
+          "data-text-clicktocopy": torbutton_get_property_string(
+            "torbutton.circuit_display.click_to_copy"
+          ),
+          "data-text-copied": torbutton_get_property_string(
+            "torbutton.circuit_display.copied"
+          ),
+          tooltiptext: domain,
+        },
+        ...domainParts,
+      ]);
+
+      // Hide the note about guards if we are using a bridge.
+      document.getElementById("circuit-guard-note-container").style.display =
+        nodeData[0].type === "bridge" ? "none" : "block";
     } else {
-      // Stop syncing.
-      gBrowser.removeTabsProgressListener(listener);
-      popupMenu.removeEventListener("popupshowing", updateCircuitDisplay);
-      // Hide the display.
-      showCircuitDisplay(false);
+      // Only show the Tor circuit if we have credentials and node data.
+      logger.eclog(4, "no SOCKS credentials found for current document.");
     }
+    showCircuitDisplay(domain && nodeData);
   };
-})();
 
-// __setupGuardNote()__.
-// Call once to show the Guard note as intended.
-let setupGuardNote = function () {
-  let guardNote = document.getElementById("circuit-guard-note-container");
-  let guardNoteString = uiString("guard_note");
-  let learnMoreString = uiString("learn_more");
-  let [noteBefore, name, noteAfter] = guardNoteString.split(/[\[\]]/);
-  let localeCode = getLocale();
-  appendHtml(guardNote,
-             ["div", {},
-              noteBefore, ["span", {class: "circuit-guard-name"}, name],
-              noteAfter, " ",
-              ["span", {onclick: `gBrowser.selectedTab = gBrowser.addWebTab('https://support.torproject.org/${localeCode}/tbb/tbb-2/');`,
-                        class: "circuit-link"},
-               learnMoreString]]);
-};
-
-// __ensureCorrectPopupDimensions()__.
-// Make sure the identity popup always displays with the correct height.
-let ensureCorrectPopupDimensions = function () {
-  let setDimensions = () => {
-    setTimeout(() => {
-      let view = document.querySelector("#identity-popup-multiView .panel-viewcontainer");
-      let stack = document.querySelector("#identity-popup-multiView .panel-viewstack");
+  // __syncDisplayWithSelectedTab(syncOn)__.
+  // Whenever the user starts to open the popup menu, make sure the display
+  // is the correct one for this tab. It's also possible that a new site
+  // can be loaded while the popup menu is open.
+  // Update the display if this happens.
+  let syncDisplayWithSelectedTab = (function() {
+    let listener = {
+      onLocationChange(aBrowser) {
+        if (aBrowser === gBrowser.selectedBrowser) {
+          updateCircuitDisplay();
+        }
+      },
+    };
+    return function(syncOn) {
+      let popupMenu = document.getElementById("identity-popup");
+      if (syncOn) {
+        // Update the circuit display just before the popup menu is shown.
+        popupMenu.addEventListener("popupshowing", updateCircuitDisplay);
+        // If the currently selected tab has been sent to a new location,
+        // update the circuit to reflect that.
+        gBrowser.addTabsProgressListener(listener);
+      } else {
+        // Stop syncing.
+        gBrowser.removeTabsProgressListener(listener);
+        popupMenu.removeEventListener("popupshowing", updateCircuitDisplay);
+        // Hide the display.
+        showCircuitDisplay(false);
+      }
+    };
+  })();
+
+  // __setupGuardNote()__.
+  // Call once to show the Guard note as intended.
+  let setupGuardNote = function() {
+    let guardNote = document.getElementById("circuit-guard-note-container");
+    let guardNoteString = uiString("guard_note");
+    let learnMoreString = uiString("learn_more");
+    let [noteBefore, name, noteAfter] = guardNoteString.split(/[\[\]]/);
+    let localeCode = getLocale();
+    appendHtml(guardNote, [
+      "div",
+      {},
+      noteBefore,
+      ["span", { class: "circuit-guard-name" }, name],
+      noteAfter,
+      " ",
+      [
+        "span",
+        {
+          onclick: `gBrowser.selectedTab = gBrowser.addWebTab('https://support.torproject.org/${localeCode}/tbb/tbb-2/');`,
+          class: "circuit-link",
+        },
+        learnMoreString,
+      ],
+    ]);
+  };
+
+  // __ensureCorrectPopupDimensions()__.
+  // Make sure the identity popup always displays with the correct height.
+  let ensureCorrectPopupDimensions = function() {
+    let setDimensions = () => {
+      setTimeout(() => {
+        let view = document.querySelector(
+          "#identity-popup-multiView .panel-viewcontainer"
+        );
+        let stack = document.querySelector(
+          "#identity-popup-multiView .panel-viewstack"
+        );
+        let view2 = document.getElementById("identity-popup-mainView");
+        if (view && stack && view2) {
+          let newWidth = Math.max(
+            ...[...view2.children].map(el => el.clientWidth)
+          );
+          let newHeight = stack.clientHeight;
+          stack.setAttribute("width", newWidth);
+          view2.style.minWidth = view2.style.maxWidth = newWidth + "px";
+          view.setAttribute("width", newWidth);
+          view.setAttribute("height", newHeight);
+        }
+      }, 0);
+    };
+    let removeDimensions = () => {
+      let view = document.querySelector(
+        "#identity-popup-multiView .panel-viewcontainer"
+      );
+      let stack = document.querySelector(
+        "#identity-popup-multiView .panel-viewstack"
+      );
       let view2 = document.getElementById("identity-popup-mainView");
       if (view && stack && view2) {
-        let newWidth = Math.max(...[...view2.children].map(el => el.clientWidth));
-        let newHeight = stack.clientHeight;
-        stack.setAttribute("width", newWidth);
-        view2.style.minWidth = view2.style.maxWidth = newWidth + "px";
-        view.setAttribute("width", newWidth);
-        view.setAttribute("height", newHeight);
+        view.removeAttribute("width");
+        view.removeAttribute("height");
+        stack.removeAttribute("width");
+        view2.style.minWidth = view2.style.maxWidth = "";
       }
-    }, 0);
+    };
+    let popupMenu = document.getElementById("identity-popup");
+    popupMenu.addEventListener("popupshowing", setDimensions);
+    popupMenu.addEventListener("popuphiding", removeDimensions);
+    return () => {
+      popupMenu.removeEventListener("popupshowing", setDimensions);
+      popupMenu.removeEventListener("popuphiding", removeDimensions);
+    };
   };
-  let removeDimensions = () => {
-    let view = document.querySelector("#identity-popup-multiView .panel-viewcontainer");
-    let stack = document.querySelector("#identity-popup-multiView .panel-viewstack");
-    let view2 = document.getElementById("identity-popup-mainView");
-    if (view && stack && view2) {
-      view.removeAttribute("width");
-      view.removeAttribute("height");
-      stack.removeAttribute("width");
-      view2.style.minWidth = view2.style.maxWidth = "";
+
+  // ## Main function
+
+  // __setupDisplay(enablePrefName)__.
+  // Once called, the Tor circuit display will be started whenever
+  // the "enablePref" is set to true, and stopped when it is set to false.
+  // A reference to this function (called createTorCircuitDisplay) is exported as a global.
+  let setupDisplay = function(enablePrefName) {
+    // From 79 on the identity popup is initialized lazily
+    if (gIdentityHandler._initializePopup) {
+      gIdentityHandler._initializePopup();
     }
-  };
-  let popupMenu = document.getElementById("identity-popup");
-  popupMenu.addEventListener("popupshowing", setDimensions);
-  popupMenu.addEventListener("popuphiding", removeDimensions);
-  return () => {
-    popupMenu.removeEventListener("popupshowing", setDimensions);
-    popupMenu.removeEventListener("popuphiding", removeDimensions);
-  };
-};
-
-// ## Main function
-
-// __setupDisplay(enablePrefName)__.
-// Once called, the Tor circuit display will be started whenever
-// the "enablePref" is set to true, and stopped when it is set to false.
-// A reference to this function (called createTorCircuitDisplay) is exported as a global.
-let setupDisplay = function (enablePrefName) {
-  // From 79 on the identity popup is initialized lazily
-  if (gIdentityHandler._initializePopup) {
-    gIdentityHandler._initializePopup();
-  }
-  setupGuardNote();
-  let myController = null,
+    setupGuardNote();
+    let myController = null,
       stopCollectingIsolationData = null,
       stopCollectingBrowserCredentials = null,
       stopEnsuringCorrectPopupDimensions = null,
@@ -486,35 +549,47 @@ let setupDisplay = function (enablePrefName) {
           myController = null;
         }
       },
-      start = async function () {
+      start = async function() {
         if (!myController) {
           try {
             myController = await wait_for_controller();
             syncDisplayWithSelectedTab(true);
-            stopCollectingIsolationData = collectIsolationData(myController, updateCircuitDisplay);
+            stopCollectingIsolationData = collectIsolationData(
+              myController,
+              updateCircuitDisplay
+            );
             stopCollectingBrowserCredentials = collectBrowserCredentials();
             stopEnsuringCorrectPopupDimensions = ensureCorrectPopupDimensions();
           } catch (err) {
             logger.eclog(5, err);
-            logger.eclog(5, "Disabling tor display circuit because of an error.");
+            logger.eclog(
+              5,
+              "Disabling tor display circuit because of an error."
+            );
             myController.close();
             stop();
           }
-       }
-     };
-  try {
-    let unbindPref = bindPrefAndInit(enablePrefName, on => { if (on) start(); else stop(); });
-    // When this chrome window is unloaded, we need to unbind the pref.
-    window.addEventListener("unload", function () {
-      unbindPref();
-      stop();
-    });
-  } catch (e) {
-    logger.eclog(5, "Error: " + e.message + "\n" + e.stack);
-  }
-};
+        }
+      };
+    try {
+      let unbindPref = bindPrefAndInit(enablePrefName, on => {
+        if (on) {
+          start();
+        } else {
+          stop();
+        }
+      });
+      // When this chrome window is unloaded, we need to unbind the pref.
+      window.addEventListener("unload", function() {
+        unbindPref();
+        stop();
+      });
+    } catch (e) {
+      logger.eclog(5, "Error: " + e.message + "\n" + e.stack);
+    }
+  };
 
-return setupDisplay;
+  return setupDisplay;
 
-// Finish createTorCircuitDisplay()
+  // Finish createTorCircuitDisplay()
 })();
diff --git a/chrome/content/torbutton.js b/chrome/content/torbutton.js
index fde5e1fa..ec2680f2 100644
--- a/chrome/content/torbutton.js
+++ b/chrome/content/torbutton.js
@@ -3,121 +3,105 @@ var torbutton_init;
 var torbutton_new_circuit;
 
 (() => {
-// Bug 1506 P1-P5: This is the main Torbutton overlay file. Much needs to be
-// preserved here, but in an ideal world, most of this code should perhaps be
-// moved into an XPCOM service, and much can also be tossed. See also
-// individual 1506 comments for details.
+  // Bug 1506 P1-P5: This is the main Torbutton overlay file. Much needs to be
+  // preserved here, but in an ideal world, most of this code should perhaps be
+  // moved into an XPCOM service, and much can also be tossed. See also
+  // individual 1506 comments for details.
 
-// TODO: check for leaks: http://www.mozilla.org/scriptable/avoiding-leaks.html
-// TODO: Double-check there are no strange exploits to defeat:
-//       http://kb.mozillazine.org/Links_to_local_pages_don%27t_work
+  // TODO: check for leaks: http://www.mozilla.org/scriptable/avoiding-leaks.html
+  // TODO: Double-check there are no strange exploits to defeat:
+  //       http://kb.mozillazine.org/Links_to_local_pages_don%27t_work
 
-/* global gBrowser, CustomizableUI,
+  /* global gBrowser, CustomizableUI,
    createTorCircuitDisplay, gFindBarInitialized,
    gFindBar, OpenBrowserWindow, PrivateBrowsingUtils,
    Services, AppConstants
  */
 
-let {
-  show_torbrowser_manual,
-  unescapeTorString,
-  bindPrefAndInit,
-  getDomainForBrowser,
-  torbutton_safelog,
-  torbutton_log,
-  torbutton_get_property_string,
-} = ChromeUtils.import("resource://torbutton/modules/utils.js", {});
-let { configureControlPortModule, wait_for_controller } = Cu.import("resource://torbutton/modules/tor-control-port.js", {});
-
-const k_tb_tor_check_failed_topic = "Torbutton:TorCheckFailed";
-
-var m_tb_prefs = Services.prefs;
-
-// status
-var m_tb_wasinited = false;
-var m_tb_is_main_window = false;
-
-var m_tb_control_ipc_file = null;    // Set if using IPC (UNIX domain socket).
-var m_tb_control_port = null;        // Set if using TCP.
-var m_tb_control_host = null;        // Set if using TCP.
-var m_tb_control_pass = null;
-var m_tb_control_desc = null;        // For logging.
-
-var m_tb_domWindowUtils = window.windowUtils;
-
-async function clearData(flags) {
-  return new Promise((resolve, reject) => {
-    Services.clearData.deleteData(flags, {
-      onDataDeleted(code) {
-        if (code === Cr.NS_OK) {
-          resolve();
-        } else {
-          reject(new Error(`Error deleting data with flags ${flags}: ${code}`));
-        }
-      },
-    });
-  });
-}
-
-// Bug 1506 P2: This object keeps Firefox prefs in sync with Torbutton prefs.
-// It probably could stand some simplification (See #3100). It also belongs
-// in a component, not the XUL overlay.
-var torbutton_unique_pref_observer =
-{
-    register: function()
-    {
-        this.forced_ua = false;
-        m_tb_prefs.addObserver("extensions.torbutton", this, false);
-        m_tb_prefs.addObserver("browser.privatebrowsing.autostart", this, false);
-        m_tb_prefs.addObserver("javascript", this, false);
-        m_tb_prefs.addObserver("privacy.resistFingerprinting", this, false);
-        m_tb_prefs.addObserver("privacy.resistFingerprinting.letterboxing", this, false);
+  let {
+    show_torbrowser_manual,
+    unescapeTorString,
+    bindPrefAndInit,
+    getDomainForBrowser,
+    torbutton_log,
+    torbutton_get_property_string,
+  } = ChromeUtils.import("resource://torbutton/modules/utils.js");
+  let { configureControlPortModule, wait_for_controller } = ChromeUtils.import(
+    "resource://torbutton/modules/tor-control-port.js"
+  );
+
+  const k_tb_tor_check_failed_topic = "Torbutton:TorCheckFailed";
+
+  var m_tb_prefs = Services.prefs;
+
+  // status
+  var m_tb_wasinited = false;
+  var m_tb_is_main_window = false;
+
+  var m_tb_control_ipc_file = null; // Set if using IPC (UNIX domain socket).
+  var m_tb_control_port = null; // Set if using TCP.
+  var m_tb_control_host = null; // Set if using TCP.
+  var m_tb_control_pass = null;
+
+  // Bug 1506 P2: This object keeps Firefox prefs in sync with Torbutton prefs.
+  // It probably could stand some simplification (See #3100). It also belongs
+  // in a component, not the XUL overlay.
+  var torbutton_unique_pref_observer = {
+    register() {
+      this.forced_ua = false;
+      m_tb_prefs.addObserver("extensions.torbutton", this);
+      m_tb_prefs.addObserver("browser.privatebrowsing.autostart", this);
+      m_tb_prefs.addObserver("javascript", this);
+      m_tb_prefs.addObserver("privacy.resistFingerprinting", this);
+      m_tb_prefs.addObserver("privacy.resistFingerprinting.letterboxing", this);
     },
 
-    unregister: function()
-    {
-        m_tb_prefs.removeObserver("extensions.torbutton", this);
-        m_tb_prefs.removeObserver("browser.privatebrowsing.autostart", this);
-        m_tb_prefs.removeObserver("javascript", this);
-        m_tb_prefs.removeObserver("privacy.resistFingerprinting", this);
-        m_tb_prefs.removeObserver("privacy.resistFingerprinting.letterboxing", this);
+    unregister() {
+      m_tb_prefs.removeObserver("extensions.torbutton", this);
+      m_tb_prefs.removeObserver("browser.privatebrowsing.autostart", this);
+      m_tb_prefs.removeObserver("javascript", this);
+      m_tb_prefs.removeObserver("privacy.resistFingerprinting", this);
+      m_tb_prefs.removeObserver(
+        "privacy.resistFingerprinting.letterboxing",
+        this
+      );
     },
 
     // topic:   what event occurred
     // subject: what nsIPrefBranch we're observing
     // data:    which pref has been changed (relative to subject)
-    observe: function(subject, topic, data)
-    {
-        if (topic !== "nsPref:changed") return;
-        switch (data) {
-            case "browser.privatebrowsing.autostart":
-                torbutton_update_disk_prefs();
-                break;
-            case "extensions.torbutton.use_nontor_proxy":
-                torbutton_use_nontor_proxy();
-                break;
-            case "privacy.resistFingerprinting":
-            case "privacy.resistFingerprinting.letterboxing":
-                torbutton_update_fingerprinting_prefs();
-                break;
-        }
-    }
-}
+    observe(subject, topic, data) {
+      if (topic !== "nsPref:changed") {
+        return;
+      }
+      switch (data) {
+        case "browser.privatebrowsing.autostart":
+          torbutton_update_disk_prefs();
+          break;
+        case "extensions.torbutton.use_nontor_proxy":
+          torbutton_use_nontor_proxy();
+          break;
+        case "privacy.resistFingerprinting":
+        case "privacy.resistFingerprinting.letterboxing":
+          torbutton_update_fingerprinting_prefs();
+          break;
+      }
+    },
+  };
 
-var torbutton_tor_check_observer = {
+  var torbutton_tor_check_observer = {
     register() {
-        this._obsSvc = Services.obs;
-        this._obsSvc.addObserver(this, k_tb_tor_check_failed_topic);
+      this._obsSvc = Services.obs;
+      this._obsSvc.addObserver(this, k_tb_tor_check_failed_topic);
     },
 
-    unregister: function()
-    {
-        if (this._obsSvc)
-          this._obsSvc.removeObserver(this, k_tb_tor_check_failed_topic);
+    unregister() {
+      if (this._obsSvc) {
+        this._obsSvc.removeObserver(this, k_tb_tor_check_failed_topic);
+      }
     },
 
-    observe: function(subject, topic, data)
-    {
+    observe(subject, topic, data) {
       if (topic === k_tb_tor_check_failed_topic) {
         // Update all open about:tor pages.
         torbutton_abouttor_message_handler.updateAllOpenPages();
@@ -129,9 +113,9 @@ var torbutton_tor_check_observer = {
         if (win == window) {
           let foundTab = false;
           let tabBrowser = top.gBrowser;
-          for (let i = 0; !foundTab && (i < tabBrowser.browsers.length); ++i) {
+          for (let i = 0; !foundTab && i < tabBrowser.browsers.length; ++i) {
             let b = tabBrowser.getBrowserAtIndex(i);
-            foundTab = (b.currentURI.spec.toLowerCase() == "about:tor");
+            foundTab = b.currentURI.spec.toLowerCase() == "about:tor";
           }
 
           if (!foundTab) {
@@ -140,82 +124,102 @@ var torbutton_tor_check_observer = {
         }
       }
     },
-};
+  };
 
-var torbutton_new_identity_observers = {
-  register() {
-    Services.obs.addObserver(this, "new-identity-requested");
-  },
+  var torbutton_new_identity_observers = {
+    register() {
+      Services.obs.addObserver(this, "new-identity-requested");
+    },
 
-  observe(aSubject, aTopic, aData) {
-    if (aTopic !== "new-identity-requested") {
-      return;
-    }
+    observe(aSubject, aTopic, aData) {
+      if (aTopic !== "new-identity-requested") {
+        return;
+      }
 
-    // Clear the domain isolation state.
-    torbutton_log(3, "Clearing domain isolator");
-    const domainIsolator = Cc["@torproject.org/domain-isolator;1"].getService(
-      Ci.nsISupports
-    ).wrappedJSObject;
-    domainIsolator.clearIsolation();
-
-    torbutton_log(3, "New Identity: Sending NEWNYM");
-    // We only support TBB for newnym.
-    if (!m_tb_control_pass || (!m_tb_control_ipc_file && !m_tb_control_port)) {
-      var warning = torbutton_get_property_string("torbutton.popup.no_newnym");
-      torbutton_log(5, "Torbutton cannot safely newnym. It does not have access to the Tor Control Port.");
-      window.alert(warning);
-    } else {
-      var warning = torbutton_get_property_string("torbutton.popup.no_newnym");
-      torbutton_send_ctrl_cmd("SIGNAL NEWNYM").then(res => {
-        if (!res) {
-          torbutton_log(5, "Torbutton was unable to request a new circuit from Tor");
-          window.alert(warning);
-        }
-      }).catch(e => {
-        torbutton_log(5, "Torbutton was unable to request a new circuit from Tor " + e);
+      // Clear the domain isolation state.
+      torbutton_log(3, "Clearing domain isolator");
+      const domainIsolator = Cc["@torproject.org/domain-isolator;1"].getService(
+        Ci.nsISupports
+      ).wrappedJSObject;
+      domainIsolator.clearIsolation();
+
+      torbutton_log(3, "New Identity: Sending NEWNYM");
+      // We only support TBB for newnym.
+      if (
+        !m_tb_control_pass ||
+        (!m_tb_control_ipc_file && !m_tb_control_port)
+      ) {
+        const warning = torbutton_get_property_string(
+          "torbutton.popup.no_newnym"
+        );
+        torbutton_log(
+          5,
+          "Torbutton cannot safely newnym. It does not have access to the Tor Control Port."
+        );
         window.alert(warning);
-      });
-    }
-  },
-}
+      } else {
+        const warning = torbutton_get_property_string(
+          "torbutton.popup.no_newnym"
+        );
+        torbutton_send_ctrl_cmd("SIGNAL NEWNYM")
+          .then(res => {
+            if (!res) {
+              torbutton_log(
+                5,
+                "Torbutton was unable to request a new circuit from Tor"
+              );
+              window.alert(warning);
+            }
+          })
+          .catch(e => {
+            torbutton_log(
+              5,
+              "Torbutton was unable to request a new circuit from Tor " + e
+            );
+            window.alert(warning);
+          });
+      }
+    },
+  };
 
-function torbutton_is_mobile() {
+  function torbutton_is_mobile() {
     return Services.appinfo.OS === "Android";
-}
+  }
 
-// Bug 1506 P2-P4: This code sets some version variables that are irrelevant.
-// It does read out some important environment variables, though. It is
-// called once per browser window.. This might belong in a component.
-torbutton_init = function() {
-    torbutton_log(3, 'called init()');
+  // Bug 1506 P2-P4: This code sets some version variables that are irrelevant.
+  // It does read out some important environment variables, though. It is
+  // called once per browser window.. This might belong in a component.
+  torbutton_init = function() {
+    torbutton_log(3, "called init()");
 
     if (m_tb_wasinited) {
-        return;
+      return;
     }
     m_tb_wasinited = true;
 
     let tlps;
     try {
-        tlps = Cc["@torproject.org/torlauncher-protocol-service;1"]
-                 .getService(Ci.nsISupports).wrappedJSObject;
-    } catch(e) {}
+      tlps = Cc["@torproject.org/torlauncher-protocol-service;1"].getService(
+        Ci.nsISupports
+      ).wrappedJSObject;
+    } catch (e) {}
 
     // Bug 1506 P4: These vars are very important for New Identity
-    var environ = Cc["@mozilla.org/process/environment;1"]
-                   .getService(Ci.nsIEnvironment);
+    var environ = Cc["@mozilla.org/process/environment;1"].getService(
+      Ci.nsIEnvironment
+    );
 
     if (environ.exists("TOR_CONTROL_PASSWD")) {
-        m_tb_control_pass = environ.get("TOR_CONTROL_PASSWD");
+      m_tb_control_pass = environ.get("TOR_CONTROL_PASSWD");
     } else if (environ.exists("TOR_CONTROL_COOKIE_AUTH_FILE")) {
-        var cookie_path = environ.get("TOR_CONTROL_COOKIE_AUTH_FILE");
-        try {
-            if ("" != cookie_path) {
-                m_tb_control_pass = torbutton_read_authentication_cookie(cookie_path);
-            }
-        } catch(e) {
-            torbutton_log(4, 'unable to read authentication cookie');
+      var cookie_path = environ.get("TOR_CONTROL_COOKIE_AUTH_FILE");
+      try {
+        if ("" != cookie_path) {
+          m_tb_control_pass = torbutton_read_authentication_cookie(cookie_path);
         }
+      } catch (e) {
+        torbutton_log(4, "unable to read authentication cookie");
+      }
     } else {
       try {
         // Try to get password from Tor Launcher.
@@ -227,47 +231,47 @@ torbutton_init = function() {
     // since Tor Launcher knows how to handle its own preferences and how to
     // resolve relative paths.
     try {
-        m_tb_control_ipc_file = tlps.TorGetControlIPCFile();
-    } catch(e) {}
-
-    if (m_tb_control_ipc_file) {
-        m_tb_control_desc = m_tb_control_ipc_file.path;
-    } else {
-        if (environ.exists("TOR_CONTROL_PORT")) {
-            m_tb_control_port = environ.get("TOR_CONTROL_PORT");
-        } else {
-            try {
-                const kTLControlPortPref = "extensions.torlauncher.control_port";
-                m_tb_control_port = m_tb_prefs.getIntPref(kTLControlPortPref);
-            } catch(e) {
-              // Since we want to disable some features when Tor Launcher is
-              // not installed (e.g., New Identity), we do not set a default
-              // port value here.
-            }
-        }
+      m_tb_control_ipc_file = tlps.TorGetControlIPCFile();
+    } catch (e) {}
 
-        if (m_tb_control_port) {
-          m_tb_control_desc = "" + m_tb_control_port;
+    if (!m_tb_control_ipc_file) {
+      if (environ.exists("TOR_CONTROL_PORT")) {
+        m_tb_control_port = environ.get("TOR_CONTROL_PORT");
+      } else {
+        try {
+          const kTLControlPortPref = "extensions.torlauncher.control_port";
+          m_tb_control_port = m_tb_prefs.getIntPref(kTLControlPortPref);
+        } catch (e) {
+          // Since we want to disable some features when Tor Launcher is
+          // not installed (e.g., New Identity), we do not set a default
+          // port value here.
         }
+      }
 
-        if (environ.exists("TOR_CONTROL_HOST")) {
-            m_tb_control_host = environ.get("TOR_CONTROL_HOST");
-        } else {
-            try {
-                const kTLControlHostPref = "extensions.torlauncher.control_host";
-                m_tb_control_host = m_tb_prefs.getCharPref(kTLControlHostPref);
-            } catch(e) {
-              m_tb_control_host = "127.0.0.1";
-            }
+      if (environ.exists("TOR_CONTROL_HOST")) {
+        m_tb_control_host = environ.get("TOR_CONTROL_HOST");
+      } else {
+        try {
+          const kTLControlHostPref = "extensions.torlauncher.control_host";
+          m_tb_control_host = m_tb_prefs.getCharPref(kTLControlHostPref);
+        } catch (e) {
+          m_tb_control_host = "127.0.0.1";
         }
+      }
     }
 
-    configureControlPortModule(m_tb_control_ipc_file, m_tb_control_host,
-                               m_tb_control_port, m_tb_control_pass);
+    configureControlPortModule(
+      m_tb_control_ipc_file,
+      m_tb_control_host,
+      m_tb_control_port,
+      m_tb_control_pass
+    );
 
     // Add about:tor IPC message listener.
-    window.messageManager.addMessageListener("AboutTor:Loaded",
-                                   torbutton_abouttor_message_handler);
+    window.messageManager.addMessageListener(
+      "AboutTor:Loaded",
+      torbutton_abouttor_message_handler
+    );
 
     setupPreferencesForMobile();
 
@@ -275,361 +279,387 @@ torbutton_init = function() {
     torbutton_tor_check_observer.register();
 
     try {
-        createTorCircuitDisplay("extensions.torbutton.display_circuit");
-    } catch(e) {
-        torbutton_log(4, "Error creating the tor circuit display " + e);
+      createTorCircuitDisplay("extensions.torbutton.display_circuit");
+    } catch (e) {
+      torbutton_log(4, "Error creating the tor circuit display " + e);
     }
 
     try {
-        torbutton_init_user_manual_links();
-    } catch(e) {
-        torbutton_log(4, "Error loading the user manual " + e);
+      torbutton_init_user_manual_links();
+    } catch (e) {
+      torbutton_log(4, "Error loading the user manual " + e);
     }
 
     // Arrange for our about:tor content script to be loaded in each frame.
     window.messageManager.loadFrameScript(
-              "chrome://torbutton/content/aboutTor/aboutTor-content.js", true);
+      "chrome://torbutton/content/aboutTor/aboutTor-content.js",
+      true
+    );
 
     torbutton_new_identity_observers.register();
 
-    torbutton_log(3, 'init completed');
-}
-
-var torbutton_abouttor_message_handler = {
-  // Receive IPC messages from the about:tor content script.
-  receiveMessage: async function(aMessage) {
-    switch(aMessage.name) {
-      case "AboutTor:Loaded":
-        aMessage.target.messageManager.sendAsyncMessage("AboutTor:ChromeData",
-                                                    await this.getChromeData(true));
-        break;
-    }
-  },
-
-  // Send privileged data to all of the about:tor content scripts.
-  updateAllOpenPages: async function() {
-    window.messageManager.broadcastAsyncMessage("AboutTor:ChromeData",
-                                                await this.getChromeData(false));
-  },
-
-  // The chrome data contains all of the data needed by the about:tor
-  // content process that is only available here (in the chrome process).
-  // It is sent to the content process when an about:tor window is opened
-  // and in response to events such as the browser noticing that Tor is
-  // not working.
-  getChromeData: async function(aIsRespondingToPageLoad) {
-    let dataObj = {
-      mobile: torbutton_is_mobile(),
-      updateChannel: AppConstants.MOZ_UPDATE_CHANNEL,
-      torOn: await torbutton_tor_check_ok()
-    };
-
-    if (aIsRespondingToPageLoad) {
-      const kShouldNotifyPref = "torbrowser.post_update.shouldNotify";
-      if (m_tb_prefs.getBoolPref(kShouldNotifyPref, false)) {
-        m_tb_prefs.clearUserPref(kShouldNotifyPref);
-        dataObj.hasBeenUpdated = true;
-        dataObj.updateMoreInfoURL = this.getUpdateMoreInfoURL();
+    torbutton_log(3, "init completed");
+  };
+
+  var torbutton_abouttor_message_handler = {
+    // Receive IPC messages from the about:tor content script.
+    async receiveMessage(aMessage) {
+      switch (aMessage.name) {
+        case "AboutTor:Loaded":
+          aMessage.target.messageManager.sendAsyncMessage(
+            "AboutTor:ChromeData",
+            await this.getChromeData(true)
+          );
+          break;
       }
-    }
+    },
 
-    return dataObj;
-  },
+    // Send privileged data to all of the about:tor content scripts.
+    async updateAllOpenPages() {
+      window.messageManager.broadcastAsyncMessage(
+        "AboutTor:ChromeData",
+        await this.getChromeData(false)
+      );
+    },
 
-  getUpdateMoreInfoURL: function() {
-    try {
-      return Services.prefs.getCharPref("torbrowser.post_update.url");
-    } catch (e) {}
+    // The chrome data contains all of the data needed by the about:tor
+    // content process that is only available here (in the chrome process).
+    // It is sent to the content process when an about:tor window is opened
+    // and in response to events such as the browser noticing that Tor is
+    // not working.
+    async getChromeData(aIsRespondingToPageLoad) {
+      let dataObj = {
+        mobile: torbutton_is_mobile(),
+        updateChannel: AppConstants.MOZ_UPDATE_CHANNEL,
+        torOn: await torbutton_tor_check_ok(),
+      };
+
+      if (aIsRespondingToPageLoad) {
+        const kShouldNotifyPref = "torbrowser.post_update.shouldNotify";
+        if (m_tb_prefs.getBoolPref(kShouldNotifyPref, false)) {
+          m_tb_prefs.clearUserPref(kShouldNotifyPref);
+          dataObj.hasBeenUpdated = true;
+          dataObj.updateMoreInfoURL = this.getUpdateMoreInfoURL();
+        }
+      }
+
+      return dataObj;
+    },
 
-    // Use the default URL as a fallback.
-    return Services.urlFormatter.formatURLPref("startup.homepage_override_url");
+    getUpdateMoreInfoURL() {
+      try {
+        return Services.prefs.getCharPref("torbrowser.post_update.url");
+      } catch (e) {}
+
+      // Use the default URL as a fallback.
+      return Services.urlFormatter.formatURLPref(
+        "startup.homepage_override_url"
+      );
+    },
+  };
+
+  // Bug 1506 P4: Control port interaction. Needed for New Identity.
+  function torbutton_read_authentication_cookie(path) {
+    var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
+    file.initWithPath(path);
+    var fileStream = Cc[
+      "@mozilla.org/network/file-input-stream;1"
+    ].createInstance(Ci.nsIFileInputStream);
+    fileStream.init(file, 1, 0, false);
+    var binaryStream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(
+      Ci.nsIBinaryInputStream
+    );
+    binaryStream.setInputStream(fileStream);
+    var array = binaryStream.readByteArray(fileStream.available());
+    binaryStream.close();
+    fileStream.close();
+    return torbutton_array_to_hexdigits(array);
   }
-};
-
-// Bug 1506 P4: Control port interaction. Needed for New Identity.
-function torbutton_socket_readline(input) {
-  var str = "";
-  var bytes;
-  while((bytes = input.readBytes(1)) != "\n") {
-    if (bytes != '\r')
-      str += bytes;
+
+  // Bug 1506 P4: Control port interaction. Needed for New Identity.
+  function torbutton_array_to_hexdigits(array) {
+    return array
+      .map(function(c) {
+        return String("0" + c.toString(16)).slice(-2);
+      })
+      .join("");
   }
-  return str;
-}
-
-// Bug 1506 P4: Control port interaction. Needed for New Identity.
-function torbutton_read_authentication_cookie(path) {
-  var file = Cc["@mozilla.org/file/local;1"]
-             .createInstance(Ci.nsIFile);
-  file.initWithPath(path);
-  var fileStream = Cc["@mozilla.org/network/file-input-stream;1"]
-                   .createInstance(Ci.nsIFileInputStream);
-  fileStream.init(file, 1, 0, false);
-  var binaryStream = Cc["@mozilla.org/binaryinputstream;1"]
-                     .createInstance(Ci.nsIBinaryInputStream);
-  binaryStream.setInputStream(fileStream);
-  var array = binaryStream.readByteArray(fileStream.available());
-  binaryStream.close();
-  fileStream.close();
-  return torbutton_array_to_hexdigits(array);
-}
-
-// Bug 1506 P4: Control port interaction. Needed for New Identity.
-function torbutton_array_to_hexdigits(array) {
-  return array.map(function(c) {
-                     return String("0" + c.toString(16)).slice(-2)
-                   }).join('');
-};
-
-// Bug 1506 P4: Control port interaction. Needed for New Identity.
-//
-// Asynchronously executes a command on the control port.
-// returns the response as a string, or null on error
-async function torbutton_send_ctrl_cmd(command) {
-  const getErrorMessage = e => (e && (e.torMessage || e.message)) || "";
-  let response = null;
-  try {
-    const avoidCache = true;
-    let torController = await wait_for_controller(avoidCache);
-
-    let bytes = await torController.sendCommand(command);
-    if (!bytes.startsWith("250")) {
-      throw `Unexpected command response on control port '${bytes}'`;
-    }
-    response = bytes.slice(4);
 
-    torController.close();
-  } catch(err) {
-    let msg = getErrorMessage(err);
-    torbutton_log(4, `Error: ${msg}`);
+  // Bug 1506 P4: Control port interaction. Needed for New Identity.
+  //
+  // Asynchronously executes a command on the control port.
+  // returns the response as a string, or null on error
+  async function torbutton_send_ctrl_cmd(command) {
+    const getErrorMessage = e => (e && (e.torMessage || e.message)) || "";
+    let response = null;
+    try {
+      const avoidCache = true;
+      let torController = await wait_for_controller(avoidCache);
+
+      let bytes = await torController.sendCommand(command);
+      if (!bytes.startsWith("250")) {
+        throw new Error(
+          `Unexpected command response on control port '${bytes}'`
+        );
+      }
+      response = bytes.slice(4);
+
+      torController.close();
+    } catch (err) {
+      let msg = getErrorMessage(err);
+      torbutton_log(4, `Error: ${msg}`);
+    }
+    return response;
   }
-  return response;
-}
 
-// Bug 1506 P4: Needed for New IP Address
-torbutton_new_circuit = function() {
-  let firstPartyDomain = getDomainForBrowser(gBrowser.selectedBrowser);
+  // Bug 1506 P4: Needed for New IP Address
+  torbutton_new_circuit = function() {
+    let firstPartyDomain = getDomainForBrowser(gBrowser.selectedBrowser);
 
-  let domainIsolator = Cc["@torproject.org/domain-isolator;1"]
-                          .getService(Ci.nsISupports).wrappedJSObject;
+    let domainIsolator = Cc["@torproject.org/domain-isolator;1"].getService(
+      Ci.nsISupports
+    ).wrappedJSObject;
 
-  domainIsolator.newCircuitForDomain(firstPartyDomain);
+    domainIsolator.newCircuitForDomain(firstPartyDomain);
 
-  gBrowser.reloadWithFlags(Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE);
-}
+    gBrowser.reloadWithFlags(Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE);
+  };
 
-/* Called when we switch the use_nontor_proxy pref in either direction.
- *
- * Enables/disables domain isolation and then does new identity
- */
-function torbutton_use_nontor_proxy()
-{
-  let domainIsolator = Cc["@torproject.org/domain-isolator;1"]
-      .getService(Ci.nsISupports).wrappedJSObject;
-
-  if (m_tb_prefs.getBoolPref("extensions.torbutton.use_nontor_proxy")) {
-    // Disable domain isolation
-    domainIsolator.disableIsolation();
-  } else {
-    domainIsolator.enableIsolation();
+  /* Called when we switch the use_nontor_proxy pref in either direction.
+   *
+   * Enables/disables domain isolation and then does new identity
+   */
+  function torbutton_use_nontor_proxy() {
+    let domainIsolator = Cc["@torproject.org/domain-isolator;1"].getService(
+      Ci.nsISupports
+    ).wrappedJSObject;
+
+    if (m_tb_prefs.getBoolPref("extensions.torbutton.use_nontor_proxy")) {
+      // Disable domain isolation
+      domainIsolator.disableIsolation();
+    } else {
+      domainIsolator.enableIsolation();
+    }
   }
-}
-
-async function torbutton_do_tor_check()
-{
-  let checkSvc = Cc["@torproject.org/torbutton-torCheckService;1"]
-                   .getService(Ci.nsISupports).wrappedJSObject;
-  if (m_tb_prefs.getBoolPref("extensions.torbutton.use_nontor_proxy") ||
-      !m_tb_prefs.getBoolPref("extensions.torbutton.test_enabled"))
-    return; // Only do the check once.
-
-  // If we have a tor control port and transparent torification is off,
-  // perform a check via the control port.
-  const kEnvSkipControlPortTest = "TOR_SKIP_CONTROLPORTTEST";
-  const kEnvUseTransparentProxy = "TOR_TRANSPROXY";
-  var env = Cc["@mozilla.org/process/environment;1"]
-                 .getService(Ci.nsIEnvironment);
-  if ((m_tb_control_ipc_file || m_tb_control_port) &&
+
+  async function torbutton_do_tor_check() {
+    let checkSvc = Cc["@torproject.org/torbutton-torCheckService;1"].getService(
+      Ci.nsISupports
+    ).wrappedJSObject;
+    if (
+      m_tb_prefs.getBoolPref("extensions.torbutton.use_nontor_proxy") ||
+      !m_tb_prefs.getBoolPref("extensions.torbutton.test_enabled")
+    ) {
+      return;
+    } // Only do the check once.
+
+    // If we have a tor control port and transparent torification is off,
+    // perform a check via the control port.
+    const kEnvSkipControlPortTest = "TOR_SKIP_CONTROLPORTTEST";
+    const kEnvUseTransparentProxy = "TOR_TRANSPROXY";
+    var env = Cc["@mozilla.org/process/environment;1"].getService(
+      Ci.nsIEnvironment
+    );
+    if (
+      (m_tb_control_ipc_file || m_tb_control_port) &&
       !env.exists(kEnvUseTransparentProxy) &&
       !env.exists(kEnvSkipControlPortTest) &&
-      m_tb_prefs.getBoolPref("extensions.torbutton.local_tor_check")) {
-    if (await torbutton_local_tor_check())
-      checkSvc.statusOfTorCheck = checkSvc.kCheckSuccessful;
-    else {
-      // The check failed.  Update toolbar icon and tooltip.
-      checkSvc.statusOfTorCheck = checkSvc.kCheckFailed;
+      m_tb_prefs.getBoolPref("extensions.torbutton.local_tor_check")
+    ) {
+      if (await torbutton_local_tor_check()) {
+        checkSvc.statusOfTorCheck = checkSvc.kCheckSuccessful;
+      } else {
+        // The check failed.  Update toolbar icon and tooltip.
+        checkSvc.statusOfTorCheck = checkSvc.kCheckFailed;
+      }
+    } else {
+      // A local check is not possible, so perform a remote check.
+      torbutton_initiate_remote_tor_check();
     }
   }
-  else {
-    // A local check is not possible, so perform a remote check.
-    torbutton_initiate_remote_tor_check();
-  }
-}
-
-async function torbutton_local_tor_check()
-{
-  let didLogError = false;
-
-  let proxyType = m_tb_prefs.getIntPref("network.proxy.type");
-  if (0 == proxyType)
-    return false;
-
-  // Ask tor for its SOCKS listener address and port and compare to the
-  // browser preferences.
-  const kCmdArg = "net/listeners/socks";
-  let resp = await torbutton_send_ctrl_cmd("GETINFO " + kCmdArg);
-  if (!resp)
-    return false;
-
-  function logUnexpectedResponse()
-  {
-    if (!didLogError) {
-      didLogError = true;
-      torbutton_log(5, "Local Tor check: unexpected GETINFO response: " + resp);
+
+  async function torbutton_local_tor_check() {
+    let didLogError = false;
+
+    let proxyType = m_tb_prefs.getIntPref("network.proxy.type");
+    if (0 == proxyType) {
+      return false;
     }
-  }
 
-  function removeBrackets(aStr)
-  {
-    // Remove enclosing square brackets if present.
-    if (aStr.startsWith('[') && aStr.endsWith(']'))
-      return aStr.substr(1, aStr.length - 2);
+    // Ask tor for its SOCKS listener address and port and compare to the
+    // browser preferences.
+    const kCmdArg = "net/listeners/socks";
+    let resp = await torbutton_send_ctrl_cmd("GETINFO " + kCmdArg);
+    if (!resp) {
+      return false;
+    }
 
-    return aStr;
-  }
+    function logUnexpectedResponse() {
+      if (!didLogError) {
+        didLogError = true;
+        torbutton_log(
+          5,
+          "Local Tor check: unexpected GETINFO response: " + resp
+        );
+      }
+    }
 
-  // Sample response: net/listeners/socks="127.0.0.1:9149" "127.0.0.1:9150"
-  // First, check for and remove the command argument prefix.
-  if (0 != resp.indexOf(kCmdArg + '=')) {
-    logUnexpectedResponse();
-    return false;
-  }
-  resp = resp.substr(kCmdArg.length + 1);
-
-  // Retrieve configured proxy settings and check each listener against them.
-  // When the SOCKS prefs are set to use IPC (e.g., a Unix domain socket), a
-  // file URL should be present in network.proxy.socks.
-  // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1211567
-  let socksAddr = m_tb_prefs.getCharPref("network.proxy.socks");
-  let socksPort = m_tb_prefs.getIntPref("network.proxy.socks_port");
-  let socksIPCPath;
-  if (socksAddr && socksAddr.startsWith("file:")) {
-    // Convert the file URL to a file path.
-    try {
-      let ioService = Services.io;
-      let fph = ioService.getProtocolHandler("file")
-                         .QueryInterface(Ci.nsIFileProtocolHandler);
-      socksIPCPath = fph.getFileFromURLSpec(socksAddr).path;
-    } catch (e) {
-      torbutton_log(5, "Local Tor check: IPC file error: " + e);
+    function removeBrackets(aStr) {
+      // Remove enclosing square brackets if present.
+      if (aStr.startsWith("[") && aStr.endsWith("]")) {
+        return aStr.substr(1, aStr.length - 2);
+      }
+
+      return aStr;
+    }
+
+    // Sample response: net/listeners/socks="127.0.0.1:9149" "127.0.0.1:9150"
+    // First, check for and remove the command argument prefix.
+    if (0 != resp.indexOf(kCmdArg + "=")) {
+      logUnexpectedResponse();
       return false;
     }
-  } else {
-    socksAddr = removeBrackets(socksAddr);
-  }
+    resp = resp.substr(kCmdArg.length + 1);
+
+    // Retrieve configured proxy settings and check each listener against them.
+    // When the SOCKS prefs are set to use IPC (e.g., a Unix domain socket), a
+    // file URL should be present in network.proxy.socks.
+    // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1211567
+    let socksAddr = m_tb_prefs.getCharPref("network.proxy.socks");
+    let socksPort = m_tb_prefs.getIntPref("network.proxy.socks_port");
+    let socksIPCPath;
+    if (socksAddr && socksAddr.startsWith("file:")) {
+      // Convert the file URL to a file path.
+      try {
+        let ioService = Services.io;
+        let fph = ioService
+          .getProtocolHandler("file")
+          .QueryInterface(Ci.nsIFileProtocolHandler);
+        socksIPCPath = fph.getFileFromURLSpec(socksAddr).path;
+      } catch (e) {
+        torbutton_log(5, "Local Tor check: IPC file error: " + e);
+        return false;
+      }
+    } else {
+      socksAddr = removeBrackets(socksAddr);
+    }
+
+    // Split into quoted strings. This code is adapted from utils.splitAtSpaces()
+    // within tor-control-port.js; someday this code should use the entire
+    // tor-control-port.js framework.
+    let addrArray = [];
+    resp.replace(/((\S*?"(.*?)")+\S*|\S+)/g, function(a, captured) {
+      addrArray.push(captured);
+    });
 
-  // Split into quoted strings. This code is adapted from utils.splitAtSpaces()
-  // within tor-control-port.js; someday this code should use the entire
-  // tor-control-port.js framework.
-  let addrArray = [];
-  resp.replace(/((\S*?"(.*?)")+\S*|\S+)/g, function (a, captured) {
-    addrArray.push(captured);
-  });
-
-  let foundSocksListener = false;
-  for (let i = 0; !foundSocksListener && (i < addrArray.length); ++i) {
-    let addr;
-    try { addr = unescapeTorString(addrArray[i]); } catch (e) {}
-    if (!addr)
-      continue;
-
-    // Remove double quotes if present.
-    let len = addr.length;
-    if ((len > 2) && ('"' == addr.charAt(0)) && ('"' == addr.charAt(len - 1)))
-      addr = addr.substring(1, len - 1);
-
-    if (addr.startsWith("unix:")) {
-      if (!socksIPCPath)
+    let foundSocksListener = false;
+    for (let i = 0; !foundSocksListener && i < addrArray.length; ++i) {
+      let addr;
+      try {
+        addr = unescapeTorString(addrArray[i]);
+      } catch (e) {}
+      if (!addr) {
         continue;
+      }
 
-      // Check against the configured UNIX domain socket proxy.
-      let path = addr.substring(5);
-      torbutton_log(2, "Tor socks listener (Unix domain socket): " + path);
-      foundSocksListener = (socksIPCPath === path);
-    } else if (!socksIPCPath) {
-      // Check against the configured TCP proxy. We expect addr:port where addr
-      // may be an IPv6 address; that is, it may contain colon characters.
-      // Also, we remove enclosing square brackets before comparing addresses
-      // because tor requires them but Firefox does not.
-      let idx = addr.lastIndexOf(':');
-      if (idx < 0) {
-        logUnexpectedResponse();
-      } else {
-        let torSocksAddr = removeBrackets(addr.substring(0, idx));
-        let torSocksPort = parseInt(addr.substring(idx + 1), 10);
-        if ((torSocksAddr.length < 1) || isNaN(torSocksPort)) {
+      // Remove double quotes if present.
+      let len = addr.length;
+      if (len > 2 && '"' == addr.charAt(0) && '"' == addr.charAt(len - 1)) {
+        addr = addr.substring(1, len - 1);
+      }
+
+      if (addr.startsWith("unix:")) {
+        if (!socksIPCPath) {
+          continue;
+        }
+
+        // Check against the configured UNIX domain socket proxy.
+        let path = addr.substring(5);
+        torbutton_log(2, "Tor socks listener (Unix domain socket): " + path);
+        foundSocksListener = socksIPCPath === path;
+      } else if (!socksIPCPath) {
+        // Check against the configured TCP proxy. We expect addr:port where addr
+        // may be an IPv6 address; that is, it may contain colon characters.
+        // Also, we remove enclosing square brackets before comparing addresses
+        // because tor requires them but Firefox does not.
+        let idx = addr.lastIndexOf(":");
+        if (idx < 0) {
           logUnexpectedResponse();
         } else {
-          torbutton_log(2, "Tor socks listener: " + torSocksAddr + ':'
-                           + torSocksPort);
-          foundSocksListener = ((socksAddr === torSocksAddr) &&
-                                (socksPort === torSocksPort));
+          let torSocksAddr = removeBrackets(addr.substring(0, idx));
+          let torSocksPort = parseInt(addr.substring(idx + 1), 10);
+          if (torSocksAddr.length < 1 || isNaN(torSocksPort)) {
+            logUnexpectedResponse();
+          } else {
+            torbutton_log(
+              2,
+              "Tor socks listener: " + torSocksAddr + ":" + torSocksPort
+            );
+            foundSocksListener =
+              socksAddr === torSocksAddr && socksPort === torSocksPort;
+          }
         }
       }
     }
-  }
-
-  return foundSocksListener;
-} // torbutton_local_tor_check
 
+    return foundSocksListener;
+  } // torbutton_local_tor_check
 
-function torbutton_initiate_remote_tor_check() {
-  let obsSvc = Services.obs;
-  try {
-      let checkSvc = Cc["@torproject.org/torbutton-torCheckService;1"]
-                       .getService(Ci.nsISupports).wrappedJSObject;
+  function torbutton_initiate_remote_tor_check() {
+    let obsSvc = Services.obs;
+    try {
+      let checkSvc = Cc[
+        "@torproject.org/torbutton-torCheckService;1"
+      ].getService(Ci.nsISupports).wrappedJSObject;
       let req = checkSvc.createCheckRequest(true); // async
-      req.onreadystatechange = function (aEvent) {
-          if (req.readyState === 4) {
-            let ret = checkSvc.parseCheckResponse(req);
-
-            // If we received an error response from check.torproject.org,
-            // set the status of the tor check to failure (we don't want
-            // to indicate failure if we didn't receive a response).
-            if (ret == 2 || ret == 3 || ret == 5 || ret == 6
-                || ret == 7 || ret == 8) {
-              checkSvc.statusOfTorCheck = checkSvc.kCheckFailed;
-              obsSvc.notifyObservers(null, k_tb_tor_check_failed_topic, null);
-            } else if (ret == 4) {
-              checkSvc.statusOfTorCheck = checkSvc.kCheckSuccessful;
-            } // Otherwise, redo the check later
-
-            torbutton_log(3, "Tor remote check done. Result: " + ret);
-          }
+      req.onreadystatechange = function(aEvent) {
+        if (req.readyState === 4) {
+          let ret = checkSvc.parseCheckResponse(req);
+
+          // If we received an error response from check.torproject.org,
+          // set the status of the tor check to failure (we don't want
+          // to indicate failure if we didn't receive a response).
+          if (
+            ret == 2 ||
+            ret == 3 ||
+            ret == 5 ||
+            ret == 6 ||
+            ret == 7 ||
+            ret == 8
+          ) {
+            checkSvc.statusOfTorCheck = checkSvc.kCheckFailed;
+            obsSvc.notifyObservers(null, k_tb_tor_check_failed_topic);
+          } else if (ret == 4) {
+            checkSvc.statusOfTorCheck = checkSvc.kCheckSuccessful;
+          } // Otherwise, redo the check later
+
+          torbutton_log(3, "Tor remote check done. Result: " + ret);
+        }
       };
 
       torbutton_log(3, "Sending async Tor remote check");
       req.send(null);
-  } catch(e) {
-    if (e.result == 0x80004005) // NS_ERROR_FAILURE
-      torbutton_log(5, "Tor check failed! Is tor running?");
-    else
-      torbutton_log(5, "Tor check failed! Tor internal error: "+e);
-
-    checkSvc.statusOfTorCheck = checkSvc.kCheckFailed;
-    obsSvc.notifyObservers(null, k_tb_tor_check_failed_topic, null);
-  }
-} // torbutton_initiate_remote_tor_check()
+    } catch (e) {
+      if (e.result == 0x80004005) {
+        // NS_ERROR_FAILURE
+        torbutton_log(5, "Tor check failed! Is tor running?");
+      } else {
+        torbutton_log(5, "Tor check failed! Tor internal error: " + e);
+      }
 
-async function torbutton_tor_check_ok()
-{
-  await torbutton_do_tor_check();
-  let checkSvc = Cc["@torproject.org/torbutton-torCheckService;1"]
-                   .getService(Ci.nsISupports).wrappedJSObject;
-  return (checkSvc.kCheckFailed != checkSvc.statusOfTorCheck);
-}
+      obsSvc.notifyObservers(null, k_tb_tor_check_failed_topic);
+    }
+  } // torbutton_initiate_remote_tor_check()
 
-function torbutton_update_disk_prefs() {
+  async function torbutton_tor_check_ok() {
+    await torbutton_do_tor_check();
+    let checkSvc = Cc["@torproject.org/torbutton-torCheckService;1"].getService(
+      Ci.nsISupports
+    ).wrappedJSObject;
+    return checkSvc.kCheckFailed != checkSvc.statusOfTorCheck;
+  }
+
+  function torbutton_update_disk_prefs() {
     var mode = m_tb_prefs.getBoolPref("browser.privatebrowsing.autostart");
 
     m_tb_prefs.setBoolPref("browser.cache.disk.enable", !mode);
@@ -647,184 +677,205 @@ function torbutton_update_disk_prefs() {
 
     // Force prefs to be synced to disk
     Services.prefs.savePrefFile(null);
-}
+  }
 
-function torbutton_update_fingerprinting_prefs() {
+  function torbutton_update_fingerprinting_prefs() {
     var mode = m_tb_prefs.getBoolPref("privacy.resistFingerprinting");
-    var letterboxing = m_tb_prefs.getBoolPref("privacy.resistFingerprinting.letterboxing", false);
-    m_tb_prefs.setBoolPref("extensions.torbutton.resize_new_windows", mode && !letterboxing);
+    var letterboxing = m_tb_prefs.getBoolPref(
+      "privacy.resistFingerprinting.letterboxing",
+      false
+    );
+    m_tb_prefs.setBoolPref(
+      "extensions.torbutton.resize_new_windows",
+      mode && !letterboxing
+    );
 
     // Force prefs to be synced to disk
     Services.prefs.savePrefFile(null);
-}
-
-// Bug 1506 P1: This function just cleans up prefs that got set badly in previous releases
-function torbutton_fixup_old_prefs()
-{
-    if(m_tb_prefs.getIntPref('extensions.torbutton.pref_fixup_version') < 1) {
-        // TBB 5.0a3 had bad Firefox code that silently flipped this pref on us
-        if (m_tb_prefs.prefHasUserValue("browser.newtabpage.enhanced")) {
-            m_tb_prefs.clearUserPref("browser.newtabpage.enhanced");
-            // TBB 5.0a3 users had all the necessary data cached in
-            // directoryLinks.json. This meant that resetting the pref above
-            // alone was not sufficient as the tiles features uses the cache
-            // even if the pref indicates that feature should be disabled.
-            // We flip the preference below as this forces a refetching which
-            // effectively results in an empty JSON file due to our spoofed
-            // URLs.
-            let matchOS = m_tb_prefs.getBoolPref("intl.locale.matchOS");
-            m_tb_prefs.setBoolPref("intl.locale.matchOS", !matchOS);
-            m_tb_prefs.setBoolPref("intl.locale.matchOS", matchOS);
-        }
+  }
 
-        // For some reason, the Share This Page button also survived the
-        // TBB 5.0a4 update's attempt to remove it.
-        if (m_tb_prefs.prefHasUserValue("browser.uiCustomization.state")) {
-            m_tb_prefs.clearUserPref("browser.uiCustomization.state");
-        }
+  // Bug 1506 P1: This function just cleans up prefs that got set badly in previous releases
+  function torbutton_fixup_old_prefs() {
+    if (m_tb_prefs.getIntPref("extensions.torbutton.pref_fixup_version") < 1) {
+      // TBB 5.0a3 had bad Firefox code that silently flipped this pref on us
+      if (m_tb_prefs.prefHasUserValue("browser.newtabpage.enhanced")) {
+        m_tb_prefs.clearUserPref("browser.newtabpage.enhanced");
+        // TBB 5.0a3 users had all the necessary data cached in
+        // directoryLinks.json. This meant that resetting the pref above
+        // alone was not sufficient as the tiles features uses the cache
+        // even if the pref indicates that feature should be disabled.
+        // We flip the preference below as this forces a refetching which
+        // effectively results in an empty JSON file due to our spoofed
+        // URLs.
+        let matchOS = m_tb_prefs.getBoolPref("intl.locale.matchOS");
+        m_tb_prefs.setBoolPref("intl.locale.matchOS", !matchOS);
+        m_tb_prefs.setBoolPref("intl.locale.matchOS", matchOS);
+      }
 
-        m_tb_prefs.setIntPref('extensions.torbutton.pref_fixup_version', 1);
+      // For some reason, the Share This Page button also survived the
+      // TBB 5.0a4 update's attempt to remove it.
+      if (m_tb_prefs.prefHasUserValue("browser.uiCustomization.state")) {
+        m_tb_prefs.clearUserPref("browser.uiCustomization.state");
+      }
+
+      m_tb_prefs.setIntPref("extensions.torbutton.pref_fixup_version", 1);
     }
-}
+  }
 
-// ---------------------- Event handlers -----------------
+  // ---------------------- Event handlers -----------------
 
-// Bug 1506 P1-P3: Most of these observers aren't very important.
-// See their comments for details
-function torbutton_do_main_window_startup()
-{
+  // Bug 1506 P1-P3: Most of these observers aren't very important.
+  // See their comments for details
+  function torbutton_do_main_window_startup() {
     torbutton_log(3, "Torbutton main window startup");
     m_tb_is_main_window = true;
     torbutton_unique_pref_observer.register();
-}
+  }
 
-// Bug 1506 P4: Most of this function is now useless, save
-// for the very important SOCKS environment vars at the end.
-// Those could probably be rolled into a function with the
-// control port vars, though. See 1506 comments inside.
-function torbutton_do_startup()
-{
-    if(m_tb_prefs.getBoolPref("extensions.torbutton.startup")) {
-        // Bug 1506: Should probably be moved to an XPCOM component
-        torbutton_do_main_window_startup();
+  // Bug 1506 P4: Most of this function is now useless, save
+  // for the very important SOCKS environment vars at the end.
+  // Those could probably be rolled into a function with the
+  // control port vars, though. See 1506 comments inside.
+  function torbutton_do_startup() {
+    if (m_tb_prefs.getBoolPref("extensions.torbutton.startup")) {
+      // Bug 1506: Should probably be moved to an XPCOM component
+      torbutton_do_main_window_startup();
 
-        // For charsets
-        torbutton_update_fingerprinting_prefs();
+      // For charsets
+      torbutton_update_fingerprinting_prefs();
 
-        // Bug 30565: sync browser.privatebrowsing.autostart with security.nocertdb
-        torbutton_update_disk_prefs();
+      // Bug 30565: sync browser.privatebrowsing.autostart with security.nocertdb
+      torbutton_update_disk_prefs();
 
-        // For general pref fixups to handle pref damage in older versions
-        torbutton_fixup_old_prefs();
+      // For general pref fixups to handle pref damage in older versions
+      torbutton_fixup_old_prefs();
 
-        m_tb_prefs.setBoolPref("extensions.torbutton.startup", false);
+      m_tb_prefs.setBoolPref("extensions.torbutton.startup", false);
     }
-}
-
-// Bug 1506 P3: Used to decide if we should resize the window.
-//
-// Returns true if the window wind is neither maximized, full screen,
-// ratpoisioned/evilwmed, nor minimized.
-function torbutton_is_windowed(wind) {
-    torbutton_log(3, "Window: (" + wind.outerWidth + "," + wind.outerHeight + ") ?= ("
-                     + wind.screen.availWidth + "," + wind.screen.availHeight + ")");
-    if (wind.windowState == Ci.nsIDOMChromeWindow.STATE_MINIMIZED
-      || wind.windowState == Ci.nsIDOMChromeWindow.STATE_MAXIMIZED) {
-        torbutton_log(2, "Window is minimized/maximized");
-        return false;
+  }
+
+  // Bug 1506 P3: Used to decide if we should resize the window.
+  //
+  // Returns true if the window wind is neither maximized, full screen,
+  // ratpoisioned/evilwmed, nor minimized.
+  function torbutton_is_windowed(wind) {
+    torbutton_log(
+      3,
+      "Window: (" +
+        wind.outerWidth +
+        "," +
+        wind.outerHeight +
+        ") ?= (" +
+        wind.screen.availWidth +
+        "," +
+        wind.screen.availHeight +
+        ")"
+    );
+    if (
+      wind.windowState == Ci.nsIDOMChromeWindow.STATE_MINIMIZED ||
+      wind.windowState == Ci.nsIDOMChromeWindow.STATE_MAXIMIZED
+    ) {
+      torbutton_log(2, "Window is minimized/maximized");
+      return false;
     }
     if ("fullScreen" in wind && wind.fullScreen) {
-        torbutton_log(2, "Window is fullScreen");
-        return false;
+      torbutton_log(2, "Window is fullScreen");
+      return false;
     }
-    if(wind.outerHeight == wind.screen.availHeight
-            && wind.outerWidth == wind.screen.availWidth) {
-        torbutton_log(3, "Window is ratpoisoned/evilwm'ed");
-        return false;
+    if (
+      wind.outerHeight == wind.screen.availHeight &&
+      wind.outerWidth == wind.screen.availWidth
+    ) {
+      torbutton_log(3, "Window is ratpoisoned/evilwm'ed");
+      return false;
     }
 
     torbutton_log(2, "Window is normal");
     return true;
-}
+  }
 
-function showSecurityPreferencesPanel(chromeWindow) {
-  const tabBrowser = chromeWindow.BrowserApp;
-  let settingsTab = null;
+  function showSecurityPreferencesPanel(chromeWindow) {
+    const tabBrowser = chromeWindow.BrowserApp;
+    let settingsTab = null;
 
-  const SECURITY_PREFERENCES_URI = 'chrome://torbutton/content/preferences.xhtml';
+    const SECURITY_PREFERENCES_URI =
+      "chrome://torbutton/content/preferences.xhtml";
 
-  tabBrowser.tabs.some(function (tab) {
+    tabBrowser.tabs.some(function(tab) {
       // If the security prefs tab is opened, send the user to it
       if (tab.browser.currentURI.spec === SECURITY_PREFERENCES_URI) {
-          settingsTab = tab;
-          return true;
+        settingsTab = tab;
+        return true;
       }
       return false;
-  });
+    });
 
-  if (settingsTab === null) {
+    if (settingsTab === null) {
       // Open up the settings panel in a new tab.
       tabBrowser.addTab(SECURITY_PREFERENCES_URI, {
-          "selected": true,
-          "parentId": tabBrowser.selectedTab.id,
-          triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+        selected: true,
+        parentId: tabBrowser.selectedTab.id,
+        triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
       });
-  } else {
+    } else {
       // Activate an existing settings panel tab.
       tabBrowser.selectTab(settingsTab);
+    }
   }
-}
 
-function setupPreferencesForMobile() {
-  if (!torbutton_is_mobile()) {
-    return;
-  }
+  function setupPreferencesForMobile() {
+    if (!torbutton_is_mobile()) {
+      return;
+    }
 
-  torbutton_log(4, "Setting up settings preferences for Android.");
+    torbutton_log(4, "Setting up settings preferences for Android.");
 
-  const chromeWindow = Services.wm.getMostRecentWindow('navigator:browser');
+    const chromeWindow = Services.wm.getMostRecentWindow("navigator:browser");
 
-  // Add the extension's chrome menu item to the main browser menu.
-  chromeWindow.NativeWindow.menu.add({
-    'name': torbutton_get_property_string("torbutton.security_settings.menu.title"),
-    'callback': showSecurityPreferencesPanel.bind(this, chromeWindow)
-  });
-}
+    // Add the extension's chrome menu item to the main browser menu.
+    chromeWindow.NativeWindow.menu.add({
+      name: torbutton_get_property_string(
+        "torbutton.security_settings.menu.title"
+      ),
+      callback: showSecurityPreferencesPanel.bind(this, chromeWindow),
+    });
+  }
 
-// Bug 1506 P3: This is needed pretty much only for the window resizing.
-// See comments for individual functions for details
-function torbutton_new_window(event)
-{
+  // Bug 1506 P3: This is needed pretty much only for the window resizing.
+  // See comments for individual functions for details
+  function torbutton_new_window(event) {
     torbutton_log(3, "New window");
     var browser = window.gBrowser;
 
-    if(!browser) {
+    if (!browser) {
       torbutton_log(5, "No browser for new window.");
       return;
     }
 
     if (!m_tb_wasinited) {
-        torbutton_init();
+      torbutton_init();
     }
 
     torbutton_do_startup();
 
-    let progress = Cc["@mozilla.org/docloaderservice;1"]
-                     .getService(Ci.nsIWebProgress);
+    let progress = Cc["@mozilla.org/docloaderservice;1"].getService(
+      Ci.nsIWebProgress
+    );
 
     if (torbutton_is_windowed(window)) {
-      progress.addProgressListener(torbutton_resizelistener,
-                                   Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
+      progress.addProgressListener(
+        torbutton_resizelistener,
+        Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT
+      );
     }
-}
+  }
 
-// Bug 1506 P2: This is only needed because we have observers
-// in XUL that should be in an XPCOM component
-function torbutton_close_window(event) {
+  // Bug 1506 P2: This is only needed because we have observers
+  // in XUL that should be in an XPCOM component
+  function torbutton_close_window(event) {
     torbutton_tor_check_observer.unregister();
 
-    window.removeEventListener("sizemodechange", m_tb_resize_handler,
-        false);
+    window.removeEventListener("sizemodechange", m_tb_resize_handler);
 
     // TODO: This is a real ghetto hack.. When the original window
     // closes, we need to find another window to handle observing
@@ -832,151 +883,179 @@ function torbutton_close_window(event) {
     // majority of torbutton functionality into a XPCOM component..
     // But that is a major overhaul..
     if (m_tb_is_main_window) {
-        torbutton_log(3, "Original window closed. Searching for another");
-        var wm = Services.wm;
-        var enumerator = wm.getEnumerator("navigator:browser");
-        while(enumerator.hasMoreElements()) {
-            var win = enumerator.getNext();
-            // For some reason, when New Identity is called from a pref
-            // observer (ex: torbutton_use_nontor_proxy) on an ASAN build,
-            // we sometimes don't have this symbol set in the new window yet.
-            // However, the new window will run this init later in that case,
-            // as it does in the OSX case.
-            if(win != window && "torbutton_do_main_window_startup" in win) {
-                torbutton_log(3, "Found another window");
-                win.torbutton_do_main_window_startup();
-                m_tb_is_main_window = false;
-                break;
-            }
+      torbutton_log(3, "Original window closed. Searching for another");
+      var wm = Services.wm;
+      var enumerator = wm.getEnumerator("navigator:browser");
+      while (enumerator.hasMoreElements()) {
+        var win = enumerator.getNext();
+        // For some reason, when New Identity is called from a pref
+        // observer (ex: torbutton_use_nontor_proxy) on an ASAN build,
+        // we sometimes don't have this symbol set in the new window yet.
+        // However, the new window will run this init later in that case,
+        // as it does in the OSX case.
+        if (win != window && "torbutton_do_main_window_startup" in win) {
+          torbutton_log(3, "Found another window");
+          win.torbutton_do_main_window_startup();
+          m_tb_is_main_window = false;
+          break;
         }
+      }
 
-        torbutton_unique_pref_observer.unregister();
+      torbutton_unique_pref_observer.unregister();
 
-        if(m_tb_is_main_window) { // main window not reset above
-            // This happens on Mac OS because they allow firefox
-            // to still persist without a navigator window
-            torbutton_log(3, "Last window closed. None remain.");
-            m_tb_prefs.setBoolPref("extensions.torbutton.startup", true);
-            m_tb_is_main_window = false;
-        }
+      if (m_tb_is_main_window) {
+        // main window not reset above
+        // This happens on Mac OS because they allow firefox
+        // to still persist without a navigator window
+        torbutton_log(3, "Last window closed. None remain.");
+        m_tb_prefs.setBoolPref("extensions.torbutton.startup", true);
+        m_tb_is_main_window = false;
+      }
     }
-}
-
-window.addEventListener('load',torbutton_new_window,false);
-window.addEventListener('unload', torbutton_close_window, false);
-
-var m_tb_resize_handler = null;
-var m_tb_resize_date = null;
-
-// Bug 1506 P1/P3: Setting a fixed window size is important, but
-// probably not for android.
-var torbutton_resizelistener =
-{
-  QueryInterface: ChromeUtils.generateQI(["nsIWebProgressListener", "nsISupportsWeakReference"]),
-
-  onLocationChange: function(aProgress, aRequest, aURI) {},
-  onStateChange: function(aProgress, aRequest, aFlag, aStatus) {
-    if (aFlag & Ci.nsIWebProgressListener.STATE_STOP) {
-      m_tb_resize_handler = async function() {
-        // Wait for end of execution queue to ensure we have correct windowState.
-        await new Promise(resolve => setTimeout(resolve, 0));
-        if (window.windowState === window.STATE_MAXIMIZED ||
-            window.windowState === window.STATE_FULLSCREEN) {
-          if (m_tb_prefs.getBoolPref("extensions.torbutton.resize_new_windows") &&
-              m_tb_prefs.getIntPref("extensions.torbutton.maximize_warnings_remaining") > 0) {
-
-            // Do not add another notification if one is already showing.
-            const kNotificationName = "torbutton-maximize-notification";
-            let box = gBrowser.getNotificationBox();
-            if (box.getNotificationWithValue(kNotificationName))
-              return;
-
-            // Rate-limit showing our notification if needed.
-            if (m_tb_resize_date === null) {
-              m_tb_resize_date = Date.now();
-            } else {
-              // We wait at least another second before we show a new
-              // notification. Should be enough to rule out OSes that call our
-              // handler rapidly due to internal workings.
-              if (Date.now() - m_tb_resize_date < 1000) {
+  }
+
+  window.addEventListener("load", torbutton_new_window);
+  window.addEventListener("unload", torbutton_close_window);
+
+  var m_tb_resize_handler = null;
+  var m_tb_resize_date = null;
+
+  // Bug 1506 P1/P3: Setting a fixed window size is important, but
+  // probably not for android.
+  var torbutton_resizelistener = {
+    QueryInterface: ChromeUtils.generateQI([
+      "nsIWebProgressListener",
+      "nsISupportsWeakReference",
+    ]),
+
+    onLocationChange(aProgress, aRequest, aURI) {},
+    onStateChange(aProgress, aRequest, aFlag, aStatus) {
+      if (aFlag & Ci.nsIWebProgressListener.STATE_STOP) {
+        m_tb_resize_handler = async function() {
+          // Wait for end of execution queue to ensure we have correct windowState.
+          await new Promise(resolve => setTimeout(resolve, 0));
+          if (
+            window.windowState === window.STATE_MAXIMIZED ||
+            window.windowState === window.STATE_FULLSCREEN
+          ) {
+            if (
+              m_tb_prefs.getBoolPref(
+                "extensions.torbutton.resize_new_windows"
+              ) &&
+              m_tb_prefs.getIntPref(
+                "extensions.torbutton.maximize_warnings_remaining"
+              ) > 0
+            ) {
+              // Do not add another notification if one is already showing.
+              const kNotificationName = "torbutton-maximize-notification";
+              let box = gBrowser.getNotificationBox();
+              if (box.getNotificationWithValue(kNotificationName)) {
                 return;
               }
-              // Resizing but we need to reset |m_tb_resize_date| now.
-              m_tb_resize_date = Date.now();
-            }
 
-            // No need to get "OK" translated again.
-            let sbSvc = Services.strings;
-            let bundle = sbSvc.
-              createBundle("chrome://global/locale/commonDialogs.properties");
-            let button_label = bundle.GetStringFromName("OK");
-
-            let buttons = [{
-              label: button_label,
-              accessKey: 'O',
-              popup: null,
-              callback:
-                function() {
-                  m_tb_prefs.setIntPref("extensions.torbutton.maximize_warnings_remaining",
-                  m_tb_prefs.getIntPref("extensions.torbutton.maximize_warnings_remaining") - 1);
+              // Rate-limit showing our notification if needed.
+              if (m_tb_resize_date === null) {
+                m_tb_resize_date = Date.now();
+              } else {
+                // We wait at least another second before we show a new
+                // notification. Should be enough to rule out OSes that call our
+                // handler rapidly due to internal workings.
+                if (Date.now() - m_tb_resize_date < 1000) {
+                  return;
                 }
-            }];
-
-            let priority = box.PRIORITY_WARNING_LOW;
-            let message =
-              torbutton_get_property_string("torbutton.maximize_warning");
+                // Resizing but we need to reset |m_tb_resize_date| now.
+                m_tb_resize_date = Date.now();
+              }
 
-            box.appendNotification(message, kNotificationName, null,
-                                   priority, buttons);
-            return;
+              // No need to get "OK" translated again.
+              let sbSvc = Services.strings;
+              let bundle = sbSvc.createBundle(
+                "chrome://global/locale/commonDialogs.properties"
+              );
+              let button_label = bundle.GetStringFromName("OK");
+
+              let buttons = [
+                {
+                  label: button_label,
+                  accessKey: "O",
+                  popup: null,
+                  callback() {
+                    m_tb_prefs.setIntPref(
+                      "extensions.torbutton.maximize_warnings_remaining",
+                      m_tb_prefs.getIntPref(
+                        "extensions.torbutton.maximize_warnings_remaining"
+                      ) - 1
+                    );
+                  },
+                },
+              ];
+
+              let priority = box.PRIORITY_WARNING_LOW;
+              let message = torbutton_get_property_string(
+                "torbutton.maximize_warning"
+              );
+
+              box.appendNotification(
+                message,
+                kNotificationName,
+                null,
+                priority,
+                buttons
+              );
+            }
           }
-        }
-      }; // m_tb_resize_handler
-
-      // We need to handle OSes that auto-maximize windows depending on user
-      // settings and/or screen resolution in the start-up phase and users that
-      // try to shoot themselves in the foot by maximizing the window manually.
-      // We add a listener which is triggerred as soon as the window gets
-      // maximized (windowState = 1). We are resizing during start-up but not
-      // later as the user should see only a warning there as a stopgap before
-      // #14229 lands.
-      // Alas, the Firefox window code is handling the event not itself:
-      // "// Note the current implementation of SetSizeMode just stores
-      //  // the new state; it doesn't actually resize. So here we store
-      //  // the state and pass the event on to the OS."
-      // (See: https://mxr.mozilla.org/mozilla-esr31/source/xpfe/appshell/src/
-      // nsWebShellWindow.cpp#348)
-      // This means we have to cope with race conditions and resizing in the
-      // sizemodechange listener is likely to fail. Thus, we add a specific
-      // resize listener that is doing the work for us. It seems (at least on
-      // Ubuntu) to be the case that maximizing (and then again normalizing) of
-      // the window triggers more than one resize event the first being not the
-      // one we need. Thus we can't remove the listener after the first resize
-      // event got fired. Thus, we have the rather klunky setTimeout() call.
-      window.addEventListener("sizemodechange", m_tb_resize_handler, false);
-
-      let progress = Cc["@mozilla.org/docloaderservice;1"]
-                       .getService(Ci.nsIWebProgress);
-      progress.removeProgressListener(this);
-    }
-  }, // onStateChange
-
-  onProgressChange: function(aProgress, aRequest, curSelfProgress,
-                             maxSelfProgress, curTotalProgress,
-                             maxTotalProgress) {},
-  onStatusChange: function(aProgress, aRequest, stat, message) {},
-  onSecurityChange: function() {}
-};
-
-// Makes sure the item in the Help Menu and the link in about:tor
-// for the Tor Browser User Manual are only visible when
-// show_torbrowser_manual() returns true.
-function torbutton_init_user_manual_links() {
-  let menuitem = document.getElementById("torBrowserUserManual");
-  bindPrefAndInit("intl.locale.requested", val => {
-    menuitem.hidden = !show_torbrowser_manual();
-    torbutton_abouttor_message_handler.updateAllOpenPages();
-  });
-}
+        }; // m_tb_resize_handler
+
+        // We need to handle OSes that auto-maximize windows depending on user
+        // settings and/or screen resolution in the start-up phase and users that
+        // try to shoot themselves in the foot by maximizing the window manually.
+        // We add a listener which is triggerred as soon as the window gets
+        // maximized (windowState = 1). We are resizing during start-up but not
+        // later as the user should see only a warning there as a stopgap before
+        // #14229 lands.
+        // Alas, the Firefox window code is handling the event not itself:
+        // "// Note the current implementation of SetSizeMode just stores
+        //  // the new state; it doesn't actually resize. So here we store
+        //  // the state and pass the event on to the OS."
+        // (See: https://mxr.mozilla.org/mozilla-esr31/source/xpfe/appshell/src/
+        // nsWebShellWindow.cpp#348)
+        // This means we have to cope with race conditions and resizing in the
+        // sizemodechange listener is likely to fail. Thus, we add a specific
+        // resize listener that is doing the work for us. It seems (at least on
+        // Ubuntu) to be the case that maximizing (and then again normalizing) of
+        // the window triggers more than one resize event the first being not the
+        // one we need. Thus we can't remove the listener after the first resize
+        // event got fired. Thus, we have the rather klunky setTimeout() call.
+        window.addEventListener("sizemodechange", m_tb_resize_handler);
+
+        let progress = Cc["@mozilla.org/docloaderservice;1"].getService(
+          Ci.nsIWebProgress
+        );
+        progress.removeProgressListener(this);
+      }
+    }, // onStateChange
+
+    onProgressChange(
+      aProgress,
+      aRequest,
+      curSelfProgress,
+      maxSelfProgress,
+      curTotalProgress,
+      maxTotalProgress
+    ) {},
+    onStatusChange(aProgress, aRequest, stat, message) {},
+    onSecurityChange() {},
+  };
+
+  // Makes sure the item in the Help Menu and the link in about:tor
+  // for the Tor Browser User Manual are only visible when
+  // show_torbrowser_manual() returns true.
+  function torbutton_init_user_manual_links() {
+    let menuitem = document.getElementById("torBrowserUserManual");
+    bindPrefAndInit("intl.locale.requested", val => {
+      menuitem.hidden = !show_torbrowser_manual();
+      torbutton_abouttor_message_handler.updateAllOpenPages();
+    });
+  }
 })();
 //vim:set ts=4
diff --git a/components/domain-isolator.js b/components/domain-isolator.js
index 06fe1e2e..1c77b577 100644
--- a/components/domain-isolator.js
+++ b/components/domain-isolator.js
@@ -9,15 +9,17 @@
 // ### Abbreviations
 
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+const { XPCOMUtils } = ChromeUtils.import(
+  "resource://gre/modules/XPCOMUtils.jsm"
+);
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   ComponentUtils: "resource://gre/modules/ComponentUtils.jsm",
 });
 
 // Make the logger available.
-let logger = Cc["@torproject.org/torbutton-logger;1"]
-               .getService(Ci.nsISupports).wrappedJSObject;
+let logger = Cc["@torproject.org/torbutton-logger;1"].getService(Ci.nsISupports)
+  .wrappedJSObject;
 
 // Import crypto object (FF 37+).
 Cu.importGlobalProperties(["crypto"]);
@@ -29,8 +31,9 @@ let mozilla = {};
 // __mozilla.protocolProxyService__.
 // Mozilla's protocol proxy service, useful for managing proxy connections made
 // by the browser.
-mozilla.protocolProxyService = Cc["@mozilla.org/network/protocol-proxy-service;1"]
-                                 .getService(Ci.nsIProtocolProxyService);
+mozilla.protocolProxyService = Cc[
+  "@mozilla.org/network/protocol-proxy-service;1"
+].getService(Ci.nsIProtocolProxyService);
 
 // __mozilla.registerProxyChannelFilter(filterFunction, positionIndex)__.
 // Registers a proxy channel filter with the Mozilla Protocol Proxy Service,
@@ -38,13 +41,16 @@ mozilla.protocolProxyService = Cc["@mozilla.org/network/protocol-proxy-service;1
 // The filterFunction should expect two arguments, (aChannel, aProxy),
 // where aProxy is the proxy or list of proxies that would be used by default
 // for the given channel, and should return a new Proxy or list of Proxies.
-mozilla.registerProxyChannelFilter = function (filterFunction, positionIndex) {
+mozilla.registerProxyChannelFilter = function(filterFunction, positionIndex) {
   let proxyFilter = {
-    applyFilter : function (aChannel, aProxy, aCallback) {
+    applyFilter(aChannel, aProxy, aCallback) {
       aCallback.onProxyFilterResult(filterFunction(aChannel, aProxy));
-    }
+    },
   };
-  mozilla.protocolProxyService.registerChannelFilter(proxyFilter, positionIndex);
+  mozilla.protocolProxyService.registerChannelFilter(
+    proxyFilter,
+    positionIndex
+  );
 };
 
 // ## tor functionality.
@@ -66,24 +72,25 @@ tor.unknownDirtySince = Date.now();
 // Takes a proxyInfo object (originalProxy) and returns a new proxyInfo
 // object with the same properties, except the username is set to the
 // the domain, and the password is a nonce.
-tor.socksProxyCredentials = function (originalProxy, domain) {
+tor.socksProxyCredentials = function(originalProxy, domain) {
   // Check if we already have a nonce. If not, create
   // one for this domain.
   if (!tor.noncesForDomains.hasOwnProperty(domain)) {
     tor.noncesForDomains[domain] = tor.nonce();
   }
   let proxy = originalProxy.QueryInterface(Ci.nsIProxyInfo);
-  return mozilla.protocolProxyService
-    .newProxyInfoWithAuth("socks",
-                          proxy.host,
-                          proxy.port,
-                          domain, // username
-                          tor.noncesForDomains[domain], // password
-                          "", // aProxyAuthorizationHeader
-                          "", // aConnectionIsolationKey
-                          proxy.flags,
-                          proxy.failoverTimeout,
-                          proxy.failoverProxy);
+  return mozilla.protocolProxyService.newProxyInfoWithAuth(
+    "socks",
+    proxy.host,
+    proxy.port,
+    domain, // username
+    tor.noncesForDomains[domain], // password
+    "", // aProxyAuthorizationHeader
+    "", // aConnectionIsolationKey
+    proxy.flags,
+    proxy.failoverTimeout,
+    proxy.failoverProxy
+  );
 };
 
 tor.nonce = function() {
@@ -98,7 +105,7 @@ tor.nonce = function() {
   let tagStr = "";
   for (let i = 0; i < tag.length; i++) {
     tagStr += (tag[i] >>> 4).toString(16);
-    tagStr += (tag[i] & 0x0F).toString(16);
+    tagStr += (tag[i] & 0x0f).toString(16);
   }
 
   return tagStr;
@@ -110,13 +117,16 @@ tor.newCircuitForDomain = function(domain) {
     domain = "--unknown--";
   }
   tor.noncesForDomains[domain] = tor.nonce();
-  logger.eclog(3, "New domain isolation for " + domain + ": " + tor.noncesForDomains[domain]);
+  logger.eclog(
+    3,
+    "New domain isolation for " + domain + ": " + tor.noncesForDomains[domain]
+  );
 };
 
 // __tor.clearIsolation()_.
 // Clear the isolation state cache, forcing new circuits to be used for all
 // subsequent requests.
-tor.clearIsolation = function () {
+tor.clearIsolation = function() {
   // Per-domain nonces are stored in a map, so simply re-initialize the map.
   tor.noncesForDomains = {};
 
@@ -130,28 +140,38 @@ tor.clearIsolation = function () {
 // to the SOCKS server (the tor client process) with a username (the first party domain)
 // and a nonce password. Tor provides a separate circuit for each username+password
 // combination.
-tor.isolateCircuitsByDomain = function () {
-  mozilla.registerProxyChannelFilter(function (aChannel, aProxy) {
+tor.isolateCircuitsByDomain = function() {
+  mozilla.registerProxyChannelFilter(function(aChannel, aProxy) {
     if (!tor.isolationEnabled) {
       return aProxy;
     }
     try {
       let channel = aChannel.QueryInterface(Ci.nsIChannel),
-          firstPartyDomain = channel.loadInfo.originAttributes.firstPartyDomain;
+        firstPartyDomain = channel.loadInfo.originAttributes.firstPartyDomain;
       if (firstPartyDomain === "") {
         firstPartyDomain = "--unknown--";
-        if (Date.now() - tor.unknownDirtySince > 1000*10*60) {
-          logger.eclog(3, "tor catchall circuit has been dirty for over 10 minutes. Rotating.");
+        if (Date.now() - tor.unknownDirtySince > 1000 * 10 * 60) {
+          logger.eclog(
+            3,
+            "tor catchall circuit has been dirty for over 10 minutes. Rotating."
+          );
           tor.newCircuitForDomain("--unknown--");
           tor.unknownDirtySince = Date.now();
         }
       }
-      let replacementProxy = tor.socksProxyCredentials(aProxy, firstPartyDomain);
-      logger.eclog(3, `tor SOCKS: ${channel.URI.spec} via
-                       ${replacementProxy.username}:${replacementProxy.password}`);
+      let replacementProxy = tor.socksProxyCredentials(
+        aProxy,
+        firstPartyDomain
+      );
+      logger.eclog(
+        3,
+        `tor SOCKS: ${channel.URI.spec} via
+                       ${replacementProxy.username}:${replacementProxy.password}`
+      );
       return replacementProxy;
     } catch (e) {
       logger.eclog(4, `tor domain isolator error: ${e.message}`);
+      return null;
     }
   }, 0);
 };
@@ -164,7 +184,7 @@ const kMODULE_CID = Components.ID("e33fd6d4-270f-475f-a96f-ff3140279f68");
 
 // DomainIsolator object.
 function DomainIsolator() {
-    this.wrappedJSObject = this;
+  this.wrappedJSObject = this;
 }
 
 // Firefox component requirements
@@ -173,7 +193,7 @@ DomainIsolator.prototype = {
   classDescription: kMODULE_NAME,
   classID: kMODULE_CID,
   contractID: kMODULE_CONTRACTID,
-  observe: function (subject, topic, data) {
+  observe(subject, topic, data) {
     if (topic === "profile-after-change") {
       logger.eclog(3, "domain isolator: set up isolating circuits by domain");
 
@@ -183,23 +203,23 @@ DomainIsolator.prototype = {
       tor.isolateCircuitsByDomain();
     }
   },
-  newCircuitForDomain: function (domain) {
+  newCircuitForDomain(domain) {
     tor.newCircuitForDomain(domain);
   },
 
-  enableIsolation: function() {
+  enableIsolation() {
     tor.isolationEnabled = true;
   },
 
-  disableIsolation: function() {
+  disableIsolation() {
     tor.isolationEnabled = false;
   },
 
-  clearIsolation: function() {
+  clearIsolation() {
     tor.clearIsolation();
   },
 
-  wrappedJSObject: null
+  wrappedJSObject: null,
 };
 
 // Assign factory to global object.
diff --git a/components/dragDropFilter.js b/components/dragDropFilter.js
index 361424d1..4b76bd10 100644
--- a/components/dragDropFilter.js
+++ b/components/dragDropFilter.js
@@ -5,8 +5,9 @@
  * access to URLs (a potential proxy bypass vector).
  *************************************************************************/
 
-
-const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+const { XPCOMUtils } = ChromeUtils.import(
+  "resource://gre/modules/XPCOMUtils.jsm"
+);
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyModuleGetters(this, {
@@ -21,8 +22,9 @@ const kMODULE_CID = Components.ID("f605ec27-d867-44b5-ad97-2a29276642c3");
 const kInterfaces = [Ci.nsIObserver, Ci.nsIClassInfo];
 
 function DragDropFilter() {
-  this.logger = Cc["@torproject.org/torbutton-logger;1"]
-      .getService(Ci.nsISupports).wrappedJSObject;
+  this.logger = Cc["@torproject.org/torbutton-logger;1"].getService(
+    Ci.nsISupports
+  ).wrappedJSObject;
   this.logger.log(3, "Component Load 0: New DragDropFilter.");
 
   try {
@@ -32,8 +34,7 @@ function DragDropFilter() {
   }
 }
 
-DragDropFilter.prototype =
-{
+DragDropFilter.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
 
   // make this an nsIClassInfo object
@@ -43,23 +44,25 @@ DragDropFilter.prototype =
   classID: kMODULE_CID,
 
   // method of nsIClassInfo
-  getInterfaces: function(count) {
+  getInterfaces(count) {
     count.value = kInterfaces.length;
     return kInterfaces;
   },
 
   // method of nsIClassInfo
-  getHelperForLanguage: function(count) { return null; },
+  getHelperForLanguage(count) {
+    return null;
+  },
 
   // method of nsIObserver
-  observe: function(subject, topic, data) {
-    if (topic == "on-datatransfer-available") {
+  observe(subject, topic, data) {
+    if (topic === "on-datatransfer-available") {
       this.logger.log(3, "The DataTransfer is available");
-      return this.filterDataTransferURLs(subject);
+      this.filterDataTransferURLs(subject);
     }
   },
 
-  filterDataTransferURLs: function(aDataTransfer) {
+  filterDataTransferURLs(aDataTransfer) {
     var types = null;
     var type = "";
     var count = aDataTransfer.mozItemCount;
@@ -71,16 +74,18 @@ DragDropFilter.prototype =
       for (var j = 0; j < len; ++j) {
         type = types[j];
         this.logger.log(3, "Type is: " + type);
-        if (type == "text/x-moz-url" ||
-            type == "text/x-moz-url-data" ||
-            type == "text/uri-list" ||
-            type == "application/x-moz-file-promise-url") {
+        if (
+          type == "text/x-moz-url" ||
+          type == "text/x-moz-url-data" ||
+          type == "text/uri-list" ||
+          type == "application/x-moz-file-promise-url"
+        ) {
           aDataTransfer.clearData(type);
           this.logger.log(3, "Removing " + type);
         }
       }
     }
-  }
+  },
 };
 
 // Assign factory to global object.
diff --git a/components/external-app-blocker.js b/components/external-app-blocker.js
index 2fa80d9d..6a53fc01 100644
--- a/components/external-app-blocker.js
+++ b/components/external-app-blocker.js
@@ -12,15 +12,21 @@
  * handle an URL (e.g., when the user clicks on a mailto: URL).
  *************************************************************************/
 
-const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+const { XPCOMUtils } = ChromeUtils.import(
+  "resource://gre/modules/XPCOMUtils.jsm"
+);
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const { PromptUtils } = ChromeUtils.import("resource://gre/modules/SharedPromptUtils.jsm");
+const { PromptUtils } = ChromeUtils.import(
+  "resource://gre/modules/SharedPromptUtils.jsm"
+);
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   ComponentUtils: "resource://gre/modules/ComponentUtils.jsm",
 });
 
-let { torbutton_get_property_string } = ChromeUtils.import("resource://torbutton/modules/utils.js", {});
+let { torbutton_get_property_string } = ChromeUtils.import(
+  "resource://torbutton/modules/utils.js"
+);
 
 // Module specific constants
 const kMODULE_NAME = "Torbutton External App Handler";
@@ -30,16 +36,19 @@ const kMODULE_CID = Components.ID("3da0269f-fc29-4e9e-a678-c3b1cafcf13f");
 const kInterfaces = [Ci.nsIObserver, Ci.nsIClassInfo];
 
 function ExternalAppBlocker() {
-  this.logger = Cc["@torproject.org/torbutton-logger;1"]
-      .getService(Ci.nsISupports).wrappedJSObject;
+  this.logger = Cc["@torproject.org/torbutton-logger;1"].getService(
+    Ci.nsISupports
+  ).wrappedJSObject;
   this.logger.log(3, "Component Load 0: New ExternalAppBlocker.");
 }
 
-ExternalAppBlocker.prototype =
-{
+ExternalAppBlocker.prototype = {
   _helperAppLauncher: undefined,
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver, Ci.nsIHelperAppWarningDialog]),
+  QueryInterface: ChromeUtils.generateQI([
+    Ci.nsIObserver,
+    Ci.nsIHelperAppWarningDialog,
+  ]),
 
   // make this an nsIClassInfo object
   flags: Ci.nsIClassInfo.DOM_OBJECT,
@@ -48,17 +57,18 @@ ExternalAppBlocker.prototype =
   classID: kMODULE_CID,
 
   // method of nsIClassInfo
-  getInterfaces: function(count) {
+  getInterfaces(count) {
     count.value = kInterfaces.length;
     return kInterfaces;
   },
 
   // method of nsIClassInfo
-  getHelperForLanguage: function(count) { return null; },
+  getHelperForLanguage(count) {
+    return null;
+  },
 
   // method of nsIHelperAppWarningDialog
-  maybeShow: function(aLauncher, aWindowContext)
-  {
+  maybeShow(aLauncher, aWindowContext) {
     // Hold a reference to the object that called this component. This is
     // important not just because we need to later invoke the
     // continueRequest() or cancelRequest() callback on aLauncher, but also
@@ -80,7 +90,7 @@ ExternalAppBlocker.prototype =
    * on chrome://global/content/commonDialog.xhtml as well as some of the code
    * in resource://gre/modules/SharedPromptUtils.jsm.
    */
-  _showPrompt: function(aWindowContext) {
+  _showPrompt(aWindowContext) {
     let parentWin;
     try {
       parentWin = aWindowContext.getInterface(Ci.nsIDOMWindow);
@@ -91,20 +101,22 @@ ExternalAppBlocker.prototype =
     let title = torbutton_get_property_string("torbutton.popup.external.title");
     let app = torbutton_get_property_string("torbutton.popup.external.app");
     let note = torbutton_get_property_string("torbutton.popup.external.note");
-    let suggest = torbutton_get_property_string("torbutton.popup.external.suggest");
+    let suggest = torbutton_get_property_string(
+      "torbutton.popup.external.suggest"
+    );
     let launch = torbutton_get_property_string("torbutton.popup.launch");
     let cancel = torbutton_get_property_string("torbutton.popup.cancel");
     let dontask = torbutton_get_property_string("torbutton.popup.dontask");
 
     let args = {
-      promptType:       "confirmEx",
-      title:            title,
-      text:             app+note+suggest+" ",
-      checkLabel:       dontask,
-      checked:          false,
-      ok:               false,
-      button0Label:     launch,
-      button1Label:     cancel,
+      promptType: "confirmEx",
+      title,
+      text: app + note + suggest + " ",
+      checkLabel: dontask,
+      checked: false,
+      ok: false,
+      button0Label: launch,
+      button1Label: cancel,
       defaultButtonNum: 1, // Cancel
       buttonNumClicked: 1, // Cancel
       enableDelay: true,
@@ -112,8 +124,13 @@ ExternalAppBlocker.prototype =
 
     let propBag = PromptUtils.objectToPropBag(args);
     let uri = "chrome://global/content/commonDialog.xhtml";
-    let promptWin = Services.ww.openWindow(parentWin, uri, "_blank",
-                                    "centerscreen,chrome,titlebar", propBag);
+    let promptWin = Services.ww.openWindow(
+      parentWin,
+      uri,
+      "_blank",
+      "centerscreen,chrome,titlebar",
+      propBag
+    );
     promptWin.addEventListener("load", aEvent => {
       promptWin.addEventListener("unload", aEvent => {
         PromptUtils.propBagToObject(propBag, args);
@@ -122,16 +139,18 @@ ExternalAppBlocker.prototype =
           // Save the checkbox value and tell the browser's external helper app
           // module about the user's choice.
           if (args.checked) {
-            Services.prefs.setBoolPref("extensions.torbutton.launch_warning",
-                                       false);
+            Services.prefs.setBoolPref(
+              "extensions.torbutton.launch_warning",
+              false
+            );
           }
 
           this._helperAppLauncher.continueRequest();
         } else {
           this._helperAppLauncher.cancelRequest(Cr.NS_BINDING_ABORTED);
         }
-      }, false);
-    }, false);
+      });
+    });
   },
 };
 
diff --git a/components/startup-observer.js b/components/startup-observer.js
index 164c9219..77df172a 100644
--- a/components/startup-observer.js
+++ b/components/startup-observer.js
@@ -13,7 +13,9 @@
  *************************************************************************/
 
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+const { XPCOMUtils } = ChromeUtils.import(
+  "resource://gre/modules/XPCOMUtils.jsm"
+);
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   ComponentUtils: "resource://gre/modules/ComponentUtils.jsm",
@@ -47,155 +49,163 @@ function cleanupCookies() {
 }
 
 function StartupObserver() {
-    this.logger = Cc["@torproject.org/torbutton-logger;1"]
-                    .getService(Ci.nsISupports).wrappedJSObject;
-    this._prefs = Services.prefs;
-    this.logger.log(3, "Startup Observer created");
-
-    var env = Cc["@mozilla.org/process/environment;1"]
-                .getService(Ci.nsIEnvironment);
-    var prefName = "browser.startup.homepage";
-    if (env.exists("TOR_DEFAULT_HOMEPAGE")) {
-      // if the user has set this value in a previous installation, don't override it
-      if (!this._prefs.prefHasUserValue(prefName)) {
-        this._prefs.setCharPref(prefName, env.get("TOR_DEFAULT_HOMEPAGE"));
-      }
-    }
-
-    try {
-      var test = this._prefs.getCharPref("torbrowser.version");
-      this.is_tbb = true;
-      this.logger.log(3, "This is a Tor Browser's XPCOM");
-    } catch(e) {
-      this.logger.log(3, "This is not a Tor Browser's XPCOM");
-    }
-
-    try {
-      // XXX: We're in a race with HTTPS-Everywhere to update our proxy settings
-      // before the initial SSL-Observatory test... If we lose the race, Firefox
-      // caches the old proxy settings for check.tp.o somehwere, and it never loads :(
-      this.setProxySettings();
-    } catch(e) {
-      this.logger.log(4, "Early proxy change failed. Will try again at profile load. Error: "+e);
+  this.logger = Cc["@torproject.org/torbutton-logger;1"].getService(
+    Ci.nsISupports
+  ).wrappedJSObject;
+  this._prefs = Services.prefs;
+  this.logger.log(3, "Startup Observer created");
+
+  var env = Cc["@mozilla.org/process/environment;1"].getService(
+    Ci.nsIEnvironment
+  );
+  var prefName = "browser.startup.homepage";
+  if (env.exists("TOR_DEFAULT_HOMEPAGE")) {
+    // if the user has set this value in a previous installation, don't override it
+    if (!this._prefs.prefHasUserValue(prefName)) {
+      this._prefs.setCharPref(prefName, env.get("TOR_DEFAULT_HOMEPAGE"));
     }
+  }
 
-    cleanupCookies();
-
-    // Using all possible locales so that we do not have to change this list every time we support
-    // a new one.
-    const allLocales = [
-      "en-US", "ach", "af", "an", "ar", "ast", "az", "be", "bg", "bn", "br", "bs", "ca", "cak",
-      "crh", "cs", "cy", "da", "de", "dsb", "el", "en-CA", "en-GB", "eo", "es-AR", "es-CL",
-      "es-ES", "es-MX", "et", "eu", "fa", "ff", "fi", "fr", "fy-NL", "ga-IE", "gd", "gl", "gn",
-      "gu-IN", "he", "hi-IN", "hr", "hsb", "hu", "hy-AM", "ia", "id", "is", "it", "ja",
-      "ja-JP-mac", "ka", "kab", "kk", "km", "kn", "ko", "lij", "lo", "lt", "ltg", "lv", "mk", "mr",
-      "ms", "my", "nb-NO", "ne-NP", "nl", "nn-NO", "oc", "pa-IN", "pl", "pt-BR", "pt-PT", "rm",
-      "ro", "ru", "si", "sk", "sl", "son", "sq", "sr", "sv-SE", "ta", "te", "th", "tl", "tr",
-      "trs", "uk", "ur", "uz", "vi", "wo", "xh", "zh-CN", "zh-TW"
-    ];
-    let torSource = new FileSource(
-      "torbutton",
-      allLocales,
-      "resource://torbutton/locale/{locale}/",
-      true, // skip this FileSource locales when computing Services.locale.availableLocales
+  this.is_tbb = true;
+
+  try {
+    // XXX: We're in a race with HTTPS-Everywhere to update our proxy settings
+    // before the initial SSL-Observatory test... If we lose the race, Firefox
+    // caches the old proxy settings for check.tp.o somehwere, and it never loads :(
+    this.setProxySettings();
+  } catch (e) {
+    this.logger.log(
+      4,
+      "Early proxy change failed. Will try again at profile load. Error: " + e
     );
-    if (L10nRegistry.registerSources) {
-      L10nRegistry.registerSources([torSource]);
-    } else {
-      L10nRegistry.registerSource(torSource);
-    }
+  }
+
+  cleanupCookies();
+
+  // Using all possible locales so that we do not have to change this list every time we support
+  // a new one.
+  /* eslint-disable */
+  const allLocales = [
+    "en-US", "ach", "af", "an", "ar", "ast", "az", "be", "bg", "bn", "br", "bs", "ca", "cak",
+    "crh", "cs", "cy", "da", "de", "dsb", "el", "en-CA", "en-GB", "eo", "es-AR", "es-CL",
+    "es-ES", "es-MX", "et", "eu", "fa", "ff", "fi", "fr", "fy-NL", "ga-IE", "gd", "gl", "gn",
+    "gu-IN", "he", "hi-IN", "hr", "hsb", "hu", "hy-AM", "ia", "id", "is", "it", "ja",
+    "ja-JP-mac", "ka", "kab", "kk", "km", "kn", "ko", "lij", "lo", "lt", "ltg", "lv", "mk", "mr",
+    "ms", "my", "nb-NO", "ne-NP", "nl", "nn-NO", "oc", "pa-IN", "pl", "pt-BR", "pt-PT", "rm",
+    "ro", "ru", "si", "sk", "sl", "son", "sq", "sr", "sv-SE", "ta", "te", "th", "tl", "tr",
+    "trs", "uk", "ur", "uz", "vi", "wo", "xh", "zh-CN", "zh-TW"
+  ];
+  /* eslint-enable */
+  let torSource = new FileSource(
+    "torbutton",
+    allLocales,
+    "resource://torbutton/locale/{locale}/",
+    true // skip this FileSource locales when computing Services.locale.availableLocales
+  );
+  if (L10nRegistry.registerSources) {
+    L10nRegistry.registerSources([torSource]);
+  } else {
+    L10nRegistry.registerSource(torSource);
+  }
 }
 
 StartupObserver.prototype = {
-    // Bug 6803: We need to get the env vars early due to
-    // some weird proxy caching code that showed up in FF15.
-    // Otherwise, homepage domain loads fail forever.
-    setProxySettings: function() {
-      if (!this.is_tbb)
-        return;
-
-      // Bug 1506: Still want to get these env vars
-      let environ = Cc["@mozilla.org/process/environment;1"]
-                      .getService(Ci.nsIEnvironment);
-      if (environ.exists("TOR_TRANSPROXY")) {
-        this.logger.log(3, "Resetting Tor settings to transproxy");
-        this._prefs.setBoolPref("network.proxy.socks_remote_dns", false);
-        this._prefs.setIntPref("network.proxy.type", 0);
-        this._prefs.setIntPref("network.proxy.socks_port", 0);
-        this._prefs.setCharPref("network.proxy.socks", "");
-      } else {
-        // Try to retrieve SOCKS proxy settings from Tor Launcher.
-        let socksPortInfo;
-        try {
-          let tlps = Cc["@torproject.org/torlauncher-protocol-service;1"]
-                     .getService(Ci.nsISupports).wrappedJSObject;
-          socksPortInfo = tlps.TorGetSOCKSPortInfo();
-        } catch(e) {
-          this.logger.log(3, "tor launcher failed " + e);
-        }
+  // Bug 6803: We need to get the env vars early due to
+  // some weird proxy caching code that showed up in FF15.
+  // Otherwise, homepage domain loads fail forever.
+  setProxySettings() {
+    if (!this.is_tbb) {
+      return;
+    }
 
-        // If Tor Launcher is not available, check environment variables.
-        if (!socksPortInfo) {
-          socksPortInfo = { ipcFile: undefined, host: undefined, port: 0 };
+    // Bug 1506: Still want to get these env vars
+    let environ = Cc["@mozilla.org/process/environment;1"].getService(
+      Ci.nsIEnvironment
+    );
+    if (environ.exists("TOR_TRANSPROXY")) {
+      this.logger.log(3, "Resetting Tor settings to transproxy");
+      this._prefs.setBoolPref("network.proxy.socks_remote_dns", false);
+      this._prefs.setIntPref("network.proxy.type", 0);
+      this._prefs.setIntPref("network.proxy.socks_port", 0);
+      this._prefs.setCharPref("network.proxy.socks", "");
+    } else {
+      // Try to retrieve SOCKS proxy settings from Tor Launcher.
+      let socksPortInfo;
+      try {
+        let tlps = Cc[
+          "@torproject.org/torlauncher-protocol-service;1"
+        ].getService(Ci.nsISupports).wrappedJSObject;
+        socksPortInfo = tlps.TorGetSOCKSPortInfo();
+      } catch (e) {
+        this.logger.log(3, "tor launcher failed " + e);
+      }
 
-          let isWindows = Services.appinfo.OS === "WINNT";
-          if (!isWindows && environ.exists("TOR_SOCKS_IPC_PATH")) {
-            socksPortInfo.ipcFile = new FileUtils.File(
-                                           environ.get("TOR_SOCKS_IPC_PATH"));
-          }
-          else
-          {
-            if (environ.exists("TOR_SOCKS_HOST"))
-              socksPortInfo.host = environ.get("TOR_SOCKS_HOST");
-            if (environ.exists("TOR_SOCKS_PORT"))
-              socksPortInfo.port = parseInt(environ.get("TOR_SOCKS_PORT"));
-          }
-        }
+      // If Tor Launcher is not available, check environment variables.
+      if (!socksPortInfo) {
+        socksPortInfo = { ipcFile: undefined, host: undefined, port: 0 };
 
-        // Adjust network.proxy prefs.
-        if (socksPortInfo.ipcFile) {
-          let fph = Services.io.getProtocolHandler("file")
-                               .QueryInterface(Ci.nsIFileProtocolHandler);
-          let fileURI = fph.newFileURI(socksPortInfo.ipcFile);
-          this.logger.log(3, "Reset socks to "+fileURI.spec);
-          this._prefs.setCharPref("network.proxy.socks", fileURI.spec);
-          this._prefs.setIntPref("network.proxy.socks_port", 0);
+        let isWindows = Services.appinfo.OS === "WINNT";
+        if (!isWindows && environ.exists("TOR_SOCKS_IPC_PATH")) {
+          socksPortInfo.ipcFile = new FileUtils.File(
+            environ.get("TOR_SOCKS_IPC_PATH")
+          );
         } else {
-          if (socksPortInfo.host) {
-            this._prefs.setCharPref("network.proxy.socks", socksPortInfo.host);
-            this.logger.log(3, "Reset socks host to "+socksPortInfo.host);
+          if (environ.exists("TOR_SOCKS_HOST")) {
+            socksPortInfo.host = environ.get("TOR_SOCKS_HOST");
           }
-          if (socksPortInfo.port) {
-            this._prefs.setIntPref("network.proxy.socks_port",
-                                   socksPortInfo.port);
-            this.logger.log(3, "Reset socks port to "+socksPortInfo.port);
+          if (environ.exists("TOR_SOCKS_PORT")) {
+            socksPortInfo.port = parseInt(environ.get("TOR_SOCKS_PORT"));
           }
         }
+      }
 
-        if (socksPortInfo.ipcFile || socksPortInfo.host || socksPortInfo.port) {
-          this._prefs.setBoolPref("network.proxy.socks_remote_dns", true);
-          this._prefs.setIntPref("network.proxy.type", 1);
+      // Adjust network.proxy prefs.
+      if (socksPortInfo.ipcFile) {
+        let fph = Services.io
+          .getProtocolHandler("file")
+          .QueryInterface(Ci.nsIFileProtocolHandler);
+        let fileURI = fph.newFileURI(socksPortInfo.ipcFile);
+        this.logger.log(3, "Reset socks to " + fileURI.spec);
+        this._prefs.setCharPref("network.proxy.socks", fileURI.spec);
+        this._prefs.setIntPref("network.proxy.socks_port", 0);
+      } else {
+        if (socksPortInfo.host) {
+          this._prefs.setCharPref("network.proxy.socks", socksPortInfo.host);
+          this.logger.log(3, "Reset socks host to " + socksPortInfo.host);
+        }
+        if (socksPortInfo.port) {
+          this._prefs.setIntPref(
+            "network.proxy.socks_port",
+            socksPortInfo.port
+          );
+          this.logger.log(3, "Reset socks port to " + socksPortInfo.port);
         }
       }
 
-      // Force prefs to be synced to disk
-      Services.prefs.savePrefFile(null);
+      if (socksPortInfo.ipcFile || socksPortInfo.host || socksPortInfo.port) {
+        this._prefs.setBoolPref("network.proxy.socks_remote_dns", true);
+        this._prefs.setIntPref("network.proxy.type", 1);
+      }
+    }
+
+    // Force prefs to be synced to disk
+    Services.prefs.savePrefFile(null);
 
-      this.logger.log(3, "Synced network settings to environment.");
-    },
+    this.logger.log(3, "Synced network settings to environment.");
+  },
 
-    observe: function(subject, topic, data) {
-      if(topic == "profile-after-change") {
-        // Bug 1506 P1: We listen to these prefs as signals for startup,
-        // but only for hackish reasons.
-        this._prefs.setBoolPref("extensions.torbutton.startup", true);
+  observe(subject, topic, data) {
+    if (topic == "profile-after-change") {
+      // Bug 1506 P1: We listen to these prefs as signals for startup,
+      // but only for hackish reasons.
+      this._prefs.setBoolPref("extensions.torbutton.startup", true);
 
-        this.setProxySettings();
-      }
+      this.setProxySettings();
+    }
 
-      // In all cases, force prefs to be synced to disk
-      Services.prefs.savePrefFile(null);
-    },
+    // In all cases, force prefs to be synced to disk
+    Services.prefs.savePrefFile(null);
+  },
 
   QueryInterface: ChromeUtils.generateQI([Ci.nsIClassInfo]),
 
@@ -205,7 +215,7 @@ StartupObserver.prototype = {
   contractID: kMODULE_CONTRACTID,
 
   // Hack to get us registered early to observe recovery
-  _xpcom_categories: [{category:"profile-after-change"}],
+  _xpcom_categories: [{ category: "profile-after-change" }],
 };
 
 // Assign factory to global object.
diff --git a/components/torCheckService.js b/components/torCheckService.js
index 07b1aa99..41d716ff 100644
--- a/components/torCheckService.js
+++ b/components/torCheckService.js
@@ -3,12 +3,14 @@
  * See LICENSE for licensing information.
  *
  * vim: set sw=2 sts=2 ts=8 et syntax=javascript:
- * 
+ *
  * Tor check service
  *************************************************************************/
 
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+const { XPCOMUtils } = ChromeUtils.import(
+  "resource://gre/modules/XPCOMUtils.jsm"
+);
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   ComponentUtils: "resource://gre/modules/ComponentUtils.jsm",
@@ -20,16 +22,16 @@ const kMODULE_CONTRACTID = "@torproject.org/torbutton-torCheckService;1";
 const kMODULE_CID = Components.ID("5d57312b-5d8c-4169-b4af-e80d6a28a72e");
 
 function TBTorCheckService() {
-  this._logger = Cc["@torproject.org/torbutton-logger;1"]
-                   .getService(Ci.nsISupports).wrappedJSObject;
+  this._logger = Cc["@torproject.org/torbutton-logger;1"].getService(
+    Ci.nsISupports
+  ).wrappedJSObject;
   this._logger.log(3, "Torbutton Tor Check Service initialized");
 
   this._statusOfTorCheck = this.kCheckNotInitiated;
   this.wrappedJSObject = this;
 }
 
-TBTorCheckService.prototype =
-{
+TBTorCheckService.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.nsIClassInfo]),
 
   kCheckNotInitiated: 0, // Possible values for statusOfTorCheck.
@@ -49,87 +51,84 @@ TBTorCheckService.prototype =
   contractID: kMODULE_CONTRACTID,
 
   // method of nsIClassInfo
-  getInterfaces: function(count) {
+  getInterfaces(count) {
     var interfaceList = [Ci.nsIClassInfo];
     count.value = interfaceList.length;
     return interfaceList;
   },
 
   // method of nsIClassInfo
-  getHelperForLanguage: function(count) { return null; },
+  getHelperForLanguage(count) {
+    return null;
+  },
 
   // Public methods.
-  get statusOfTorCheck()
-  {
+  get statusOfTorCheck() {
     return this._statusOfTorCheck;
   },
 
-  set statusOfTorCheck(aStatus)
-  {
+  set statusOfTorCheck(aStatus) {
     this._statusOfTorCheck = aStatus;
   },
 
-  createCheckRequest: function(aAsync)
-  {
-    Cu.importGlobalProperties(["XMLHttpRequest"]);
+  createCheckRequest(aAsync) {
     let req = new XMLHttpRequest();
     let url = Services.prefs.getCharPref("extensions.torbutton.test_url");
     req.open("GET", url, aAsync);
     req.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
     req.overrideMimeType("text/xml");
-    req.timeout = 120000;  // Wait at most two minutes for a response.
+    req.timeout = 120000; // Wait at most two minutes for a response.
     return req;
   },
 
-  parseCheckResponse: function(aReq)
-  {
+  parseCheckResponse(aReq) {
     let ret = 0;
-    if(aReq.status == 200) {
-        if(!aReq.responseXML) {
-            this._logger.log(5, "Check failed! Not text/xml!");
-            ret = 1;
-        } else {
-          let result = aReq.responseXML.getElementById('TorCheckResult');
-
-          if(result===null) {
-              this._logger.log(5, "Test failed! No TorCheckResult element");
-              ret = 2;
-          } else if(typeof(result.target) == 'undefined' 
-                  || result.target === null) {
-              this._logger.log(5, "Test failed! No target");
-              ret = 3;
-          } else if(result.target === "success") {
-              this._logger.log(3, "Test Successful");
-              ret = 4;
-          } else if(result.target === "failure") {
-              this._logger.log(5, "Tor test failed!");
-              ret = 5;
-          } else if(result.target === "unknown") {
-              this._logger.log(5, "Tor test failed. TorDNSEL Failure?");
-              ret = 6;
-          } else {
-              this._logger.log(5, "Tor test failed. Strange target.");
-              ret = 7;
-          }
-        }
+    if (aReq.status == 200) {
+      if (!aReq.responseXML) {
+        this._logger.log(5, "Check failed! Not text/xml!");
+        ret = 1;
       } else {
-        if (0 == aReq.status) {
-          try {
-            var req = aReq.channel.QueryInterface(Ci.nsIRequest);
-            if (req.status == Cr.NS_ERROR_PROXY_CONNECTION_REFUSED)
-            {
-              this._logger.log(5, "Tor test failed. Proxy connection refused");
-              ret = 8;
-            }
-          } catch (e) {}
+        let result = aReq.responseXML.getElementById("TorCheckResult");
+
+        if (result === null) {
+          this._logger.log(5, "Test failed! No TorCheckResult element");
+          ret = 2;
+        } else if (
+          typeof result.target == "undefined" ||
+          result.target === null
+        ) {
+          this._logger.log(5, "Test failed! No target");
+          ret = 3;
+        } else if (result.target === "success") {
+          this._logger.log(3, "Test Successful");
+          ret = 4;
+        } else if (result.target === "failure") {
+          this._logger.log(5, "Tor test failed!");
+          ret = 5;
+        } else if (result.target === "unknown") {
+          this._logger.log(5, "Tor test failed. TorDNSEL Failure?");
+          ret = 6;
+        } else {
+          this._logger.log(5, "Tor test failed. Strange target.");
+          ret = 7;
         }
+      }
+    } else {
+      if (0 == aReq.status) {
+        try {
+          var req = aReq.channel.QueryInterface(Ci.nsIRequest);
+          if (req.status == Cr.NS_ERROR_PROXY_CONNECTION_REFUSED) {
+            this._logger.log(5, "Tor test failed. Proxy connection refused");
+            ret = 8;
+          }
+        } catch (e) {}
+      }
 
-        if (ret == 0)
-        {
-          this._logger.log(5, "Tor test failed. HTTP Error: "+aReq.status);
-          ret = -aReq.status;
-        }
+      if (ret == 0) {
+        this._logger.log(5, "Tor test failed. HTTP Error: " + aReq.status);
+        ret = -aReq.status;
       }
+    }
 
     return ret;
   },
diff --git a/components/torbutton-logger.js b/components/torbutton-logger.js
index d80d13c4..2fdcd7e6 100644
--- a/components/torbutton-logger.js
+++ b/components/torbutton-logger.js
@@ -14,31 +14,34 @@ const kMODULE_CONTRACTID = "@torproject.org/torbutton-logger;1";
 const kMODULE_CID = Components.ID("f36d72c9-9718-4134-b550-e109638331d7");
 
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+const { XPCOMUtils } = ChromeUtils.import(
+  "resource://gre/modules/XPCOMUtils.jsm"
+);
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   ComponentUtils: "resource://gre/modules/ComponentUtils.jsm",
 });
 
 function TorbuttonLogger() {
-    // Register observer
-    Services.prefs.addObserver("extensions.torbutton", this);
-
-    this.loglevel = Services.prefs.getIntPref("extensions.torbutton.loglevel");
-    this.logmethod = Services.prefs.getIntPref("extensions.torbutton.logmethod");
-
-    try {
-        var logMngr = Cc["@mozmonkey.com/debuglogger/manager;1"]
-            .getService(Ci.nsIDebugLoggerManager);
-        this._debuglog = logMngr.registerLogger("torbutton");
-    } catch (exErr) {
-        this._debuglog = false;
-    }
-    this._console = Services.console;
+  // Register observer
+  Services.prefs.addObserver("extensions.torbutton", this);
+
+  this.loglevel = Services.prefs.getIntPref("extensions.torbutton.loglevel");
+  this.logmethod = Services.prefs.getIntPref("extensions.torbutton.logmethod");
+
+  try {
+    var logMngr = Cc["@mozmonkey.com/debuglogger/manager;1"].getService(
+      Ci.nsIDebugLoggerManager
+    );
+    this._debuglog = logMngr.registerLogger("torbutton");
+  } catch (exErr) {
+    this._debuglog = false;
+  }
+  this._console = Services.console;
 
-    // This JSObject is exported directly to chrome
-    this.wrappedJSObject = this;
-    this.log(3, "Torbutton debug output ready");
+  // This JSObject is exported directly to chrome
+  this.wrappedJSObject = this;
+  this.log(3, "Torbutton debug output ready");
 }
 
 /**
@@ -49,18 +52,16 @@ function TorbuttonLogger() {
 
 const nsIClassInfo = Ci.nsIClassInfo;
 
-const logString = { 1:"VERB", 2:"DBUG", 3: "INFO", 4:"NOTE", 5:"WARN" };
+const logString = { 1: "VERB", 2: "DBUG", 3: "INFO", 4: "NOTE", 5: "WARN" };
 
-function padInt(i)
-{
-    return (i < 10) ? '0' + i : i;
+function padInt(i) {
+  return i < 10 ? "0" + i : i;
 }
 
-TorbuttonLogger.prototype =
-{
+TorbuttonLogger.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.nsIClassInfo]),
 
-  wrappedJSObject: null,  // Initialized by constructor
+  wrappedJSObject: null, // Initialized by constructor
 
   // make this an nsIClassInfo object
   flags: nsIClassInfo.DOM_OBJECT,
@@ -71,62 +72,78 @@ TorbuttonLogger.prototype =
   contractID: kMODULE_CONTRACTID,
 
   // method of nsIClassInfo
-  getInterfaces: function(count) {
+  getInterfaces(count) {
     var interfaceList = [nsIClassInfo];
     count.value = interfaceList.length;
     return interfaceList;
   },
 
   // method of nsIClassInfo
-  getHelperForLanguage: function(count) { return null; },
+  getHelperForLanguage(count) {
+    return null;
+  },
 
-  formatLog: function(str, level) {
-      var d = new Date();
-      var now = padInt(d.getUTCMonth()+1)+"-"+padInt(d.getUTCDate())+" "+padInt(d.getUTCHours())+":"+padInt(d.getUTCMinutes())+":"+padInt(d.getUTCSeconds());
-      return "["+now+"] Torbutton "+logString[level]+": "+str;
+  formatLog(str, level) {
+    var d = new Date();
+    var now =
+      padInt(d.getUTCMonth() + 1) +
+      "-" +
+      padInt(d.getUTCDate()) +
+      " " +
+      padInt(d.getUTCHours()) +
+      ":" +
+      padInt(d.getUTCMinutes()) +
+      ":" +
+      padInt(d.getUTCSeconds());
+    return "[" + now + "] Torbutton " + logString[level] + ": " + str;
   },
 
   // error console log
-  eclog: function(level, str) {
-      switch(this.logmethod) {
-          case 0: // stderr
-              if(this.loglevel <= level)
-                  dump(this.formatLog(str, level)+"\n");
-              break;
-          default: // errorconsole
-              if(this.loglevel <= level)
-                  this._console.logStringMessage(this.formatLog(str,level));
-              break;
-      }
+  eclog(level, str) {
+    switch (this.logmethod) {
+      case 0: // stderr
+        if (this.loglevel <= level) {
+          dump(this.formatLog(str, level) + "\n");
+        }
+        break;
+      default:
+        // errorconsole
+        if (this.loglevel <= level) {
+          this._console.logStringMessage(this.formatLog(str, level));
+        }
+        break;
+    }
   },
 
-  safe_log: function(level, str, scrub) {
-      if (this.loglevel < 4) {
-          this.eclog(level, str+scrub);
-      } else {
-          this.eclog(level, str+" [scrubbed]");
-      }
+  safe_log(level, str, scrub) {
+    if (this.loglevel < 4) {
+      this.eclog(level, str + scrub);
+    } else {
+      this.eclog(level, str + " [scrubbed]");
+    }
   },
 
-  log: function(level, str) {
-      switch(this.logmethod) {
-          case 2: // debuglogger
-              if(this._debuglog) {
-                  this._debuglog.log((6-level), this.formatLog(str,level));
-                  break;
-              }
-              // fallthrough
-          case 0: // stderr
-              if(this.loglevel <= level) 
-                  dump(this.formatLog(str,level)+"\n");
-              break;
-          default:
-              dump("Bad log method: "+this.logmethod);
-          case 1: // errorconsole
-              if(this.loglevel <= level)
-                  this._console.logStringMessage(this.formatLog(str,level));
-              break;
-      }
+  log(level, str) {
+    switch (this.logmethod) {
+      case 2: // debuglogger
+        if (this._debuglog) {
+          this._debuglog.log(6 - level, this.formatLog(str, level));
+          break;
+        }
+      // fallthrough
+      case 0: // stderr
+        if (this.loglevel <= level) {
+          dump(this.formatLog(str, level) + "\n");
+        }
+        break;
+      case 1: // errorconsole
+        if (this.loglevel <= level) {
+          this._console.logStringMessage(this.formatLog(str, level));
+        }
+        break;
+      default:
+        dump("Bad log method: " + this.logmethod);
+    }
   },
 
   // Pref observer interface implementation
@@ -134,29 +151,33 @@ TorbuttonLogger.prototype =
   // topic:   what event occurred
   // subject: what nsIPrefBranch we're observing
   // data:    which pref has been changed (relative to subject)
-  observe: function(subject, topic, data)
-  {
-      if (topic != "nsPref:changed") return;
-      switch (data) {
-          case "extensions.torbutton.logmethod":
-              this.logmethod = Services.prefs.getIntPref("extensions.torbutton.logmethod");
-              if (this.logmethod === 0) {
-                Services.prefs.setBoolPref("browser.dom.window.dump.enabled",
-                  true);
-              } else if (Services.prefs.
-                getIntPref("extensions.torlauncher.logmethod", 3) !== 0) {
-                // If Tor Launcher is not available or its log method is not 0
-                // then let's reset the dump pref.
-                Services.prefs.setBoolPref("browser.dom.window.dump.enabled",
-                  false);
-              }
-              break;
-          case "extensions.torbutton.loglevel":
-              this.loglevel = Services.prefs.getIntPref("extensions.torbutton.loglevel");
-              break;
-      }
-  }
-}
+  observe(subject, topic, data) {
+    if (topic != "nsPref:changed") {
+      return;
+    }
+    switch (data) {
+      case "extensions.torbutton.logmethod":
+        this.logmethod = Services.prefs.getIntPref(
+          "extensions.torbutton.logmethod"
+        );
+        if (this.logmethod === 0) {
+          Services.prefs.setBoolPref("browser.dom.window.dump.enabled", true);
+        } else if (
+          Services.prefs.getIntPref("extensions.torlauncher.logmethod", 3) !== 0
+        ) {
+          // If Tor Launcher is not available or its log method is not 0
+          // then let's reset the dump pref.
+          Services.prefs.setBoolPref("browser.dom.window.dump.enabled", false);
+        }
+        break;
+      case "extensions.torbutton.loglevel":
+        this.loglevel = Services.prefs.getIntPref(
+          "extensions.torbutton.loglevel"
+        );
+        break;
+    }
+  },
+};
 
 // Assign factory to global object.
 const NSGetFactory = XPCOMUtils.generateNSGetFactory
diff --git a/modules/tor-control-port.js b/modules/tor-control-port.js
index 51ac8ac0..dc59c8da 100644
--- a/modules/tor-control-port.js
+++ b/modules/tor-control-port.js
@@ -20,27 +20,24 @@
 
 /* jshint esnext: true */
 /* jshint -W097 */
-/* global Components, console, Services */
+/* global console */
 "use strict";
 
-// ### Mozilla Abbreviations
-let { Constructor: CC } = Components;
-
 // ### Import Mozilla Services
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 const { TorProtocolService, TorProcessStatus } = ChromeUtils.import(
-    "resource:///modules/TorProtocolService.jsm"
+  "resource:///modules/TorProtocolService.jsm"
 );
 // tor-launcher observer topics
 const TorTopics = Object.freeze({
-    ProcessIsReady: "TorProcessIsReady",
+  ProcessIsReady: "TorProcessIsReady",
 });
 
 // __log__.
 // Logging function
-let logger = Cc["@torproject.org/torbutton-logger;1"]
-               .getService(Ci.nsISupports).wrappedJSObject;
+let logger = Cc["@torproject.org/torbutton-logger;1"].getService(Ci.nsISupports)
+  .wrappedJSObject;
 let log = x => logger.eclog(3, x.trimRight().replace(/\r\n/g, "\n"));
 
 // ### announce this file
@@ -48,19 +45,26 @@ log("Loading tor-control-port.js\n");
 
 class AsyncSocket {
   constructor(ipcFile, host, port) {
-    let sts = Cc["@mozilla.org/network/socket-transport-service;1"].getService(Ci.nsISocketTransportService);
+    let sts = Cc["@mozilla.org/network/socket-transport-service;1"].getService(
+      Ci.nsISocketTransportService
+    );
     const OPEN_UNBUFFERED = Ci.nsITransport.OPEN_UNBUFFERED;
 
-    let socketTransport = ipcFile ?
-                          sts.createUnixDomainTransport(ipcFile) :
-                          sts.createTransport([], host, port, null, null);
-
+    let socketTransport = ipcFile
+      ? sts.createUnixDomainTransport(ipcFile)
+      : sts.createTransport([], host, port, null, null);
 
-    this.outputStream = socketTransport.openOutputStream(OPEN_UNBUFFERED, 1, 1).QueryInterface(Ci.nsIAsyncOutputStream);
+    this.outputStream = socketTransport
+      .openOutputStream(OPEN_UNBUFFERED, 1, 1)
+      .QueryInterface(Ci.nsIAsyncOutputStream);
     this.outputQueue = [];
 
-    this.inputStream = socketTransport.openInputStream(OPEN_UNBUFFERED, 1, 1).QueryInterface(Ci.nsIAsyncInputStream);
-    this.scriptableInputStream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream);
+    this.inputStream = socketTransport
+      .openInputStream(OPEN_UNBUFFERED, 1, 1)
+      .QueryInterface(Ci.nsIAsyncInputStream);
+    this.scriptableInputStream = Cc[
+      "@mozilla.org/scriptableinputstream;1"
+    ].createInstance(Ci.nsIScriptableInputStream);
     this.scriptableInputStream.init(this.inputStream);
     this.inputQueue = [];
   }
@@ -68,13 +72,15 @@ class AsyncSocket {
   // asynchronously write string to underlying socket and return number of bytes written
   async write(str) {
     return new Promise((resolve, reject) => {
-
       // asyncWait next write request
       const tryAsyncWait = () => {
-        if (this.outputQueue.length > 0) {
+        if (this.outputQueue.length) {
           this.outputStream.asyncWait(
             this.outputQueue.at(0), // next request
-            0, 0, Services.tm.currentThread);
+            0,
+            0,
+            Services.tm.currentThread
+          );
         }
       };
 
@@ -98,7 +104,7 @@ class AsyncSocket {
             // reject promise on error
             reject(err);
           }
-        }
+        },
       });
 
       // length 1 imples that there is no in-flight asyncWait, so we may immediately
@@ -112,20 +118,24 @@ class AsyncSocket {
   // asynchronously read string from underlying socket and return it
   async read() {
     return new Promise((resolve, reject) => {
-
       const tryAsyncWait = () => {
-        if (this.inputQueue.length > 0) {
+        if (this.inputQueue.length) {
           this.inputStream.asyncWait(
-            this.inputQueue.at(0),  // next input request
-            0, 0, Services.tm.currentThread);
+            this.inputQueue.at(0), // next input request
+            0,
+            0,
+            Services.tm.currentThread
+          );
         }
       };
 
       this.inputQueue.push({
-        onInputStreamReady: (stream) => {
+        onInputStreamReady: stream => {
           try {
             // read our string from input stream
-            let str = this.scriptableInputStream.read(this.scriptableInputStream.available());
+            let str = this.scriptableInputStream.read(
+              this.scriptableInputStream.available()
+            );
 
             // remove this callback object from queue now that we have read
             this.inputQueue.shift();
@@ -138,7 +148,7 @@ class AsyncSocket {
           } catch (err) {
             reject(err);
           }
-        }
+        },
       });
 
       // length 1 imples that there is no in-flight asyncWait, so we may immediately
@@ -153,7 +163,7 @@ class AsyncSocket {
     this.outputStream.close();
     this.inputStream.close();
   }
-};
+}
 
 class ControlSocket {
   constructor(asyncSocket) {
@@ -165,9 +175,15 @@ class ControlSocket {
     this.mainDispatcher = io.callbackDispatcher();
     this.notificationDispatcher = io.callbackDispatcher();
     // mainDispatcher pushes only async notifications (650) to notificationDispatcher
-    this.mainDispatcher.addCallback(/^650/, this._handleNotification.bind(this));
+    this.mainDispatcher.addCallback(
+      /^650/,
+      this._handleNotification.bind(this)
+    );
     // callback for handling responses and errors
-    this.mainDispatcher.addCallback(/^[245]\d\d/, this._handleCommandReply.bind(this) );
+    this.mainDispatcher.addCallback(
+      /^[245]\d\d/,
+      this._handleCommandReply.bind(this)
+    );
 
     this.commandQueue = [];
 
@@ -178,7 +194,7 @@ class ControlSocket {
   // immediately returns next line in queue (pendingLines) if present
   async _readLine() {
     // keep reading from socket until we have a full line to return
-    while(this.pendingLines.length == 0) {
+    while (!this.pendingLines.length) {
       // read data from our socket and spit on newline tokens
       this.pendingData += await this.socket.read();
       let lines = this.pendingData.split("\r\n");
@@ -189,7 +205,6 @@ class ControlSocket {
 
       // copy remaining full lines to our pendingLines list
       this.pendingLines = this.pendingLines.concat(lines);
-
     }
     return this.pendingLines.shift();
   }
@@ -216,23 +231,24 @@ class ControlSocket {
         // and waiting for a terminating "." on its own line.
         // (See control-spec section 3.9 and https://trac.torproject.org/16990#comment:28
         // Ensure this is the first line of a new message
+        // eslint-disable-next-line no-lonely-if
         if (message.length === 1 && line.match(/^\d\d\d\+.+?=$/)) {
           handlingMultlineValue = true;
         }
         // look for end of message (note the space character at end of the regex)
-        else if(line.match(/^\d\d\d /)) {
+        else if (line.match(/^\d\d\d /)) {
           if (message.length == 1) {
             endOfMessageFound = true;
           } else {
-            let firstReplyCode = message[0].substring(0,3);
-            let lastReplyCode = line.substring(0,3);
+            let firstReplyCode = message[0].substring(0, 3);
+            let lastReplyCode = line.substring(0, 3);
             if (firstReplyCode == lastReplyCode) {
               endOfMessageFound = true;
             }
           }
         }
       }
-    } while(!endOfMessageFound);
+    } while (!endOfMessageFound);
 
     // join our lines back together to form one message
     return message.join("\r\n");
@@ -240,14 +256,14 @@ class ControlSocket {
 
   async _startMessagePump() {
     try {
-      while(true) {
+      while (true) {
         let message = await this._readMessage();
         log("controlPort >> " + message);
         this.mainDispatcher.pushMessage(message);
       }
     } catch (err) {
       this._isOpen = false;
-      for(const cmd of this.commandQueue) {
+      for (const cmd of this.commandQueue) {
         cmd.reject(err);
       }
       this.commandQueue = [];
@@ -269,9 +285,9 @@ class ControlSocket {
     // in _startMessagePump (on stream error)
     return new Promise((resolve, reject) => {
       let command = {
-        commandString: commandString,
-        resolve: resolve,
-        reject: reject,
+        commandString,
+        resolve,
+        reject,
       };
 
       this.commandQueue.push(command);
@@ -288,7 +304,7 @@ class ControlSocket {
     } else if (message.match(/^[45]/)) {
       let myErr = new Error(cmd.commandString + " -> " + message);
       // Add Tor-specific information to the Error object.
-      let idx = message.indexOf(' ');
+      let idx = message.indexOf(" ");
       if (idx > 0) {
         myErr.torStatusCode = message.substring(0, idx);
         myErr.torMessage = message.substring(idx);
@@ -297,11 +313,15 @@ class ControlSocket {
       }
       cmd.reject(myErr);
     } else {
-      cmd.reject(new Error(`ControlSocket::_handleCommandReply received unexpected message:\n----\n${message}\n----`));
+      cmd.reject(
+        new Error(
+          `ControlSocket::_handleCommandReply received unexpected message:\n----\n${message}\n----`
+        )
+      );
     }
 
     // send next command if one is available
-    if (this.commandQueue.length > 0) {
+    if (this.commandQueue.length) {
       this._writeNextCommand();
     }
   }
@@ -322,7 +342,7 @@ class ControlSocket {
   isOpen() {
     return this._isOpen;
   }
-};
+}
 
 // ## io
 // I/O utilities namespace
@@ -336,28 +356,33 @@ let io = {};
 // Pass pushMessage to another function that needs a callback with a single string
 // argument. Whenever dispatcher.pushMessage receives a string, the dispatcher will
 // check for any regex matches and pass the string on to the corresponding callback(s).
-io.callbackDispatcher = function () {
+io.callbackDispatcher = function() {
   let callbackPairs = [],
-      removeCallback = function (aCallback) {
-        callbackPairs = callbackPairs.filter(function ([regex, callback]) {
-          return callback !== aCallback;
-        });
-      },
-      addCallback = function (regex, callback) {
-        if (callback) {
-          callbackPairs.push([regex, callback]);
-        }
-        return function () { removeCallback(callback); };
-      },
-      pushMessage = function (message) {
-        for (let [regex, callback] of callbackPairs) {
-          if (message.match(regex)) {
-            callback(message);
-          }
-        }
+    removeCallback = function(aCallback) {
+      callbackPairs = callbackPairs.filter(function([regex, callback]) {
+        return callback !== aCallback;
+      });
+    },
+    addCallback = function(regex, callback) {
+      if (callback) {
+        callbackPairs.push([regex, callback]);
+      }
+      return function() {
+        removeCallback(callback);
       };
-  return { pushMessage : pushMessage, removeCallback : removeCallback,
-           addCallback : addCallback };
+    },
+    pushMessage = function(message) {
+      for (let [regex, callback] of callbackPairs) {
+        if (message.match(regex)) {
+          callback(message);
+        }
+      }
+    };
+  return {
+    pushMessage,
+    removeCallback,
+    addCallback,
+  };
 };
 
 // __io.controlSocket(ipcFile, host, port, password)__.
@@ -374,7 +399,7 @@ io.callbackDispatcher = function () {
 //     socket.removeNotificationCallback(callback);
 //     // Close the socket permanently
 //     socket.close();
-io.controlSocket = async function (ipcFile, host, port, password) {
+io.controlSocket = async function(ipcFile, host, port, password) {
   let socket = new AsyncSocket(ipcFile, host, port);
   let controlSocket = new ControlSocket(socket);
 
@@ -392,21 +417,23 @@ let utils = {};
 
 // __utils.identity(x)__.
 // Returns its argument unchanged.
-utils.identity = function (x) { return x; };
+utils.identity = function(x) {
+  return x;
+};
 
 // __utils.isString(x)__.
 // Returns true iff x is a string.
-utils.isString = function (x) {
-  return typeof(x) === 'string' || x instanceof String;
+utils.isString = function(x) {
+  return typeof x === "string" || x instanceof String;
 };
 
 // __utils.capture(string, regex)__.
 // Takes a string and returns an array of capture items, where regex must have a single
 // capturing group and use the suffix /.../g to specify a global search.
-utils.capture = function (string, regex) {
+utils.capture = function(string, regex) {
   let matches = [];
   // Special trick to use string.replace for capturing multiple matches.
-  string.replace(regex, function (a, captured) {
+  string.replace(regex, function(a, captured) {
     matches.push(captured);
   });
   return matches;
@@ -415,15 +442,17 @@ utils.capture = function (string, regex) {
 // __utils.extractor(regex)__.
 // Returns a function that takes a string and returns an array of regex matches. The
 // regex must use the suffix /.../g to specify a global search.
-utils.extractor = function (regex) {
-  return function (text) {
+utils.extractor = function(regex) {
+  return function(text) {
     return utils.capture(text, regex);
   };
 };
 
 // __utils.splitLines(string)__.
 // Splits a string into an array of strings, each corresponding to a line.
-utils.splitLines = function (string) { return string.split(/\r?\n/); };
+utils.splitLines = function(string) {
+  return string.split(/\r?\n/);
+};
 
 // __utils.splitAtSpaces(string)__.
 // Splits a string into chunks between spaces. Does not split at spaces
@@ -433,11 +462,14 @@ utils.splitAtSpaces = utils.extractor(/((\S*?"(.*?)")+\S*|\S+)/g);
 // __utils.splitAtFirst(string, regex)__.
 // Splits a string at the first instance of regex match. If no match is
 // found, returns the whole string.
-utils.splitAtFirst = function (string, regex) {
+utils.splitAtFirst = function(string, regex) {
   let match = string.match(regex);
-  return match ? [ string.substring(0, match.index),
-                   string.substring(match.index + match[0].length) ]
-               : string;
+  return match
+    ? [
+        string.substring(0, match.index),
+        string.substring(match.index + match[0].length),
+      ]
+    : string;
 };
 
 // __utils.splitAtEquals(string)__.
@@ -448,7 +480,7 @@ utils.splitAtEquals = utils.extractor(/(([^=]*?"(.*?)")+[^=]*|[^=]+)/g);
 // __utils.mergeObjects(arrayOfObjects)__.
 // Takes an array of objects like [{"a":"b"},{"c":"d"}] and merges to a single object.
 // Pure function.
-utils.mergeObjects = function (arrayOfObjects) {
+utils.mergeObjects = function(arrayOfObjects) {
   let result = {};
   for (let obj of arrayOfObjects) {
     for (let key in obj) {
@@ -468,10 +500,10 @@ utils.mergeObjects = function (arrayOfObjects) {
 //                       ["streamID", "event", "circuitID", "IP"])
 //     // --> {"streamID" : "40", "event" : "FAILED", "circuitID" : "0",
 //     //      "address" : "95.78.59.36:80", "REASON" : "CANT_ATTACH"}"
-utils.listMapData = function (parameterString, listNames) {
+utils.listMapData = function(parameterString, listNames) {
   // Split out the space-delimited parameters.
   let parameters = utils.splitAtSpaces(parameterString),
-      dataMap = {};
+    dataMap = {};
   // Assign listNames to the first n = listNames.length parameters.
   for (let i = 0; i < listNames.length; ++i) {
     dataMap[listNames[i]] = parameters[i];
@@ -506,13 +538,15 @@ let info = {};
 // or single-line (with a `250-` or `250 ` prefix):
 //
 //     250-version=0.2.6.0-alpha-dev (git-b408125288ad6943)
-info.keyValueStringsFromMessage = utils.extractor(/^(250\+[\s\S]+?^\.|250[- ].+?)$/gmi);
+info.keyValueStringsFromMessage = utils.extractor(
+  /^(250\+[\s\S]+?^\.|250[- ].+?)$/gim
+);
 
 // __info.applyPerLine(transformFunction)__.
 // Returns a function that splits text into lines,
 // and applies transformFunction to each line.
-info.applyPerLine = function (transformFunction) {
-  return function (text) {
+info.applyPerLine = function(transformFunction) {
+  return function(text) {
     return utils.splitLines(text.trim()).map(transformFunction);
   };
 };
@@ -521,23 +555,31 @@ info.applyPerLine = function (transformFunction) {
 // Parses a router status entry as, described in
 // https://gitweb.torproject.org/torspec.git/tree/dir-spec.txt
 // (search for "router status entry")
-info.routerStatusParser = function (valueString) {
+info.routerStatusParser = function(valueString) {
   let lines = utils.splitLines(valueString),
-      objects = [];
+    objects = [];
   for (let line of lines) {
     // Drop first character and grab data following it.
     let myData = line.substring(2),
-    // Accumulate more maps with data, depending on the first character in the line.
-        dataFun = {
-          "r" : data => utils.listMapData(data, ["nickname", "identity", "digest",
-                                                 "publicationDate", "publicationTime",
-                                                 "IP", "ORPort", "DirPort"]),
-          "a" : data => ({ "IPv6" :  data }),
-          "s" : data => ({ "statusFlags" : utils.splitAtSpaces(data) }),
-          "v" : data => ({ "version" : data }),
-          "w" : data => utils.listMapData(data, []),
-          "p" : data => ({ "portList" : data.split(",") }),
-        }[line.charAt(0)];
+      // Accumulate more maps with data, depending on the first character in the line.
+      dataFun = {
+        r: data =>
+          utils.listMapData(data, [
+            "nickname",
+            "identity",
+            "digest",
+            "publicationDate",
+            "publicationTime",
+            "IP",
+            "ORPort",
+            "DirPort",
+          ]),
+        a: data => ({ IPv6: data }),
+        s: data => ({ statusFlags: utils.splitAtSpaces(data) }),
+        v: data => ({ version: data }),
+        w: data => utils.listMapData(data, []),
+        p: data => ({ portList: data.split(",") }),
+      }[line.charAt(0)];
     if (dataFun !== undefined) {
       objects.push(dataFun(myData));
     }
@@ -547,12 +589,12 @@ info.routerStatusParser = function (valueString) {
 
 // __info.circuitStatusParser(line)__.
 // Parse the output of a circuit status line.
-info.circuitStatusParser = function (line) {
-  let data = utils.listMapData(line, ["id","status","circuit"]),
-      circuit = data.circuit;
+info.circuitStatusParser = function(line) {
+  let data = utils.listMapData(line, ["id", "status", "circuit"]),
+    circuit = data.circuit;
   // Parse out the individual circuit IDs and names.
   if (circuit) {
-    data.circuit = circuit.split(",").map(function (x) {
+    data.circuit = circuit.split(",").map(function(x) {
       return x.split(/~|=/);
     });
   }
@@ -561,12 +603,15 @@ info.circuitStatusParser = function (line) {
 
 // __info.streamStatusParser(line)__.
 // Parse the output of a stream status line.
-info.streamStatusParser = function (text) {
-  return utils.listMapData(text, ["StreamID", "StreamStatus",
-                                  "CircuitID", "Target"]);
+info.streamStatusParser = function(text) {
+  return utils.listMapData(text, [
+    "StreamID",
+    "StreamStatus",
+    "CircuitID",
+    "Target",
+  ]);
 };
 
-
 // TODO: fix this parsing logic to handle bridgeLine correctly
 // fingerprint/id is an optional parameter
 // __info.bridgeParser(bridgeLine)__.
@@ -574,16 +619,26 @@ info.streamStatusParser = function (text) {
 // a map containing the bridge's type, address, and ID.
 info.bridgeParser = function(bridgeLine) {
   let result = {},
-      tokens = bridgeLine.split(/\s+/);
+    tokens = bridgeLine.split(/\s+/);
   // First check if we have a "vanilla" bridge:
   if (tokens[0].match(/^\d+\.\d+\.\d+\.\d+/)) {
     result.type = "vanilla";
     [result.address, result.ID] = tokens;
-  // Several bridge types have a similar format:
+    // Several bridge types have a similar format:
   } else {
     result.type = tokens[0];
-    if (["flashproxy", "fte", "meek", "meek_lite", "obfs3", "obfs4", "scramblesuit",
-          "snowflake"].indexOf(result.type) >= 0) {
+    if (
+      [
+        "flashproxy",
+        "fte",
+        "meek",
+        "meek_lite",
+        "obfs3",
+        "obfs4",
+        "scramblesuit",
+        "snowflake",
+      ].includes(result.type)
+    ) {
       [result.address, result.ID] = tokens.slice(1);
     }
   }
@@ -594,10 +649,10 @@ info.bridgeParser = function(bridgeLine) {
 // A map of GETINFO and GETCONF keys to parsing function, which convert
 // result strings to JavaScript data.
 info.parsers = {
-  "ns/id/" : info.routerStatusParser,
-  "ip-to-country/" : utils.identity,
-  "circuit-status" : info.applyPerLine(info.circuitStatusParser),
-  "bridge" : info.bridgeParser,
+  "ns/id/": info.routerStatusParser,
+  "ip-to-country/": utils.identity,
+  "circuit-status": info.applyPerLine(info.circuitStatusParser),
+  bridge: info.bridgeParser,
   // Currently unused parsers:
   //  "ns/name/" : info.routerStatusParser,
   //  "stream-status" : info.applyPerLine(info.streamStatusParser),
@@ -609,26 +664,31 @@ info.parsers = {
 // Takes a key and determines the parser function that should be used to
 // convert its corresponding valueString to JavaScript data.
 info.getParser = function(key) {
-  return info.parsers[key] ||
-         info.parsers[key.substring(0, key.lastIndexOf("/") + 1)];
+  return (
+    info.parsers[key] ||
+    info.parsers[key.substring(0, key.lastIndexOf("/") + 1)]
+  );
 };
 
 // __info.stringToValue(string)__.
 // Converts a key-value string as from GETINFO or GETCONF to a value.
-info.stringToValue = function (string) {
+info.stringToValue = function(string) {
   // key should look something like `250+circuit-status=` or `250-circuit-status=...`
   // or `250 circuit-status=...`
   let matchForKey = string.match(/^250[ +-](.+?)=/),
-      key = matchForKey ? matchForKey[1] : null;
-  if (key === null) return null;
+    key = matchForKey ? matchForKey[1] : null;
+  if (key === null) {
+    return null;
+  }
   // matchResult finds a single-line result for `250-` or `250 `,
   // or a multi-line one for `250+`.
-  let matchResult = string.match(/^250[ -].+?=(.*)$/) ||
-                    string.match(/^250\+.+?=([\s\S]*?)^\.$/m),
-      // Retrieve the captured group (the text of the value in the key-value pair)
-      valueString = matchResult ? matchResult[1] : null,
-      // Get the parser function for the key found.
-      parse = info.getParser(key.toLowerCase());
+  let matchResult =
+      string.match(/^250[ -].+?=(.*)$/) ||
+      string.match(/^250\+.+?=([\s\S]*?)^\.$/m),
+    // Retrieve the captured group (the text of the value in the key-value pair)
+    valueString = matchResult ? matchResult[1] : null,
+    // Get the parser function for the key found.
+    parse = info.getParser(key.toLowerCase());
   if (parse === undefined) {
     throw new Error("No parser found for '" + key + "'");
   }
@@ -638,15 +698,16 @@ info.stringToValue = function (string) {
 
 // __info.getMultipleResponseValues(message)__.
 // Process multiple responses to a GETINFO or GETCONF request.
-info.getMultipleResponseValues = function (message) {
-  return info.keyValueStringsFromMessage(message)
-             .map(info.stringToValue)
-             .filter(utils.identity);
+info.getMultipleResponseValues = function(message) {
+  return info
+    .keyValueStringsFromMessage(message)
+    .map(info.stringToValue)
+    .filter(utils.identity);
 };
 
 // __info.getInfo(controlSocket, key)__.
 // Sends GETINFO for a single key. Returns a promise with the result.
-info.getInfo = function (aControlSocket, key) {
+info.getInfo = function(aControlSocket, key) {
   if (!utils.isString(key)) {
     return utils.rejectPromise("key argument should be a string");
   }
@@ -657,7 +718,7 @@ info.getInfo = function (aControlSocket, key) {
 
 // __info.getConf(aControlSocket, key)__.
 // Sends GETCONF for a single key. Returns a promise with the result.
-info.getConf = function (aControlSocket, key) {
+info.getConf = function(aControlSocket, key) {
   // GETCONF with a single argument returns results with
   // one or more lines that look like `250[- ]key=value`.
   // Any GETCONF lines that contain a single keyword only are currently dropped.
@@ -665,21 +726,23 @@ info.getConf = function (aControlSocket, key) {
   if (!utils.isString(key)) {
     return utils.rejectPromise("key argument should be a string");
   }
-  return aControlSocket.sendCommand("getconf " + key)
-                       .then(info.getMultipleResponseValues);
+  return aControlSocket
+    .sendCommand("getconf " + key)
+    .then(info.getMultipleResponseValues);
 };
 
 // ## onionAuth
 // A namespace for functions related to tor's ONION_CLIENT_AUTH_* commands.
 let onionAuth = {};
 
-onionAuth.keyInfoStringsFromMessage = utils.extractor(/^250-CLIENT\s+(.+)$/gmi);
+onionAuth.keyInfoStringsFromMessage = utils.extractor(/^250-CLIENT\s+(.+)$/gim);
 
 onionAuth.keyInfoObjectsFromMessage = function(message) {
   let keyInfoStrings = onionAuth.keyInfoStringsFromMessage(message);
-  return keyInfoStrings.map(infoStr => utils.listMapData(infoStr,
-                                            ["hsAddress", "typeAndKey"]));
-}
+  return keyInfoStrings.map(infoStr =>
+    utils.listMapData(infoStr, ["hsAddress", "typeAndKey"])
+  );
+};
 
 // __onionAuth.viewKeys()__.
 // Sends a ONION_CLIENT_AUTH_VIEW command to retrieve the list of private keys.
@@ -688,16 +751,22 @@ onionAuth.keyInfoObjectsFromMessage = function(message) {
 //   hsAddress
 //   typeAndKey
 //   Flags (e.g., "Permanent")
-onionAuth.viewKeys = function (aControlSocket) {
+onionAuth.viewKeys = function(aControlSocket) {
   let cmd = "onion_client_auth_view";
-  return aControlSocket.sendCommand(cmd).then(onionAuth.keyInfoObjectsFromMessage);
+  return aControlSocket
+    .sendCommand(cmd)
+    .then(onionAuth.keyInfoObjectsFromMessage);
 };
 
 // __onionAuth.add(controlSocket, hsAddress, b64PrivateKey, isPermanent)__.
 // Sends a ONION_CLIENT_AUTH_ADD command to add a private key to the
 // Tor configuration.
-onionAuth.add = function (aControlSocket, hsAddress, b64PrivateKey,
-                          isPermanent) {
+onionAuth.add = function(
+  aControlSocket,
+  hsAddress,
+  b64PrivateKey,
+  isPermanent
+) {
   if (!utils.isString(hsAddress)) {
     return utils.rejectPromise("hsAddress argument should be a string");
   }
@@ -708,15 +777,16 @@ onionAuth.add = function (aControlSocket, hsAddress, b64PrivateKey,
 
   const keyType = "x25519";
   let cmd = `onion_client_auth_add ${hsAddress} ${keyType}:${b64PrivateKey}`;
-  if (isPermanent)
+  if (isPermanent) {
     cmd += " Flags=Permanent";
+  }
   return aControlSocket.sendCommand(cmd);
 };
 
 // __onionAuth.remove(controlSocket, hsAddress)__.
 // Sends a ONION_CLIENT_AUTH_REMOVE command to remove a private key from the
 // Tor configuration.
-onionAuth.remove = function (aControlSocket, hsAddress) {
+onionAuth.remove = function(aControlSocket, hsAddress) {
   if (!utils.isString(hsAddress)) {
     return utils.rejectPromise("hsAddress argument should be a string");
   }
@@ -725,7 +795,6 @@ onionAuth.remove = function (aControlSocket, hsAddress) {
   return aControlSocket.sendCommand(cmd);
 };
 
-
 // ## event
 // Handlers for events
 
@@ -735,7 +804,7 @@ let event = {};
 // A map of EVENT keys to parsing functions, which convert result strings to JavaScript
 // data.
 event.parsers = {
-  "stream" : info.streamStatusParser,
+  stream: info.streamStatusParser,
   // Currently unused:
   // "circ" : info.circuitStatusParser,
 };
@@ -743,9 +812,11 @@ event.parsers = {
 // __event.messageToData(type, message)__.
 // Extract the data from an event. Note, at present
 // we only extract streams that look like `"650" SP...`
-event.messageToData = function (type, message) {
+event.messageToData = function(type, message) {
   let dataText = message.match(/^650 \S+?\s(.*)/m)[1];
-  return (dataText && type.toLowerCase() in event.parsers) ? event.parsers[type.toLowerCase()](dataText) : null;
+  return dataText && type.toLowerCase() in event.parsers
+    ? event.parsers[type.toLowerCase()](dataText)
+    : null;
 };
 
 // __event.watchEvent(controlSocket, type, filter, onData)__.
@@ -753,17 +824,20 @@ event.messageToData = function (type, message) {
 // data is passed to the onData callback. Returns a zero arg function that
 // stops watching the event. Note: we only observe `"650" SP...` events
 // currently (no `650+...` or `650-...` events).
-event.watchEvent = function (controlSocket, type, filter, onData, raw=false) {
-  return controlSocket.addNotificationCallback(new RegExp("^650 " + type),
-    function (message) {
+event.watchEvent = function(controlSocket, type, filter, onData, raw = false) {
+  return controlSocket.addNotificationCallback(
+    new RegExp("^650 " + type),
+    function(message) {
       let data = event.messageToData(type, message);
       if (filter === null || filter(data)) {
         if (raw || !data) {
-          return onData(message);
+          onData(message);
+          return;
         }
         onData(data);
       }
-    });
+    }
+  );
 };
 
 // ## tor
@@ -778,22 +852,23 @@ tor.controllerCache = new Map();
 // __tor.controller(ipcFile, host, port, password)__.
 // Creates a tor controller at the given ipcFile or host and port, with the
 // given password.
-tor.controller = async function (ipcFile, host, port, password) {
+tor.controller = async function(ipcFile, host, port, password) {
   let socket = await io.controlSocket(ipcFile, host, port, password);
-  return { getInfo : key => info.getInfo(socket, key),
-           getConf : key => info.getConf(socket, key),
-           onionAuthViewKeys : () => onionAuth.viewKeys(socket),
-           onionAuthAdd : (hsAddress, b64PrivateKey, isPermanent) =>
-                            onionAuth.add(socket, hsAddress, b64PrivateKey,
-                                          isPermanent),
-           onionAuthRemove : (hsAddress) =>
-                               onionAuth.remove(socket, hsAddress),
-           watchEvent : (type, filter, onData, raw=false) =>
-                          event.watchEvent(socket, type, filter, onData, raw),
-           isOpen : () => socket.isOpen(),
-           close : () => { socket.close(); },
-           sendCommand: cmd => socket.sendCommand(cmd),
-         };
+  return {
+    getInfo: key => info.getInfo(socket, key),
+    getConf: key => info.getConf(socket, key),
+    onionAuthViewKeys: () => onionAuth.viewKeys(socket),
+    onionAuthAdd: (hsAddress, b64PrivateKey, isPermanent) =>
+      onionAuth.add(socket, hsAddress, b64PrivateKey, isPermanent),
+    onionAuthRemove: hsAddress => onionAuth.remove(socket, hsAddress),
+    watchEvent: (type, filter, onData, raw = false) =>
+      event.watchEvent(socket, type, filter, onData, raw),
+    isOpen: () => socket.isOpen(),
+    close: () => {
+      socket.close();
+    },
+    sendCommand: cmd => socket.sendCommand(cmd),
+  };
 };
 
 // ## Export
@@ -804,7 +879,7 @@ let controlPortInfo = {};
 // Sets Tor control port connection parameters to be used in future calls to
 // the controller() function. Example:
 //     configureControlPortModule(undefined, "127.0.0.1", 9151, "MyPassw0rd");
-var configureControlPortModule = function (ipcFile, host, port, password) {
+var configureControlPortModule = function(ipcFile, host, port, password) {
   controlPortInfo.ipcFile = ipcFile;
   controlPortInfo.host = host;
   controlPortInfo.port = port || 9151;
@@ -827,28 +902,28 @@ var configureControlPortModule = function (ipcFile, host, port, password) {
 //     let replyPromise = c.getInfo("ip-to-country/16.16.16.16");
 //     // Close the controller permanently
 //     c.close();
-var controller = async function (avoidCache) {
-
-  if (!controlPortInfo.ipcFile && !controlPortInfo.host)
+var controller = async function(avoidCache) {
+  if (!controlPortInfo.ipcFile && !controlPortInfo.host) {
     throw new Error("Please call configureControlPortModule first");
+  }
 
-  const dest = (controlPortInfo.ipcFile)
-               ? `unix:${controlPortInfo.ipcFile.path}`
-               : `${controlPortInfo.host}:${controlPortInfo.port}`;
+  const dest = controlPortInfo.ipcFile
+    ? `unix:${controlPortInfo.ipcFile.path}`
+    : `${controlPortInfo.host}:${controlPortInfo.port}`;
 
   // constructor shorthand
-  const newTorController =
-    async () => {
-      return await tor.controller(
-        controlPortInfo.ipcFile,
-        controlPortInfo.host,
-        controlPortInfo.port,
-        controlPortInfo.password);
-    };
+  const newTorController = async () => {
+    return tor.controller(
+      controlPortInfo.ipcFile,
+      controlPortInfo.host,
+      controlPortInfo.port,
+      controlPortInfo.password
+    );
+  };
 
   // avoid cache so always return a new controller
   if (avoidCache) {
-    return await newTorController();
+    return newTorController();
   }
 
   // first check our cache and see if we already have one
@@ -872,17 +947,19 @@ var controller = async function (avoidCache) {
 // Same as controller() function, but explicitly waits until there is a tor daemon
 // to connect to (either launched by tor-launcher, or if we have an existing system
 // tor daemon)
-var wait_for_controller = async function(avoidCache) {
+var wait_for_controller = function(avoidCache) {
   // if tor process is running (either ours or system) immediately return controller
-  if (!TorProtocolService.ownsTorDaemon ||
-      TorProtocolService.torProcessStatus == TorProcessStatus.Running) {
-      return await controller(avoidCache);
+  if (
+    !TorProtocolService.ownsTorDaemon ||
+    TorProtocolService.torProcessStatus == TorProcessStatus.Running
+  ) {
+    return controller(avoidCache);
   }
 
   // otherwise we must wait for tor to finish launching before resolving
   return new Promise((resolve, reject) => {
     let observer = {
-      observe : async (subject, topic, data) => {
+      observe: async (subject, topic, data) => {
         if (topic === TorTopics.ProcessIsReady) {
           try {
             resolve(await controller(avoidCache));
@@ -898,4 +975,8 @@ var wait_for_controller = async function(avoidCache) {
 };
 
 // Export functions for external use.
-var EXPORTED_SYMBOLS = ["configureControlPortModule", "controller", "wait_for_controller"];
+var EXPORTED_SYMBOLS = [
+  "configureControlPortModule",
+  "controller",
+  "wait_for_controller",
+];
diff --git a/modules/utils.js b/modules/utils.js
index b726342b..7ccd2da1 100644
--- a/modules/utils.js
+++ b/modules/utils.js
@@ -11,12 +11,16 @@ let prefs = Services.prefs;
 
 // __getPrefValue(prefName)__
 // Returns the current value of a preference, regardless of its type.
-var getPrefValue = function (prefName) {
-  switch(prefs.getPrefType(prefName)) {
-    case prefs.PREF_BOOL: return prefs.getBoolPref(prefName);
-    case prefs.PREF_INT: return prefs.getIntPref(prefName);
-    case prefs.PREF_STRING: return prefs.getCharPref(prefName);
-    default: return null;
+var getPrefValue = function(prefName) {
+  switch (prefs.getPrefType(prefName)) {
+    case prefs.PREF_BOOL:
+      return prefs.getBoolPref(prefName);
+    case prefs.PREF_INT:
+      return prefs.getIntPref(prefName);
+    case prefs.PREF_STRING:
+      return prefs.getCharPref(prefName);
+    default:
+      return null;
   }
 };
 
@@ -24,18 +28,24 @@ var getPrefValue = function (prefName) {
 // Applies prefHandler whenever the value of the pref changes.
 // If init is true, applies prefHandler to the current value.
 // Returns a zero-arg function that unbinds the pref.
-var bindPref = function (prefName, prefHandler, init = false) {
-  let update = () => { prefHandler(getPrefValue(prefName)); },
-      observer = { observe : function (subject, topic, data) {
-                     if (data === prefName) {
-                         update();
-                     }
-                   } };
-  prefs.addObserver(prefName, observer, false);
+var bindPref = function(prefName, prefHandler, init = false) {
+  let update = () => {
+      prefHandler(getPrefValue(prefName));
+    },
+    observer = {
+      observe(subject, topic, data) {
+        if (data === prefName) {
+          update();
+        }
+      },
+    };
+  prefs.addObserver(prefName, observer);
   if (init) {
     update();
   }
-  return () => { prefs.removeObserver(prefName, observer); };
+  return () => {
+    prefs.removeObserver(prefName, observer);
+  };
 };
 
 // __bindPrefAndInit(prefName, prefHandler)__
@@ -43,7 +53,7 @@ var bindPref = function (prefName, prefHandler, init = false) {
 // Re-applies prefHandler whenever the value of the pref changes.
 // Returns a zero-arg function that unbinds the pref.
 var bindPrefAndInit = (prefName, prefHandler) =>
-    bindPref(prefName, prefHandler, true);
+  bindPref(prefName, prefHandler, true);
 
 // ## Observers
 
@@ -51,15 +61,15 @@ var bindPrefAndInit = (prefName, prefHandler) =>
 // Observe the given topic. When notification of that topic
 // occurs, calls callback(subject, data). Returns a zero-arg
 // function that stops observing.
-var observe = function (topic, callback) {
+var observe = function(topic, callback) {
   let observer = {
-    observe: function (aSubject, aTopic, aData) {
+    observe(aSubject, aTopic, aData) {
       if (topic === aTopic) {
         callback(aSubject, aData);
       }
     },
   };
-  Services.obs.addObserver(observer, topic, false);
+  Services.obs.addObserver(observer, topic);
   return () => Services.obs.removeObserver(observer, topic);
 };
 
@@ -67,12 +77,13 @@ var observe = function (topic, callback) {
 
 // __env__.
 // Provides access to process environment variables.
-let env = Cc["@mozilla.org/process/environment;1"]
-            .getService(Ci.nsIEnvironment);
+let env = Cc["@mozilla.org/process/environment;1"].getService(
+  Ci.nsIEnvironment
+);
 
 // __getEnv(name)__.
 // Reads the environment variable of the given name.
-var getEnv = function (name) {
+var getEnv = function(name) {
   return env.exists(name) ? env.get(name) : undefined;
 };
 
@@ -91,17 +102,15 @@ let dialogsByName = {};
 // __showDialog(parent, url, name, features, arg1, arg2, ...)__.
 // Like window.openDialog, but if the window is already
 // open, just focuses it instead of opening a new one.
-var showDialog = function (parent, url, name, features) {
+var showDialog = function(parent, url, name, features) {
   let existingDialog = dialogsByName[name];
   if (existingDialog && !existingDialog.closed) {
     existingDialog.focus();
     return existingDialog;
-  } else {
-    let newDialog = parent.openDialog.apply(parent,
-                                            Array.slice(arguments, 1));
-    dialogsByName[name] = newDialog;
-    return newDialog;
   }
+  let newDialog = parent.openDialog.apply(parent, Array.slice(arguments, 1));
+  dialogsByName[name] = newDialog;
+  return newDialog;
 };
 
 // ## Tor control protocol utility functions
@@ -112,71 +121,69 @@ let _torControl = {
   // Returns the unescaped string. Throws upon failure.
   // Within Tor Launcher, the file components/tl-protocol.js also contains a
   // copy of _strUnescape().
-  _strUnescape: function(aStr)
-  {
-    if (!aStr)
+  _strUnescape(aStr) {
+    if (!aStr) {
       return aStr;
+    }
 
     var len = aStr.length;
-    if ((len < 2) || ('"' != aStr.charAt(0)) || ('"' != aStr.charAt(len - 1)))
+    if (len < 2 || '"' != aStr.charAt(0) || '"' != aStr.charAt(len - 1)) {
       return aStr;
+    }
 
     const kHexRE = /[0-9A-Fa-f]{2}/;
     const kOctalRE = /[0-7]{3}/;
     var rv = "";
     var i = 1;
     var lastCharIndex = len - 2;
-    while (i <= lastCharIndex)
-    {
+    while (i <= lastCharIndex) {
       var c = aStr.charAt(i);
-      if ('\\' == c)
-      {
-        if (++i > lastCharIndex)
+      if ("\\" == c) {
+        if (++i > lastCharIndex) {
           throw new Error("missing character after \\");
+        }
 
         c = aStr.charAt(i);
-        if ('n' == c)
-          rv += '\n';
-        else if ('r' == c)
-          rv += '\r';
-        else if ('t' == c)
-          rv += '\t';
-        else if ('x' == c)
-        {
-          if ((i + 2) > lastCharIndex)
+        if ("n" == c) {
+          rv += "\n";
+        } else if ("r" == c) {
+          rv += "\r";
+        } else if ("t" == c) {
+          rv += "\t";
+        } else if ("x" == c) {
+          if (i + 2 > lastCharIndex) {
             throw new Error("not enough hex characters");
+          }
 
           let s = aStr.substr(i + 1, 2);
-          if (!kHexRE.test(s))
+          if (!kHexRE.test(s)) {
             throw new Error("invalid hex characters");
+          }
 
           let val = parseInt(s, 16);
           rv += String.fromCharCode(val);
           i += 3;
-        }
-        else if (this._isDigit(c))
-        {
+        } else if (this._isDigit(c)) {
           let s = aStr.substr(i, 3);
-          if ((i + 2) > lastCharIndex)
+          if (i + 2 > lastCharIndex) {
             throw new Error("not enough octal characters");
+          }
 
-          if (!kOctalRE.test(s))
+          if (!kOctalRE.test(s)) {
             throw new Error("invalid octal characters");
+          }
 
           let val = parseInt(s, 8);
           rv += String.fromCharCode(val);
           i += 3;
-        }
-        else // "\\" and others
-        {
+        } // "\\" and others
+        else {
           rv += c;
           ++i;
         }
-      }
-      else if ('"' == c)
-        throw new Error("unescaped \" within string");
-      else
-      {
+      } else if ('"' == c) {
+        throw new Error('unescaped " within string');
+      } else {
         rv += c;
         ++i;
       }
@@ -188,8 +195,7 @@ let _torControl = {
 
   // Within Tor Launcher, the file components/tl-protocol.js also contains a
   // copy of _isDigit().
-  _isDigit: function(aChar)
-  {
+  _isDigit(aChar) {
     const kRE = /^\d$/;
     return aChar && kRE.test(aChar);
   },
@@ -206,30 +212,35 @@ var unescapeTorString = function(str) {
 var show_torbrowser_manual = () => {
   let availableLocales = ["de", "en", "es", "fr", "nl", "pt", "tr", "vi", "zh"];
   let shortLocale = getLocale().substring(0, 2);
-  return availableLocales.indexOf(shortLocale) >= 0;
-}
+  return availableLocales.includes(shortLocale);
+};
 
-var getFPDFromHost = (hostname) => {
+var getFPDFromHost = hostname => {
   try {
     return Services.eTLD.getBaseDomainFromHost(hostname);
   } catch (e) {
-    if (e.result == Cr.NS_ERROR_HOST_IS_IP_ADDRESS ||
-        e.result == Cr.NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
+    if (
+      e.result == Cr.NS_ERROR_HOST_IS_IP_ADDRESS ||
+      e.result == Cr.NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS
+    ) {
       return hostname;
     }
   }
   return null;
-}
+};
 
 // Assuming this is called with gBrowser.selectedBrowser
-var getDomainForBrowser = (browser) => {
+var getDomainForBrowser = browser => {
   let fpd = browser.contentPrincipal.originAttributes.firstPartyDomain;
   // Bug 31562: For neterror or certerror, get the original URL from
   // browser.currentURI and use it to calculate the firstPartyDomain.
   let knownErrors = ["about:neterror", "about:certerror"];
   let documentURI = browser.documentURI;
-  if (documentURI && documentURI.schemeIs('about') &&
-      knownErrors.some(x => documentURI.spec.startsWith(x))) {
+  if (
+    documentURI &&
+    documentURI.schemeIs("about") &&
+    knownErrors.some(x => documentURI.spec.startsWith(x))
+  ) {
     let knownSchemes = ["http", "https", "ftp"];
     let currentURI = browser.currentURI;
     if (currentURI && knownSchemes.some(x => currentURI.schemeIs(x))) {
@@ -239,58 +250,71 @@ var getDomainForBrowser = (browser) => {
   return fpd;
 };
 
-var m_tb_torlog = Cc["@torproject.org/torbutton-logger;1"]
-.getService(Ci.nsISupports).wrappedJSObject;
+var m_tb_torlog = Cc["@torproject.org/torbutton-logger;1"].getService(
+  Ci.nsISupports
+).wrappedJSObject;
 
 var m_tb_string_bundle = torbutton_get_stringbundle();
 
 function torbutton_safelog(nLevel, sMsg, scrub) {
-    m_tb_torlog.safe_log(nLevel, sMsg, scrub);
-    return true;
+  m_tb_torlog.safe_log(nLevel, sMsg, scrub);
+  return true;
 }
 
 function torbutton_log(nLevel, sMsg) {
-    m_tb_torlog.log(nLevel, sMsg);
+  m_tb_torlog.log(nLevel, sMsg);
 
-    // So we can use it in boolean expressions to determine where the
-    // short-circuit is..
-    return true;
+  // So we can use it in boolean expressions to determine where the
+  // short-circuit is..
+  return true;
 }
 
 // load localization strings
-function torbutton_get_stringbundle()
-{
-    var o_stringbundle = false;
-
-    try {
-        var oBundle = Services.strings;
-        o_stringbundle = oBundle.createBundle("chrome://torbutton/locale/torbutton.properties");
-    } catch(err) {
-        o_stringbundle = false;
-    }
-    if (!o_stringbundle) {
-        torbutton_log(5, 'ERROR (init): failed to find torbutton-bundle');
-    }
+function torbutton_get_stringbundle() {
+  var o_stringbundle = false;
 
-    return o_stringbundle;
-}
+  try {
+    var oBundle = Services.strings;
+    o_stringbundle = oBundle.createBundle(
+      "chrome://torbutton/locale/torbutton.properties"
+    );
+  } catch (err) {
+    o_stringbundle = false;
+  }
+  if (!o_stringbundle) {
+    torbutton_log(5, "ERROR (init): failed to find torbutton-bundle");
+  }
 
-function torbutton_get_property_string(propertyname)
-{
-    try {
-        if (!m_tb_string_bundle) {
-            m_tb_string_bundle = torbutton_get_stringbundle();
-        }
+  return o_stringbundle;
+}
 
-        return m_tb_string_bundle.GetStringFromName(propertyname);
-    } catch(e) {
-        torbutton_log(4, "Unlocalized string "+propertyname);
+function torbutton_get_property_string(propertyname) {
+  try {
+    if (!m_tb_string_bundle) {
+      m_tb_string_bundle = torbutton_get_stringbundle();
     }
 
-    return propertyname;
+    return m_tb_string_bundle.GetStringFromName(propertyname);
+  } catch (e) {
+    torbutton_log(4, "Unlocalized string " + propertyname);
+  }
+
+  return propertyname;
 }
 
 // Export utility functions for external use.
-let EXPORTED_SYMBOLS = ["bindPref", "bindPrefAndInit", "getEnv", "getLocale", "getDomainForBrowser",
-                        "getPrefValue", "observe", "showDialog", "show_torbrowser_manual", "unescapeTorString",
-                        "torbutton_safelog", "torbutton_log", "torbutton_get_property_string"];
+let EXPORTED_SYMBOLS = [
+  "bindPref",
+  "bindPrefAndInit",
+  "getEnv",
+  "getLocale",
+  "getDomainForBrowser",
+  "getPrefValue",
+  "observe",
+  "showDialog",
+  "show_torbrowser_manual",
+  "unescapeTorString",
+  "torbutton_safelog",
+  "torbutton_log",
+  "torbutton_get_property_string",
+];

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the tor-commits mailing list