Bug 1525190 - Manual changes to abide by eslint in chat. r=florian
authorPatrick Cloke <clokep@gmail.com>
Thu, 28 Feb 2019 09:49:44 -0500
changeset 25961 c0d2cf4f7d090db9f59dabd36beec99b3f898bb7
parent 25960 9ba93261c6b1a274d46121a7e5b8523bab728f78
child 25962 276188d87e1bddeb98705e6f949802ed3591f65f
push id15583
push userclokep@gmail.com
push dateThu, 28 Feb 2019 17:00:20 +0000
treeherdercomm-central@c0d2cf4f7d09 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersflorian
bugs1525190
Bug 1525190 - Manual changes to abide by eslint in chat. r=florian
chat/components/src/imAccounts.js
chat/components/src/imConversations.js
chat/components/src/logger.js
chat/components/src/smileProtocolHandler.js
chat/components/src/test/test_accounts.js
chat/components/src/test/test_conversations.js
chat/components/src/test/test_logger.js
chat/content/account.xml
chat/content/conversation-browser.js
chat/modules/DNS.jsm
chat/modules/ToLocaleFormat.jsm
chat/modules/imContentSink.jsm
chat/modules/imSmileys.jsm
chat/modules/imStatusUtils.jsm
chat/modules/imThemes.jsm
chat/modules/imXPCOMUtils.jsm
chat/modules/jsProtoHelper.jsm
chat/modules/socket.jsm
chat/modules/test/test_filtering.js
chat/protocols/irc/irc.js
chat/protocols/irc/ircCTCP.jsm
chat/protocols/irc/ircCommands.jsm
chat/protocols/irc/ircUtils.jsm
chat/protocols/irc/test/test_ircCommands.js
chat/protocols/xmpp/xmpp.jsm
--- a/chat/components/src/imAccounts.js
+++ b/chat/components/src/imAccounts.js
@@ -4,16 +4,17 @@
 var {
   ClassInfo,
   EmptyEnumerator,
   nsSimpleEnumerator,
   XPCOMUtils,
   setTimeout,
   clearTimeout,
   executeSoon,
+  l10nHelper,
 } = ChromeUtils.import("resource:///modules/imXPCOMUtils.jsm");
 var {Services} = ChromeUtils.import("resource:///modules/imServices.jsm");
 var {GenericAccountPrototype, GenericAccountBuddyPrototype} = ChromeUtils.import("resource:///modules/jsProtoHelper.jsm");
 
 var kPrefAutologinPending = "messenger.accounts.autoLoginPending";
 var kPrefMessengerAccounts = "messenger.accounts";
 var kPrefAccountPrefix = "messenger.account.";
 var kAccountKeyPrefix = "account";
@@ -576,21 +577,17 @@ imAccount.prototype = {
     if (aException.result != Cr.NS_ERROR_ABORT)
       throw aException;
 
     gUserCanceledMasterPasswordPrompt = true;
     executeSoon(function() { gUserCanceledMasterPasswordPrompt = false; });
   },
 
   get autoLogin() {
-    let autoLogin = true;
-    try {
-      autoLogin = this.prefBranch.getBoolPref(kPrefAccountAutoLogin);
-    } catch (e) { }
-    return autoLogin;
+    return this.prefBranch.getBoolPref(kPrefAccountAutoLogin, true);
   },
   set autoLogin(val) {
     this.prefBranch.setBoolPref(kPrefAccountAutoLogin, val);
     SavePrefTimer.initTimer();
     this._sendUpdateNotification();
   },
   _autoLoginPending: false,
   checkAutoLogin() {
--- a/chat/components/src/imConversations.js
+++ b/chat/components/src/imConversations.js
@@ -665,17 +665,17 @@ ConversationsService.prototype = {
       if (conv.id == aId)
         return conv;
     return null;
   },
   getConversationByNameAndAccount(aName, aAccount, aIsChat) {
     let normalizedName = aAccount.normalize(aName);
     for (let conv of this._prplConversations) {
       if (aAccount.normalize(conv.name) == normalizedName &&
-          aAccount.numericId == aAccount.numericId &&
+          aAccount.numericId == conv.account.numericId &&
           conv.isChat == aIsChat)
         return conv;
     }
     return null;
   },
 
   QueryInterface: ChromeUtils.generateQI([Ci.imIConversationsService]),
   classDescription: "Conversations",
--- a/chat/components/src/logger.js
+++ b/chat/components/src/logger.js
@@ -1,20 +1,25 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var CC = Components.Constructor;
 
 var {Services} = ChromeUtils.import("resource:///modules/imServices.jsm");
-var {EmptyEnumerator, XPCOMUtils} = ChromeUtils.import("resource:///modules/imXPCOMUtils.jsm");
+var {
+  EmptyEnumerator,
+  l10nHelper,
+  XPCOMUtils,
+} = ChromeUtils.import("resource:///modules/imXPCOMUtils.jsm");
 var {GenericMessagePrototype} = ChromeUtils.import("resource:///modules/jsProtoHelper.jsm");
 var {ClassInfo} = ChromeUtils.import("resource:///modules/imXPCOMUtils.jsm");
 var {ToLocaleFormat} = ChromeUtils.import("resource:///modules/ToLocaleFormat.jsm");
 var {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm");
+var {getHiddenHTMLWindow} = ChromeUtils.import("resource:///modules/hiddenWindow.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "_", () =>
   l10nHelper("chrome://chat/locale/logger.properties")
 );
 
 var kLineBreak = "@mozilla.org/windows-registry-key;1" in Cc ? "\r\n" : "\n";
 
 /*
@@ -132,17 +137,19 @@ function getNewLogFileName(aFormat, aSta
     dateTime += "+";
     offset *= -1;
   }
   else
     dateTime += "-";
   let minutes = offset % 60;
   offset = (offset - minutes) / 60;
   function twoDigits(aNumber) {
-    return aNumber == 0 ? "00" : aNumber < 10 ? "0" + aNumber : aNumber;
+    if (aNumber == 0)
+      return "00";
+    return aNumber < 10 ? "0" + aNumber : aNumber;
   }
   if (!aFormat)
     aFormat = "txt";
   return dateTime + twoDigits(offset) + twoDigits(minutes) + "." + aFormat;
 }
 
 
 // One of these is maintained for every conversation being logged. It initializes
@@ -162,17 +169,17 @@ LogWriter.prototype = {
   // Constructor sets this to a promise that will resolve when the log header
   // has been written.
   _initialized: null,
   _startTime: null,
   _lastMessageTime: null,
   _messageCount: 0,
   format: "txt",
   encoder: new TextEncoder(),
-  startNewFile: function lw_startNewFile(aStartTime, aContinuedSession) {
+  startNewFile(aStartTime, aContinuedSession) {
     // We start a new log file every 1000 messages. The start time of this new
     // log file is the time of the next message. Since message times are in seconds,
     // if we receive 1000 messages within a second after starting the new file,
     // we will create another file, using the same start time - and so the same
     // file name. To avoid this, ensure the new start time is at least one second
     // greater than the current one. This is ugly, but should rarely be needed.
     aStartTime = Math.max(aStartTime, this._startTime + 1000);
     this._startTime = this._lastMessageTime = aStartTime;
@@ -205,20 +212,21 @@ LogWriter.prototype = {
     }
     this._initialized =
       appendToFile(this.currentPath, this.encoder.encode(header), true);
     // Catch the error separately so that _initialized will stay rejected if
     // writing the header failed.
     this._initialized.catch(aError =>
                             Cu.reportError("Failed to initialize log file:\n" + aError));
   },
-  _serialize: function cl_serialize(aString) {
+  _serialize(aString) {
     // TODO cleanup once bug 102699 is fixed
     let doc = getHiddenHTMLWindow().document;
     let div = doc.createElementNS("http://www.w3.org/1999/xhtml", "div");
+    // eslint-disable-next-line no-unsanitized/property
     div.innerHTML = aString.replace(/\r?\n/g, "<br/>").replace(/<br>/gi, "<br/>");
     const type = "text/plain";
     let encoder = Cu.createDocumentEncoder(type);
     encoder.init(doc, type, 0);
     encoder.setContainerNode(div);
     encoder.setNodeFixup({fixupNode(aNode, aSerializeKids) {
       if (aNode.localName == "a" && aNode.hasAttribute("href")) {
         let url = aNode.getAttribute("href");
@@ -232,17 +240,17 @@ LogWriter.prototype = {
   },
   // We start a new log file in the following cases:
   // - If it has been 30 minutes since the last message.
   kInactivityLimit: 30 * 60 * 1000,
   // - If at midnight, it's been longer than 3 hours since we started the file.
   kDayOverlapLimit: 3 * 60 * 60 * 1000,
   // - After every 1000 messages.
   kMessageCountLimit: 1000,
-  logMessage: function cl_logMessage(aMessage) {
+  logMessage(aMessage) {
     // aMessage.time is in seconds, we need it in milliseconds.
     let messageTime = aMessage.time * 1000;
     let messageMidnight = new Date(messageTime).setHours(0, 0, 0, 0);
 
     let inactivityLimitExceeded =
       !aMessage.delayed && messageTime - this._lastMessageTime > this.kInactivityLimit;
     let dayOverlapLimitExceeded =
       !aMessage.delayed && messageMidnight - this._startTime > this.kDayOverlapLimit;
@@ -343,17 +351,17 @@ function SystemLogWriter(aAccount) {
                           Cu.reportError("Error initializing system log:\n" + aError));
 }
 SystemLogWriter.prototype = {
   encoder: new TextEncoder(),
   // Constructor sets this to a promise that will resolve when the log header
   // has been written.
   _initialized: null,
   path: null,
-  logEvent: function sl_logEvent(aString) {
+  logEvent(aString) {
     let date = ToLocaleFormat("%x %X", new Date());
     let lineToWrite =
       this.encoder.encode("---- " + aString + " @ " + date + " ----" + kLineBreak);
     this._initialized.then(() => {
       appendToFile(this.path, lineToWrite)
         .catch(aError => Cu.reportError("Failed to log event:\n" + aError));
     });
   },
@@ -707,17 +715,17 @@ Logger.prototype = {
     } catch (aError) {
       if (iterator)
         iterator.close();
       Cu.reportError("Error getting directory entries for \"" +
                      path + "\":\n" + aError);
     }
     return [];
   },
-  getLogFromFile: function logger_getLogFromFile(aFilePath, aGroupByDay) {
+  getLogFromFile(aFilePath, aGroupByDay) {
     if (!aGroupByDay)
       return Promise.resolve(new Log(aFilePath));
     let [targetDate] = getDateFromFilename(OS.Path.basename(aFilePath));
     if (!targetDate)
       return null;
 
     targetDate = targetDate.toDateString();
 
@@ -742,40 +750,38 @@ Logger.prototype = {
       return new Log(relevantEntries);
     }, aError => {
       iterator.close();
       throw aError;
     });
   },
   // Creates and returns the appropriate LogEnumerator for the given log array
   // depending on aGroupByDay, or an EmptyEnumerator if the input array is empty.
-  _getEnumerator: function logger__getEnumerator(aLogArray, aGroupByDay) {
+  _getEnumerator(aLogArray, aGroupByDay) {
     let enumerator = aGroupByDay ? DailyLogEnumerator : LogEnumerator;
     return aLogArray.length ? new enumerator(aLogArray) : EmptyEnumerator;
   },
   async getLogPathsForConversation(aConversation) {
     let writer = gLogWritersById.get(aConversation.id);
     // Resolve to null if we haven't created a LogWriter yet for this conv, or
     // if logging is disabled (paths will be null).
     if (!writer || !writer.paths)
       return null;
     let paths = writer.paths;
     // Wait for any pending file operations to finish, then resolve to the paths
     // regardless of whether these operations succeeded.
     for (let path of paths)
       await gFilePromises.get(path);
     return paths;
   },
-  getLogsForAccountAndName: function logger_getLogsForAccountAndName(aAccount,
-                                       aNormalizedName, aGroupByDay) {
+  getLogsForAccountAndName(aAccount, aNormalizedName, aGroupByDay) {
     return this._getLogArray(aAccount, aNormalizedName)
                .then(aEntries => this._getEnumerator(aEntries, aGroupByDay));
   },
-  getLogsForAccountBuddy: function logger_getLogsForAccountBuddy(aAccountBuddy,
-                                                                 aGroupByDay) {
+  getLogsForAccountBuddy(aAccountBuddy, aGroupByDay) {
     return this.getLogsForAccountAndName(aAccountBuddy.account,
                                          aAccountBuddy.normalizedName, aGroupByDay);
   },
   async getLogsForBuddy(aBuddy, aGroupByDay) {
     let entries = [];
     for (let accountBuddy of aBuddy.getAccountBuddies()) {
       entries = entries.concat(await this._getLogArray(accountBuddy.account,
                                                        accountBuddy.normalizedName));
@@ -787,24 +793,23 @@ Logger.prototype = {
     for (let buddy of aContact.getBuddies()) {
       for (let accountBuddy of buddy.getAccountBuddies()) {
         entries = entries.concat(await this._getLogArray(accountBuddy.account,
                                                          accountBuddy.normalizedName));
       }
     }
     return this._getEnumerator(entries, aGroupByDay);
   },
-  getLogsForConversation: function logger_getLogsForConversation(aConversation,
-                                                                 aGroupByDay) {
+  getLogsForConversation(aConversation, aGroupByDay) {
     let name = aConversation.normalizedName;
     if (convIsRealMUC(aConversation))
       name += ".chat";
     return this.getLogsForAccountAndName(aConversation.account, name, aGroupByDay);
   },
-  getSystemLogsForAccount: function logger_getSystemLogsForAccount(aAccount) {
+  getSystemLogsForAccount(aAccount) {
     return this.getLogsForAccountAndName(aAccount, ".system");
   },
   async getSimilarLogs(aLog, aGroupByDay) {
     let iterator = new OS.File.DirectoryIterator(OS.Path.dirname(aLog.path));
     let entries;
     try {
       entries = await iterator.nextBatch();
     } catch (aError) {
@@ -879,17 +884,17 @@ Logger.prototype = {
           throw aError;
         Cu.reportError("Error sweeping log folder:\n" + aError);
       } finally {
         iterator.close();
       }
     }
   },
 
-  observe: function logger_observe(aSubject, aTopic, aData) {
+  observe(aSubject, aTopic, aData) {
     switch (aTopic) {
     case "profile-after-change":
       Services.obs.addObserver(this, "final-ui-startup");
       break;
     case "final-ui-startup":
       Services.obs.removeObserver(this, "final-ui-startup");
       ["new-text", "conversation-closed", "conversation-left-chat",
        "account-connected", "account-disconnected",
--- a/chat/components/src/smileProtocolHandler.js
+++ b/chat/components/src/smileProtocolHandler.js
@@ -18,29 +18,29 @@ function smileProtocolHandler() { }
 
 smileProtocolHandler.prototype = {
   scheme: "smile",
   defaultPort: -1,
   protocolFlags: Ci.nsIProtocolHandler.URI_NORELATIVE |
                  Ci.nsIProtocolHandler.URI_NOAUTH |
                  Ci.nsIProtocolHandler.URI_IS_UI_RESOURCE |
                  Ci.nsIProtocolHandler.URI_IS_LOCAL_RESOURCE,
-  newURI: function SPH_newURI(aSpec, aOriginCharset, aBaseURI) {
+  newURI(aSpec, aOriginCharset, aBaseURI) {
     let mutator = Cc["@mozilla.org/network/simple-uri-mutator;1"]
                     .createInstance(Ci.nsIURIMutator);
     return mutator.setSpec(aSpec).finalize();
   },
-  newChannel: function SPH_newChannel2(aURI, aLoadInfo) {
+  newChannel(aURI, aLoadInfo) {
     let smile = aURI.spec.replace(kSmileRegexp, "");
     let uri = Services.io.newURI(getSmileRealURI(smile));
     let channel = Services.io.newChannelFromURIWithLoadInfo(uri, aLoadInfo);
     channel.originalURI = aURI;
     return channel;
   },
-  allowPort: function SPH_allowPort(aPort, aScheme) { return false; },
+  allowPort(aPort, aScheme) { return false; },
 
   classDescription: "Smile Protocol Handler",
   classID: Components.ID("{04e58eae-dfbc-4c9e-8130-6d9ef19cbff4}"),
   contractID: "@mozilla.org/network/protocol;1?name=smile",
   QueryInterface: ChromeUtils.generateQI([Ci.nsIProtocolHandler]),
 };
 
 var NSGetFactory = XPCOMUtils.generateNSGetFactory([smileProtocolHandler]);
--- a/chat/components/src/test/test_accounts.js
+++ b/chat/components/src/test/test_accounts.js
@@ -1,13 +1,12 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-var {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 var {Services} = ChromeUtils.import("resource:///modules/imServices.jsm");
 const {updateAppInfo} = ChromeUtils.import("resource://testing-common/AppInfo.jsm");
 
 function run_test() {
   do_get_profile();
 
   // Test the handling of accounts for unknown protocols.
   const kAccountName = "Unknown";
--- a/chat/components/src/test/test_conversations.js
+++ b/chat/components/src/test/test_conversations.js
@@ -1,23 +1,15 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 var {Services} = ChromeUtils.import("resource:///modules/imServices.jsm");
 var {
-  GenericAccountPrototype,
-  GenericAccountBuddyPrototype,
   GenericConvIMPrototype,
-  GenericConvChatPrototype,
-  GenericConvChatBuddyPrototype,
-  GenericConversationPrototype,
-  GenericMessagePrototype,
-  GenericProtocolPrototype,
   Message,
-  TooltipInfo,
 } = ChromeUtils.import("resource:///modules/jsProtoHelper.jsm");
 
 var imConversations = {};
 Services.scriptloader.loadSubScript(
   "resource:///components/imConversations.js", imConversations
 );
 
 // Fake prplConversation
--- a/chat/components/src/test/test_logger.js
+++ b/chat/components/src/test/test_logger.js
@@ -1,26 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 do_get_profile();
 
 var {Services} = ChromeUtils.import("resource:///modules/imServices.jsm");
-var {
-  XPCOMUtils,
-  setTimeout,
-  clearTimeout,
-  executeSoon,
-  nsSimpleEnumerator,
-  EmptyEnumerator,
-  ClassInfo,
-  l10nHelper,
-  initLogModule,
-} = ChromeUtils.import("resource:///modules/imXPCOMUtils.jsm");
 const {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm");
 
 var gLogger = {};
 Services.scriptloader.loadSubScript("resource:///components/logger.js", gLogger);
 
 var logDirPath = OS.Path.join(OS.Constants.Path.profileDir, "logs");
 
 var dummyAccount = {
@@ -36,18 +25,16 @@ var dummyTwitterAccount = {
   name: "dummy-twitter",
   normalizedName: "dummytwitter",
   protocol: {
     normalizedName: "twitter",
     id: "prpl-twitter",
   },
 };
 
-var test_accounts = [dummyAccount, dummyTwitterAccount];
-
 var dummyConv = {
   account: dummyAccount,
   id: 0,
   title: "dummy conv",
   normalizedName: "dummyconv",
   get name() { return this.normalizedName; },
   get startDate() { return new Date(2011, 5, 28).valueOf() * 1000; },
   isChat: false,
@@ -79,18 +66,16 @@ var dummyTwitterConv = {
   id: 2,
   title: "Dummy Twitter Conv",
   normalizedName: "dummytwitterconv",
   get name() { return this.normalizedName; },
   startDate: new Date(2011, 5, 28).valueOf() * 1000,
   isChat: true,
 };
 
-var test_convs = [dummyConv, dummyMUC, dummyTwitterConv];
-
 var encodeName_input = [
   "CON",
   "PRN",
   "AUX",
   "NUL",
   "COM3",
   "LPT5",
   "file",
@@ -172,22 +157,20 @@ var encodeName_output = [
   "%22file",
   "%2ffile",
   "%5cfile",
   "%7cfile",
   "%3ffile",
   "%2afile",
   "%26file",
   "%25file",
-  "%5c" + "fi" + "%3f%2a%26%25" + "le" + "%3c%3e",
+  "%5c" + "fi" + "%3f%2a%26%25" + "le" + "%3c%3e", // eslint-disable-line no-useless-concat
 ];
 
 var test_queueFileOperation = async function() {
-  let dummyOperation = function() {};
-
   let dummyRejectedOperation = () => Promise.reject("Rejected!");
   let dummyResolvedOperation = () => Promise.resolve("Resolved!");
 
   let gFP = gLogger.gFilePromises;
   let qFO = gLogger.queueFileOperation;
 
   // Immediately after calling qFO, "path1" should be mapped to p1.
   // After yielding, the reference should be cleared from the map.
--- a/chat/content/account.xml
+++ b/chat/content/account.xml
@@ -1,13 +1,14 @@
 <?xml version="1.0"?>
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
+<!-- import-globals-from ../../mail/components/im/content/imAccounts.js -->
 
 <!DOCTYPE bindings [
   <!ENTITY % accountsDTD SYSTEM "chrome://chat/locale/accounts.dtd">
   %accountsDTD;
 ]>
 
 <bindings id="accountBindings"
           xmlns="http://www.mozilla.org/xbl"
@@ -134,20 +135,20 @@
 
           var updateReconnect = (function() {
             var date = Math.round((account.timeOfNextReconnect - Date.now()) / 1000);
             let reconnect = "";
             if (date > 0) {
               let [val1, unit1, val2, unit2] = DownloadUtils.convertTimeUnits(date);
               if (!val2)
                 reconnect = bundle.getFormattedString("account.reconnectInSingle",
-                                                      [val1, unit1])
+                                                      [val1, unit1]);
               else
                 reconnect = bundle.getFormattedString("account.reconnectInDouble",
-                                                      [val1, unit1, val2, unit2])
+                                                      [val1, unit1, val2, unit2]);
             }
             document.getAnonymousElementByAttribute(this, "anonid", "reconnect")
                     .textContent = reconnect;
             return reconnect;
           }).bind(this);
           if (updateReconnect() && !this.reconnectUpdateInterval) {
             this.setAttribute("reconnectPending", "true");
             this.reconnectUpdateInterval = setInterval(updateReconnect, 1000);
@@ -163,20 +164,20 @@
           var bundle = document.getElementById("accountsBundle");
           var date =
             60 * Math.floor((Date.now() - this._account.timeOfLastConnect) / 60000);
           let value;
           if (date > 0) {
             let [val1, unit1, val2, unit2] = DownloadUtils.convertTimeUnits(date);
             if (!val2)
               value = bundle.getFormattedString("account.connectedForSingle",
-                                                [val1, unit1])
+                                                [val1, unit1]);
             else
               value = bundle.getFormattedString("account.connectedForDouble",
-                                                [val1, unit1, val2, unit2])
+                                                [val1, unit1, val2, unit2]);
           }
           else
             value = bundle.getString("account.connectedForSeconds");
           this.connectedLabel.value = value;
         ]]>
         </body>
       </method>
 
--- a/chat/content/conversation-browser.js
+++ b/chat/content/conversation-browser.js
@@ -1,19 +1,27 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
   * License, v. 2.0. If a copy of the MPL was not distributed with this
   * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 /* global MozXULElement */
 
-var { initHTMLDocument, serializeSelection, getCurrentTheme, isNextMessage, getHTMLForMessage, insertHTMLForMessage } = ChromeUtils.import("resource:///modules/imThemes.jsm");
-var { smileTextNode } = ChromeUtils.import("resource:///modules/imSmileys.jsm");
-var { cleanupImMarkup } = ChromeUtils.import("resource:///modules/imContentSink.jsm");
+var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+var {
+  initHTMLDocument,
+  serializeSelection,
+  getCurrentTheme,
+  isNextMessage,
+  getHTMLForMessage,
+  insertHTMLForMessage,
+} = ChromeUtils.import("resource:///modules/imThemes.jsm");
+var {smileTextNode} = ChromeUtils.import("resource:///modules/imSmileys.jsm");
+var {cleanupImMarkup} = ChromeUtils.import("resource:///modules/imContentSink.jsm");
 
 (function() {
   // <browser> is lazily set up through setElementCreationCallback,
   // i.e. put into customElements the first time it's really seen.
   // Create a fake to ensure browser exists in customElements, since otherwise
   // we can't extend it. Then make sure this fake doesn't stay around.
   if (!customElements.get("browser")) {
     delete document.createElement("browser");
--- a/chat/modules/DNS.jsm
+++ b/chat/modules/DNS.jsm
@@ -286,32 +286,35 @@ function SRVRecord(aPrio, aWeight, aHost
 }
 
 // Used to make results of different libraries consistent for TXT queries.
 function TXTRecord(aData) {
   this.data = aData;
 }
 
 if (typeof Components === "undefined") {
+  /* eslint-env worker */
+
   // We are in a worker, wait for our message then execute the wanted method.
   importScripts("resource://gre/modules/workers/require.js");
   let PromiseWorker = require("resource://gre/modules/workers/PromiseWorker.js");
 
   let worker = new PromiseWorker.AbstractWorker();
   worker.dispatch = function(aMethod, aArgs = []) {
     return self[aMethod](...aArgs);
-  },
+  };
   worker.postMessage = function(...aArgs) {
     self.postMessage(...aArgs);
   };
   worker.close = function() {
     self.close();
   };
   self.addEventListener("message", msg => worker.handleMessage(msg));
 
+  // eslint-disable-next-line no-unused-vars
   function execute(aOS, aMethod, aArgs) {
     let DNS = (aOS == "WINNT" ? new load_dnsapi() : new load_libresolv());
     return DNS[aMethod].apply(DNS, aArgs);
   }
 }
 else {
   // We are loaded as a JSM, provide the async front that will start the
   // worker.
--- a/chat/modules/ToLocaleFormat.jsm
+++ b/chat/modules/ToLocaleFormat.jsm
@@ -40,17 +40,17 @@ function dayPeriod(aDate) {
     dtf.formatToParts(aDate).find(part => part.type === "dayPeriod");
   return dayPeriodPart ? dayPeriodPart.value : "";
 }
 function weekNumber(aDate, weekStart) {
   let day = aDate.getDay();
   if (weekStart) {
     day = (day || 7) - weekStart;
   }
-  return Math.max(Math.floor((DayWithinYear(t) + 7 - day) / 7), 0);
+  return Math.max(Math.floor((DayWithinYear(aDate) + 7 - day) / 7), 0);
 }
 function weekNumberISO(t) {
   let thisWeek = weekNumber(1, t);
   let firstDayOfYear =
     (new Date(t.getFullYear(), 0, 1).getDay() || 7) - 1;
   if (thisWeek === 0 && firstDayOfYear >= 4)
     return weekNumberISO(new Date(t.getFullYear() - 1, 11, 31));
   if (t.getMonth() === 11 &&
--- a/chat/modules/imContentSink.jsm
+++ b/chat/modules/imContentSink.jsm
@@ -1,14 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 const {Services} = ChromeUtils.import("resource:///modules/imServices.jsm");
-Cu.importGlobalProperties(["DOMParser"]);
 
 this.EXPORTED_SYMBOLS = [
   "cleanupImMarkup", // used to clean up incoming IMs.
                      // This will use the global ruleset of acceptable stuff
                      // except if another (custom one) is provided
   "createDerivedRuleset", // used to create a ruleset that inherits from the
                           // default one
                           // useful if you want to allow or forbid
@@ -170,17 +169,17 @@ var gGlobalRuleset = null;
 function initGlobalRuleset()
 {
   gGlobalRuleset = newRuleset();
 
   Services.prefs.addObserver(kModePref, styleObserver);
 }
 
 var styleObserver = {
-  observe: function so_observe(aObject, aTopic, aMsg) {
+  observe(aObject, aTopic, aMsg) {
     if (aTopic != "nsPref:changed" || aMsg != kModePref)
       throw "bad notification";
 
     if (!gGlobalRuleset)
       throw "gGlobalRuleset not initialized";
 
     setBaseRuleset(getModePref(), gGlobalRuleset);
   },
@@ -257,17 +256,17 @@ function cleanupNode(aNode, aRules, aTex
       if (!(nodeName in aRules.tags)) {
         if (nodeName in kForbiddenTags) {
           Cu.reportError("removing a " + nodeName +
                          " tag from a message before display");
         }
         else {
           // this node is not allowed, replace it with its children
           while (node.hasChildNodes())
-            aNode.insertBefore(node.removeChild(node.firstChild), node);
+            aNode.insertBefore(node.firstChild, node);
         }
         aNode.removeChild(node);
         // We want to process again the node at the index i which is
         // now the first child of the node we removed
         --i;
         continue;
       }
 
--- a/chat/modules/imSmileys.jsm
+++ b/chat/modules/imSmileys.jsm
@@ -30,33 +30,31 @@ Object.defineProperty(this, "gTheme", {
   get() {
     delete this.gTheme;
     gPrefObserver.init();
     return this.gTheme = getTheme();
   },
 });
 
 var gPrefObserver = {
-  init: function po_init() {
+  init() {
     Services.prefs.addObserver(kEmoticonsThemePref, gPrefObserver);
   },
 
-  observe: function so_observe(aObject, aTopic, aMsg) {
+  observe(aObject, aTopic, aMsg) {
     if (aTopic != "nsPref:changed" || aMsg != kEmoticonsThemePref)
       throw "bad notification";
 
     gTheme = getTheme();
   },
 };
 
 function getSmileRealURI(aSmile)
 {
-  aSmile = Cc["@mozilla.org/intl/texttosuburi;1"]
-             .getService(Ci.nsITextToSubURI)
-             .unEscapeURIForUI("UTF-8", aSmile);
+  aSmile = Services.textToSubURI.unEscapeURIForUI("UTF-8", aSmile);
   if (aSmile in gTheme.iconsHash)
     return gTheme.baseUri + gTheme.iconsHash[aSmile].filename;
 
   throw "Invalid smile!";
 }
 
 function getSmileyList(aThemeName)
 {
@@ -223,12 +221,13 @@ function smileImMarkup(aDocument, aText)
   if (!aDocument)
     throw "providing an HTML document is required";
 
   // return early if smileys are disabled
   if (!gTheme.iconsHash)
     return aText;
 
   let div = aDocument.createElement("div");
+  // eslint-disable-next-line no-unsanitized/property
   div.innerHTML = aText;
   smileNode(div);
   return div.innerHTML;
 }
--- a/chat/modules/imStatusUtils.jsm
+++ b/chat/modules/imStatusUtils.jsm
@@ -1,26 +1,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 this.EXPORTED_SYMBOLS = ["Status"];
 
 var {
   XPCOMUtils,
-  setTimeout,
-  clearTimeout,
-  executeSoon,
-  nsSimpleEnumerator,
-  EmptyEnumerator,
-  ClassInfo,
   l10nHelper,
-  initLogModule,
 } = ChromeUtils.import("resource:///modules/imXPCOMUtils.jsm");
-var {Services} = ChromeUtils.import("resource:///modules/imServices.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "_", () =>
   l10nHelper("chrome://chat/locale/status.properties")
 );
 
 var imIStatusInfo = Ci.imIStatusInfo;
 var statusAttributes = {};
 statusAttributes[imIStatusInfo.STATUS_UNKNOWN] = "unknown";
--- a/chat/modules/imThemes.jsm
+++ b/chat/modules/imThemes.jsm
@@ -12,17 +12,16 @@ this.EXPORTED_SYMBOLS = [
   "initHTMLDocument",
   "getMessagesForRange",
   "serializeSelection",
 ];
 
 const {Services} = ChromeUtils.import("resource:///modules/imServices.jsm");
 const {DownloadUtils} = ChromeUtils.import("resource://gre/modules/DownloadUtils.jsm");
 const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.importGlobalProperties(["DOMParser", "Element"]);
 
 var kMessagesStylePrefBranch = "messenger.options.messagesStyle.";
 var kThemePref = "theme";
 var kVariantPref = "variant";
 var kShowHeaderPref = "showHeader";
 var kCombineConsecutivePref = "combineConsecutive";
 var kCombineConsecutiveIntervalPref = "combineConsecutiveInterval";
 
@@ -534,16 +533,17 @@ function insertHTMLForMessage(aMsg, aHTM
   if (insert && !aIsNext) {
     insert.remove();
     insert = null;
   }
 
   let range = aDoc.createRange();
   let parent = insert ? insert.parentNode : aDoc.getElementById("Chat");
   range.selectNode(parent);
+  // eslint-disable-next-line no-unsanitized/method
   let documentFragment = range.createContextualFragment(aHTML);
   let result = documentFragment.firstChild;
 
   // store the prplIMessage object in each of the "root" node that
   // will be inserted into the document, so that selection code can
   // retrieve the message by just looking at the parent node until it
   // finds something.
   for (let root = result; root; root = root.nextSibling)
@@ -889,16 +889,17 @@ SelectedMessage.prototype = {
     if (this._textSelected) {
       // Add ellipsis is needed
       text = (this._cutBegin ? getEllipsis() + " " : "") +
              this._selectedText +
              (this._cutEnd ? " " + getEllipsis() : "");
     }
     else {
       let div = this._rootNodes[0].ownerDocument.createElement("div");
+      // eslint-disable-next-line no-unsanitized/property
       div.innerHTML = msg.autoResponse ? formatAutoResponce(msg.message) : msg.message;
       text = serializeNode(div);
     }
 
     // then get the suitable replacements and templates for this message
     let getLocalizedPrefWithDefault = function(aName, aDefault) {
       try {
         let prefBranch =
--- a/chat/modules/imXPCOMUtils.jsm
+++ b/chat/modules/imXPCOMUtils.jsm
@@ -89,17 +89,17 @@ function scriptError(aModule, aLevel, aM
 function initLogModule(aModule, aObj = {})
 {
   aObj.DEBUG = scriptError.bind(aObj, aModule, Ci.imIDebugMessage.LEVEL_DEBUG);
   aObj.LOG   = scriptError.bind(aObj, aModule, Ci.imIDebugMessage.LEVEL_LOG);
   aObj.WARN  = scriptError.bind(aObj, aModule, Ci.imIDebugMessage.LEVEL_WARNING);
   aObj.ERROR = scriptError.bind(aObj, aModule, Ci.imIDebugMessage.LEVEL_ERROR);
   return aObj;
 }
-XPCOMUtils.defineLazyGetter(Cu.getGlobalForObject({}), "gLogLevels", function() {
+XPCOMUtils.defineLazyGetter(this, "gLogLevels", function() {
   // This object functions both as an obsever as well as a dict keeping the
   // log levels with prefs; the log levels all start with "level" (i.e. "level"
   // for the global level, "level.irc" for the IRC module).  The dual-purpose
   // is necessary to make sure the observe is left alive while being a weak ref
   // to avoid cycles with the pref service.
   let logLevels = {
     observe(aSubject, aTopic, aData) {
       let module = "level" + aData.substr(kLogLevelPref.length);
--- a/chat/modules/jsProtoHelper.jsm
+++ b/chat/modules/jsProtoHelper.jsm
@@ -27,17 +27,17 @@ const {ClassInfo} = ChromeUtils.import("
 
 XPCOMUtils.defineLazyGetter(this, "_", () =>
   l10nHelper("chrome://chat/locale/conversations.properties")
 );
 
 var GenericAccountPrototype = {
   __proto__: ClassInfo("prplIAccount", "generic account object"),
   get wrappedJSObject() { return this; },
-  _init: function _init(aProtocol, aImAccount) {
+  _init(aProtocol, aImAccount) {
     this.protocol = aProtocol;
     this.imAccount = aImAccount;
     initLogModule(aProtocol.id, this);
   },
   observe(aSubject, aTopic, aData) {},
   remove() { throw Cr.NS_ERROR_NOT_IMPLEMENTED; },
   unInit() { throw Cr.NS_ERROR_NOT_IMPLEMENTED; },
   connect() { throw Cr.NS_ERROR_NOT_IMPLEMENTED; },
--- a/chat/modules/socket.jsm
+++ b/chat/modules/socket.jsm
@@ -85,22 +85,18 @@ var {
   setTimeout,
   clearTimeout,
   executeSoon,
 } = ChromeUtils.import("resource:///modules/imXPCOMUtils.jsm");
 var {getHiddenHTMLWindow} = ChromeUtils.import("resource:///modules/hiddenWindow.jsm");
 
 // Network errors see: xpcom/base/nsError.h
 var NS_ERROR_MODULE_NETWORK = 2152398848;
-var NS_ERROR_CONNECTION_REFUSED = NS_ERROR_MODULE_NETWORK + 13;
 var NS_ERROR_NET_TIMEOUT = NS_ERROR_MODULE_NETWORK + 14;
 var NS_ERROR_NET_RESET = NS_ERROR_MODULE_NETWORK + 20;
-var NS_ERROR_UNKNOWN_HOST = NS_ERROR_MODULE_NETWORK + 30;
-var NS_ERROR_UNKNOWN_PROXY_HOST = NS_ERROR_MODULE_NETWORK + 42;
-var NS_ERROR_PROXY_CONNECTION_REFUSED = NS_ERROR_MODULE_NETWORK + 72;
 
 var BinaryInputStream =
   Components.Constructor("@mozilla.org/binaryinputstream;1",
                          "nsIBinaryInputStream", "setInputStream");
 var BinaryOutputStream =
   Components.Constructor("@mozilla.org/binaryoutputstream;1",
                          "nsIBinaryOutputStream", "setOutputStream");
 var ScriptableInputStream =
--- a/chat/modules/test/test_filtering.js
+++ b/chat/modules/test/test_filtering.js
@@ -138,18 +138,18 @@ function test_standardMode() {
 
   // Keep special allowed classes.
   for (let className of ["moz-txt-underscore", "moz-txt-tag"]) {
     let string = "<span class=\"" + className + "\">foo</span>";
     Assert.equal(string, cleanupImMarkup(string));
   }
 
   // Remove font settings
-  let string = "<font face=\"Times\" color=\"pink\" size=\"3\">foo</font>";
-  Assert.equal("foo", cleanupImMarkup(string));
+  let font_string = "<font face=\"Times\" color=\"pink\" size=\"3\">foo</font>";
+  Assert.equal("foo", cleanupImMarkup(font_string));
 
   // Discard hr
   Assert.equal("foobar", cleanupImMarkup("foo<hr>bar"));
 
   const okCSS = [
     "font-style: italic",
     "font-weight: bold",
   ];
@@ -206,18 +206,18 @@ function test_permissiveMode() {
     "size=\"3\"",
   ];
   for (let fontAttribute of fontAttributes) {
     let string = "<font " + fontAttribute + ">foo</font>";
     Assert.equal(string, cleanupImMarkup(string));
   }
 
   // Allow hr
-  let string = "foo<hr>bar";
-  Assert.equal(string, cleanupImMarkup(string));
+  let hr_string = "foo<hr>bar";
+  Assert.equal(hr_string, cleanupImMarkup(hr_string));
 
   // Allow most CSS rules changing the text appearance.
   const okCSS = [
     "font-style: italic",
     "font-weight: bold",
     "text-decoration: underline",
     "color: pink;",
     "font-family: Times",
--- a/chat/protocols/irc/irc.js
+++ b/chat/protocols/irc/irc.js
@@ -3,23 +3,23 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var {
   ClassInfo,
   clearTimeout,
   EmptyEnumerator,
   setTimeout,
   executeSoon,
+  l10nHelper,
   XPCOMUtils,
   nsSimpleEnumerator,
 } = ChromeUtils.import("resource:///modules/imXPCOMUtils.jsm");
 var {Services} = ChromeUtils.import("resource:///modules/imServices.jsm");
 var {
   _,
-  _conv,
   ctcpFormatToText,
   ctcpFormatToHTML,
   conversationErrorMessage,
   kListRefreshInterval,
 } = ChromeUtils.import("resource:///modules/ircUtils.jsm");
 var {ircHandlers} = ChromeUtils.import("resource:///modules/ircHandlers.jsm");
 var {
   GenericAccountPrototype,
@@ -37,16 +37,20 @@ var {NormalizedMap} = ChromeUtils.import
 var {Socket} = ChromeUtils.import("resource:///modules/socket.jsm");
 
 ChromeUtils.defineModuleGetter(this, "PluralForm",
   "resource://gre/modules/PluralForm.jsm");
 
 ChromeUtils.defineModuleGetter(this, "DownloadUtils",
   "resource://gre/modules/DownloadUtils.jsm");
 
+XPCOMUtils.defineLazyGetter(this, "_conv", () =>
+  l10nHelper("chrome://chat/locale/conversations.properties")
+);
+
 /*
  * Parses a raw IRC message into an object (see section 2.3 of RFC 2812). This
  * returns an object with the following fields:
  *   rawMessage The initial message string received without any processing.
  *   command    A string that is the command or response code.
  *   params     An array of strings for the parameters. The last parameter is
  *              stripped of its : prefix.
  *   origin     The user's nickname or the server who sent the message. Can be
@@ -733,16 +737,17 @@ ircSocket.prototype = {
     // We've received data and are past the authentication stage.
     if (this._account.connected)
       this.resetPingTimer();
 
     // Low level dequote: replace quote character \020 followed by 0, n, r or
     // \020 with a \0, \n, \r or \020, respectively. Any other character is
     // replaced with itself.
     const lowDequote = {"0": "\0", "n": "\n", "r": "\r", "\x10": "\x10"};
+    // eslint-disable-next-line no-control-regex
     let dequotedMessage = aRawMessage.replace(/\x10./g,
       aStr => lowDequote[aStr[1]] || aStr[1]);
 
     try {
       let message = new ircMessage(dequotedMessage,
                                    this._account._currentServerName);
       this.DEBUG(JSON.stringify(message) + conversionWarning);
       if (!ircHandlers.handleMessage(this._account, message)) {
@@ -754,17 +759,17 @@ ircSocket.prototype = {
       // Catch the error, display it and hope the connection can continue with
       // this message in error. Errors are also caught inside of handleMessage,
       // but we expect to handle message parsing errors here.
       this.DEBUG(aRawMessage + conversionWarning);
       this.ERROR(e);
     }
   },
   onConnection() {
-    this._account._connectionRegistration.call(this._account);
+    this._account._connectionRegistration();
   },
   disconnect() {
     if (!this._account)
       return;
     Socket.disconnect.call(this);
     delete this._account;
   },
 
@@ -988,24 +993,24 @@ ircAccount.prototype = {
       this.sendMessage("AWAY"); // Mark as back.
   },
 
   // The user's user mode.
   _modes: null,
   _userModeReceived: false,
   setUserMode(aNick, aNewModes, aSetter, aDisplayFullMode) {
     if (this.normalizeNick(aNick) != this.normalizeNick(this._nickname)) {
-      WARN("Received unexpected mode for " + aNick);
+      this.WARN("Received unexpected mode for " + aNick);
       return false;
     }
 
     // Are modes being added or removed?
     let addNewMode = aNewModes[0] == "+";
     if (!addNewMode && aNewModes[0] != "-") {
-      WARN("Invalid mode string: " + aNewModes);
+      this.WARN("Invalid mode string: " + aNewModes);
       return false;
     }
     _setMode.call(this, addNewMode, aNewModes.slice(1));
 
     // The server informs us of the user's mode when connecting.
     // We should not report this initial mode message as a mode change
     // initiated by the user, but instead display the full mode
     // and then remember we have done so.
@@ -1218,17 +1223,19 @@ ircAccount.prototype = {
           whoisInformation.serverInfo);
     }
 
     // Sort the list of channels, ignoring the prefixes of channel and user.
     let prefixes = this.userPrefixes.concat(this.channelPrefixes);
     let sortWithoutPrefix = function(a, b) {
       a = this.normalize(a, prefixes);
       b = this.normalize(b, prefixes);
-      return a < b ? -1 : a > b ? 1 : 0;
+      if (a < b)
+        return -1;
+      return a > b ? 1 : 0;
     }.bind(this);
     let sortChannels = channels =>
       channels.trim().split(/\s+/).sort(sortWithoutPrefix).join(" ");
 
     // Convert booleans into a human-readable form.
     let normalizeBool = aBool => _(aBool ? "yes" : "no");
 
     // Convert timespan in seconds into a human-readable form.
@@ -1504,23 +1511,27 @@ ircAccount.prototype = {
   countBytes(aStr) {
     // Assume that if it's not UTF-8 then each character is 1 byte.
     if (this._encoding != "UTF-8")
       return aStr.length;
 
     // Count the number of bytes in a UTF-8 encoded string.
     function charCodeToByteCount(c) {
       // UTF-8 stores:
-      // - code points below U+0080 on 1 byte,
-      // - code points below U+0800 on 2 bytes,
+      // - code points below U+0080 are 1 byte,
+      // - code points below U+0800 are 2 bytes,
       // - code points U+D800 through U+DFFF are UTF-16 surrogate halves
       // (they indicate that JS has split a 4 bytes UTF-8 character
       // in two halves of 2 bytes each),
-      // - other code points on 3 bytes.
-      return c < 0x80 ? 1 : (c < 0x800 || (c >= 0xD800 && c <= 0xDFFF)) ? 2 : 3;
+      // - other code points are 3 bytes.
+      if (c < 0x80)
+        return 1;
+      if (c < 0x800 || (c >= 0xD800 && c <= 0xDFFF))
+        return 2;
+      return 3;
     }
     let bytes = 0;
     for (let i = 0; i < aStr.length; i++)
       bytes += charCodeToByteCount(aStr.charCodeAt(i));
     return bytes;
   },
 
   // To check if users are online, we need to queue multiple messages.
@@ -1844,16 +1855,17 @@ ircAccount.prototype = {
     // If aParams is not an array, consider it to be a single parameter and put
     // it into an array.
     let params = Array.isArray(aParams) ? aParams : [aParams];
     if (params.length)
       ircParam += " " + params.join(" ");
 
     // High/CTCP level quoting, replace \134 or \001 with \134\134 or \134a,
     // respectively. This is only done inside the extended data message.
+    // eslint-disable-next-line no-control-regex
     const highRegex = /\\|\x01/g;
     ircParam = ircParam.replace(highRegex,
       aChar => "\\" + (aChar == "\\" ? "\\" : "a"));
 
     // Add the CTCP tagging.
     ircParam = "\x01" + ircParam + "\x01";
 
     // Send the IRC message as a NOTICE or PRIVMSG.
--- a/chat/protocols/irc/ircCTCP.jsm
+++ b/chat/protocols/irc/ircCTCP.jsm
@@ -21,17 +21,21 @@ function CTCPMessage(aMessage, aRawCTCPM
   let message = Object.assign({}, aMessage);
   message.ctcp = {};
   message.ctcp.rawMessage = aRawCTCPMessage;
 
   // High/CTCP level dequote: replace the quote char \134 followed by a or \134
   // with \001 or \134, respectively. Any other character after \134 is replaced
   // with itself.
   let dequotedCTCPMessage = message.ctcp.rawMessage.replace(/\\(.|$)/g,
-    aStr => aStr[1] ? (aStr[1] == "a" ? "\x01" : aStr[1]) : "");
+    aStr => {
+      if (aStr[1])
+        return aStr[1] == "a" ? "\x01" : aStr[1];
+      return "";
+    });
 
   let separator = dequotedCTCPMessage.indexOf(" ");
   // If there's no space, then only a command is given.
   // Do not capitalize the command, case sensitive
   if (separator == -1) {
     message.ctcp.command = dequotedCTCPMessage;
     message.ctcp.param = "";
   }
@@ -63,16 +67,17 @@ function ctcpHandleMessage(aMessage) {
     return false;
 
   // The raw CTCP message is in the last parameter of the IRC message.
   let rawCTCPParam = aMessage.params.slice(-1)[0];
 
   // Split the raw message into the multiple CTCP messages and pull out the
   // command and parameters.
   let ctcpMessages = [];
+  // eslint-disable-next-line no-control-regex
   let otherMessage = rawCTCPParam.replace(/\x01([^\x01]*)\x01/g,
     function(aMatch, aMsg) {
       if (aMsg)
         ctcpMessages.push(new CTCPMessage(aMessage, aMsg));
       return "";
     });
 
   // If no CTCP messages were found, return false.
--- a/chat/protocols/irc/ircCommands.jsm
+++ b/chat/protocols/irc/ircCommands.jsm
@@ -341,16 +341,17 @@ var commands = [
     get helpString() { return _("command.msg", "msg"); },
     run: messageCommand,
   },
   {
     name: "nick",
     get helpString() { return _("command.nick", "nick"); },
     run(aMsg, aConv) {
       let newNick = aMsg.trim();
+      // eslint-disable-next-line mozilla/use-includes-instead-of-indexOf
       if (newNick.indexOf(/\s+/) != -1)
         return false;
 
       let account = getAccount(aConv);
       // The user wants to change their nick, so overwrite the account
       // nickname for this session.
       account._requestedNickname = newNick;
       account.changeNick(newNick);
--- a/chat/protocols/irc/ircUtils.jsm
+++ b/chat/protocols/irc/ircUtils.jsm
@@ -1,28 +1,24 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-this.EXPORTED_SYMBOLS = ["_", "_conv", "ctcpFormatToText", "ctcpFormatToHTML",
+this.EXPORTED_SYMBOLS = ["_", "ctcpFormatToText", "ctcpFormatToHTML",
                           "conversationErrorMessage", "kListRefreshInterval"];
 
 var {
   XPCOMUtils,
   l10nHelper,
 } = ChromeUtils.import("resource:///modules/imXPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "_", () =>
   l10nHelper("chrome://chat/locale/irc.properties")
 );
 
-XPCOMUtils.defineLazyGetter(this, "_conv", () =>
-  l10nHelper("chrome://chat/locale/conversations.properties")
-);
-
 XPCOMUtils.defineLazyGetter(this, "TXTToHTML", function() {
   let cs = Cc["@mozilla.org/txttohtmlconv;1"].getService(Ci.mozITXTToHTMLConv);
   return aTXT => cs.scanTXT(aTXT, cs.kEntities);
 });
 
 // The timespan after which we consider LIST roomInfo to be stale.
 var kListRefreshInterval = 12 * 60 * 60 * 1000; // 12 hours.
 
@@ -35,22 +31,24 @@ var kListRefreshInterval = 12 * 60 * 60 
  *  aStack  The ordered list of open HTML tags.
  *  aInput  The current input string.
  * There are three output values returned in an array:
  *  The new ordered list of open HTML tags.
  *  The new text output to append.
  *  The number of characters (from the start of the input string) that the
  *  function handled.
  */
-var CTCP_TAGS = {"\x02": "b", // \002, ^B, Bold
-                   "\x16": "i", // \026, ^V, Reverse or Inverse (Italics)
-                   "\x1D": "i", // \035, ^], Italics (mIRC)
-                   "\x1F": "u", // \037, ^_, Underline
-                   "\x03": mIRCColoring, // \003, ^C, Coloring
-                   "\x0F": null}; // \017, ^O, Clear all formatting
+var CTCP_TAGS = {
+  "\x02": "b", // \002, ^B, Bold
+  "\x16": "i", // \026, ^V, Reverse or Inverse (Italics)
+  "\x1D": "i", // \035, ^], Italics (mIRC)
+  "\x1F": "u", // \037, ^_, Underline
+  "\x03": mIRCColoring, // \003, ^C, Coloring
+  "\x0F": null, // \017, ^O, Clear all formatting
+};
 
 // Generate an expression that will search for any of the control characters.
 var CTCP_TAGS_EXP = new RegExp("[" + Object.keys(CTCP_TAGS).join("") + "]");
 
 // Remove all CTCP formatting characters.
 function ctcpFormatToText(aString) {
   let next,
       input = aString,
@@ -135,16 +133,17 @@ function ctcpFormatToHTML(aString) {
     input = input.substr(next.index + length);
   }
   // Return unmatched bits and close any open tags at the end.
   return output + input + closeStack(stack);
 }
 
 // mIRC colors are defined at http://www.mirc.com/colors.html.
 // This expression matches \003<one or two digits>[,<one or two digits>].
+// eslint-disable-next-line no-control-regex
 var M_IRC_COLORS_EXP = /^\x03(?:(\d\d?)(?:,(\d\d?))?)?/;
 var M_IRC_COLOR_MAP = {
   "0": "white",
   "1": "black",
   "2": "navy", // blue (navy)
   "3": "green",
   "4": "red",
   "5": "maroon", // brown (maroon)
--- a/chat/protocols/irc/test/test_ircCommands.js
+++ b/chat/protocols/irc/test/test_ircCommands.js
@@ -197,9 +197,10 @@ function testUserModeCommand() {
 function _getRunCommand(aCommandName) {
   for (let command of commands) {
     if (command.name == aCommandName)
       return command.run;
   }
 
   // Fail if no command was found.
   ok(false, "Could not find the '" + aCommandName + "' command.");
+  return null; // Shut-up eslint.
 }
--- a/chat/protocols/xmpp/xmpp.jsm
+++ b/chat/protocols/xmpp/xmpp.jsm
@@ -1669,36 +1669,16 @@ var XMPPAccountPrototype = {
 
       // If this happens, there's a bug somewhere.
       this.ERROR("HandleErrors was passed a handler for '" + condition +
         "'' which is neither a function nor a string.");
       return false;
     };
   },
 
-  // Send an error stanza in response to the given stanza (rfc6120#8.3).
-  // aCondition is the name of the defined-condition child, aText an
-  // optional plain-text description.
-  sendErrorStanza(aStanza, aCondition, aType, aText) {
-    // TODO: Support the other stanza types (message, presence).
-    let qName = aStanza.qName;
-    if (qName != "iq") {
-      this.ERROR(`Sending an error stanza for a ${qName} stanza is not ` +
-                 `implemented yet.`);
-      return;
-    }
-
-    let error = Stanza.node("error", null, {type: aType},
-                            Stanza.node(aCondition, Stanza.NS.stanzas));
-    if (aText)
-      error.addChild(Stanza.node("text", Stanza.NS.stanzas, null, aText));
-    return this.sendStanza(Stanza.iq("error", aStanza.attributes.id,
-      aStanza.attributes.from, error));
-  },
-
   // Returns a callback suitable for use in sendStanza, to handle type==result
   // responses. aHandlers and aThis are passed on to handleErrors for error
   // handling.
   _handleResult(aHandlers, aThis) {
     return aStanza => {
       if (aStanza.attributes.type == "result")
         return true;
       return this.handleErrors(aHandlers, aThis)(aStanza);
@@ -1947,25 +1927,23 @@ var XMPPAccountPrototype = {
     if (this._pendingList)
       this._roomInfoCallbacks.add(aCallback);
   },
 
   onRoomDiscovery(aStanza) {
     let query = aStanza.getElement(["query"]);
     if (!query || query.uri != Stanza.NS.disco_items) {
       this.LOG("Could not get rooms for this server: " + this._jid.domain);
-      return true;
+      return;
     }
 
     // XEP-0059: Result Set Management.
     let set = query.getElement(["set"]);
     let last = set ? set.getElement(["last"]) : null;
     if (last) {
-      let after = Stanza.node("after", null, null, last.innerText);
-      let setNode = Stanza.node("set", Stanza.NS.rsm, null, after);
       let iq = Stanza.iq("get", null, this._mucService,
                          Stanza.node("query", Stanza.NS.disco_items));
       this.sendStanza(iq, this.onRoomDiscovery, this);
     }
     else
       this._pendingList = false;
 
     let rooms = [];