Bug 1478572 - Turn on ESLint in mail/components/compose; r=jorgk, aceman
authorGeoff Lankow <geoff@darktrojan.net>
Wed, 26 Sep 2018 11:32:06 +1200
changeset 33228 49bf37634232a6237ccc84219a365000affc9739
parent 33227 bff3cba93b7ce29a2a0747c540e4ec59461b54b1
child 33229 9a567595d18a5e0a8aa8ba229fba6e080a82a620
push id387
push userclokep@gmail.com
push dateMon, 10 Dec 2018 21:30:47 +0000
reviewersjorgk, aceman
bugs1478572
Bug 1478572 - Turn on ESLint in mail/components/compose; r=jorgk, aceman
.eslintignore
mail/components/compose/content/.eslintrc.js
mail/components/compose/content/MsgComposeCommands.js
mail/components/compose/content/addressingWidgetOverlay.js
mail/components/compose/content/bigFileObserver.js
mail/components/compose/content/cloudAttachmentLinkManager.js
--- a/.eslintignore
+++ b/.eslintignore
@@ -47,17 +47,16 @@ mailnews/test/*
 mailnews/extensions/*
 !mailnews/extensions/newsblog
 
 # mail exclusions
 mail/app/**
 mail/base/**
 mail/branding/**
 mail/components/cloudfile/**
-mail/components/compose/**
 mail/components/im/**
 mail/components/newmailaccount/**
 mail/components/search/**
 mail/config/**
 mail/extensions/**
 mail/installer/**
 mail/locales/**
 mail/test/**
new file mode 100644
--- /dev/null
+++ b/mail/components/compose/content/.eslintrc.js
@@ -0,0 +1,57 @@
+"use strict";
+/* eslint-env node */
+
+module.exports = {
+  globals: {
+    // editor/ui/composer/content/ComposerCommands.js
+    doStatefulCommand: true,
+    SaveDocument: true,
+    // editor/ui/composer/content/editor.js
+    EditorCleanup: true,
+    EditorSetFontSize: true,
+    EditorSharedStartup: true,
+    gChromeState: true,
+    gDefaultBackgroundColor: true,
+    gDefaultTextColor: true,
+    GetBodyElement: true,
+    initLocalFontFaceMenu: true,
+    onBackgroundColorChange: true,
+    onFontColorChange: true,
+    // editor/ui/composer/content/editorUtilities.js:
+    GetCurrentCommandManager: true,
+    GetCurrentEditor: true,
+    GetCurrentEditorElement: true,
+
+    // mail/base/content/contentAreaClick.js
+    openLinkExternally: true,
+    // mail/base/content/mailCore.js
+    CreateAttachmentTransferData: true,
+    MailToolboxCustomizeDone: true,
+    openOptionsDialog: true,
+    // mail/base/content/mail-compacttheme.js
+    CompactTheme: true,
+    // mail/base/content/nsDragAndDrop.js
+    FlavourSet: true,
+    nsDragAndDrop: true,
+    // mail/base/content/toolbarIconColor.js
+    ToolbarIconColor: true,
+    // mail/base/content/utilityOverlay.js
+    goToggleToolbar: true,
+    openContentTab: true,
+
+    // mailnews/addrbook/content/abDragDrop.js
+    DragAddressOverTargetControl: true,
+    // mailnews/base/prefs/content/accountUtils.js
+    MsgAccountManager: true,
+    verifyAccounts: true,
+
+    // toolkit/components/printing/content/printUtils.js
+    PrintUtils: true,
+    // toolkit/content/globalOverlay.js
+    goDoCommand: true,
+    goSetCommandEnabled: true,
+    goUpdateCommand: true,
+    // toolkit/content/viewZoomOverlay.js
+    ZoomManager: true,
+  },
+};
--- a/mail/components/compose/content/MsgComposeCommands.js
+++ b/mail/components/compose/content/MsgComposeCommands.js
@@ -1,53 +1,41 @@
 /* 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 addressingWidgetOverlay.js */
+
 /**
  * Commands for the message composition window.
  */
 
 // Ensure the activity modules are loaded for this window.
 ChromeUtils.import("resource:///modules/activity/activityModules.jsm");
-ChromeUtils.import("resource:///modules/attachmentChecker.js");
+const { GetAttachmentKeywords } = ChromeUtils.import("resource:///modules/attachmentChecker.js", null);
 ChromeUtils.import("resource:///modules/cloudFileAccounts.js");
-ChromeUtils.import("resource:///modules/mimeParser.jsm");
-ChromeUtils.import("resource:///modules/errUtils.js");
-ChromeUtils.import("resource:///modules/folderUtils.jsm");
-ChromeUtils.import("resource:///modules/iteratorUtils.jsm");
+const { MimeParser } = ChromeUtils.import("resource:///modules/mimeParser.jsm", null);
+const { allAccountsSorted } = ChromeUtils.import("resource:///modules/folderUtils.jsm", null);
+const { fixIterator, toArray } = ChromeUtils.import("resource:///modules/iteratorUtils.jsm", null);
 ChromeUtils.import("resource:///modules/MailServices.jsm");
 ChromeUtils.import("resource:///modules/MailUtils.js");
 ChromeUtils.import("resource://gre/modules/InlineSpellChecker.jsm");
 ChromeUtils.import("resource://gre/modules/PluralForm.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
 
 ChromeUtils.defineModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
 ChromeUtils.defineModuleGetter(this, "ShortcutUtils",
                                "resource://gre/modules/ShortcutUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   LightweightThemeManager: "resource://gre/modules/LightweightThemeManager.jsm",
 });
 
-/**
- * interfaces
- */
-var nsIMsgCompDeliverMode = Ci.nsIMsgCompDeliverMode;
-var nsIMsgCompSendFormat = Ci.nsIMsgCompSendFormat;
-var nsIMsgCompConvertible = Ci.nsIMsgCompConvertible;
-var nsIMsgCompType = Ci.nsIMsgCompType;
-var nsIMsgCompFormat = Ci.nsIMsgCompFormat;
-var nsIAbPreferMailFormat = Ci.nsIAbPreferMailFormat;
-var nsIPlaintextEditorMail = Ci.nsIPlaintextEditor;
-var nsISupportsString = Ci.nsISupportsString;
-var mozISpellCheckingEngine = Ci.mozISpellCheckingEngine;
-
 var sDictCount = 0;
 
 /**
  * Global message window object. This is used by mail-offline.js and therefore
  * should not be renamed. We need to avoid doing this kind of cross file global
  * stuff in the future and instead pass this object as parameter when needed by
  * functions in the other js file.
  */
@@ -113,53 +101,51 @@ var gAutoSaveInterval;
 var gAutoSaveTimeout;
 var gAutoSaveKickedIn;
 var gEditingDraft;
 var gAttachmentsSize;
 var gNumUploadingAttachments;
 
 var kComposeAttachDirPrefName = "mail.compose.attach.dir";
 
-function InitializeGlobalVariables()
-{
+function InitializeGlobalVariables() {
   gMessenger = Cc["@mozilla.org/messenger;1"]
                  .createInstance(Ci.nsIMessenger);
 
   gMsgCompose = null;
   gOriginalMsgURI = null;
   gWindowLocked = false;
   gContentChanged = false;
   gSubjectChanged = false;
   gCurrentIdentity = null;
   defaultSaveOperation = "draft";
   gSendOperationInProgress = false;
   gSaveOperationInProgress = false;
   gAutoSaving = false;
   gCloseWindowAfterSave = false;
   gSavedSendNowKey = null;
-  gSendFormat = nsIMsgCompSendFormat.AskUser;
-  gCharsetConvertManager = Cc['@mozilla.org/charset-converter-manager;1'].getService(Ci.nsICharsetConverterManager);
+  gSendFormat = Ci.nsIMsgCompSendFormat.AskUser;
+  gCharsetConvertManager = Cc["@mozilla.org/charset-converter-manager;1"].getService(Ci.nsICharsetConverterManager);
   gManualAttachmentReminder = false;
   gDisableAttachmentReminder = false;
   gLanguageObserver = null;
 
   gLastWindowToHaveFocus = null;
   gReceiptOptionChanged = false;
   gDSNOptionChanged = false;
   gAttachVCardOptionChanged = false;
   gAttachmentsSize = 0;
   gNumUploadingAttachments = 0;
   msgWindow = Cc["@mozilla.org/messenger/msgwindow;1"]
                 .createInstance(Ci.nsIMsgWindow);
   MailServices.mailSession.AddMsgWindow(msgWindow);
 }
 InitializeGlobalVariables();
 
-function ReleaseGlobalVariables()
-{
+function ReleaseGlobalVariables() {
   gCurrentIdentity = null;
   gCharsetConvertManager = null;
   gMsgCompose = null;
   gOriginalMsgURI = null;
   gMessenger = null;
   gDisableAttachmentReminder = false;
   _gComposeBundle = null;
   MailServices.mailSession.RemoveMsgWindow(msgWindow);
@@ -179,62 +165,61 @@ function getPrettyKey(aKeyId) {
 /**
  * Disables or enables editable elements in the window.
  * The elements to operate on are marked with the "disableonsend" attribute.
  * This includes elements like the address list, attachment list, subject
  * and message body.
  *
  * @param aDisable  true = disable items. false = enable items.
  */
-function updateEditableFields(aDisable)
-{
+function updateEditableFields(aDisable) {
   if (!gMsgCompose)
     return;
 
   if (aDisable)
-    gMsgCompose.editor.flags |= nsIPlaintextEditorMail.eEditorReadonlyMask;
+    gMsgCompose.editor.flags |= Ci.nsIPlaintextEditor.eEditorReadonlyMask;
   else
-    gMsgCompose.editor.flags &= ~nsIPlaintextEditorMail.eEditorReadonlyMask;
+    gMsgCompose.editor.flags &= ~Ci.nsIPlaintextEditor.eEditorReadonlyMask;
 
   let elements = document.querySelectorAll('[disableonsend="true"]');
   for (let i = 0; i < elements.length; i++)
     elements[i].disabled = aDisable;
 }
 
 var PrintPreviewListener = {
-  getPrintPreviewBrowser: function() {
+  getPrintPreviewBrowser() {
     let browser = document.getElementById("cppBrowser");
     if (!gChromeState)
-      gChromeState = new Object;
+      gChromeState = {};
     preparePrintPreviewTitleHeader();
     if (!browser) {
       browser = document.createElement("browser");
       browser.setAttribute("id", "cppBrowser");
       browser.setAttribute("flex", "1");
       browser.setAttribute("disablehistory", "true");
       browser.setAttribute("type", "content");
       document.getElementById("headers-parent").
         insertBefore(browser, document.getElementById("appcontent"));
     }
     return browser;
   },
-  getSourceBrowser: function() {
+  getSourceBrowser() {
     return GetCurrentEditorElement();
   },
-  getNavToolbox: function() {
+  getNavToolbox() {
     return document.getElementById("compose-toolbox");
   },
-  onEnter: function() {
+  onEnter() {
     toggleAffectedChrome(true);
   },
-  onExit: function() {
+  onExit() {
     document.getElementById("cppBrowser").collapsed = true;
     toggleAffectedChrome(false);
-  }
-}
+  },
+};
 
 function sidebar_is_hidden() {
   let sidebar_box = document.getElementById("sidebar-box");
   return sidebar_box.getAttribute("hidden") == "true";
 }
 
 function sidebar_is_collapsed() {
   let sidebar_splitter = document.getElementById("sidebar-splitter");
@@ -261,64 +246,60 @@ function SidebarGetState() {
 function preparePrintPreviewTitleHeader() {
   // For title header of print (preview), use message content document title
   // if existing, otherwise message subject. To apply the message subject,
   // we temporarily change the title of message content document before going
   // into print preview (workaround for bug 1396455).
   let msgDocument = getBrowser().contentDocument;
   let msgSubject = GetMsgSubjectElement().value.trim() ||
                    getComposeBundle().getString("defaultSubject");
-  gChromeState.msgDocumentHadTitle = !!msgDocument.querySelector('title');
+  gChromeState.msgDocumentHadTitle = !!msgDocument.querySelector("title");
   gChromeState.msgDocumentTitle = msgDocument.title;
   msgDocument.title = msgDocument.title || msgSubject;
 }
 
 /**
  * When going in and out of Print Preview, hide or show respective UI elements.
  *
  * @param aHide  true:  Hide UI elements to go into print preview mode.
  *               false: Restore UI elements to their previous state to exit
  *                      print preview mode.
  */
-function toggleAffectedChrome(aHide)
-{
+function toggleAffectedChrome(aHide) {
   // Chrome to toggle includes:
   //   (*) menubar
   //   (*) toolbox
   //   (*) message headers box
   //   (*) sidebar
   //   (*) statusbar
   let statusbar = document.getElementById("status-bar");
 
   // Contacts Sidebar states map as follows:
   //   hidden    => hide/show nothing
   //   collapsed => hide/show only the splitter
   //   shown     => hide/show the splitter and the box
 
-  if (aHide)
-  {
+  if (aHide) {
     // Going into print preview mode.
     SetComposeWindowTitle(true);
     // Hide headers box, Contacts Sidebar, and Status Bar
     // after remembering their current state where applicable.
     document.getElementById("headers-box").hidden = true;
     gChromeState.sidebar = SidebarGetState();
     SidebarSetState("hidden");
     gChromeState.statusbarWasHidden = statusbar.hidden;
     statusbar.hidden = true;
-  }
-  else
-  {
+  } else {
     // Restoring normal mode (i.e. leaving print preview mode).
     SetComposeWindowTitle();
     // Restore original "empty" HTML document title of the message, or remove
     // the temporary title tag altogether if there was none before.
     let msgDocument = getBrowser().contentDocument;
     if (!gChromeState.msgDocumentHadTitle) {
-      msgDocument.querySelector('title').remove();
+      msgDocument.querySelector("title").remove();
     } else {
       msgDocument.title = gChromeState.msgDocumentTitle;
     }
 
     // Restore Contacts Sidebar, headers box, and Status Bar.
     SidebarSetState(gChromeState.sidebar);
     document.getElementById("headers-box").hidden = false;
     statusbar.hidden = gChromeState.statusbarWasHidden;
@@ -328,27 +309,27 @@ function toggleAffectedChrome(aHide)
   document.getElementById("appcontent").collapsed = aHide;
 }
 
 /**
  * Small helper function to check whether the node passed in is a signature.
  * Note that a text node is not a DOM element, hence .localName can't be used.
  */
 function isSignature(aNode) {
-  return ["DIV","PRE"].includes(aNode.nodeName) &&
+  return ["DIV", "PRE"].includes(aNode.nodeName) &&
          aNode.classList.contains("moz-signature");
 }
 
 var stateListener = {
-  NotifyComposeFieldsReady: function() {
+  NotifyComposeFieldsReady() {
     ComposeFieldsReady();
     updateSendCommands(true);
   },
 
-  NotifyComposeBodyReady: function() {
+  NotifyComposeBodyReady() {
     // Look all the possible compose types (nsIMsgComposeParams.idl):
     switch (gComposeType) {
 
     case Ci.nsIMsgCompType.MailToUrl:
       gBodyFromArgs = true;
     case Ci.nsIMsgCompType.New:
     case Ci.nsIMsgCompType.NewsPost:
     case Ci.nsIMsgCompType.ForwardAsAttachment:
@@ -404,17 +385,17 @@ var stateListener = {
       editor.resetModificationCount();
       selection.collapse(startNode, start);
     }
     if (gMsgCompose.composeHTML)
       loadHTMLMsgPrefs();
     AdjustFocus();
   },
 
-  NotifyComposeBodyReadyNew: function() {
+  NotifyComposeBodyReadyNew() {
     let useParagraph = Services.prefs.getBoolPref("mail.compose.default_to_paragraph");
     let insertParagraph = gMsgCompose.composeHTML && useParagraph;
 
     let mailBody = getBrowser().contentDocument.querySelector("body");
     if (insertParagraph && gBodyFromArgs) {
       // Check for "empty" body before allowing paragraph to be inserted.
       // Non-empty bodies in a new message can occur when clicking on a
       // mailto link or when using the command line option -compose.
@@ -444,17 +425,17 @@ var stateListener = {
       editor.beginningOfDocument();
       editor.enableUndo(true);
       editor.resetModificationCount();
     } else {
       document.getElementById("cmd_paragraphState").setAttribute("state", "");
     }
   },
 
-  NotifyComposeBodyReadyReply: function() {
+  NotifyComposeBodyReadyReply() {
     // Control insertion of line breaks.
     let useParagraph = Services.prefs.getBoolPref("mail.compose.default_to_paragraph");
     if (gMsgCompose.composeHTML && useParagraph) {
       let mailBody = getBrowser().contentDocument.querySelector("body");
       let editor = GetCurrentEditor();
       let selection = editor.selection;
 
       // Make sure the selection isn't inside the signature.
@@ -488,17 +469,17 @@ var stateListener = {
 
       editor.enableUndo(true);
       editor.resetModificationCount();
     } else {
       document.getElementById("cmd_paragraphState").setAttribute("state", "");
     }
   },
 
-  NotifyComposeBodyReadyForwardInline: function() {
+  NotifyComposeBodyReadyForwardInline() {
     let mailBody = getBrowser().contentDocument.querySelector("body");
     let editor = GetCurrentEditor();
     let selection = editor.selection;
 
     editor.enableUndo(false);
 
     // Control insertion of line breaks.
     selection.collapse(mailBody, 0);
@@ -517,547 +498,533 @@ var stateListener = {
       document.getElementById("cmd_paragraphState").setAttribute("state", "");
     }
 
     editor.beginningOfDocument();
     editor.enableUndo(true);
     editor.resetModificationCount();
   },
 
-  ComposeProcessDone: function(aResult) {
+  ComposeProcessDone(aResult) {
     ToggleWindowLock(false);
 
-    if (aResult== Cr.NS_OK)
-    {
+    if (aResult == Cr.NS_OK) {
       if (!gAutoSaving)
         SetContentAndBodyAsUnmodified();
 
-      if (gCloseWindowAfterSave)
-      {
+      if (gCloseWindowAfterSave) {
         // Notify the SendListener that Send has been aborted and Stopped
         if (gMsgCompose)
           gMsgCompose.onSendNotPerformed(null, Cr.NS_ERROR_ABORT);
 
         MsgComposeCloseWindow();
       }
-    }
-    // else if we failed to save, and we're autosaving, need to re-mark the editor
-    // as changed, so that we won't lose the changes.
-    else if (gAutoSaving)
-    {
+    } else if (gAutoSaving) {
+      // If we failed to save, and we're autosaving, need to re-mark the editor
+      // as changed, so that we won't lose the changes.
       gMsgCompose.bodyModified = true;
       gContentChanged = true;
     }
     gAutoSaving = false;
     gCloseWindowAfterSave = false;
   },
 
-  SaveInFolderDone: function(folderURI) {
+  SaveInFolderDone(folderURI) {
     DisplaySaveFolderDlg(folderURI);
-  }
+  },
 };
 
 var gSendListener = {
   // nsIMsgSendListener
-  onStartSending: function (aMsgID, aMsgSize) {},
-  onProgress: function (aMsgID, aProgress, aProgressMax) {},
-  onStatus: function (aMsgID, aMsg) {},
-  onStopSending: function (aMsgID, aStatus, aMsg, aReturnFile) {
+  onStartSending(aMsgID, aMsgSize) {},
+  onProgress(aMsgID, aProgress, aProgressMax) {},
+  onStatus(aMsgID, aMsg) {},
+  onStopSending(aMsgID, aStatus, aMsg, aReturnFile) {
     if (Components.isSuccessCode(aStatus))
       Services.obs.notifyObservers(null, "mail:composeSendSucceeded");
   },
-  onGetDraftFolderURI: function (aFolderURI) {},
-  onSendNotPerformed: function (aMsgID, aStatus) {},
+  onGetDraftFolderURI(aFolderURI) {},
+  onSendNotPerformed(aMsgID, aStatus) {},
 };
 
 // all progress notifications are done through the nsIWebProgressListener implementation...
 var progressListener = {
-    onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus)
-    {
-      if (aStateFlags & Ci.nsIWebProgressListener.STATE_START)
-      {
-        document.getElementById('compose-progressmeter').setAttribute( "mode", "undetermined" );
+    onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) {
+      if (aStateFlags & Ci.nsIWebProgressListener.STATE_START) {
+        document.getElementById("compose-progressmeter").setAttribute("mode", "undetermined");
         document.getElementById("statusbar-progresspanel").collapsed = false;
       }
 
-      if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP)
-      {
+      if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
         gSendOperationInProgress = false;
         gSaveOperationInProgress = false;
-        document.getElementById('compose-progressmeter').setAttribute( "mode", "normal" );
-        document.getElementById('compose-progressmeter').setAttribute( "value", 0 );
+        document.getElementById("compose-progressmeter").setAttribute("mode", "normal");
+        document.getElementById("compose-progressmeter").setAttribute("value", 0);
         document.getElementById("statusbar-progresspanel").collapsed = true;
-        document.getElementById('statusText').setAttribute('label', '');
+        document.getElementById("statusText").setAttribute("label", "");
       }
     },
 
-    onProgressChange: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress)
-    {
+    onProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress) {
       // Calculate percentage.
       var percent;
-      if ( aMaxTotalProgress > 0 )
-      {
-        percent = Math.round( (aCurTotalProgress*100)/aMaxTotalProgress );
-        if ( percent > 100 )
+      if (aMaxTotalProgress > 0) {
+        percent = Math.round((aCurTotalProgress * 100) / aMaxTotalProgress);
+        if (percent > 100)
           percent = 100;
 
-        document.getElementById('compose-progressmeter').removeAttribute("mode");
+        document.getElementById("compose-progressmeter").removeAttribute("mode");
 
         // Advance progress meter.
-        document.getElementById('compose-progressmeter').setAttribute( "value", percent );
-      }
-      else
-      {
+        document.getElementById("compose-progressmeter").setAttribute("value", percent);
+      } else {
         // Progress meter should be barber-pole in this case.
-        document.getElementById('compose-progressmeter').setAttribute( "mode", "undetermined" );
+        document.getElementById("compose-progressmeter").setAttribute("mode", "undetermined");
       }
     },
 
-    onLocationChange: function(aWebProgress, aRequest, aLocation, aFlags)
-    {
+    onLocationChange(aWebProgress, aRequest, aLocation, aFlags) {
       // we can ignore this notification
     },
 
-    onStatusChange: function(aWebProgress, aRequest, aStatus, aMessage)
-    {
+    onStatusChange(aWebProgress, aRequest, aStatus, aMessage) {
       // Looks like it's possible that we get call while the document has been already delete!
       // therefore we need to protect ourself by using try/catch
       try {
         let statusText = document.getElementById("statusText");
         if (statusText)
           statusText.setAttribute("label", aMessage);
       } catch (ex) {}
     },
 
-    onSecurityChange: function(aWebProgress, aRequest, state)
-    {
+    onSecurityChange(aWebProgress, aRequest, state) {
       // we can ignore this notification
     },
 
     QueryInterface: ChromeUtils.generateQI(["nsIWebProgressListener",
                                             "nsISupportsWeakReference"]),
 };
 
 var defaultController = {
   commands: {
     cmd_attachFile: {
-      isEnabled: function() {
+      isEnabled() {
         return !gWindowLocked;
       },
-      doCommand: function() {
+      doCommand() {
         AttachFile();
-      }
+      },
     },
 
     cmd_attachCloud: {
-      isEnabled: function() {
+      isEnabled() {
         // Hide the command entirely if there are no cloud accounts or
         // the feature is disbled.
         let cmd = document.getElementById("cmd_attachCloud");
         cmd.hidden = !Services.prefs.getBoolPref("mail.cloud_files.enabled") ||
                      (cloudFileAccounts.accounts.length == 0) ||
                      Services.io.offline;
         return !cmd.hidden && !gWindowLocked;
       },
-      doCommand: function() {
+      doCommand() {
         // We should never actually call this, since the <command> node calls
         // a different function.
-      }
+      },
     },
 
     cmd_attachPage: {
-      isEnabled: function() {
+      isEnabled() {
         return !gWindowLocked;
       },
-      doCommand: function() {
+      doCommand() {
         AttachPage();
-      }
+      },
     },
 
     cmd_toggleAttachmentPane: {
-      isEnabled: function() {
+      isEnabled() {
         let cmdToggleAttachmentPane =
           document.getElementById("cmd_toggleAttachmentPane");
         let paneShown = !document.getElementById("attachments-box").collapsed;
         cmdToggleAttachmentPane.setAttribute("checked", paneShown);
 
         // Enable this command when the compose window isn't locked.
         return !gWindowLocked;
       },
-      doCommand: function() {
+      doCommand() {
         toggleAttachmentPane();
-      }
+      },
     },
 
     cmd_reorderAttachments: {
-      isEnabled: function() {
+      isEnabled() {
         if (attachmentsCount() == 0) {
           let reorderAttachmentsPanel =
             document.getElementById("reorderAttachmentsPanel");
           if (reorderAttachmentsPanel.state == "open") {
             // When the panel is open and all attachments get deleted,
             // we get notified here and want to close the panel.
             reorderAttachmentsPanel.hidePopup();
           }
         }
         return (attachmentsCount() > 1);
       },
-      doCommand: function() {
+      doCommand() {
         showReorderAttachmentsPanel();
-      }
+      },
     },
 
     cmd_removeAllAttachments: {
-      isEnabled: function() {
+      isEnabled() {
         return !gWindowLocked && attachmentsCount() > 0;
       },
-      doCommand: function() {
+      doCommand() {
         RemoveAllAttachments();
-      }
+      },
     },
 
     cmd_close: {
-      isEnabled: function() {
+      isEnabled() {
         return !gWindowLocked;
       },
-      doCommand: function() {
+      doCommand() {
         DoCommandClose();
-      }
+      },
     },
 
     cmd_saveDefault: {
-      isEnabled: function() {
+      isEnabled() {
         return !gWindowLocked;
       },
-      doCommand: function() {
+      doCommand() {
         Save();
-      }
+      },
     },
 
     cmd_saveAsFile: {
-      isEnabled: function() {
+      isEnabled() {
         return !gWindowLocked;
       },
-      doCommand: function() {
+      doCommand() {
         SaveAsFile(true);
-      }
+      },
     },
 
     cmd_saveAsDraft: {
-      isEnabled: function() {
+      isEnabled() {
         return !gWindowLocked;
       },
-      doCommand: function() {
+      doCommand() {
         SaveAsDraft();
-      }
+      },
     },
 
     cmd_saveAsTemplate: {
-      isEnabled: function() {
+      isEnabled() {
         return !gWindowLocked;
       },
-      doCommand: function() {
+      doCommand() {
         SaveAsTemplate();
-      }
+      },
     },
 
     cmd_sendButton: {
-      isEnabled: function() {
+      isEnabled() {
         return !gWindowLocked && !gNumUploadingAttachments && !gSendLocked;
       },
-      doCommand: function() {
+      doCommand() {
         if (Services.io.offline)
           SendMessageLater();
         else
           SendMessage();
-      }
+      },
     },
 
     cmd_sendNow: {
-      isEnabled: function() {
+      isEnabled() {
         return !gWindowLocked && !Services.io.offline && !gSendLocked &&
                !gNumUploadingAttachments;
       },
-      doCommand: function() {
+      doCommand() {
         SendMessage();
-      }
+      },
     },
 
     cmd_sendLater: {
-      isEnabled: function() {
+      isEnabled() {
         return !gWindowLocked && !gNumUploadingAttachments && !gSendLocked;
       },
-      doCommand: function() {
+      doCommand() {
         SendMessageLater();
-      }
+      },
     },
 
     cmd_sendWithCheck: {
-      isEnabled: function() {
+      isEnabled() {
         return !gWindowLocked && !gNumUploadingAttachments && !gSendLocked;
       },
-      doCommand: function() {
+      doCommand() {
         SendMessageWithCheck();
-      }
+      },
     },
 
     cmd_printSetup: {
-      isEnabled: function() {
+      isEnabled() {
         return !gWindowLocked;
       },
-      doCommand: function() {
+      doCommand() {
         PrintUtils.showPageSetup();
-      }
+      },
     },
 
     cmd_print: {
-      isEnabled: function() {
+      isEnabled() {
         return !gWindowLocked;
       },
-      doCommand: function() {
+      doCommand() {
         DoCommandPrint();
-      }
+      },
     },
 
     cmd_printPreview: {
-      isEnabled: function() {
+      isEnabled() {
         return !gWindowLocked;
       },
-      doCommand: function() {
+      doCommand() {
         DoCommandPrintPreview();
-      }
+      },
     },
 
     cmd_delete: {
-      isEnabled: function() {
+      isEnabled() {
         let cmdDelete = document.getElementById("cmd_delete");
         let textValue = cmdDelete.getAttribute("valueDefault");
         let accesskeyValue = cmdDelete.getAttribute("valueDefaultAccessKey");
 
         cmdDelete.setAttribute("label", textValue);
         cmdDelete.setAttribute("accesskey", accesskeyValue);
 
         return false;
       },
-      doCommand: function() {
-      }
+      doCommand() {
+      },
     },
 
     cmd_account: {
-      isEnabled: function() {
+      isEnabled() {
         return true;
       },
-      doCommand: function() {
+      doCommand() {
         let currentAccountKey = getCurrentAccountKey();
         let account = MailServices.accounts.getAccount(currentAccountKey);
         MsgAccountManager(null, account.incomingServer);
-      }
+      },
     },
 
     cmd_showFormatToolbar: {
-      isEnabled: function() {
+      isEnabled() {
         return gMsgCompose && gMsgCompose.composeHTML;
       },
-      doCommand: function() {
+      doCommand() {
         goToggleToolbar("FormatToolbar", "menu_showFormatToolbar");
-      }
+      },
     },
 
     cmd_quoteMessage: {
-      isEnabled: function() {
+      isEnabled() {
         let selectedURIs = GetSelectedMessages();
-        return (selectedURIs && selectedURIs.length > 0)
+        return (selectedURIs && selectedURIs.length > 0);
       },
-      doCommand: function() {
+      doCommand() {
         QuoteSelectedMessage();
-      }
+      },
     },
 
     cmd_fullZoomReduce: {
-      isEnabled: function () {
+      isEnabled() {
         return true;
       },
-      doCommand: function() {
+      doCommand() {
         ZoomManager.reduce();
-      }
+      },
     },
 
     cmd_fullZoomEnlarge: {
-      isEnabled: function () {
+      isEnabled() {
         return true;
       },
-      doCommand: function() {
+      doCommand() {
         ZoomManager.enlarge();
-      }
+      },
     },
 
     cmd_fullZoomReset: {
-      isEnabled: function () {
+      isEnabled() {
         return true;
       },
-      doCommand: function() {
+      doCommand() {
         ZoomManager.reset();
-      }
+      },
     },
 
     cmd_spelling: {
-      isEnabled: function() {
+      isEnabled() {
         return true;
       },
-      doCommand: function() {
+      doCommand() {
         window.cancelSendMessage = false;
         var skipBlockQuotes =
           (window.document.documentElement.getAttribute("windowtype") ==
           "msgcompose");
         window.openDialog("chrome://editor/content/EdSpellCheck.xul", "_blank",
                           "dialog,close,titlebar,modal,resizable",
                           false, skipBlockQuotes, true);
-      }
+      },
     },
 
     cmd_fullZoomToggle: {
-      isEnabled: function () {
+      isEnabled() {
         return true;
       },
-      doCommand: function() {
+      doCommand() {
         ZoomManager.toggleZoom();
-      }
+      },
     },
   },
 
-  supportsCommand: function(aCommand) {
+  supportsCommand(aCommand) {
     return (aCommand in this.commands);
   },
 
-  isCommandEnabled: function(aCommand) {
+  isCommandEnabled(aCommand) {
     if (!this.supportsCommand(aCommand))
       return false;
     return this.commands[aCommand].isEnabled();
   },
 
-  doCommand: function(aCommand) {
+  doCommand(aCommand) {
     if (!this.supportsCommand(aCommand))
       return;
     var cmd = this.commands[aCommand];
     if (!cmd.isEnabled())
       return;
     cmd.doCommand();
   },
 
-  onEvent: function(event) {},
+  onEvent(event) {},
 };
 
 var attachmentBucketController = {
   commands: {
     cmd_selectAll: {
-      isEnabled: function() {
+      isEnabled() {
         return true;
       },
-      doCommand: function() {
+      doCommand() {
         document.getElementById("attachmentBucket").selectAll();
-      }
+      },
     },
 
     cmd_delete: {
-      isEnabled: function() {
+      isEnabled() {
         let selectedCount = attachmentsSelectedCount();
         let cmdDelete = document.getElementById("cmd_delete");
         let textValue = getComposeBundle().getString("removeAttachmentMsgs");
         textValue = PluralForm.get(selectedCount, textValue);
         let accesskeyValue = cmdDelete.getAttribute("valueRemoveAttachmentAccessKey");
         cmdDelete.setAttribute("label", textValue);
         cmdDelete.setAttribute("accesskey", accesskeyValue);
 
         return selectedCount > 0;
       },
-      doCommand: function() {
+      doCommand() {
         RemoveSelectedAttachment();
-      }
+      },
     },
 
     cmd_openAttachment: {
-      isEnabled: function() {
+      isEnabled() {
         return attachmentsSelectedCount() == 1;
       },
-      doCommand: function() {
+      doCommand() {
         OpenSelectedAttachment();
-      }
+      },
     },
 
     cmd_renameAttachment: {
-      isEnabled: function() {
+      isEnabled() {
         return attachmentsSelectedCount() == 1;
       },
-      doCommand: function() {
+      doCommand() {
         RenameSelectedAttachment();
-      }
+      },
     },
 
     cmd_moveAttachmentUp: {
-      isEnabled: function() {
+      isEnabled() {
         return attachmentsSelectedCount() > 0 &&
                !attachmentsSelectionIsBlock("top");
       },
-      doCommand: function() {
+      doCommand() {
         moveSelectedAttachments("up");
-      }
+      },
     },
 
     cmd_moveAttachmentDown: {
-      isEnabled: function() {
+      isEnabled() {
         return attachmentsSelectedCount() > 0 &&
                !attachmentsSelectionIsBlock("bottom");
       },
-      doCommand: function() {
+      doCommand() {
         moveSelectedAttachments("down");
-      }
+      },
     },
 
     cmd_moveAttachmentBundleUp: {
-      isEnabled: function() {
+      isEnabled() {
         return attachmentsSelectedCount() > 1 &&
                !attachmentsSelectionIsBlock();
       },
-      doCommand: function() {
+      doCommand() {
         moveSelectedAttachments("bundleUp");
-      }
+      },
     },
 
     cmd_moveAttachmentBundleDown: {
-      isEnabled: function() {
+      isEnabled() {
         return attachmentsSelectedCount() > 1 &&
                !attachmentsSelectionIsBlock();
       },
-      doCommand: function() {
+      doCommand() {
         moveSelectedAttachments("bundleDown");
-      }
+      },
     },
 
     cmd_moveAttachmentTop: {
-      isEnabled: function() {
+      isEnabled() {
         return attachmentsSelectedCount() > 0 &&
                !attachmentsSelectionIsBlock("top");
       },
-      doCommand: function() {
+      doCommand() {
         moveSelectedAttachments("top");
-      }
+      },
     },
 
     cmd_moveAttachmentBottom: {
-      isEnabled: function() {
+      isEnabled() {
         return attachmentsSelectedCount() > 0 &&
                !attachmentsSelectionIsBlock("bottom");
       },
-      doCommand: function() {
+      doCommand() {
         moveSelectedAttachments("bottom");
-      }
+      },
     },
 
     cmd_sortAttachmentsToggle: {
-      isEnabled: function() {
+      isEnabled() {
         let attachmentsSelCount = attachmentsSelectedCount();
         let sortSelection;
         let currSortOrder;
         let isBlock;
         let btnAscending;
         let toggleCmd = document.getElementById("cmd_sortAttachmentsToggle");
         let toggleBtn = document.getElementById("btn_sortAttachmentsToggle");
         let sortDirection;
@@ -1083,17 +1050,17 @@ var attachmentBucketController = {
           } else {
             sortDirection = "descending";
             btnLabelAttr = "label-selection-ZA";
           }
         } else { // attachmentsSelectedCount() <= 1 or all attachments selected
           // Sort all attachments.
           sortSelection = false;
           currSortOrder = attachmentsGetSortOrder();
-          btnAscending = !(currSortOrder == "ascending")
+          btnAscending = !(currSortOrder == "ascending");
           // Set sortDirection for toggleCmd, and respective button face.
           if (btnAscending) {
             sortDirection = "ascending";
             btnLabelAttr = "label-AZ";
           } else {
             sortDirection = "descending";
             btnLabelAttr = "label-ZA";
           }
@@ -1103,23 +1070,23 @@ var attachmentBucketController = {
         toggleCmd.setAttribute("sortdirection", sortDirection);
         // The button's icon is set dynamically via CSS involving the button's
         // sortdirection attribute, which is forwarded by the command.
         toggleBtn.setAttribute("label", toggleBtn.getAttribute(btnLabelAttr));
 
         return sortSelection ? !(currSortOrder == "equivalent" && isBlock)
                              : !(currSortOrder == "equivalent");
       },
-      doCommand: function() {
+      doCommand() {
         moveSelectedAttachments("toggleSort");
-      }
+      },
     },
 
     cmd_convertCloud: {
-      isEnabled: function() {
+      isEnabled() {
         // Hide the command entirely if Filelink is disabled, or if there are
         // no cloud accounts.
         let cmd = document.getElementById("cmd_convertCloud");
 
         cmd.hidden = (!Services.prefs.getBoolPref("mail.cloud_files.enabled") ||
                       cloudFileAccounts.accounts.length == 0) ||
                       Services.io.offline;
         if (cmd.hidden)
@@ -1127,41 +1094,41 @@ var attachmentBucketController = {
 
         let bucket = document.getElementById("attachmentBucket");
         for (let item of bucket.selectedItems) {
           if (item.uploading)
             return false;
         }
         return true;
       },
-      doCommand: function() {
+      doCommand() {
         // We should never actually call this, since the <command> node calls
         // a different function.
-      }
+      },
     },
 
     cmd_convertAttachment: {
-      isEnabled: function() {
+      isEnabled() {
         if (!Services.prefs.getBoolPref("mail.cloud_files.enabled"))
           return false;
 
         let bucket = document.getElementById("attachmentBucket");
         for (let item of bucket.selectedItems) {
           if (item.uploading)
             return false;
         }
         return true;
       },
-      doCommand: function() {
+      doCommand() {
         convertSelectedToRegularAttachment();
-      }
+      },
     },
 
     cmd_cancelUpload: {
-      isEnabled: function() {
+      isEnabled() {
         let cmd = document.getElementById("composeAttachmentContext_cancelUploadItem");
 
         // If Filelink is disabled, hide this menuitem and bailout.
         if (!Services.prefs.getBoolPref("mail.cloud_files.enabled")) {
           cmd.hidden = true;
           return false;
         }
 
@@ -1175,136 +1142,127 @@ var attachmentBucketController = {
 
         // Hide the command entirely if the selected attachments aren't cloud
         // files.
         // For some reason, the hidden property isn't propagating from the cmd
         // to the menuitem.
         cmd.hidden = true;
         return false;
       },
-      doCommand: function() {
+      doCommand() {
         let fileHandler = Services.io.getProtocolHandler("file")
                                   .QueryInterface(Ci.nsIFileProtocolHandler);
 
         let bucket = document.getElementById("attachmentBucket");
         for (let item of bucket.selectedItems) {
           if (item && item.uploading) {
             let file = fileHandler.getFileFromURLSpec(item.attachment.url);
             item.cloudProvider.cancelFileUpload(file);
           }
         }
       },
     },
   },
 
-  supportsCommand: function(aCommand) {
+  supportsCommand(aCommand) {
     return (aCommand in this.commands);
   },
 
-  isCommandEnabled: function(aCommand) {
+  isCommandEnabled(aCommand) {
     if (!this.supportsCommand(aCommand))
       return false;
     return this.commands[aCommand].isEnabled();
   },
 
-  doCommand: function(aCommand) {
+  doCommand(aCommand) {
     if (!this.supportsCommand(aCommand))
       return;
     var cmd = this.commands[aCommand];
     if (!cmd.isEnabled())
       return;
     cmd.doCommand();
   },
 
-  onEvent: function(event) {},
+  onEvent(event) {},
 };
 
 /**
  * Start composing a new message.
  */
-function goOpenNewMessage(aEvent)
-{
+function goOpenNewMessage(aEvent) {
   // If aEvent is passed, check if Shift key was pressed for composition in
   // non-default format (HTML vs. plaintext).
   let msgCompFormat = (aEvent && aEvent.shiftKey) ?
     Ci.nsIMsgCompFormat.OppositeOfDefault :
     Ci.nsIMsgCompFormat.Default;
 
   let identity = getCurrentIdentity();
   MailServices.compose.OpenComposeWindow(null, null, null,
     Ci.nsIMsgCompType.New,
     msgCompFormat, identity, null);
 }
 
-function QuoteSelectedMessage()
-{
+function QuoteSelectedMessage() {
   var selectedURIs = GetSelectedMessages();
   if (selectedURIs)
     for (let i = 0; i < selectedURIs.length; i++)
       gMsgCompose.quoteMessage(selectedURIs[i]);
 }
 
-function GetSelectedMessages()
-{
+function GetSelectedMessages() {
   let mailWindow = Services.wm.getMostRecentWindow("mail:3pane");
   return (mailWindow) ? mailWindow.gFolderDisplay.selectedMessageUris : null;
 }
 
-function SetupCommandUpdateHandlers()
-{
+function SetupCommandUpdateHandlers() {
   let attachmentBucket = document.getElementById("attachmentBucket");
 
   top.controllers.appendController(defaultController);
   attachmentBucket.controllers.appendController(attachmentBucketController);
 
   document.getElementById("optionsMenuPopup")
           .addEventListener("popupshowing", updateOptionItems, true);
 }
 
-function UnloadCommandUpdateHandlers()
-{
+function UnloadCommandUpdateHandlers() {
   let attachmentBucket = document.getElementById("attachmentBucket");
 
   document.getElementById("optionsMenuPopup")
           .removeEventListener("popupshowing", updateOptionItems, true);
 
   attachmentBucket.controllers.removeController(attachmentBucketController);
   top.controllers.removeController(defaultController);
 }
 
-function CommandUpdate_MsgCompose()
-{
+function CommandUpdate_MsgCompose() {
   var focusedWindow = top.document.commandDispatcher.focusedWindow;
 
   // we're just setting focus to where it was before
   if (focusedWindow == gLastWindowToHaveFocus)
     return;
 
   gLastWindowToHaveFocus = focusedWindow;
   updateComposeItems();
 }
 
-function findbarFindReplace()
-{
+function findbarFindReplace() {
   SetMsgBodyFrameFocus();
   let findbar = document.getElementById("FindToolbar");
   findbar.close();
   goDoCommand("cmd_findReplace");
   findbar.open();
 }
 
-function updateComposeItems()
-{
+function updateComposeItems() {
   try {
     // Edit Menu
     goUpdateCommand("cmd_rewrap");
 
     // Insert Menu
-    if (gMsgCompose && gMsgCompose.composeHTML)
-    {
+    if (gMsgCompose && gMsgCompose.composeHTML) {
       goUpdateCommand("cmd_renderedHTMLEnabler");
       goUpdateCommand("cmd_fontColor");
       goUpdateCommand("cmd_backgroundColor");
       goUpdateCommand("cmd_decreaseFontStep");
       goUpdateCommand("cmd_increaseFontStep");
       goUpdateCommand("cmd_bold");
       goUpdateCommand("cmd_italic");
       goUpdateCommand("cmd_underline");
@@ -1316,136 +1274,126 @@ function updateComposeItems()
       goUpdateCommand("cmd_smiley");
     }
 
     // Options Menu
     goUpdateCommand("cmd_spelling");
 
     // Workaround to update 'Quote' toolbar button. (See bug 609926.)
     goUpdateCommand("cmd_quoteMessage");
-  } catch(e) {}
+  } catch (e) {}
 }
 
 /**
  * Disables or restores all toolbar items (menus/buttons) in the window.
  *
  * @param aDisable  true = disable all items. false = restore items to the state
  *                  stored before disabling them.
  */
-function updateAllItems(aDisable)
-{
+function updateAllItems(aDisable) {
   function getDisabledState(aElement) {
     if ("disabled" in aElement)
       return (aElement.disabled ? "true" : "false");
     else if (!aElement.hasAttribute("disabled"))
       return "";
-    else
-      return aElement.getAttribute("disabled");
+    return aElement.getAttribute("disabled");
   }
 
   function setDisabledState(aElement, aValue) {
     if ("disabled" in aElement)
       aElement.disabled = (aValue == "true");
     else if (aValue == "")
       aElement.removeAttribute("disabled");
     else
       aElement.setAttribute("disabled", aValue);
   }
 
 
   // This array will contain HTMLCollection objects as members.
   let commandItemCollections = [];
   commandItemCollections.push(document.getElementsByTagName("menu"));
   commandItemCollections.push(document.getElementsByTagName("toolbarbutton"));
-  commandItemCollections.push(document.querySelectorAll('[command]'));
-  commandItemCollections.push(document.querySelectorAll('[oncommand]'));
+  commandItemCollections.push(document.querySelectorAll("[command]"));
+  commandItemCollections.push(document.querySelectorAll("[oncommand]"));
   for (let itemCollection of commandItemCollections) {
     for (let item = 0; item < itemCollection.length; item++) {
       let commandItem = itemCollection[item];
       if (aDisable) {
         // Any element can appear multiple times in the commandItemCollections
         // list so only act on it if we didn't already set the "stateBeforeSend"
         // attribute on previous visit.
         if (!commandItem.hasAttribute("stateBeforeSend")) {
           commandItem.setAttribute("stateBeforeSend", getDisabledState(commandItem));
           setDisabledState(commandItem, true);
         }
-      }
-      else {
+      } else if (commandItem.hasAttribute("stateBeforeSend")) {
         // Any element can appear multiple times in the commandItemCollections
         // list so only act on it if it still has the "stateBeforeSend"
         // attribute.
-        if (commandItem.hasAttribute("stateBeforeSend")) {
-          setDisabledState(commandItem, commandItem.getAttribute("stateBeforeSend"));
-          commandItem.removeAttribute("stateBeforeSend");
-        }
+        setDisabledState(commandItem, commandItem.getAttribute("stateBeforeSend"));
+        commandItem.removeAttribute("stateBeforeSend");
       }
     }
   }
 }
 
-function InitFileSaveAsMenu()
-{
+function InitFileSaveAsMenu() {
   document.getElementById("cmd_saveAsFile")
           .setAttribute("checked", defaultSaveOperation == "file");
   document.getElementById("cmd_saveAsDraft")
           .setAttribute("checked", defaultSaveOperation == "draft");
   document.getElementById("cmd_saveAsTemplate")
           .setAttribute("checked", defaultSaveOperation == "template");
 }
 
-function openEditorContextMenu(popup)
-{
+function openEditorContextMenu(popup) {
   gSpellChecker.clearSuggestionsFromMenu();
   gSpellChecker.initFromEvent(document.popupRangeParent, document.popupRangeOffset);
   var onMisspelling = gSpellChecker.overMisspelling;
-  document.getElementById('spellCheckSuggestionsSeparator').hidden = !onMisspelling;
-  document.getElementById('spellCheckAddToDictionary').hidden = !onMisspelling;
-  document.getElementById('spellCheckIgnoreWord').hidden = !onMisspelling;
-  var separator = document.getElementById('spellCheckAddSep');
+  document.getElementById("spellCheckSuggestionsSeparator").hidden = !onMisspelling;
+  document.getElementById("spellCheckAddToDictionary").hidden = !onMisspelling;
+  document.getElementById("spellCheckIgnoreWord").hidden = !onMisspelling;
+  var separator = document.getElementById("spellCheckAddSep");
   separator.hidden = !onMisspelling;
-  document.getElementById('spellCheckNoSuggestions').hidden = !onMisspelling ||
+  document.getElementById("spellCheckNoSuggestions").hidden = !onMisspelling ||
       gSpellChecker.addSuggestionsToMenu(popup, separator, 5);
 
   // We ought to do that, otherwise changing dictionaries will have no effect!
   // InlineSpellChecker only registers callbacks for entries that are not the
   // current dictionary, so if we changed dictionaries in the meanwhile, we must
   // rebuild the list so that the right callbacks are registered in the Language
   // menu.
   gSpellChecker.clearDictionaryListFromMenu();
   let dictMenu = document.getElementById("spellCheckDictionariesMenu");
   let dictSep = document.getElementById("spellCheckLanguageSeparator");
   gSpellChecker.addDictionaryListToMenu(dictMenu, dictSep);
 
   updateEditItems();
 }
 
-function updateEditItems()
-{
+function updateEditItems() {
   goUpdateCommand("cmd_paste");
   goUpdateCommand("cmd_pasteNoFormatting");
   goUpdateCommand("cmd_pasteQuote");
   goUpdateCommand("cmd_delete");
   goUpdateCommand("cmd_renameAttachment");
   goUpdateCommand("cmd_reorderAttachments");
   goUpdateCommand("cmd_selectAll");
   goUpdateCommand("cmd_openAttachment");
   goUpdateCommand("cmd_findReplace");
   goUpdateCommand("cmd_find");
   goUpdateCommand("cmd_findNext");
   goUpdateCommand("cmd_findPrev");
 }
 
-function updateViewItems()
-{
+function updateViewItems() {
   goUpdateCommand("cmd_toggleAttachmentPane");
 }
 
-function updateAttachmentItems()
-{
+function updateAttachmentItems() {
   goUpdateCommand("cmd_toggleAttachmentPane");
   goUpdateCommand("cmd_attachCloud");
   goUpdateCommand("cmd_convertCloud");
   goUpdateCommand("cmd_convertAttachment");
   goUpdateCommand("cmd_cancelUpload");
   goUpdateCommand("cmd_delete");
   goUpdateCommand("cmd_removeAllAttachments");
   goUpdateCommand("cmd_renameAttachment");
@@ -1463,34 +1411,32 @@ function updateReorderAttachmentsItems()
   goUpdateCommand("cmd_moveAttachmentTop");
   goUpdateCommand("cmd_moveAttachmentBottom");
   goUpdateCommand("cmd_sortAttachmentsToggle");
 }
 
 /**
  * Update all the commands for sending a message to reflect their current state.
  */
-function updateSendCommands(aHaveController)
-{
+function updateSendCommands(aHaveController) {
   updateSendLock();
   if (aHaveController) {
     goUpdateCommand("cmd_sendButton");
     goUpdateCommand("cmd_sendNow");
     goUpdateCommand("cmd_sendLater");
     goUpdateCommand("cmd_sendWithCheck");
   } else {
-    goSetCommandEnabled("cmd_sendButton",    defaultController.isCommandEnabled("cmd_sendButton"));
-    goSetCommandEnabled("cmd_sendNow",       defaultController.isCommandEnabled("cmd_sendNow"));
-    goSetCommandEnabled("cmd_sendLater",     defaultController.isCommandEnabled("cmd_sendLater"));
+    goSetCommandEnabled("cmd_sendButton", defaultController.isCommandEnabled("cmd_sendButton"));
+    goSetCommandEnabled("cmd_sendNow", defaultController.isCommandEnabled("cmd_sendNow"));
+    goSetCommandEnabled("cmd_sendLater", defaultController.isCommandEnabled("cmd_sendLater"));
     goSetCommandEnabled("cmd_sendWithCheck", defaultController.isCommandEnabled("cmd_sendWithCheck"));
   }
 }
 
-function addAttachCloudMenuItems(aParentMenu)
-{
+function addAttachCloudMenuItems(aParentMenu) {
   while (aParentMenu.hasChildNodes())
     aParentMenu.lastChild.remove();
 
   for (let cloudProvider of cloudFileAccounts.accounts) {
     let item = document.createElement("menuitem");
     let iconClass = cloudProvider.iconClass;
     item.cloudProvider = cloudProvider;
     item.setAttribute("label", cloudFileAccounts.getDisplayName(cloudProvider));
@@ -1498,18 +1444,17 @@ function addAttachCloudMenuItems(aParent
     if (iconClass) {
       item.setAttribute("class", "menu-iconic");
       item.setAttribute("image", iconClass);
     }
     aParentMenu.appendChild(item);
   }
 }
 
-function addConvertCloudMenuItems(aParentMenu, aAfterNodeId, aRadioGroup)
-{
+function addConvertCloudMenuItems(aParentMenu, aAfterNodeId, aRadioGroup) {
   let attachment = document.getElementById("attachmentBucket").selectedItem;
   let afterNode = document.getElementById(aAfterNodeId);
   while (afterNode.nextSibling)
     afterNode.nextSibling.remove();
 
   if (!attachment.sendViaCloud) {
     let item = document.getElementById("convertCloudMenuItems_popup_convertAttachment");
     item.setAttribute("checked", "true");
@@ -1521,45 +1466,43 @@ function addConvertCloudMenuItems(aParen
     item.cloudProvider = cloudProvider;
     item.setAttribute("label", cloudFileAccounts.getDisplayName(cloudProvider));
     item.setAttribute("type", "radio");
     item.setAttribute("name", aRadioGroup);
 
     if (attachment.cloudProvider &&
         attachment.cloudProvider.accountKey == cloudProvider.accountKey) {
       item.setAttribute("checked", "true");
-    }
-    else if (iconClass) {
+    } else if (iconClass) {
       item.setAttribute("class", "menu-iconic");
       item.setAttribute("image", iconClass);
     }
 
     aParentMenu.appendChild(item);
   }
 }
 
-function uploadListener(aAttachment, aFile, aCloudProvider)
-{
+function uploadListener(aAttachment, aFile, aCloudProvider) {
   this.attachment = aAttachment;
   this.file = aFile;
   this.cloudProvider = aCloudProvider;
 
   // Notify the UI that we're starting the upload process: disable send commands
   // and show a "connecting" icon for the attachment.
   this.attachment.sendViaCloud = true;
   gNumUploadingAttachments++;
   updateSendCommands(true);
 
   let bucket = document.getElementById("attachmentBucket");
   let item = bucket.findItemForAttachment(this.attachment);
   if (item) {
     item.image = "chrome://messenger/skin/icons/connecting.png";
     item.setAttribute("tooltiptext",
       getComposeBundle().getFormattedString("cloudFileUploadingTooltip", [
-        cloudFileAccounts.getDisplayName(this.cloudProvider)
+        cloudFileAccounts.getDisplayName(this.cloudProvider),
       ]));
     item.uploading = true;
     item.cloudProvider = this.cloudProvider;
   }
 }
 
 uploadListener.prototype = {
   onStartRequest: function uploadListener_onStartRequest(aRequest, aContext) {
@@ -1579,17 +1522,17 @@ uploadListener.prototype = {
       this.attachment.contentLocation = this.cloudProvider.urlForFile(this.file);
       this.attachment.cloudProviderKey = this.cloudProvider.accountKey;
       if (attachmentItem) {
         // Update relevant bits on the attachment list item.
         if (!attachmentItem.originalUrl)
           attachmentItem.originalUrl = originalUrl;
         attachmentItem.setAttribute("tooltiptext",
           getComposeBundle().getFormattedString("cloudFileUploadedTooltip", [
-            cloudFileAccounts.getDisplayName(this.cloudProvider)
+            cloudFileAccounts.getDisplayName(this.cloudProvider),
           ]));
         attachmentItem.uploading = false;
 
         // Set the icon for the attachment.
         let iconClass = this.cloudProvider.iconClass;
         if (iconClass)
           attachmentItem.image = iconClass;
         else {
@@ -1598,18 +1541,17 @@ uploadListener.prototype = {
           attachmentItem.image = null;
         }
       }
 
       let event = document.createEvent("Events");
       event.initEvent("attachment-uploaded", true, true);
       attachmentItem.dispatchEvent(new Event("attachment-uploaded",
         { bubbles: true, cancelable: true }));
-    }
-    else {
+    } else {
       let title;
       let msg;
       let displayName = cloudFileAccounts.getDisplayName(this.cloudProvider);
       let bundle = getComposeBundle();
       let displayError = true;
       switch (aStatusCode) {
       case this.cloudProvider.authErr:
         title = bundle.getString("errorCloudFileAuth.title");
@@ -1678,21 +1620,20 @@ uploadListener.prototype = {
       }
     }
 
     gNumUploadingAttachments--;
     updateSendCommands(true);
   },
 
   QueryInterface: ChromeUtils.generateQI(["nsIRequestObserver",
-                                          "nsISupportsWeakReference"])
+                                          "nsISupportsWeakReference"]),
 };
 
-function deletionListener(aAttachment, aCloudProvider)
-{
+function deletionListener(aAttachment, aCloudProvider) {
   this.attachment = aAttachment;
   this.cloudProvider = aCloudProvider;
 }
 
 deletionListener.prototype = {
   onStartRequest: function deletionListener_onStartRequest(aRequest, aContext) {
   },
 
@@ -1704,77 +1645,71 @@ deletionListener.prototype = {
         getComposeBundle().getString("errorCloudFileDeletion.title"),
         getComposeBundle().getFormattedString("errorCloudFileDeletion.message",
                                               [displayName,
                                                this.attachment.name]));
     }
   },
 
   QueryInterface: ChromeUtils.generateQI(["nsIRequestObserver",
-                                          "nsISupportsWeakReference"])
+                                          "nsISupportsWeakReference"]),
 };
 
 /**
  * Prompt the user for a list of files to attach via a cloud provider.
  *
  * @param aProvider the cloud provider to upload the files to
  */
-function attachToCloud(aProvider)
-{
+function attachToCloud(aProvider) {
   // We need to let the user pick local file(s) to upload to the cloud and
   // gather url(s) to those files.
   var fp = Cc["@mozilla.org/filepicker;1"]
-             .createInstance(nsIFilePicker);
+             .createInstance(Ci.nsIFilePicker);
   fp.init(window, getComposeBundle().getFormattedString(
             "chooseFileToAttachViaCloud",
             [cloudFileAccounts.getDisplayName(aProvider)]),
-          nsIFilePicker.modeOpenMultiple);
+          Ci.nsIFilePicker.modeOpenMultiple);
 
   var lastDirectory = GetLastAttachDirectory();
   if (lastDirectory)
     fp.displayDirectory = lastDirectory;
 
-  let files = [];
-
-  fp.appendFilters(nsIFilePicker.filterAll);
+  fp.appendFilters(Ci.nsIFilePicker.filterAll);
   fp.open(rv => {
-    if (rv != nsIFilePicker.returnOK || !fp.files) {
+    if (rv != Ci.nsIFilePicker.returnOK || !fp.files) {
       return;
     }
 
-    let files = Array.from(fixIterator(fp.files,
-                             Ci.nsIFile))
+    let files = Array.from(fixIterator(fp.files, Ci.nsIFile));
     let attachments = files.map(f => FileToAttachment(f));
 
     let i = 0;
-    let items = AddAttachments(attachments, function(aItem) {
+    AddAttachments(attachments, function(aItem) {
       let listener = new uploadListener(attachments[i], files[i], aProvider);
       try {
         aProvider.uploadFile(files[i], listener);
-      }
-      catch (ex) {
+      } catch (ex) {
         listener.onStopRequest(null, null, ex.result);
       }
       i++;
     });
 
     dispatchAttachmentBucketEvent("attachments-uploading", attachments);
-    SetLastAttachDirectory(files[files.length-1]);
+    SetLastAttachDirectory(files[files.length - 1]);
   });
 }
 
 /**
  * Convert an array of attachments to cloud attachments.
  *
  * @param aItems an array of <attachmentitem>s containing the attachments in
  *        question
  * @param aProvider the cloud provider to upload the files to
  */
-function convertListItemsToCloudAttachment(aItems, aProvider)
-{
+function convertListItemsToCloudAttachment(aItems, aProvider) {
   // If we want to display an offline error message, we should do it here.
   // No sense in doing the delete and upload and having them fail.
   if (Services.io.offline)
     return;
 
   let fileHandler = Services.io.getProtocolHandler("file")
                             .QueryInterface(Ci.nsIFileProtocolHandler);
   let convertedAttachments = Cc["@mozilla.org/array;1"]
@@ -1790,23 +1725,21 @@ function convertListItemsToCloudAttachme
     }
 
     let file = fileHandler.getFileFromURLSpec(url);
     if (item.cloudProvider) {
       item.cloudProvider.deleteFile(
         file, new deletionListener(item.attachment, item.cloudProvider));
     }
 
+    let listener = new uploadListener(item.attachment, file, aProvider);
     try {
-      let listener = new uploadListener(item.attachment, file,
-                                        aProvider);
       aProvider.uploadFile(file, listener);
       convertedAttachments.appendElement(item.attachment);
-    }
-    catch (ex) {
+    } catch (ex) {
       listener.onStopRequest(null, null, ex.result);
     }
   }
 
   if (convertedAttachments.length > 0) {
     dispatchAttachmentBucketEvent("attachments-converted", convertedAttachments);
     Services.obs.notifyObservers(convertedAttachments,
                                  "mail:attachmentsConverted",
@@ -1814,30 +1747,28 @@ function convertListItemsToCloudAttachme
   }
 }
 
 /**
  * Convert the selected attachments to cloud attachments.
  *
  * @param aProvider the cloud provider to upload the files to
  */
-function convertSelectedToCloudAttachment(aProvider)
-{
+function convertSelectedToCloudAttachment(aProvider) {
   let bucket = document.getElementById("attachmentBucket");
   convertListItemsToCloudAttachment([...bucket.selectedItems], aProvider);
 }
 
 /**
  * Convert an array of nsIMsgAttachments to cloud attachments.
  *
  * @param aAttachments an array of nsIMsgAttachments
  * @param aProvider the cloud provider to upload the files to
  */
-function convertToCloudAttachment(aAttachments, aProvider)
-{
+function convertToCloudAttachment(aAttachments, aProvider) {
   let bucket = document.getElementById("attachmentBucket");
   let items = [];
   for (let attachment of aAttachments) {
     let item = bucket.findItemForAttachment(attachment);
     if (item)
       items.push(item);
   }
 
@@ -1845,35 +1776,33 @@ function convertToCloudAttachment(aAttac
 }
 
 /**
  * Convert an array of attachments to regular (non-cloud) attachments.
  *
  * @param aItems an array of <attachmentitem>s containing the attachments in
  *        question
  */
-function convertListItemsToRegularAttachment(aItems)
-{
+function convertListItemsToRegularAttachment(aItems) {
   let fileHandler = Services.io.getProtocolHandler("file")
                             .QueryInterface(Ci.nsIFileProtocolHandler);
   let convertedAttachments = Cc["@mozilla.org/array;1"]
                                .createInstance(Ci.nsIMutableArray);
 
   for (let item of aItems) {
     if (!item.attachment.sendViaCloud || !item.cloudProvider)
       continue;
 
     let file = fileHandler.getFileFromURLSpec(item.originalUrl);
     try {
       // This will fail for drafts, but we can still send the message
       // with a normal attachment.
       item.cloudProvider.deleteFile(
         file, new deletionListener(item.attachment, item.cloudProvider));
-    }
-    catch (ex) {
+    } catch (ex) {
        Cu.reportError(ex);
     }
 
     item.attachment.url = item.originalUrl;
     item.setAttribute("tooltiptext", item.attachment.url);
     item.attachment.sendViaCloud = false;
 
     delete item.cloudProvider;
@@ -1891,287 +1820,264 @@ function convertListItemsToRegularAttach
   // it may be needed to identify the attachment. But clear it out now.
   for (let item of aItems)
     delete item.attachment.contentLocation;
 }
 
 /**
  * Convert the selected attachments to regular (non-cloud) attachments.
  */
-function convertSelectedToRegularAttachment()
-{
+function convertSelectedToRegularAttachment() {
   let bucket = document.getElementById("attachmentBucket");
   convertListItemsToRegularAttachment([...bucket.selectedItems]);
 }
 
 /**
  * Convert an array of nsIMsgAttachments to regular (non-cloud) attachments.
  *
  * @param aAttachments an array of nsIMsgAttachments
  */
-function convertToRegularAttachment(aAttachments)
-{
+function convertToRegularAttachment(aAttachments) {
   let bucket = document.getElementById("attachmentBucket");
   let items = [];
   for (let attachment of aAttachments) {
     let item = bucket.findItemForAttachment(attachment);
     if (item)
       items.push(item);
   }
 
   convertListItemsToRegularAttachment(items);
 }
 
-function updateOptionItems()
-{
+function updateOptionItems() {
   goUpdateCommand("cmd_quoteMessage");
 }
 
 /* messageComposeOfflineQuitObserver is notified whenever the network
  * connection status has switched to offline, or when the application
  * has received a request to quit.
  */
-var messageComposeOfflineQuitObserver =
-{
-  observe: function(aSubject, aTopic, aData)
-  {
+var messageComposeOfflineQuitObserver = {
+  observe(aSubject, aTopic, aData) {
     // sanity checks
-    if (aTopic == "network:offline-status-changed")
-    {
+    if (aTopic == "network:offline-status-changed") {
       MessageComposeOfflineStateChanged(Services.io.offline);
+    } else if (aTopic == "quit-application-requested"
+        && (aSubject instanceof Ci.nsISupportsPRBool)
+        && !aSubject.data) {
+      // Check whether to veto the quit request
+      // (unless another observer already did).
+      aSubject.data = !ComposeCanClose();
     }
-    // check whether to veto the quit request (unless another observer already
-    // did)
-    else if (aTopic == "quit-application-requested"
-        && (aSubject instanceof Ci.nsISupportsPRBool)
-        && !aSubject.data)
-      aSubject.data = !ComposeCanClose();
-  }
-}
-
-function AddMessageComposeOfflineQuitObserver()
-{
+  },
+};
+
+function AddMessageComposeOfflineQuitObserver() {
   Services.obs.addObserver(messageComposeOfflineQuitObserver,
                            "network:offline-status-changed");
   Services.obs.addObserver(messageComposeOfflineQuitObserver,
                            "quit-application-requested");
 
   // set the initial state of the send button
   MessageComposeOfflineStateChanged(Services.io.offline);
 }
 
-function RemoveMessageComposeOfflineQuitObserver()
-{
+function RemoveMessageComposeOfflineQuitObserver() {
   Services.obs.removeObserver(messageComposeOfflineQuitObserver,
                               "network:offline-status-changed");
   Services.obs.removeObserver(messageComposeOfflineQuitObserver,
                               "quit-application-requested");
 }
 
-function MessageComposeOfflineStateChanged(goingOffline)
-{
+function MessageComposeOfflineStateChanged(goingOffline) {
   try {
     var sendButton = document.getElementById("button-send");
     var sendNowMenuItem = document.getElementById("menu-item-send-now");
 
     if (!gSavedSendNowKey) {
-      gSavedSendNowKey = sendNowMenuItem.getAttribute('key');
+      gSavedSendNowKey = sendNowMenuItem.getAttribute("key");
     }
 
     // don't use goUpdateCommand here ... the defaultController might not be installed yet
     updateSendCommands(false);
 
-    if (goingOffline)
-    {
-      sendButton.label = sendButton.getAttribute('later_label');
-      sendButton.setAttribute('tooltiptext', sendButton.getAttribute('later_tooltiptext'));
-      sendNowMenuItem.removeAttribute('key');
-    }
-    else
-    {
-      sendButton.label = sendButton.getAttribute('now_label');
-      sendButton.setAttribute('tooltiptext', sendButton.getAttribute('now_tooltiptext'));
+    if (goingOffline) {
+      sendButton.label = sendButton.getAttribute("later_label");
+      sendButton.setAttribute("tooltiptext", sendButton.getAttribute("later_tooltiptext"));
+      sendNowMenuItem.removeAttribute("key");
+    } else {
+      sendButton.label = sendButton.getAttribute("now_label");
+      sendButton.setAttribute("tooltiptext", sendButton.getAttribute("now_tooltiptext"));
       if (gSavedSendNowKey) {
-        sendNowMenuItem.setAttribute('key', gSavedSendNowKey);
+        sendNowMenuItem.setAttribute("key", gSavedSendNowKey);
       }
     }
-
-  } catch(e) {}
-}
-
-function DoCommandClose()
-{
+  } catch (e) {}
+}
+
+function DoCommandClose() {
   if (ComposeCanClose()) {
 
     // Notify the SendListener that Send has been aborted and Stopped
     if (gMsgCompose)
       gMsgCompose.onSendNotPerformed(null, Cr.NS_ERROR_ABORT);
 
     // This destroys the window for us.
     MsgComposeCloseWindow();
   }
 
   return false;
 }
 
-function DoCommandPrint()
-{
+function DoCommandPrint() {
   try {
     let editor = GetCurrentEditorElement();
     PrintUtils.printWindow(editor.outerWindowID, editor);
-  } catch(ex) {dump("#PRINT ERROR: " + ex + "\n");}
-}
-
-function DoCommandPrintPreview()
-{
+  } catch (ex) {
+    dump("#PRINT ERROR: " + ex + "\n");
+  }
+}
+
+function DoCommandPrintPreview() {
   try {
     PrintUtils.printPreview(PrintPreviewListener);
-    } catch(ex) { Cu.reportError(ex); }
+  } catch (ex) {
+    Cu.reportError(ex);
+  }
 }
 
 /**
  * Locks/Unlocks the window widgets while a message is being saved/sent.
  * Locking means to disable all possible items in the window so that
  * the user can't click/activate anything.
  *
  * @param aDisable  true = lock the window. false = unlock the window.
  */
-function ToggleWindowLock(aDisable)
-{
+function ToggleWindowLock(aDisable) {
   gWindowLocked = aDisable;
   updateAllItems(aDisable);
   updateEditableFields(aDisable);
   if (!aDisable)
     updateComposeItems();
 }
 
 /* This function will go away soon as now arguments are passed to the window using a object of type nsMsgComposeParams instead of a string */
-function GetArgs(originalData)
-{
-  var args = new Object();
+function GetArgs(originalData) {
+  var args = {};
 
   if (originalData == "")
     return null;
 
   var data = "";
   var separator = String.fromCharCode(1);
 
   var quoteChar = "";
   var prevChar = "";
   var nextChar = "";
-  for (let i = 0; i < originalData.length; i++, prevChar = aChar)
-  {
-    var aChar = originalData.charAt(i)
-    var aCharCode = originalData.charCodeAt(i)
+  for (let i = 0; i < originalData.length; i++, prevChar = aChar) {
+    var aChar = originalData.charAt(i);
+    var aCharCode = originalData.charCodeAt(i);
     if ( i < originalData.length - 1)
       nextChar = originalData.charAt(i + 1);
     else
       nextChar = "";
 
-    if (aChar == quoteChar && (nextChar == "," || nextChar == ""))
-    {
+    if (aChar == quoteChar && (nextChar == "," || nextChar == "")) {
       quoteChar = "";
       data += aChar;
-    }
-    else if ((aCharCode == 39 || aCharCode == 34) && prevChar == "=") //quote or double quote
-    {
+    } else if ((aCharCode == 39 || aCharCode == 34) && prevChar == "=") { // quote or double quote
       if (quoteChar == "")
         quoteChar = aChar;
       data += aChar;
-    }
-    else if (aChar == ",")
-    {
+    } else if (aChar == ",") {
       if (quoteChar == "")
         data += separator;
       else
-        data += aChar
+        data += aChar;
+    } else {
+      data += aChar;
     }
-    else
-      data += aChar
   }
 
   var pairs = data.split(separator);
-//  dump("Compose: argument: {" + data + "}\n");
-
-  for (let i = pairs.length - 1; i >= 0; i--)
-  {
-    var pos = pairs[i].indexOf('=');
+  // dump("Compose: argument: {" + data + "}\n");
+
+  for (let i = pairs.length - 1; i >= 0; i--) {
+    var pos = pairs[i].indexOf("=");
     if (pos == -1)
       continue;
     var argname = pairs[i].substring(0, pos);
     var argvalue = pairs[i].substring(pos + 1);
-    if (argvalue.startsWith("'") && argvalue.endsWith("'"))
+    if (argvalue.startsWith("'") && argvalue.endsWith("'")) {
       args[argname] = argvalue.substring(1, argvalue.length - 1);
-    else
+    } else {
       try {
         args[argname] = decodeURIComponent(argvalue);
-      } catch (e) {args[argname] = argvalue;}
+      } catch (e) {
+        args[argname] = argvalue;
+      }
+    }
     // dump("[" + argname + "=" + args[argname] + "]\n");
   }
   return args;
 }
 
-function ComposeFieldsReady()
-{
+function ComposeFieldsReady() {
   // Limit the charsets to those we think are safe to encode (i.e., they are in
   // the charset menu). Easiest way to normalize this is to use the TextDecoder
   // to get the canonical alias and default if it isn't valid.
   let charset;
   try {
     charset = new TextDecoder(gMsgCompose.compFields.characterSet).encoding;
   } catch (e) {
     charset = gMsgCompose.compFields.defaultCharacterSet;
   }
   SetDocumentCharacterSet(charset);
 
-  //If we are in plain text, we need to set the wrap column
-  if (! gMsgCompose.composeHTML) {
+  // If we are in plain text, we need to set the wrap column
+  if (!gMsgCompose.composeHTML) {
     try {
-      gMsgCompose.editor.QueryInterface(nsIPlaintextEditorMail).wrapWidth
+      gMsgCompose.editor.QueryInterface(Ci.nsIPlaintextEditor).wrapWidth
           = gMsgCompose.wrapLength;
-    }
-    catch (e) {
+    } catch (e) {
       dump("### textEditor.wrapWidth exception text: " + e + " - failed\n");
     }
   }
   CompFields2Recipients(gMsgCompose.compFields);
   SetComposeWindowTitle();
   updateEditableFields(false);
 }
 
 // checks if the passed in string is a mailto url, if it is, generates nsIMsgComposeParams
 // for the url and returns them.
-function handleMailtoArgs(mailtoUrl)
-{
+function handleMailtoArgs(mailtoUrl) {
   // see if the string is a mailto url....do this by checking the first 7 characters of the string
-  if (mailtoUrl.toLowerCase().startsWith("mailto:"))
-  {
+  if (mailtoUrl.toLowerCase().startsWith("mailto:")) {
     // if it is a mailto url, turn the mailto url into a MsgComposeParams object....
     let uri = Services.io.newURI(mailtoUrl);
 
     if (uri) {
       return MailServices.compose.getParamsForMailto(uri);
     }
   }
 
   return null;
 }
 
 /**
  * Handle ESC keypress from composition window for
  * notifications with close button in the
  * attachmentNotificationBox.
  */
-function handleEsc()
-{
+function handleEsc() {
   let activeElement = document.activeElement;
 
   // If findbar is visible and the focus is in the message body,
   // hide it. (Focus on the findbar is handled by findbar itself).
-  let findbar = document.getElementById('FindToolbar');
+  let findbar = document.getElementById("FindToolbar");
   if (!findbar.hidden && activeElement.id == "content-frame") {
     findbar.close();
     return;
   }
 
   // If there is a notification in the attachmentNotificationBox
   // AND focus is in message body, subject field or on the notification,
   // hide it.
@@ -2180,18 +2086,17 @@ function handleEsc()
   if (notification && (activeElement.id == "content-frame" ||
       activeElement.parentNode.parentNode.id == "msgSubject" ||
       notification.contains(activeElement) ||
       activeElement.classList.contains("messageCloseButton"))) {
     notification.close();
   }
 }
 
-function disableAttachmentReminder()
-{
+function disableAttachmentReminder() {
   gDisableAttachmentReminder = true;
   toggleAttachmentReminder(false);
 }
 
 /**
  * This state machine manages all showing and hiding of the attachment
  * notification bar. It is only called if any change happened so that
  * recalculating of the notification is needed:
@@ -2207,18 +2112,17 @@ function disableAttachmentReminder()
  * keywords and attachments were removed (but not when we have keywords and
  * manual reminder was just turned off). We always show the notification
  * again if keywords change (if no attachments and no manual reminder).
  *
  * @param aForce  If set to true, notification will be shown immediately if
  *                there are any keywords. If set to false, it is shown only when
  *                they have changed.
  */
-function manageAttachmentNotification(aForce = false)
-{
+function manageAttachmentNotification(aForce = false) {
   let keywords;
   let keywordsCount = 0;
 
   // First see if the notification is to be hidden due to reasons other than
   // not having keywords.
   let removeNotification = attachmentNotificationSupressed();
 
   // If that is not true, we need to look at the state of keywords.
@@ -2283,41 +2187,41 @@ function manageAttachmentNotification(aF
   msgText.setAttribute("value", textValue);
   let msgKeywords = document.createElement("label");
   msg.appendChild(msgKeywords);
   msgKeywords.id = "attachmentKeywords";
   msgKeywords.setAttribute("crop", "end");
   msgKeywords.setAttribute("flex", "1000");
   msgKeywords.setAttribute("value", keywords);
   let addButton = {
-    accessKey : getComposeBundle().getString("addAttachmentButton.accesskey"),
+    accessKey: getComposeBundle().getString("addAttachmentButton.accesskey"),
     label: getComposeBundle().getString("addAttachmentButton"),
-    callback: function (aNotificationBar, aButton) {
+    callback(aNotificationBar, aButton) {
       goDoCommand("cmd_attachFile");
       return true; // keep notification open (the state machine will decide on it later)
-    }
+    },
   };
 
   let remindLaterMenuPopup = document.createElement("menupopup");
   remindLaterMenuPopup.id = "reminderBarPopup";
   let disableAttachmentReminder = document.createElement("menuitem");
   disableAttachmentReminder.id = "disableReminder";
   disableAttachmentReminder.setAttribute("label",
     getComposeBundle().getString("disableAttachmentReminderButton"));
   disableAttachmentReminder.setAttribute("command", "cmd_doNotRemindForAttachments");
   remindLaterMenuPopup.appendChild(disableAttachmentReminder);
 
   let remindButton = {
     type: "menu-button",
-    accessKey : getComposeBundle().getString("remindLaterButton.accesskey"),
+    accessKey: getComposeBundle().getString("remindLaterButton.accesskey"),
     label: getComposeBundle().getString("remindLaterButton"),
     popup: remindLaterMenuPopup,
-    callback: function (aNotificationBar, aButton) {
+    callback(aNotificationBar, aButton) {
       toggleAttachmentReminder(true);
-    }
+    },
   };
 
   notification = nBox.appendNotification("", "attachmentReminder",
                                /* fake out the image so we can do it in CSS */
                                "null",
                                nBox.PRIORITY_WARNING_MEDIUM,
                                [addButton, remindButton]);
   let buttons = notification.childNodes[0];
@@ -2334,35 +2238,33 @@ function attachmentNotificationSupressed
 }
 
 var attachmentWorker = new Worker("resource:///modules/attachmentChecker.js");
 
 // The array of currently found keywords. Or null if keyword detection wasn't
 // run yet so we don't know.
 attachmentWorker.lastMessage = null;
 
-attachmentWorker.onerror = function(error)
-{
+attachmentWorker.onerror = function(error) {
   Cu.reportError("Attachment Notification Worker error!!! " + error.message);
   throw error;
 };
 
 /**
  * Called when attachmentWorker finishes checking of the message for keywords.
  *
  * @param event    If defined, event.data contains an array of found keywords.
  * @param aManage  If set to true and we determine keywords have changed,
  *                 manage the notification.
  *                 If set to false, just store the new keyword list but do not
  *                 touch the notification. That effectively eats the
  *                 "keywords changed" event which usually shows the notification
  *                 if it was hidden. See manageAttachmentNotification().
  */
-attachmentWorker.onmessage = function(event, aManage = true)
-{
+attachmentWorker.onmessage = function(event, aManage = true) {
   // Exit if keywords haven't changed.
   if (!event || (attachmentWorker.lastMessage &&
                 (event.data.toString() == attachmentWorker.lastMessage.toString())))
     return;
 
   let data = event ? event.data : [];
   attachmentWorker.lastMessage = data.slice(0);
   if (aManage)
@@ -2401,17 +2303,17 @@ function AttachmentsChanged(aShowPane, a
  * 1) The dictionary that was selected in the preference is removed.
  * 2) The selected dictionary changes the way it announces itself to the system,
  *    so for example "it_IT" changes to "it-IT" and the previously stored
  *    preference value doesn't apply any more.
  */
 function getValidSpellcheckerDictionary(draftLanguage) {
   let prefValue = Services.prefs.getCharPref("spellchecker.dictionary");
   let spellChecker = Cc["@mozilla.org/spellchecker/engine;1"]
-                       .getService(mozISpellCheckingEngine);
+                       .getService(Ci.mozISpellCheckingEngine);
   let o1 = {};
   let o2 = {};
   spellChecker.getDictionaryList(o1, o2);
   let dictList = o1.value;
   let count    = o2.value;
 
   if (count == 0) {
     // If there are no dictionaries, we can't check the value, so return it.
@@ -2428,25 +2330,24 @@ function getValidSpellcheckerDictionary(
     return prefValue;
   }
 
   // Set a valid value, any value will do.
   Services.prefs.setCharPref("spellchecker.dictionary", dictList[0]);
   return dictList[0];
 }
 
-var dictionaryRemovalObserver =
-{
-  observe: function(aSubject, aTopic, aData) {
+var dictionaryRemovalObserver = {
+  observe(aSubject, aTopic, aData) {
     if (aTopic != "spellcheck-dictionary-remove") {
       return;
     }
     let language = document.documentElement.getAttribute("lang");
     let spellChecker = Cc["@mozilla.org/spellchecker/engine;1"]
-                         .getService(mozISpellCheckingEngine);
+                         .getService(Ci.mozISpellCheckingEngine);
     let o1 = {};
     let o2 = {};
     spellChecker.getDictionaryList(o1, o2);
     let dictList = o1.value;
     let count    = o2.value;
 
     if (count > 0 && dictList.includes(language)) {
       // There still is a dictionary for the language of the document.
@@ -2462,28 +2363,28 @@ var dictionaryRemovalObserver =
       // Fix the preference while we're here. We know it's invalid.
       Services.prefs.setCharPref("spellchecker.dictionary", language);
     }
     document.documentElement.setAttribute("lang", language);
   },
 
   isAdded: false,
 
-  addObserver: function() {
+  addObserver() {
     Services.obs.addObserver(this, "spellcheck-dictionary-remove");
     this.isAdded = true;
   },
 
-  removeObserver: function() {
+  removeObserver() {
     if (this.isAdded) {
       Services.obs.removeObserver(this, "spellcheck-dictionary-remove");
       this.isAdded = false;
     }
-  }
-}
+  },
+};
 
 /**
  * On paste or drop, we may want to modify the content before inserting it into
  * the editor, replacing file URLs with data URLs when appropriate.
  */
 function onPasteOrDrop(e) {
   // For paste use e.clipboardData, for drop use e.dataTransfer.
   let dataTransfer = ("clipboardData" in e) ? e.clipboardData : e.dataTransfer;
@@ -2551,17 +2452,17 @@ function onPasteOrDrop(e) {
       let doTheInsert = function() {
         // Now run it through sanitation to make sure there wasn't any
         // unwanted things in the content.
         let ParserUtils = Cc["@mozilla.org/parserutils;1"]
           .getService(Ci.nsIParserUtils);
         let html2 = ParserUtils.sanitize(doc.documentElement.innerHTML,
                                        ParserUtils.SanitizerAllowStyle);
         getBrowser().contentDocument.execCommand("insertHTML", false, html2);
-      }
+      };
 
       // Everything checks out. Convert file to data URL.
       let reader = new FileReader();
       reader.addEventListener("load", function() {
         let dataURL = reader.result;
         pendingConversions--;
         img.src = dataURL;
         if (pendingConversions == 0) {
@@ -2576,18 +2477,18 @@ function onPasteOrDrop(e) {
       });
 
       pendingConversions++;
       reader.readAsDataURL(file);
     });
   }
 }
 
-function ComposeStartup(aParams)
-{
+/* eslint-disable complexity */
+function ComposeStartup(aParams) {
   // Findbar overlay
   if (!document.getElementById("findbar-replaceButton")) {
     let replaceButton = document.createElement("toolbarbutton");
     replaceButton.setAttribute("id", "findbar-replaceButton");
     replaceButton.setAttribute("class", "findbar-button tabbable");
     replaceButton.setAttribute("label", getComposeBundle().getString("replaceButton.label"));
     replaceButton.setAttribute("accesskey", getComposeBundle().getString("replaceButton.accesskey"));
     replaceButton.setAttribute("tooltiptext", getComposeBundle().getString("replaceButton.tooltip"));
@@ -2608,31 +2509,30 @@ function ComposeStartup(aParams)
   if (aParams)
     params = aParams;
   else if (window.arguments && window.arguments[0]) {
     try {
       if (window.arguments[0] instanceof Ci.nsIMsgComposeParams)
         params = window.arguments[0];
       else
         params = handleMailtoArgs(window.arguments[0]);
+    } catch (ex) {
+      dump("ERROR with parameters: " + ex + "\n");
     }
-    catch(ex) { dump("ERROR with parameters: " + ex + "\n"); }
 
     // if still no dice, try and see if the params is an old fashioned list of string attributes
     // XXX can we get rid of this yet?
-    if (!params)
-    {
+    if (!params) {
       args = GetArgs(window.arguments[0]);
     }
   }
 
   // Set a sane starting width/height for all resolutions on new profiles.
   // Do this before the window loads.
-  if (!document.documentElement.hasAttribute("width"))
-  {
+  if (!document.documentElement.hasAttribute("width")) {
     // Prefer 860x800.
     let defaultHeight = Math.min(screen.availHeight, 800);
     let defaultWidth = Math.min(screen.availWidth, 860);
 
     // On small screens, default to maximized state.
     if (defaultHeight <= 600)
       document.documentElement.setAttribute("sizemode", "maximized");
 
@@ -2674,24 +2574,23 @@ function ComposeStartup(aParams)
     FillIdentityList(identityList);
 
   if (!params) {
     // This code will go away soon as now arguments are passed to the window using a object of type nsMsgComposeParams instead of a string
 
     params = Cc["@mozilla.org/messengercompose/composeparams;1"].createInstance(Ci.nsIMsgComposeParams);
     params.composeFields = Cc["@mozilla.org/messengercompose/composefields;1"].createInstance(Ci.nsIMsgCompFields);
 
-    if (args) { //Convert old fashion arguments into params
+    if (args) { // Convert old fashion arguments into params
       var composeFields = params.composeFields;
       if (args.bodyislink == "true")
         params.bodyIsLink = true;
       if (args.type)
         params.type = args.type;
-      if (args.format)
-      {
+      if (args.format) {
         // Only use valid values.
         if (args.format == Ci.nsIMsgCompFormat.PlainText ||
             args.format == Ci.nsIMsgCompFormat.HTML ||
             args.format == Ci.nsIMsgCompFormat.OppositeOfDefault)
           params.format = args.format;
         else if (args.format.toLowerCase().trim() == "html")
           params.format = Ci.nsIMsgCompFormat.HTML;
         else if (args.format.toLowerCase().trim() == "text")
@@ -2708,45 +2607,39 @@ function ComposeStartup(aParams)
       if (args.cc)
         composeFields.cc = args.cc;
       if (args.bcc)
         composeFields.bcc = args.bcc;
       if (args.newsgroups)
         composeFields.newsgroups = args.newsgroups;
       if (args.subject)
         composeFields.subject = args.subject;
-      if (args.attachment)
-      {
+      if (args.attachment) {
         let attachmentList = args.attachment.split(",");
         let commandLine = Cc["@mozilla.org/toolkit/command-line;1"]
                             .createInstance();
-        for (let attachmentName of attachmentList)
-        {
+        for (let attachmentName of attachmentList) {
           // resolveURI does all the magic around working out what the
           // attachment is, including web pages, and generating the correct uri.
           let uri = commandLine.resolveURI(attachmentName);
           let attachment = Cc["@mozilla.org/messengercompose/attachment;1"]
                              .createInstance(Ci.nsIMsgAttachment);
           // If uri is for a file and it exists set the attachment size.
-          if (uri instanceof Ci.nsIFileURL)
-          {
+          if (uri instanceof Ci.nsIFileURL) {
             if (uri.file.exists())
               attachment.size = uri.file.fileSize;
             else
               attachment = null;
           }
 
           // Only want to attach if a file that exists or it is not a file.
-          if (attachment)
-          {
+          if (attachment) {
             attachment.url = uri.spec;
             composeFields.addAttachment(attachment);
-          }
-          else
-          {
+          } else {
             let title = getComposeBundle().getString("errorFileAttachTitle");
             let msg = getComposeBundle().getFormattedString("errorFileAttachMessage",
                                                         [attachmentName]);
             Services.prompt.alert(null, title, msg);
           }
         }
       }
       if (args.newshost)
@@ -2760,18 +2653,17 @@ function ComposeStartup(aParams)
         }
         msgFile.initWithPath(args.message);
 
         if (!msgFile.exists()) {
           let title = getComposeBundle().getString("errorFileMessageTitle");
           let msg = getComposeBundle().getFormattedString("errorFileMessageMessage",
                                                           [args.message]);
           Services.prompt.alert(null, title, msg);
-        }
-        else {
+        } else {
           let data = "";
           let fstream = null;
           let cstream = null;
 
           try {
             fstream = Cc["@mozilla.org/network/file-input-stream;1"]
                         .createInstance(Ci.nsIFileInputStream);
             cstream = Cc["@mozilla.org/intl/converter-input-stream;1"]
@@ -2805,39 +2697,38 @@ function ComposeStartup(aParams)
 
             if (params.format != Ci.nsIMsgCompFormat.PlainText &&
                 (args.message.endsWith(".htm") || args.message.endsWith(".html") ||
                  data.substr(pos, 14).toLowerCase() == "<!doctype html" ||
                  data.substr(pos, 5).toLowerCase() == "<html")) {
               // We replace line breaks because otherwise they'll be converted to
               // <br> in nsMsgCompose::BuildBodyMessageAndSignature().
               // Don't do the conversion if the user asked explicitly for plain text.
-              data = data.replace(/\r?\n/g," ");
+              data = data.replace(/\r?\n/g, " ");
             }
             gBodyFromArgs = true;
             composeFields.body = data;
           }
         }
-      }
-      else if (args.body) {
+      } else if (args.body) {
         gBodyFromArgs = true;
         composeFields.body = args.body;
       }
     }
   }
 
   gComposeType = params.type;
 
   // Detect correct identity when missing or mismatched.
   // An identity with no email is likely not valid.
   // When editing a draft, 'params.identity' is pre-populated with the identity
   // that created the draft or the identity owning the draft folder for a "foreign",
   // draft, see ComposeMessage() in mailCommands.js. We don't want the latter,
   // so use the creator identity which could be null.
-  if (gComposeType == nsIMsgCompType.Draft) {
+  if (gComposeType == Ci.nsIMsgCompType.Draft) {
     let creatorKey = params.composeFields.creatorIdentityKey;
     params.identity = creatorKey ? getIdentityForKey(creatorKey) : null;
   }
   let from = [];
   if (params.composeFields.from)
     from = MailServices.headerParser
                        .parseEncodedHeader(params.composeFields.from, null);
   from = (from.length && from[0] && from[0].email) ?
@@ -2879,21 +2770,19 @@ function ComposeStartup(aParams)
   }
 
   identityList.selectedItem =
     identityList.getElementsByAttribute("identitykey", params.identity.key)[0];
 
   // Here we set the From from the original message, be it a draft or another
   // message, for example a template, we want to "edit as new".
   // Only do this if the message is our own draft or template.
-  if (params.composeFields.creatorIdentityKey && params.composeFields.from)
-  {
+  if (params.composeFields.creatorIdentityKey && params.composeFields.from) {
     let from = MailServices.headerParser.parseEncodedHeader(params.composeFields.from, null).join(", ");
-    if (from != identityList.value)
-    {
+    if (from != identityList.value) {
       MakeFromFieldEditable(true);
       identityList.value = from;
     }
   }
   LoadIdentity(true);
 
   // Get the <editor> element to startup an editor
   var editorElement = GetCurrentEditorElement();
@@ -2904,17 +2793,17 @@ function ComposeStartup(aParams)
   // For our purposes we need the URI of the message being processed, not its
   // original ancestor.
   gOriginalMsgURI = params.originalMsgURI;
   gMsgCompose = MailServices.compose.initCompose(params, window, editorElement.docShell);
 
   gMsgCompose.addMsgSendListener(gSendListener);
 
   document.getElementById("returnReceiptMenu")
-          .setAttribute('checked', gMsgCompose.compFields.returnReceipt);
+          .setAttribute("checked", gMsgCompose.compFields.returnReceipt);
   document.getElementById("dsnMenu")
           .setAttribute("checked", gMsgCompose.compFields.DSN);
   document.getElementById("cmd_attachVCard")
           .setAttribute("checked", gMsgCompose.compFields.attachVCard);
   toggleAttachmentReminder(gMsgCompose.compFields.attachmentReminder);
   gSendFormat = gMsgCompose.compFields.deliveryFormat;
   SetCompositionAsPerDeliveryFormat(gSendFormat);
   SelectDeliveryFormatMenuOption(gSendFormat);
@@ -2929,63 +2818,58 @@ function ComposeStartup(aParams)
 
   let languageToSet = getValidSpellcheckerDictionary(draftLanguage);
   document.documentElement.setAttribute("lang", languageToSet);
 
   let editortype = gMsgCompose.composeHTML ? "htmlmail" : "textmail";
   editorElement.makeEditable(editortype, true);
 
   // setEditorType MUST be called before setContentWindow
-  if (gMsgCompose.composeHTML)
-  {
+  if (gMsgCompose.composeHTML) {
     initLocalFontFaceMenu(document.getElementById("FontFacePopup"));
-  }
-  else
-  {
+  } else {
     // We are editing in plain text mode.
     // The SetCompositionAsPerDeliveryFormat call above already hid
     // the HTML toolbar, format and insert menus.
     // Also remove the delivery format from the options menu.
     document.getElementById("outputFormatMenu").setAttribute("hidden", true);
   }
 
   // Do setup common to Message Composer and Web Composer.
   EditorSharedStartup();
 
-  if (params.bodyIsLink)
-  {
+  if (params.bodyIsLink) {
     let body = gMsgCompose.compFields.body;
-    if (gMsgCompose.composeHTML)
-    {
+    if (gMsgCompose.composeHTML) {
       let cleanBody;
       try {
         cleanBody = decodeURI(body);
-      } catch(e) { cleanBody = body; }
+      } catch (e) {
+        cleanBody = body;
+      }
 
       body = body.replace(/&/g, "&amp;");
       gMsgCompose.compFields.body =
         "<br /><a href=\"" + body + "\">" + cleanBody + "</a><br />";
-    }
-    else
-    {
+    } else {
       gMsgCompose.compFields.body = "\n<" + body + ">\n";
     }
   }
 
   GetMsgSubjectElement().value = gMsgCompose.compFields.subject;
 
   AddAttachments(gMsgCompose.compFields.attachments, null, false);
 
   if (Services.prefs.getBoolPref(
       "mail.compose.show_attachment_pane")) {
     toggleAttachmentPane("show");
   }
 
   document.getElementById("msgcomposeWindow").dispatchEvent(
-    new Event("compose-window-init", { bubbles: false , cancelable: true }));
+    new Event("compose-window-init", { bubbles: false, cancelable: true }));
 
   gMsgCompose.RegisterStateListener(stateListener);
 
   // Add an observer to be called when document is done loading,
   // which creates the editor.
   try {
     GetCurrentCommandManager().
             addCommandObserver(gMsgEditorCreationObserver, "obs_documentCreated");
@@ -2994,56 +2878,52 @@ function ComposeStartup(aParams)
     editorElement.webNavigation.loadURI("about:blank", 0, null, null, null);
   } catch (e) {
     Cu.reportError(e);
   }
 
   gEditingDraft = gMsgCompose.compFields.draftId;
 
   // finally, see if we need to auto open the address sidebar.
-  var sideBarBox = document.getElementById('sidebar-box');
-  if (sideBarBox.getAttribute("sidebarVisible") == "true")
-  {
+  var sideBarBox = document.getElementById("sidebar-box");
+  if (sideBarBox.getAttribute("sidebarVisible") == "true") {
     // if we aren't supposed to have the side bar hidden, make sure it is visible
     if (document.getElementById("sidebar").getAttribute("src") == "")
       setTimeout(toggleAddressPicker, 0);   // do this on a delay so we don't hurt perf. on bringing up a new compose window
   }
   gAutoSaveInterval = getPref("mail.compose.autosave") ?
     getPref("mail.compose.autosaveinterval") * 60000 : 0;
 
   if (gAutoSaveInterval)
     gAutoSaveTimeout = setTimeout(AutoSave, gAutoSaveInterval);
 
   gAutoSaveKickedIn = false;
 }
+/* eslint-enable complexity */
 
 function splitEmailAddress(aEmail) {
   let at = aEmail.lastIndexOf("@");
   return (at != -1) ? [aEmail.slice(0, at), aEmail.slice(at + 1)] : [aEmail, ""];
 }
 
 // Emails are equal ignoring +suffixes (email+suffix@example.com).
 function emailSimilar(a, b) {
   if (!a || !b)
     return a == b;
   a = splitEmailAddress(a.toLowerCase());
   b = splitEmailAddress(b.toLowerCase());
   return a[1] == b[1] && a[0].split("+", 1)[0] == b[0].split("+", 1)[0];
 }
 
 // The new, nice, simple way of getting notified when a new editor has been created
-var gMsgEditorCreationObserver =
-{
-  observe: function(aSubject, aTopic, aData)
-  {
-    if (aTopic == "obs_documentCreated")
-    {
+var gMsgEditorCreationObserver = {
+  observe(aSubject, aTopic, aData) {
+    if (aTopic == "obs_documentCreated") {
       var editor = GetCurrentEditor();
-      if (editor && GetCurrentCommandManager() == aSubject)
-      {
+      if (editor && GetCurrentCommandManager() == aSubject) {
         var editorStyle = editor.QueryInterface(Ci.nsIEditorStyleSheets);
         // We use addOverrideStyleSheet rather than addStyleSheet so that we get
         // a synchronous load, rather than having a late-finishing async load
         // mark our editor as modified when the user hasn't typed anything yet,
         // but that means the sheet must not @import slow things, especially
         // not over the network.
         editorStyle.addOverrideStyleSheet("chrome://messenger/skin/messageQuotes.css");
         InitEditor();
@@ -3051,85 +2931,78 @@ var gMsgEditorCreationObserver =
       // Now that we know this document is an editor, update commands now if
       // the document has focus, or next time it receives focus via
       // CommandUpdate_MsgCompose()
       if (gLastWindowToHaveFocus == document.commandDispatcher.focusedWindow)
         updateComposeItems();
       else
         gLastWindowToHaveFocus = null;
     }
-  }
-}
-
-function WizCallback(state)
-{
-  if (state){
+  },
+};
+
+function WizCallback(state) {
+  if (state) {
     ComposeStartup(null);
-  }
-  else
-  {
+  } else {
     // The account wizard is still closing so we can't close just yet
     setTimeout(MsgComposeCloseWindow, 0);
   }
 }
 
-function ComposeLoad()
-{
+function ComposeLoad() {
   try {
     var other_headers = getPref("mail.compose.other.header");
-  }
-  catch (ex) {
+  } catch (ex) {
     dump("failed to get the mail.compose.other.header pref\n");
   }
 
   AddMessageComposeOfflineQuitObserver();
 
   setupAutocomplete();
 
   try {
     SetupCommandUpdateHandlers();
     // This will do migration, or create a new account if we need to.
     // We also want to open the account wizard if no identities are found
     var state = verifyAccounts(WizCallback, true);
 
     if (other_headers) {
-      var selectNode = document.getElementById('addressCol1#1');
+      var selectNode = document.getElementById("addressCol1#1");
       var other_headers_Array = other_headers.split(",");
       for (let i = 0; i < other_headers_Array.length; i++)
         selectNode.appendItem(other_headers_Array[i] + ":", "addr_other");
     }
     if (state)
       ComposeStartup(null);
-  }
-  catch (ex) {
+  } catch (ex) {
     Cu.reportError(ex);
     Services.prompt.alert(window, getComposeBundle().getString("initErrorDlogTitle"),
                           getComposeBundle().getString("initErrorDlgMessage"));
 
     MsgComposeCloseWindow();
     return;
   }
 
   CompactTheme.init();
   ToolbarIconColor.init();
 
   // initialize the customizeDone method on the customizeable toolbar
   var toolbox = document.getElementById("compose-toolbox");
   toolbox.customizeDone = function(aEvent) { MailToolboxCustomizeDone(aEvent, "CustomizeComposeToolbar"); };
 
-  var toolbarset = document.getElementById('customToolbars');
+  var toolbarset = document.getElementById("customToolbars");
   toolbox.toolbarset = toolbarset;
 
   awInitializeNumberOfRowsShown();
   updateAttachmentPane();
   attachmentBucketMarkEmptyBucket();
 }
 
-function ComposeUnload()
-{
+function ComposeUnload() {
   // Send notification that the window is going away completely.
   document.getElementById("msgcomposeWindow").dispatchEvent(
     new Event("compose-window-unload", { bubbles: false, cancelable: false }));
 
   GetCurrentCommandManager().removeCommandObserver(gMsgEditorCreationObserver,
                                                    "obs_documentCreated");
   UnloadCommandUpdateHandlers();
 
@@ -3157,128 +3030,119 @@ function ComposeUnload()
   if (gAutoSaveTimeout)
     clearTimeout(gAutoSaveTimeout);
   if (msgWindow)
     msgWindow.closeWindow();
 
   ReleaseGlobalVariables();
 }
 
-function SetDocumentCharacterSet(aCharset)
-{
+function SetDocumentCharacterSet(aCharset) {
   if (gMsgCompose) {
     gMsgCompose.SetDocumentCharset(aCharset);
     updateEncodingInStatusBar();
+  } else {
+    dump("Compose has not been created!\n");
   }
-  else
-    dump("Compose has not been created!\n");
 }
 
 /**
  * Return the full display string for any non-default text encoding of the
  * current composition (friendly name plus official character set name).
  * For the default text encoding, return empty string (""), to reduce
  * ux-complexity, e.g. for the default Status Bar display.
  * Note: The default is retrieved from mailnews.send_default_charset.
  *
  * @return string representation of non-default charset, otherwise "".
  */
-function GetCharsetUIString()
-{
+function GetCharsetUIString() {
   // The charset here is already the canonical charset (not an alias).
   let charset = gMsgCompose.compFields.characterSet;
   if (!charset)
     return "";
 
   if (charset.toLowerCase() != gMsgCompose.compFields.defaultCharacterSet.toLowerCase()) {
     try {
       return gCharsetConvertManager.getCharsetTitle(charset);
-    }
-    catch(e) { // Not a canonical charset after all...
+    } catch (e) { // Not a canonical charset after all...
       Cu.reportError("No charset title for charset=" + charset);
       return charset;
     }
   }
   return "";
 }
 
 // Add-ons can override this to customize the behavior.
-function DoSpellCheckBeforeSend()
-{
+function DoSpellCheckBeforeSend() {
   return getPref("mail.SpellCheckBeforeSend");
 }
 
 /**
  * Handles message sending operations.
  * @param msgType nsIMsgCompDeliverMode of the operation.
  */
-function GenericSendMessage(msgType)
-{
+/* eslint-disable complexity */
+function GenericSendMessage(msgType) {
   var msgCompFields = gMsgCompose.compFields;
 
   Recipients2CompFields(msgCompFields);
   let addresses = MailServices.headerParser
                               .makeFromDisplayAddress(GetMsgIdentityElement().value);
   msgCompFields.from = MailServices.headerParser.makeMimeHeader(addresses, addresses.length);
   var subject = GetMsgSubjectElement().value;
   msgCompFields.subject = subject;
   Attachments2CompFields(msgCompFields);
   // Some other msgCompFields have already been updated instantly in their respective
   // toggle functions, e.g. ToggleReturnReceipt(), ToggleDSN(),  ToggleAttachVCard(),
   // and toggleAttachmentReminder().
 
-  let sending = msgType == nsIMsgCompDeliverMode.Now ||
-      msgType == nsIMsgCompDeliverMode.Later ||
-      msgType == nsIMsgCompDeliverMode.Background;
-  if (sending)
-  {
+  let sending = msgType == Ci.nsIMsgCompDeliverMode.Now ||
+      msgType == Ci.nsIMsgCompDeliverMode.Later ||
+      msgType == Ci.nsIMsgCompDeliverMode.Background;
+  if (sending) {
     expandRecipients();
     // Check if e-mail addresses are complete, in case user turned off
     // autocomplete to local domain.
     if (!CheckValidEmailAddress(msgCompFields))
       return;
 
     // Do we need to check the spelling?
-    if (DoSpellCheckBeforeSend())
-    {
+    if (DoSpellCheckBeforeSend()) {
       // We disable spellcheck for the following -subject line, attachment
       // pane, identity and addressing widget therefore we need to explicitly
       // focus on the mail body when we have to do a spellcheck.
       SetMsgBodyFrameFocus();
       window.cancelSendMessage = false;
       window.openDialog("chrome://editor/content/EdSpellCheck.xul", "_blank",
                         "dialog,close,titlebar,modal,resizable", true, true, false);
 
       if (window.cancelSendMessage)
         return;
     }
 
     // Strip trailing spaces and long consecutive WSP sequences from the
     // subject line to prevent getting only WSP chars on a folded line.
     let fixedSubject = subject.replace(/\s{74,}/g, "    ").trimRight();
-    if (fixedSubject != subject)
-    {
+    if (fixedSubject != subject) {
       subject = fixedSubject;
       msgCompFields.subject = fixedSubject;
       GetMsgSubjectElement().value = fixedSubject;
     }
 
     // Remind the person if there isn't a subject
-    if (subject == "")
-    {
+    if (subject == "") {
       if (Services.prompt.confirmEx(
             window,
             getComposeBundle().getString("subjectEmptyTitle"),
             getComposeBundle().getString("subjectEmptyMessage"),
             (Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_0) +
             (Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_1),
             getComposeBundle().getString("sendWithEmptySubjectButton"),
             getComposeBundle().getString("cancelSendingButton"),
-            null, null, {value:0}) == 1)
-      {
+            null, null, {value: 0}) == 1) {
         GetMsgSubjectElement().focus();
         return;
       }
     }
 
     // Attachment Reminder: Alert the user if
     //  - the user requested "Remind me later" from either the notification bar or the menu
     //    (alert regardless of the number of files already attached: we can't guess for how many
@@ -3287,48 +3151,45 @@ function GenericSendMessage(msgType)
     //    that the message has no attachment(s) yet, message still contains some attachment
     //    keywords, and notification was not dismissed).
     if (gManualAttachmentReminder || (getPref("mail.compose.attachment_reminder_aggressive") &&
          document.getElementById("attachmentNotificationBox")
                  .getNotificationWithValue("attachmentReminder"))) {
       let flags = Services.prompt.BUTTON_POS_0 * Services.prompt.BUTTON_TITLE_IS_STRING +
                   Services.prompt.BUTTON_POS_1 * Services.prompt.BUTTON_TITLE_IS_STRING;
       let hadForgotten = Services.prompt.confirmEx(window,
-                            getComposeBundle().getString("attachmentReminderTitle"),
-                            getComposeBundle().getString("attachmentReminderMsg"),
-                            flags,
-                            getComposeBundle().getString("attachmentReminderFalseAlarm"),
-                            getComposeBundle().getString("attachmentReminderYesIForgot"),
-                            null, null, {value:0});
+                         getComposeBundle().getString("attachmentReminderTitle"),
+                         getComposeBundle().getString("attachmentReminderMsg"),
+                         flags,
+                         getComposeBundle().getString("attachmentReminderFalseAlarm"),
+                         getComposeBundle().getString("attachmentReminderYesIForgot"),
+                         null, null, {value: 0});
       // Deactivate manual attachment reminder after showing the alert to avoid alert loop.
       // We also deactivate reminder when user ignores alert with [x] or [ESC].
       if (gManualAttachmentReminder)
         toggleAttachmentReminder(false);
 
       if (hadForgotten)
         return;
     }
 
     // Check if the user tries to send a message to a newsgroup through a mail
     // account.
     var currentAccountKey = getCurrentAccountKey();
     let account = MailServices.accounts.getAccount(currentAccountKey);
-    if (!account)
-    {
+    if (!account) {
       throw new Error("currentAccountKey '" + currentAccountKey +
                       "' has no matching account!");
     }
-    if (account.incomingServer.type != "nntp" && msgCompFields.newsgroups != "")
-    {
+    if (account.incomingServer.type != "nntp" && msgCompFields.newsgroups != "") {
       const kDontAskAgainPref = "mail.compose.dontWarnMail2Newsgroup";
       // default to ask user if the pref is not set
       let dontAskAgain = getPref(kDontAskAgainPref);
-      if (!dontAskAgain)
-      {
-        let checkbox = {value:false};
+      if (!dontAskAgain) {
+        let checkbox = {value: false};
         let okToProceed = Services.prompt.confirmCheck(
                               window,
                               getComposeBundle().getString("noNewsgroupSupportTitle"),
                               getComposeBundle().getString("recipientDlogMessage"),
                               getComposeBundle().getString("CheckMsg"),
                               checkbox);
         if (!okToProceed)
           return;
@@ -3343,78 +3204,72 @@ function GenericSendMessage(msgType)
       msgCompFields.newsgroups = "";
     }
 
     // Before sending the message, check what to do with HTML message,
     // eventually abort.
     var convert = DetermineConvertibility();
     var action = DetermineHTMLAction(convert);
 
-    if (action == nsIMsgCompSendFormat.AskUser)
-    {
-      var recommAction = (convert == nsIMsgCompConvertible.No)
-                          ? nsIMsgCompSendFormat.AskUser
-                          : nsIMsgCompSendFormat.PlainText;
-      var result2 = {action:recommAction, convertible:convert, abort:false};
+    if (action == Ci.nsIMsgCompSendFormat.AskUser) {
+      var recommAction = (convert == Ci.nsIMsgCompConvertible.No)
+                          ? Ci.nsIMsgCompSendFormat.AskUser
+                          : Ci.nsIMsgCompSendFormat.PlainText;
+      var result2 = {action: recommAction, convertible: convert, abort: false};
       window.openDialog("chrome://messenger/content/messengercompose/askSendFormat.xul",
                         "askSendFormatDialog", "chrome,modal,titlebar,centerscreen",
                         result2);
       if (result2.abort)
         return;
       action = result2.action;
     }
 
     // We will remember the users "send format" decision in the address
     // collector code (see nsAbAddressCollector::CollectAddress())
     // by using msgCompFields.forcePlainText and msgCompFields.useMultipartAlternative
     // to determine the nsIAbPreferMailFormat (unknown, plaintext, or html).
     // If the user sends both, we remember html.
-    switch (action)
-    {
-      case nsIMsgCompSendFormat.PlainText:
+    switch (action) {
+      case Ci.nsIMsgCompSendFormat.PlainText:
         msgCompFields.forcePlainText = true;
         msgCompFields.useMultipartAlternative = false;
         break;
-      case nsIMsgCompSendFormat.HTML:
+      case Ci.nsIMsgCompSendFormat.HTML:
         msgCompFields.forcePlainText = false;
         msgCompFields.useMultipartAlternative = false;
         break;
-      case nsIMsgCompSendFormat.Both:
+      case Ci.nsIMsgCompSendFormat.Both:
         msgCompFields.forcePlainText = false;
         msgCompFields.useMultipartAlternative = true;
         break;
       default:
         throw new Error("Invalid nsIMsgCompSendFormat action; action=" + action);
     }
   }
 
   // hook for extra compose pre-processing
   Services.obs.notifyObservers(window, "mail:composeOnSend");
 
   var originalCharset = gMsgCompose.compFields.characterSet;
   // Check if the headers of composing mail can be converted to a mail charset.
-  if (msgType == nsIMsgCompDeliverMode.Now ||
-    msgType == nsIMsgCompDeliverMode.Later ||
-    msgType == nsIMsgCompDeliverMode.Background ||
-    msgType == nsIMsgCompDeliverMode.Save ||
-    msgType == nsIMsgCompDeliverMode.SaveAsDraft ||
-    msgType == nsIMsgCompDeliverMode.AutoSaveAsDraft ||
-    msgType == nsIMsgCompDeliverMode.SaveAsTemplate)
-  {
-    var fallbackCharset = new Object;
+  if (msgType == Ci.nsIMsgCompDeliverMode.Now ||
+      msgType == Ci.nsIMsgCompDeliverMode.Later ||
+      msgType == Ci.nsIMsgCompDeliverMode.Background ||
+      msgType == Ci.nsIMsgCompDeliverMode.Save ||
+      msgType == Ci.nsIMsgCompDeliverMode.SaveAsDraft ||
+      msgType == Ci.nsIMsgCompDeliverMode.AutoSaveAsDraft ||
+      msgType == Ci.nsIMsgCompDeliverMode.SaveAsTemplate) {
+    var fallbackCharset = {};
     // Check encoding, switch to UTF-8 if the default encoding doesn't fit
     // and disable_fallback_to_utf8 isn't set for this encoding.
-    if (!gMsgCompose.checkCharsetConversion(getCurrentIdentity(), fallbackCharset))
-    {
+    if (!gMsgCompose.checkCharsetConversion(getCurrentIdentity(), fallbackCharset)) {
       var disableFallback = false;
-      try
-      {
+      try {
         disableFallback = getPref("mailnews.disable_fallback_to_utf8." + originalCharset);
-      }
-      catch (e) {}
+      } catch (e) {}
       if (disableFallback)
         msgCompFields.needToCheckCharset = false;
       else
         fallbackCharset.value = "UTF-8";
     }
 
     if (fallbackCharset &&
         fallbackCharset.value && fallbackCharset.value != "")
@@ -3428,104 +3283,101 @@ function GenericSendMessage(msgType)
     var event = document.createEvent("UIEvents");
     event.initEvent("compose-send-message", false, true);
     var msgcomposeWindow = document.getElementById("msgcomposeWindow");
     msgcomposeWindow.setAttribute("msgtype", msgType);
     msgcomposeWindow.dispatchEvent(event);
     if (event.defaultPrevented)
       throw Cr.NS_ERROR_ABORT;
 
-    gAutoSaving = (msgType == nsIMsgCompDeliverMode.AutoSaveAsDraft);
+    gAutoSaving = (msgType == Ci.nsIMsgCompDeliverMode.AutoSaveAsDraft);
 
     // disable the ui if we're not auto-saving
-    if (!gAutoSaving)
+    if (!gAutoSaving) {
       ToggleWindowLock(true);
-
-    // If we're auto saving, mark the body as not changed here, and not
-    // when the save is done, because the user might change it between now
-    // and when the save is done.
-    else
-    {
+    } else {
+      // If we're auto saving, mark the body as not changed here, and not
+      // when the save is done, because the user might change it between now
+      // and when the save is done.
       SetContentAndBodyAsUnmodified();
     }
 
     var progress = Cc["@mozilla.org/messenger/progress;1"]
                      .createInstance(Ci.nsIMsgProgress);
-    if (progress)
-    {
+    if (progress) {
       progress.registerListener(progressListener);
-      if (msgType == nsIMsgCompDeliverMode.Save ||
-          msgType == nsIMsgCompDeliverMode.SaveAsDraft ||
-          msgType == nsIMsgCompDeliverMode.AutoSaveAsDraft ||
-          msgType == nsIMsgCompDeliverMode.SaveAsTemplate)
+      if (msgType == Ci.nsIMsgCompDeliverMode.Save ||
+          msgType == Ci.nsIMsgCompDeliverMode.SaveAsDraft ||
+          msgType == Ci.nsIMsgCompDeliverMode.AutoSaveAsDraft ||
+          msgType == Ci.nsIMsgCompDeliverMode.SaveAsTemplate)
         gSaveOperationInProgress = true;
       else
         gSendOperationInProgress = true;
     }
     msgWindow.domWindow = window;
     msgWindow.rootDocShell.allowAuth = true;
     gMsgCompose.SendMsg(msgType, getCurrentIdentity(),
                         getCurrentAccountKey(), msgWindow, progress);
-  }
-  catch (ex) {
+  } catch (ex) {
     Cu.reportError("GenericSendMessage FAILED: " + ex);
     ToggleWindowLock(false);
   }
   if (gMsgCompose && originalCharset != gMsgCompose.compFields.characterSet)
     SetDocumentCharacterSet(gMsgCompose.compFields.characterSet);
 }
+/* eslint-enable complexity */
 
 /**
  * Check if the given address is valid (contains a @).
  *
  * @param aAddress  The address string to check.
  */
 function isValidAddress(aAddress) {
   return (aAddress.includes("@", 1) && !aAddress.endsWith("@"));
 }
 
 /**
  * Keep the Send buttons disabled until any recipient is entered.
  */
-function updateSendLock()
-{
+function updateSendLock() {
   gSendLocked = true;
   if (!gMsgCompose)
     return;
 
   const mailTypes = [ "addr_to", "addr_cc", "addr_bcc" ];
 
   // Enable the send buttons if anything usable was entered into at least one
   // recipient field.
-  for (let row = 1; row <= top.MAX_RECIPIENTS; row ++)
-  {
+  for (let row = 1; row <= top.MAX_RECIPIENTS; row++) {
     let popupValue = awGetPopupElement(row).value;
     let inputValue = awGetInputElement(row).value.trim();
-    let listNames = null;
-    if ((mailTypes.includes(popupValue) &&
-         // a properly looking email address
-        (isValidAddress(inputValue) ||
-         // a valid mailing list name in some or our addressbooks
-         ((listNames = MimeParser.parseHeaderField(inputValue, MimeParser.HEADER_ADDRESS)) &&
-          listNames.length > 0 && MailServices.ab.mailListNameExists(listNames[0].name))
-        )) || ((popupValue == "addr_newsgroups") && (inputValue != "")))
-    {
+    if (mailTypes.includes(popupValue)) {
+      if (isValidAddress(inputValue)) { // a properly looking email address
+        gSendLocked = false;
+        break;
+      } else { // a valid mailing list name in some or our addressbooks
+        let listNames = MimeParser.parseHeaderField(inputValue, MimeParser.HEADER_ADDRESS);
+        if (listNames.length > 0 && MailServices.ab.mailListNameExists(listNames[0].name)) {
+          gSendLocked = false;
+          break;
+        }
+      }
+    } else if (popupValue == "addr_newsgroups" && inputValue != "") {
       gSendLocked = false;
       break;
     }
   }
 }
 
 /**
  * Check if the entered addresses are valid and alert the user if they are not.
  *
  * @param aMsgCompFields  A nsIMsgCompFields object containing the fields to check.
  */
-function CheckValidEmailAddress(aMsgCompFields)
-{
+function CheckValidEmailAddress(aMsgCompFields) {
   let invalidStr;
   let recipientCount = 0;
   // Check that each of the To, CC, and BCC recipients contains a '@'.
   for (let type of ["to", "cc", "bcc"]) {
     let recipients = aMsgCompFields.splitRecipients(aMsgCompFields[type], false, {});
     // MsgCompFields contains only non-empty recipients.
     recipientCount += recipients.length;
     for (let recipient of recipients) {
@@ -3539,385 +3391,367 @@ function CheckValidEmailAddress(aMsgComp
   }
 
   if (recipientCount == 0 && aMsgCompFields.newsgroups.trim() == "") {
     Services.prompt.alert(window, getComposeBundle().getString("addressInvalidTitle"),
                           getComposeBundle().getString("noRecipients"));
     return false;
   }
 
-  if (invalidStr)
-  {
+  if (invalidStr) {
     Services.prompt.alert(window, getComposeBundle().getString("addressInvalidTitle"),
                           getComposeBundle().getFormattedString("addressInvalid",
                           [invalidStr], 1));
     return false;
   }
 
   return true;
 }
 
-function SendMessage()
-{
+function SendMessage() {
   let sendInBackground =
     Services.prefs.getBoolPref("mailnews.sendInBackground");
   if (sendInBackground && (AppConstants.platform != "macosx")) {
     let enumerator = Services.wm.getEnumerator(null);
     let count = 0;
     while (enumerator.hasMoreElements() && count < 2) {
-      let win = enumerator.getNext();
+      enumerator.getNext();
       count++;
     }
     if (count == 1)
       sendInBackground = false;
   }
 
   GenericSendMessage(sendInBackground ?
-                     nsIMsgCompDeliverMode.Background :
-                     nsIMsgCompDeliverMode.Now);
+                     Ci.nsIMsgCompDeliverMode.Background :
+                     Ci.nsIMsgCompDeliverMode.Now);
   ExitFullscreenMode();
 }
 
-function SendMessageWithCheck()
-{
-    var warn = getPref("mail.warn_on_send_accel_key");
-
-    if (warn) {
-        let checkValue = {value:false};
-        let buttonPressed = Services.prompt.confirmEx(window,
-              getComposeBundle().getString('sendMessageCheckWindowTitle'),
-              getComposeBundle().getString('sendMessageCheckLabel'),
-              (Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_0) +
-              (Services.prompt.BUTTON_TITLE_CANCEL * Services.prompt.BUTTON_POS_1),
-              getComposeBundle().getString('sendMessageCheckSendButtonLabel'),
-              null, null,
-              getComposeBundle().getString('CheckMsg'),
-              checkValue);
-        if (buttonPressed != 0) {
-            return;
-        }
-        if (checkValue.value) {
-            Services.prefs.setBoolPref("mail.warn_on_send_accel_key", false);
-        }
+function SendMessageWithCheck() {
+  var warn = getPref("mail.warn_on_send_accel_key");
+
+  if (warn) {
+    let bundle = getComposeBundle();
+    let checkValue = {value: false};
+    let buttonPressed = Services.prompt.confirmEx(window,
+      bundle.getString("sendMessageCheckWindowTitle"),
+      bundle.getString("sendMessageCheckLabel"),
+      (Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_0) +
+      (Services.prompt.BUTTON_TITLE_CANCEL * Services.prompt.BUTTON_POS_1),
+      bundle.getString("sendMessageCheckSendButtonLabel"),
+      null, null,
+      bundle.getString("CheckMsg"),
+      checkValue);
+    if (buttonPressed != 0) {
+      return;
     }
+    if (checkValue.value) {
+      Services.prefs.setBoolPref("mail.warn_on_send_accel_key", false);
+    }
+  }
 
   let sendInBackground = Services.prefs.getBoolPref("mailnews.sendInBackground");
 
-  GenericSendMessage(Services.io.offline ? nsIMsgCompDeliverMode.Later :
-                     (sendInBackground ?
-                      nsIMsgCompDeliverMode.Background :
-                      nsIMsgCompDeliverMode.Now));
-
+  let mode;
+  if (Services.io.offline) {
+    mode = Ci.nsIMsgCompDeliverMode.Later;
+  } else {
+    mode = sendInBackground ? Ci.nsIMsgCompDeliverMode.Background : Ci.nsIMsgCompDeliverMode.Now;
+  }
+  GenericSendMessage(mode);
   ExitFullscreenMode();
 }
 
-function SendMessageLater()
-{
-  GenericSendMessage(nsIMsgCompDeliverMode.Later);
+function SendMessageLater() {
+  GenericSendMessage(Ci.nsIMsgCompDeliverMode.Later);
   ExitFullscreenMode();
 }
 
-function ExitFullscreenMode()
-{
+function ExitFullscreenMode() {
   // On OS X we need to deliberately exit full screen mode after sending.
   if (AppConstants.platform == "macosx") {
     window.fullScreen = false;
   }
 }
 
-function Save()
-{
-  switch (defaultSaveOperation)
-  {
-    case "file"     : SaveAsFile(false);      break;
-    case "template" : SaveAsTemplate(false);  break;
-    default         : SaveAsDraft(false);     break;
+function Save() {
+  switch (defaultSaveOperation) {
+    case "file":
+      SaveAsFile(false);
+      break;
+    case "template":
+      SaveAsTemplate(false);
+      break;
+    default:
+      SaveAsDraft(false);
+      break;
   }
 }
 
-function SaveAsFile(saveAs)
-{
+function SaveAsFile(saveAs) {
   var subject = GetMsgSubjectElement().value;
   GetCurrentEditorElement().contentDocument.title = subject;
 
-  if (gMsgCompose.bodyConvertible() == nsIMsgCompConvertible.Plain)
+  if (gMsgCompose.bodyConvertible() == Ci.nsIMsgCompConvertible.Plain)
     SaveDocument(saveAs, false, "text/plain");
   else
     SaveDocument(saveAs, false, "text/html");
   defaultSaveOperation = "file";
 }
 
-function SaveAsDraft()
-{
+function SaveAsDraft() {
   gAutoSaveKickedIn = false;
   gEditingDraft = true;
 
-  GenericSendMessage(nsIMsgCompDeliverMode.SaveAsDraft);
+  GenericSendMessage(Ci.nsIMsgCompDeliverMode.SaveAsDraft);
   defaultSaveOperation = "draft";
 }
 
-function SaveAsTemplate()
-{
+function SaveAsTemplate() {
   gAutoSaveKickedIn = false;
   gEditingDraft = false;
 
   let savedReferences = null;
   if (gMsgCompose && gMsgCompose.compFields) {
     // Clear References header. When we use the template, we don't want that
     // header, yet, "edit as new message" maintains it. So we need to clear
     // it when saving the template.
     // Note: The In-Reply-To header is the last entry in the references header,
     // so it will get cleared as well.
     savedReferences = gMsgCompose.compFields.references;
     gMsgCompose.compFields.references = null;
   }
 
-  GenericSendMessage(nsIMsgCompDeliverMode.SaveAsTemplate);
+  GenericSendMessage(Ci.nsIMsgCompDeliverMode.SaveAsTemplate);
   defaultSaveOperation = "template";
 
   if (savedReferences)
     gMsgCompose.compFields.references = savedReferences;
 }
 
 // Sets the additional FCC, in addition to the default FCC.
-function MessageFcc(aFolder)
-{
+function MessageFcc(aFolder) {
   if (!gMsgCompose)
     return;
 
   var msgCompFields = gMsgCompose.compFields;
   if (!msgCompFields)
     return;
 
   // Get the uri for the folder to FCC into.
   var fccURI = aFolder.URI;
   msgCompFields.fcc2 = (msgCompFields.fcc2 == fccURI) ? "nocopy://" : fccURI;
 }
 
-function updatePriorityMenu()
-{
-  if (gMsgCompose)
-  {
+function updatePriorityMenu() {
+  if (gMsgCompose) {
     var msgCompFields = gMsgCompose.compFields;
-    if (msgCompFields && msgCompFields.priority)
-    {
-      var priorityMenu = document.getElementById('priorityMenu' );
-      priorityMenu.querySelector('[checked="true"]').removeAttribute('checked');
-      priorityMenu.querySelector('[value="' + msgCompFields.priority + '"]').setAttribute('checked', 'true');
+    if (msgCompFields && msgCompFields.priority) {
+      var priorityMenu = document.getElementById("priorityMenu");
+      priorityMenu.querySelector('[checked="true"]').removeAttribute("checked");
+      priorityMenu.querySelector('[value="' + msgCompFields.priority + '"]').setAttribute("checked", "true");
     }
   }
 }
 
-function updatePriorityToolbarButton(newPriorityValue)
-{
-  var prioritymenu = document.getElementById('priorityMenu-button');
+function updatePriorityToolbarButton(newPriorityValue) {
+  var prioritymenu = document.getElementById("priorityMenu-button");
   if (prioritymenu)
     prioritymenu.value = newPriorityValue;
 }
 
-function PriorityMenuSelect(target)
-{
-  if (gMsgCompose)
-  {
+function PriorityMenuSelect(target) {
+  if (gMsgCompose) {
     var msgCompFields = gMsgCompose.compFields;
     if (msgCompFields)
-      msgCompFields.priority = target.getAttribute('value');
+      msgCompFields.priority = target.getAttribute("value");
 
     // keep priority toolbar button in synch with possible changes via the menu item
-    updatePriorityToolbarButton(target.getAttribute('value'));
+    updatePriorityToolbarButton(target.getAttribute("value"));
   }
 }
 
 /**
  * Shows HTML formatting menus/toolbars if they are useful for the selected
  * message delivery format. E.g. they are not needed for plain text format.
  *
  * @param aDeliveryFormat  The chosen output format from the nsIMsgCompSendFormat enum.
  */
-function SetCompositionAsPerDeliveryFormat(aDeliveryFormat)
-{
+function SetCompositionAsPerDeliveryFormat(aDeliveryFormat) {
   let format_toolbar = document.getElementById("FormatToolbar");
   let format_menu = document.getElementById("formatMenu");
   let insert_menu = document.getElementById("insertMenu");
   let view_menuitem = document.getElementById("menu_showFormatToolbar");
 
   let hideMenus = !gMsgCompose.composeHTML;
   format_menu.hidden = hideMenus;
   insert_menu.hidden = hideMenus;
   view_menuitem.hidden = hideMenus;
   // Hide the HTML toolbar for a plain text composition
   // or the user manually hid the toolbar on the view menu.
   format_toolbar.hidden = hideMenus ||
     (view_menuitem.getAttribute("checked") == "false");
 }
 
-function SelectDeliveryFormatMenuOption(aDeliveryFormat)
-{
+function SelectDeliveryFormatMenuOption(aDeliveryFormat) {
   let deliveryFormat;
 
-  switch(aDeliveryFormat) {
-    case nsIMsgCompSendFormat.PlainText:
+  switch (aDeliveryFormat) {
+    case Ci.nsIMsgCompSendFormat.PlainText:
       deliveryFormat = "format_plain";
       break;
-    case nsIMsgCompSendFormat.HTML:
+    case Ci.nsIMsgCompSendFormat.HTML:
       deliveryFormat = "format_html";
       break;
-    case nsIMsgCompSendFormat.Both:
+    case Ci.nsIMsgCompSendFormat.Both:
       deliveryFormat = "format_both";
       break;
-    case nsIMsgCompSendFormat.AskUser:
+    case Ci.nsIMsgCompSendFormat.AskUser:
     default:
       deliveryFormat = "format_auto";
   }
 
   document.getElementById(deliveryFormat).setAttribute("checked", "true");
 }
 
-function OutputFormatMenuSelect(target)
-{
+function OutputFormatMenuSelect(target) {
   let currentSendFormat = gSendFormat;
 
   if (gMsgCompose) {
     let msgCompFields = gMsgCompose.compFields;
     if (msgCompFields) {
       switch (target.getAttribute("id")) {
         case "format_plain":
-          gSendFormat = nsIMsgCompSendFormat.PlainText;
+          gSendFormat = Ci.nsIMsgCompSendFormat.PlainText;
           break;
         case "format_html":
-          gSendFormat = nsIMsgCompSendFormat.HTML;
+          gSendFormat = Ci.nsIMsgCompSendFormat.HTML;
           break;
         case "format_both":
-          gSendFormat = nsIMsgCompSendFormat.Both;
+          gSendFormat = Ci.nsIMsgCompSendFormat.Both;
           break;
         case "format_auto":
         default:
-          gSendFormat = nsIMsgCompSendFormat.AskUser;
+          gSendFormat = Ci.nsIMsgCompSendFormat.AskUser;
       }
     }
 
     SetCompositionAsPerDeliveryFormat(gSendFormat);
     gMsgCompose.compFields.deliveryFormat = gSendFormat;
     gContentChanged = currentSendFormat != gSendFormat;
   }
 }
 
 // walk through the recipients list and add them to the inline spell checker ignore list
-function addRecipientsToIgnoreList(aAddressesToAdd)
-{
-  if (gSpellChecker.enabled)
-  {
+function addRecipientsToIgnoreList(aAddressesToAdd) {
+  if (gSpellChecker.enabled) {
     // break the list of potentially many recipients back into individual names
     var emailAddresses = {};
     var names = {};
     var fullNames = {};
-    let numAddresses = MailServices.headerParser.parseHeadersWithArray(aAddressesToAdd, emailAddresses, names, fullNames);
+    MailServices.headerParser.parseHeadersWithArray(aAddressesToAdd, emailAddresses, names, fullNames);
     if (!names)
       return;
     let tokenizedNames = [];
 
     // Each name could consist of multiple word delimited by either commas or spaces, i.e. Green Lantern
     // or Lantern,Green. Tokenize on comma first, then tokenize again on spaces.
-    for (let name in names.value)
-    {
+    for (let name in names.value) {
       if (!names.value[name])
         continue;
-      let splitNames = names.value[name].split(',');
-      for (let i = 0; i < splitNames.length; i++)
-      {
+      let splitNames = names.value[name].split(",");
+      for (let i = 0; i < splitNames.length; i++) {
         // now tokenize off of white space
-        let splitNamesFromWhiteSpaceArray = splitNames[i].split(' ');
+        let splitNamesFromWhiteSpaceArray = splitNames[i].split(" ");
         for (let whiteSpaceIndex = 0; whiteSpaceIndex < splitNamesFromWhiteSpaceArray.length; whiteSpaceIndex++)
           if (splitNamesFromWhiteSpaceArray[whiteSpaceIndex])
             tokenizedNames.push(splitNamesFromWhiteSpaceArray[whiteSpaceIndex]);
       }
     }
     spellCheckReadyObserver.addWordsToIgnore(tokenizedNames);
   }
 }
 
 /**
  * Observer waiting for spell checker to become initialized or to complete
  * checking. When it fires, it pushes new words to be ignored to the speller.
  */
-var spellCheckReadyObserver =
-{
+var spellCheckReadyObserver = {
   _topic: "inlineSpellChecker-spellCheck-ended",
 
   _ignoreWords: [],
 
-  observe: function(aSubject, aTopic, aData) {
+  observe(aSubject, aTopic, aData) {
     if (aTopic != this._topic) {
       return;
     }
 
     this.removeObserver();
     this._addWords();
   },
 
   _isAdded: false,
 
-  addObserver: function() {
+  addObserver() {
     if (this._isAdded)
       return;
 
     Services.obs.addObserver(this, this._topic);
     this._isAdded = true;
   },
 
-  removeObserver: function() {
+  removeObserver() {
     if (!this._isAdded)
       return;
 
     Services.obs.removeObserver(this, this._topic);
     this._clearPendingWords();
     this._isAdded = false;
   },
 
-  addWordsToIgnore: function (aIgnoreWords) {
+  addWordsToIgnore(aIgnoreWords) {
     this._ignoreWords.push(...aIgnoreWords);
     if (gSpellChecker.mInlineSpellChecker.spellCheckPending) {
       // spellchecker is enabled, but we must wait for its init to complete
       this.addObserver();
     } else {
       this._addWords();
     }
   },
 
-  _addWords: function() {
+  _addWords() {
     // At the time the speller finally got initialized, we may already be closing
     // the compose together with the speller, so we need to check if they
     // are still valid.
     if (gMsgCompose && gSpellChecker.enabled) {
       gSpellChecker.mInlineSpellChecker.ignoreWords(this._ignoreWords, this._ignoreWords.length);
     }
     this._clearPendingWords();
   },
 
   _clearPendingWords() {
     this._ignoreWords.length = 0;
-  }
-}
-
-function onAddressColCommand(aAddressWidgetId)
-{
+  },
+};
+
+function onAddressColCommand(aAddressWidgetId) {
   gContentChanged = true;
-  awSetAutoComplete(aAddressWidgetId.slice(aAddressWidgetId.lastIndexOf('#') + 1));
+  awSetAutoComplete(aAddressWidgetId.slice(aAddressWidgetId.lastIndexOf("#") + 1));
   updateSendCommands(true);
 }
 
 /**
  * Called if the list of recipients changed in any way.
  *
  * @param aAutomatic  Set to true if the change of recipients was invoked
  *                    programmatically and should not be considered a change
  *                    of message content.
  */
-function onRecipientsChanged(aAutomatic)
-{
+function onRecipientsChanged(aAutomatic) {
   if (!aAutomatic) {
     gContentChanged = true;
   }
   updateSendCommands(true);
 }
 
 /**
  * Show the popup identified by aPopupID
@@ -3942,24 +3776,23 @@ function onRecipientsChanged(aAutomatic)
 function showPopupById(aPopupID, aAnchorID, aPosition = "after_start",
                        x, y, isContextMenu, attributesOverride, triggerEvent) {
   let popup = document.getElementById(aPopupID);
   let anchor = document.getElementById(aAnchorID);
   popup.openPopup(anchor, aPosition, x, y,
                   isContextMenu, attributesOverride, triggerEvent);
 }
 
-function InitLanguageMenu()
-{
-  var languageMenuList = document.getElementById('languageMenuList');
+function InitLanguageMenu() {
+  var languageMenuList = document.getElementById("languageMenuList");
   if (!languageMenuList)
     return;
 
-  var spellChecker = Cc['@mozilla.org/spellchecker/engine;1']
-                       .getService(mozISpellCheckingEngine);
+  var spellChecker = Cc["@mozilla.org/spellchecker/engine;1"]
+                       .getService(Ci.mozISpellCheckingEngine);
   var o1 = {};
   var o2 = {};
 
   // Get the list of dictionaries from
   // the spellchecker.
 
   spellChecker.getDictionaryList(o1, o2);
 
@@ -3974,28 +3807,26 @@ function InitLanguageMenu()
   sDictCount = count;
 
   var sortedList = gSpellChecker.sortDictionaryList(dictList);
 
   // Remove any languages from the list.
   while (languageMenuList.hasChildNodes())
     languageMenuList.lastChild.remove();
 
-  for (let i = 0; i < count; i++)
-  {
+  for (let i = 0; i < count; i++) {
     var item = document.createElement("menuitem");
     item.setAttribute("label", sortedList[i].label);
     item.setAttribute("value", sortedList[i].id);
-    item.setAttribute('type', 'radio');
+    item.setAttribute("type", "radio");
     languageMenuList.appendChild(item);
   }
 }
 
-function OnShowDictionaryMenu(aTarget)
-{
+function OnShowDictionaryMenu(aTarget) {
   InitLanguageMenu();
   let curLang = document.documentElement.getAttribute("lang");
   if (!curLang)
     return;
 
   let language = aTarget.querySelector('[value="' + curLang + '"]');
   if (language)
     language.setAttribute("checked", true);
@@ -4003,18 +3834,17 @@ function OnShowDictionaryMenu(aTarget)
 
 /**
  * Change the language of the composition and if we are using inline
  * spell check, recheck the message with the new dictionary.
  *
  * Note: called from the "Check Spelling" panel in SelectLanguage().
  * @param aLang  New language to set.
  */
-function ComposeChangeLanguage(aLang)
-{
+function ComposeChangeLanguage(aLang) {
   if (document.documentElement.getAttribute("lang") != aLang) {
     // Update the document language as well (needed to synchronise
     // the subject).
     document.documentElement.setAttribute("lang", aLang);
 
     let spellChecker = gSpellChecker.mInlineSpellChecker.spellChecker;
     if (spellChecker) {
       spellChecker.SetCurrentDictionary(aLang);
@@ -4036,24 +3866,22 @@ function ComposeChangeLanguage(aLang)
 }
 
 /**
  * Change the language of the composition and if we are using inline
  * spell check, recheck the message with the new dictionary.
  *
  * @param event  Event of selecting an item in the spelling button menulist popup.
  */
-function ChangeLanguage(event)
-{
+function ChangeLanguage(event) {
   ComposeChangeLanguage(event.target.value);
   event.stopPropagation();
 }
 
-function updateLanguageInStatusBar()
-{
+function updateLanguageInStatusBar() {
   InitLanguageMenu();
   let languageMenuList = document.getElementById("languageMenuList");
   let spellCheckStatusPanel = document.getElementById("spellCheckStatusPanel");
   let languageStatusButton = document.getElementById("languageStatusButton");
   if (!languageMenuList || !spellCheckStatusPanel || !languageStatusButton) {
     return;
   }
 
@@ -4072,87 +3900,78 @@ function updateLanguageInStatusBar()
     if (item.getAttribute("value") == language) {
       languageStatusButton.label = item.getAttribute("label");
       break;
     }
     item = item.nextSibling;
   }
 }
 
-function updateEncodingInStatusBar()
-{
+function updateEncodingInStatusBar() {
   let encodingUIString = GetCharsetUIString();
   let encodingStatusPanel = document.getElementById("encodingStatusPanel");
   if (!encodingStatusPanel) {
     return;
   }
 
   // Update status display; no status display for default text encoding.
   encodingStatusPanel.collapsed = !(encodingStatusPanel.label = encodingUIString);
 }
 
-function ToggleReturnReceipt(target)
-{
-    var msgCompFields = gMsgCompose.compFields;
-    if (msgCompFields)
-    {
-        msgCompFields.returnReceipt = ! msgCompFields.returnReceipt;
-        target.setAttribute('checked', msgCompFields.returnReceipt);
-        gReceiptOptionChanged = true;
-    }
-}
-
-function ToggleDSN(target)
-{
-    var msgCompFields = gMsgCompose.compFields;
-    if (msgCompFields)
-    {
-        msgCompFields.DSN = ! msgCompFields.DSN;
-        target.setAttribute('checked', msgCompFields.DSN);
-        gDSNOptionChanged = true;
-    }
-}
-
-function ToggleAttachVCard(target)
-{
+function ToggleReturnReceipt(target) {
+  var msgCompFields = gMsgCompose.compFields;
+  if (msgCompFields) {
+    msgCompFields.returnReceipt = !msgCompFields.returnReceipt;
+    target.setAttribute("checked", msgCompFields.returnReceipt);
+    gReceiptOptionChanged = true;
+  }
+}
+
+function ToggleDSN(target) {
   var msgCompFields = gMsgCompose.compFields;
-  if (msgCompFields)
-  {
-    msgCompFields.attachVCard = ! msgCompFields.attachVCard;
-    target.setAttribute('checked', msgCompFields.attachVCard);
+  if (msgCompFields) {
+    msgCompFields.DSN = !msgCompFields.DSN;
+    target.setAttribute("checked", msgCompFields.DSN);
+    gDSNOptionChanged = true;
+  }
+}
+
+function ToggleAttachVCard(target) {
+  var msgCompFields = gMsgCompose.compFields;
+  if (msgCompFields) {
+    msgCompFields.attachVCard = !msgCompFields.attachVCard;
+    target.setAttribute("checked", msgCompFields.attachVCard);
     gAttachVCardOptionChanged = true;
   }
 }
 
 /**
  * Toggles or sets the status of manual Attachment Reminder, i.e. whether
  * the user will get the "Attachment Reminder" alert before sending or not.
  * Toggles checkmark on "Remind me later" menuitem and internal
  * gManualAttachmentReminder flag accordingly.
  *
  * @param aState (optional) true = activate reminder.
  *                          false = deactivate reminder.
  *                          (default) = toggle reminder state.
  */
-function toggleAttachmentReminder(aState = !gManualAttachmentReminder)
-{
+function toggleAttachmentReminder(aState = !gManualAttachmentReminder) {
   gManualAttachmentReminder = aState;
   document.getElementById("cmd_remindLater")
           .setAttribute("checked", aState);
   gMsgCompose.compFields.attachmentReminder = aState;
 
   // If we enabled manual reminder, the reminder can't be turned off.
   if (aState)
     gDisableAttachmentReminder = false;
 
   manageAttachmentNotification(false);
 }
 
-function FillIdentityList(menulist)
-{
+function FillIdentityList(menulist) {
   let accounts = allAccountsSorted(true);
 
   let accountHadSeparator = false;
   let firstAccountWithIdentities = true;
   for (let acc = 0; acc < accounts.length; acc++) {
     let account = accounts[acc];
     let identities = toArray(fixIterator(account.identities,
                                          Ci.nsIMsgIdentity));
@@ -4188,59 +4007,51 @@ function FillIdentityList(menulist)
     }
   }
 
   menulist.menupopup.appendChild(document.createElement("menuseparator"));
   menulist.menupopup.appendChild(document.createElement("menuitem"))
           .setAttribute("command", "cmd_customizeFromAddress");
 }
 
-function getCurrentAccountKey()
-{
+function getCurrentAccountKey() {
   // Get the account's key.
   let identityList = GetMsgIdentityElement();
   return identityList.selectedItem.getAttribute("accountkey");
 }
 
-function getCurrentIdentityKey()
-{
+function getCurrentIdentityKey() {
   // Get the identity key.
   let identityList = GetMsgIdentityElement();
   return identityList.selectedItem.getAttribute("identitykey");
 }
 
-function getIdentityForKey(key)
-{
+function getIdentityForKey(key) {
   return MailServices.accounts.getIdentity(key);
 }
 
-function getCurrentIdentity()
-{
+function getCurrentIdentity() {
   return getIdentityForKey(getCurrentIdentityKey());
 }
 
-function AdjustFocus()
-{
-  //dump("XXX adjusting focus\n");
+function AdjustFocus() {
+  // dump("XXX adjusting focus\n");
   var element = awGetInputElement(awGetNumberOfRecipients());
   if (element.value == "") {
-      //dump("XXX focus on address\n");
-      awSetFocus(awGetNumberOfRecipients(), element);
-  }
-  else
-  {
-      element = GetMsgSubjectElement();
-      if (element.value == "") {
-        //dump("XXX focus on subject\n");
-        element.focus();
-      }
-      else {
-        //dump("XXX focus on body\n");
-        SetMsgBodyFrameFocus();
-      }
+    // dump("XXX focus on address\n");
+    awSetFocus(awGetNumberOfRecipients(), element);
+  } else {
+    element = GetMsgSubjectElement();
+    if (element.value == "") {
+      // dump("XXX focus on subject\n");
+      element.focus();
+    } else {
+      // dump("XXX focus on body\n");
+      SetMsgBodyFrameFocus();
+    }
   }
 }
 
 /**
  * Set the compose window title with flavors (Write | Print Preview).
  *
  * @param isPrintPreview (optional) true:  Set title for 'Print Preview' window.
  *                                  false: Set title for 'Write' window (default).
@@ -4254,26 +4065,24 @@ function SetComposeWindowTitle(isPrintPr
   let brandShortName = brandBundle.getString("brandShortName");
   let newTitle = getComposeBundle().getFormattedString(aStringName,
                                                        [subject, brandShortName]);
   document.title = newTitle;
 }
 
 // Check for changes to document and allow saving before closing
 // This is hooked up to the OS's window close widget (e.g., "X" for Windows)
-function ComposeCanClose()
-{
+function ComposeCanClose() {
   // No open compose window?
   if (!gMsgCompose)
     return true;
 
   // Do this early, so ldap sessions have a better chance to
   // cleanup after themselves.
-  if (gSendOperationInProgress || gSaveOperationInProgress)
-  {
+  if (gSendOperationInProgress || gSaveOperationInProgress) {
     let result;
 
     let brandBundle = document.getElementById("brandBundle");
     let brandShortName = brandBundle.getString("brandShortName");
     let promptTitle = gSendOperationInProgress ?
       getComposeBundle().getString("quitComposeWindowTitle") :
       getComposeBundle().getString("quitComposeWindowSaveTitle");
     let promptMsg = gSendOperationInProgress ?
@@ -4282,174 +4091,158 @@ function ComposeCanClose()
       getComposeBundle().getFormattedString("quitComposeWindowSaveMessage",
         [brandShortName], 1);
     let quitButtonLabel = getComposeBundle().getString("quitComposeWindowQuitButtonLabel2");
     let waitButtonLabel = getComposeBundle().getString("quitComposeWindowWaitButtonLabel2");
 
     result = Services.prompt.confirmEx(window, promptTitle, promptMsg,
         (Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_0) +
         (Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_1),
-        waitButtonLabel, quitButtonLabel, null, null, {value:0});
-
-    if (result == 1)
-    {
+        waitButtonLabel, quitButtonLabel, null, null, {value: 0});
+
+    if (result == 1) {
       gMsgCompose.abort();
       return true;
     }
     return false;
   }
 
   // Returns FALSE only if user cancels save action
-  if (gContentChanged || gMsgCompose.bodyModified || gAutoSaveKickedIn)
-  {
+  if (gContentChanged || gMsgCompose.bodyModified || gAutoSaveKickedIn) {
     // call window.focus, since we need to pop up a dialog
     // and therefore need to be visible (to prevent user confusion)
     window.focus();
     let draftFolderURI = gCurrentIdentity.draftFolder;
     let draftFolderName = MailUtils.getFolderForURI(draftFolderURI).prettyName;
     let result = Services.prompt
                          .confirmEx(window,
                                     getComposeBundle().getString("saveDlogTitle"),
                                     getComposeBundle().getFormattedString("saveDlogMessages3", [draftFolderName]),
                                     (Services.prompt.BUTTON_TITLE_SAVE * Services.prompt.BUTTON_POS_0) +
                                     (Services.prompt.BUTTON_TITLE_CANCEL * Services.prompt.BUTTON_POS_1) +
                                     (Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_2),
                                     null,
                                     null,
                                     getComposeBundle().getString("discardButtonLabel"),
-                                    null, {value:0});
-    switch (result)
-    {
-      case 0: //Save
+                                    null, {value: 0});
+    switch (result) {
+      case 0: // Save
         // Since we're going to save the message, we tell toolkit that
         // the close command failed, by returning false, and then
         // we close the window ourselves after the save is done.
         gCloseWindowAfterSave = true;
         // We catch the exception because we need to tell toolkit that it
         // shouldn't close the window, because we're going to close it
         // ourselves. If we don't tell toolkit that, and then close the window
         // ourselves, the toolkit code that keeps track of the open windows
         // gets off by one and the app can close unexpectedly on os's that
         // shutdown the app when the last window is closed.
         try {
-          GenericSendMessage(nsIMsgCompDeliverMode.AutoSaveAsDraft);
-        }
-        catch (ex) {
+          GenericSendMessage(Ci.nsIMsgCompDeliverMode.AutoSaveAsDraft);
+        } catch (ex) {
           Cu.reportError(ex);
         }
         return false;
-      case 1: //Cancel
+      case 1: // Cancel
         return false;
-      case 2: //Don't Save
+      case 2: // Don't Save
         // don't delete the draft if we didn't start off editing a draft
         // and the user hasn't explicitly saved it.
         if (!gEditingDraft && gAutoSaveKickedIn)
           RemoveDraft();
         break;
     }
   }
 
   return true;
 }
 
-function RemoveDraft()
-{
-  try
-  {
+function RemoveDraft() {
+  try {
     var draftUri = gMsgCompose.compFields.draftId;
-    var msgKey = draftUri.substr(draftUri.indexOf('#') + 1);
-    var rdf = Cc['@mozilla.org/rdf/rdf-service;1']
+    var msgKey = draftUri.substr(draftUri.indexOf("#") + 1);
+    var rdf = Cc["@mozilla.org/rdf/rdf-service;1"]
                 .getService(Ci.nsIRDFService);
 
     var folder = rdf.GetResource(gMsgCompose.savedFolderURI)
                     .QueryInterface(Ci.nsIMsgFolder);
     try {
-      if (folder.flags & Ci.nsMsgFolderFlags.Drafts)
-      {
+      if (folder.flags & Ci.nsMsgFolderFlags.Drafts) {
         var msgs = Cc["@mozilla.org/array;1"].
             createInstance(Ci.nsIMutableArray);
         msgs.appendElement(folder.GetMessageHeader(msgKey));
         folder.deleteMessages(msgs, null, true, false, null, false);
       }
-    }
-    catch (ex) // couldn't find header - perhaps an imap folder.
-    {
+    } catch (ex) { // couldn't find header - perhaps an imap folder.
       var imapFolder = folder.QueryInterface(Ci.nsIMsgImapMailFolder);
-      var keyArray = new Array;
+      var keyArray = [];
       keyArray[0] = msgKey;
       imapFolder.storeImapFlags(8, true, keyArray, 1, null);
     }
   } catch (ex) {}
 }
 
-function SetContentAndBodyAsUnmodified()
-{
+function SetContentAndBodyAsUnmodified() {
   gMsgCompose.bodyModified = false;
   gContentChanged = false;
 }
 
-function MsgComposeCloseWindow()
-{
+function MsgComposeCloseWindow() {
   if (gMsgCompose)
     gMsgCompose.CloseWindow();
   else
     window.close();
 }
 
-function GetLastAttachDirectory()
-{
+function GetLastAttachDirectory() {
   var lastDirectory;
 
   try {
     lastDirectory = Services.prefs
                             .getComplexValue(kComposeAttachDirPrefName,
                                              Ci.nsIFile);
-  }
-  catch (ex) {
+  } catch (ex) {
     // this will fail the first time we attach a file
     // as we won't have a pref value.
     lastDirectory = null;
   }
 
   return lastDirectory;
 }
 
 // attachedLocalFile must be a nsIFile
-function SetLastAttachDirectory(attachedLocalFile)
-{
+function SetLastAttachDirectory(attachedLocalFile) {
   try {
     let file = attachedLocalFile.QueryInterface(Ci.nsIFile);
     let parent = file.parent.QueryInterface(Ci.nsIFile);
 
     Services.prefs.setComplexValue(kComposeAttachDirPrefName,
                                    Ci.nsIFile, parent);
-  }
-  catch (ex) {
+  } catch (ex) {
     dump("error: SetLastAttachDirectory failed: " + ex + "\n");
   }
 }
 
-function AttachFile()
-{
+function AttachFile() {
   if (attachmentsCount() > 0) {
     // If there are existing attachments already, restore attachment pane before
     // showing the file picker so that user can see them while adding more.
     toggleAttachmentPane("show");
   }
 
-  //Get file using nsIFilePicker and convert to URL
-  let fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
+  // Get file using nsIFilePicker and convert to URL
+  let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
   fp.init(window, getComposeBundle().getString("chooseFileToAttach"),
-          nsIFilePicker.modeOpenMultiple);
+          Ci.nsIFilePicker.modeOpenMultiple);
 
   let lastDirectory = GetLastAttachDirectory();
   if (lastDirectory)
     fp.displayDirectory = lastDirectory;
 
-  fp.appendFilters(nsIFilePicker.filterAll);
+  fp.appendFilters(Ci.nsIFilePicker.filterAll);
   fp.open(rv => {
     if (rv != Ci.nsIFilePicker.returnOK || !fp.files)
       return;
 
     let file;
     let attachments = [];
 
     for (file of fixIterator(fp.files, Ci.nsIFile))
@@ -4461,18 +4254,17 @@ function AttachFile()
 }
 
 /**
  * Convert an nsIFile instance into an nsIMsgAttachment.
  *
  * @param file the nsIFile
  * @return an attachment pointing to the file
  */
-function FileToAttachment(file)
-{
+function FileToAttachment(file) {
   let fileHandler = Services.io.getProtocolHandler("file")
                             .QueryInterface(Ci.nsIFileProtocolHandler);
   let attachment = Cc["@mozilla.org/messengercompose/attachment;1"]
                      .createInstance(Ci.nsIMsgAttachment);
 
   attachment.url = fileHandler.getURLSpecFromFile(file);
   attachment.size = file.fileSize;
   return attachment;
@@ -4486,18 +4278,17 @@ function FileToAttachment(file)
  *                      attachments. Anything iterable with fixIterator is
  *                      accepted.
  * @param aCallback     an optional callback function called immediately after
  *                      adding each attachment. Takes one argument:
  *                      the newly-added <attachmentitem> node.
  * @param aContentChanged {Boolean}  optional value to assign to gContentChanged
  *                                   after adding attachments; defaults to true.
  */
-function AddAttachments(aAttachments, aCallback, aContentChanged = true)
-{
+function AddAttachments(aAttachments, aCallback, aContentChanged = true) {
   let bucket = document.getElementById("attachmentBucket");
   let addedAttachments = Cc["@mozilla.org/array;1"]
                            .createInstance(Ci.nsIMutableArray);
   let items = [];
 
   for (let attachment of fixIterator(aAttachments,
                                      Ci.nsIMsgAttachment)) {
     if (!(attachment && attachment.url) ||
@@ -4519,31 +4310,31 @@ function AddAttachments(aAttachments, aC
     let item = bucket.appendItem(attachment);
     addedAttachments.appendElement(attachment);
 
     if (attachment.size != -1)
       gAttachmentsSize += attachment.size;
 
     try {
       item.setAttribute("tooltiptext", decodeURI(attachment.url));
-    }
-    catch(e) {
+    } catch (e) {
       item.setAttribute("tooltiptext", attachment.url);
     }
     item.addEventListener("command", OpenSelectedAttachment);
 
     if (attachment.sendViaCloud) {
       try {
         let cloudProvider = cloudFileAccounts.getAccount(attachment.cloudProviderKey);
         item.cloudProvider = cloudProvider;
         item.image = cloudProvider.iconClass;
         item.originalUrl = attachment.url;
-      } catch (ex) {dump(ex);}
-    }
-    else {
+      } catch (ex) {
+        dump(ex);
+      }
+    } else {
       // For local file urls, we are better off using the full file url because
       // moz-icon will actually resolve the file url and get the right icon from
       // the file url. All other urls, we should try to extract the file name from
       // them. This fixes issues where an icon wasn't showing up if you dragged a
       // web url that had a query or reference string after the file name and for
       // mailnews urls where the filename is hidden in the url as a &filename=
       // part.
       let url = Services.io.newURI(attachment.url);
@@ -4588,30 +4379,28 @@ function AddAttachments(aAttachments, aC
 }
 
 /**
  * Get the number of all attachments of the message.
  *
  * @return the number of all attachment items in attachmentBucket;
  *         0 if attachmentBucket not found or no attachments in the list.
  */
-function attachmentsCount()
-{
+function attachmentsCount() {
   let bucketList = GetMsgAttachmentElement();
   return (bucketList) ? bucketList.itemCount : 0;
 }
 
 /**
  * Get the number of selected attachments.
  *
  * @return {number}  the number of selected attachments, or 0 if there are
  *                   no attachments selected, no attachments, or no attachmentBucket
  */
-function attachmentsSelectedCount()
-{
+function attachmentsSelectedCount() {
   let bucketList = GetMsgAttachmentElement();
   return (bucketList) ? bucketList.selectedCount : 0;
 }
 
 /**
  * Returns a sorted-by-index, "non-live" array of attachment list items.
  *
  * @param aAscending {boolean}: true (default): sort return array ascending
@@ -4660,18 +4449,17 @@ function attachmentsGetSortedArray(aAsce
  * Returns a sorted-by-index, "non-live" array of selected attachment list items.
  *
  * @param aAscending {boolean}: true (default): sort return array ascending
  *                              false         : sort return array descending
  * @return {array} an array of selected listitem elements in attachmentBucket
  *                 listbox, "non-live" and sorted by their index in the list;
  *                 [] if no attachments selected
  */
-function attachmentsSelectionGetSortedArray(aAscending = true)
-{
+function attachmentsSelectionGetSortedArray(aAscending = true) {
   return attachmentsGetSortedArray(aAscending, true);
 }
 
 /**
  * Return true if the selected attachment items are a coherent block in the list,
  * otherwise false.
  *
  * @param aListPosition (optional)  "top"   : Return true only if the block is
@@ -4681,18 +4469,17 @@ function attachmentsSelectionGetSortedAr
  * @return {boolean} true : The selected attachment items are a coherent block
  *                          (at the list edge if/as specified by 'aListPosition'),
  *                          or only 1 item selected.
  *                   false: The selected attachment items are NOT a coherent block
  *                          (at the list edge if/as specified by 'aListPosition'),
  *                          or no attachments selected, or no attachments,
  *                          or no attachmentBucket.
  */
-function attachmentsSelectionIsBlock(aListPosition)
-{
+function attachmentsSelectionIsBlock(aListPosition) {
   let selectedCount = attachmentsSelectedCount();
   if (selectedCount < 1)
     // No attachments selected, no attachments, or no attachmentBucket.
     return false;
 
   let bucketList = document.getElementById("attachmentBucket");
   let selItems = attachmentsSelectionGetSortedArray();
   let indexFirstSelAttachment =
@@ -4710,28 +4497,25 @@ function attachmentsSelectionIsBlock(aLi
     // True if selection is a coherent block at the bottom of the list.
     return (indexLastSelAttachment == (attachmentsCount() - 1)) && isBlock;
   default:
     // True if selection is a coherent block.
     return isBlock;
   }
 }
 
-function AttachPage()
-{
-  let result = {value:"http://"};
+function AttachPage() {
+  let result = {value: "http://"};
   if (Services.prompt.prompt(window,
                       getComposeBundle().getString("attachPageDlogTitle"),
                       getComposeBundle().getString("attachPageDlogMessage"),
                       result,
                       null,
-                      {value:0}))
-  {
-    if (result.value.length <= "http://".length)
-    {
+                      {value: 0})) {
+    if (result.value.length <= "http://".length) {
       // Nothing filled, just show the dialog again.
       AttachPage();
       return;
     }
 
     let attachment = Cc["@mozilla.org/messengercompose/attachment;1"]
                        .createInstance(Ci.nsIMsgAttachment);
     attachment.url = result.value;
@@ -4739,47 +4523,42 @@ function AttachPage()
   }
 }
 
 /**
  * Check if the given fileURL already exists in the attachment bucket.
  * @param fileURL the URL (as a String) of the file to check
  * @return true if the fileURL is already attached
  */
-function DuplicateFileAlreadyAttached(fileURL)
-{
-  var bucket = document.getElementById('attachmentBucket');
+function DuplicateFileAlreadyAttached(fileURL) {
+  var bucket = document.getElementById("attachmentBucket");
   let rowCount = bucket.getRowCount();
-  for (let i = 0; i < rowCount; i++)
-  {
+  for (let i = 0; i < rowCount; i++) {
     let attachment = bucket.getItemAtIndex(i).attachment;
     if (attachment && attachment.url == fileURL)
       return true;
   }
   return false;
 }
 
-function Attachments2CompFields(compFields)
-{
-  var bucket = document.getElementById('attachmentBucket');
-
-  //First, we need to clear all attachment in the compose fields
+function Attachments2CompFields(compFields) {
+  var bucket = document.getElementById("attachmentBucket");
+
+  // First, we need to clear all attachment in the compose fields
   compFields.removeAttachments();
 
   let rowCount = bucket.getRowCount();
-  for (let i = 0; i < rowCount; i++)
-  {
+  for (let i = 0; i < rowCount; i++) {
     let attachment = bucket.getItemAtIndex(i).attachment;
     if (attachment)
       compFields.addAttachment(attachment);
   }
 }
 
-function RemoveAllAttachments()
-{
+function RemoveAllAttachments() {
   // Ensure that attachment pane is shown before removing all attachments.
   toggleAttachmentPane("show");
 
   let bucket = document.getElementById("attachmentBucket");
   if (bucket.itemCount == 0)
     return;
 
   let fileHandler = Services.io.getProtocolHandler("file")
@@ -4823,31 +4602,29 @@ function RemoveAllAttachments()
 
 /**
  * Show or hide the attachment pane after updating its header bar information
  * (number and total file size of attachments) and tooltip.
  *
  * @param aShowBucket {Boolean} true: show the attachment pane
  *                              false (or omitted): hide the attachment pane
  */
-function UpdateAttachmentBucket(aShowBucket)
-{
+function UpdateAttachmentBucket(aShowBucket) {
   updateAttachmentPane(aShowBucket ? "show" : "hide");
 }
 
 /**
  * Update the header bar information (number and total file size of attachments)
  * and tooltip of attachment pane, then (optionally) show or hide the pane.
  *
  * @param aShowPane {string} "show":  show the attachment pane
  *                           "hide":  hide the attachment pane
  *                           omitted: just update without changing pane visibility
  */
-function updateAttachmentPane(aShowPane)
-{
+function updateAttachmentPane(aShowPane) {
   let bucket = GetMsgAttachmentElement();
   let bucketCountLabel = document.getElementById("attachmentBucketCount");
   let words = getComposeBundle().getString("attachmentCount");
   let count = bucket.itemCount;
   let countStr = PluralForm.get(count, words).replace("#1", count);
 
   bucketCountLabel.value = countStr;
   document.getElementById("attachmentBucketSize").value =
@@ -4864,18 +4641,17 @@ function updateAttachmentPane(aShowPane)
   // If aShowPane argument is omitted, it's just updating, so we're done.
   if (aShowPane === undefined)
     return;
 
   // Otherwise, show or hide the panel per aShowPane argument.
   toggleAttachmentPane(aShowPane);
 }
 
-function RemoveSelectedAttachment()
-{
+function RemoveSelectedAttachment() {
   let bucket = GetMsgAttachmentElement();
   if (bucket.selectedCount == 0)
     return;
 
   // Remember the current focus index so we can try to restore it when done.
   let focusIndex = bucket.currentIndex;
 
   let fileHandler = Services.io.getProtocolHandler("file")
@@ -4908,42 +4684,42 @@ function RemoveSelectedAttachment()
     item.remove();
   }
 
   // Bug workaround: Force update of selectedCount and selectedItem, both wrong
   // after item removal, to avoid confusion for listening command controllers.
   bucket.clearSelection();
 
   // Try to restore original focus or somewhere close by.
-  bucket.currentIndex = (focusIndex < bucket.itemCount) ?   // If possible,
-                        focusIndex   // restore focus at original position;
-                      : ( (bucket.itemCount > 0) ? // else: if attachments exist,
-                          (bucket.itemCount - 1)   // focus last item;
-                        : -1)                      // else: nothing to focus.
+  if (focusIndex < bucket.itemCount) { // If possible,
+    bucket.currentIndex = focusIndex;  // restore focus at original position;
+  } else {
+    bucket.currentIndex = (bucket.itemCount > 0) ? // else: if attachments exist,
+                          (bucket.itemCount - 1) : // focus last item;
+                          -1;                      // else: nothing to focus.
+  }
 
   AttachmentsChanged();
   dispatchAttachmentBucketEvent("attachments-removed", removedAttachments);
 }
 
-function RenameSelectedAttachment()
-{
+function RenameSelectedAttachment() {
   let bucket = document.getElementById("attachmentBucket");
   if (bucket.selectedItems.length != 1)
     return; // not one attachment selected
 
   let item = bucket.getSelectedItem(0);
   let attachmentName = {value: item.attachment.name};
   if (Services.prompt
               .prompt(window,
                       getComposeBundle().getString("renameAttachmentTitle"),
                       getComposeBundle().getString("renameAttachmentMessage"),
                       attachmentName,
                       null,
-                      {value: 0}))
-  {
+                      {value: 0})) {
     if (attachmentName.value == "")
       return; // name was not filled, bail out
 
     let originalName = item.attachment.name;
     item.attachment.name = attachmentName.value;
     item.setAttribute("name", attachmentName.value);
 
     gContentChanged = true;
@@ -4969,18 +4745,18 @@ function RenameSelectedAttachment()
  * @param aDirection  "up"        : Move attachments up in the list.
  *                    "down"      : Move attachments down in the list.
  *                    "top"       : Move attachments to the top of the list.
  *                    "bottom"    : Move attachments to the bottom of the list.
  *                    "bundleUp"  : Move attachments together (upwards).
  *                    "bundleDown": Move attachments together (downwards).
  *                    "toggleSort": Sort attachments alphabetically (toggle).
  */
-function moveSelectedAttachments(aDirection)
-{
+/* eslint-disable complexity */
+function moveSelectedAttachments(aDirection) {
   // Command controllers will bail out if no or all attachments are selected,
   // or if block selections can't be moved, or if other direction-specific
   // adverse circumstances prevent the intended movement.
 
   if (!aDirection)
     return;
 
   let bucket = document.getElementById("attachmentBucket");
@@ -4998,17 +4774,17 @@ function moveSelectedAttachments(aDirect
   bucket.currentItem = null;
   let upwards;
   let targetItem;
 
   switch (aDirection) {
     case "up":
     case "down":
       // Move selected attachments upwards/downwards.
-      upwards = (aDirection == "up") ? true : false;
+      upwards = aDirection == "up";
       let blockItems = [];
 
       for (let item of selItems) {
         // Handle adjacent selected items en block, via blockItems array.
         blockItems.push(item); // Add current selItem to blockItems.
         let nextItem = item.nextSibling;
         if (!nextItem || !nextItem.selected) {
           // If current selItem is the last blockItem, check out its adjacent
@@ -5042,33 +4818,34 @@ function moveSelectedAttachments(aDirect
         // Add next selItem to the block and see if that's the end of the block.
       } // Next selItem.
 
       // Ensure helpful visibility of moved items (scroll into view if needed):
       // If first item of selection is now at the top, first list item.
       // Else if last item of selection is now at the bottom, last list item.
       // Otherwise, let's see where we are going by ensuring visibility of the
       // nearest unselected sibling of selection according to direction of move.
-      visibleIndex = (bucket.getIndexOfItem(selItems[0]) == 0) ? 0
-                   : ((bucket.getIndexOfItem(selItems[selItems.length - 1]) ==
-                       (bucket.itemCount - 1)) ?
-                       (bucket.itemCount - 1)
-                     : (upwards ? bucket.getIndexOfItem(selItems[0].previousSibling)
-                       : bucket.getIndexOfItem(selItems[selItems.length - 1].nextSibling)
-                       )
-                     );
+      if (bucket.getIndexOfItem(selItems[0]) == 0) {
+        visibleIndex = 0;
+      } else if (bucket.getIndexOfItem(selItems[selItems.length - 1]) == (bucket.itemCount - 1)) {
+        visibleIndex = bucket.itemCount - 1;
+      } else if (upwards) {
+        visibleIndex = bucket.getIndexOfItem(selItems[0].previousSibling);
+      } else {
+        visibleIndex = bucket.getIndexOfItem(selItems[selItems.length - 1].nextSibling);
+      }
       break;
 
     case "top":
     case "bottom":
     case "bundleUp":
     case "bundleDown":
       // Bundle selected attachments to top/bottom of the list or upwards/downwards.
 
-      upwards = (["top", "bundleUp"].includes(aDirection)) ? true : false;
+      upwards = ["top", "bundleUp"].includes(aDirection);
       // Downwards: Reverse order of selItems so we can use the same algorithm.
       if (!upwards)
         selItems.reverse();
 
       if (["top", "bottom"].includes(aDirection)) {
         let listEdgeItem = bucket.getItemAtIndex(upwards ? 0 : bucket.itemCount - 1);
         let selEdgeItem = selItems[0];
         if (selEdgeItem != listEdgeItem) {
@@ -5190,16 +4967,17 @@ function moveSelectedAttachments(aDirect
   bucket.currentItem = focusItem;
   // Ensure smart visibility of a relevant item according to direction.
   bucket.ensureIndexIsVisible(visibleIndex);
 
   // Moving selected items around does not trigger auto-updating of our command
   // handlers, so we must do it now as the position of selected items has changed.
   updateReorderAttachmentsItems();
 }
+/* eslint-enable complexity */
 
 function keyToggleAttachmentPaneOnCommand() {
   // For easy and efficient UX with (access key == command key), remember that
   // we're coming from key_toggleAttachmentPane before going into command handling.
   document.getElementById("cmd_toggleAttachmentPane").setAttribute("eventsource",
                                                                    "key");
   goDoCommand("cmd_toggleAttachmentPane");
 }
@@ -5226,17 +5004,17 @@ function toggleAttachmentPane(aAction = 
       // If attachment pane is currently shown:
       if (!bucketHasFocus && eventSource == "key") {
         // If we get here via key_toggleAttachmentPane, here's where we mimick
         // access key functionality: First focus the pane if it isn't focused yet.
         bucket.focus();
       } else {
         // If bucket has focus, or if we get here via menu-click or header-click,
         // just toggle.
-        aAction = "hide"
+        aAction = "hide";
       }
     } else {
       // If attachment pane is currently hidden, show it.
       aAction = "show";
     }
   }
 
   switch (aAction) {
@@ -5281,17 +5059,17 @@ function showReorderAttachmentsPanel() {
  *
  * @return {string} "ascending" : Sort order is ascending.
  *                  "descending": Sort order is descending.
  *                  "equivalent": The names of all selected items are equivalent.
  *                  ""          : There's no sort order, or only 1 item selected,
  *                                or no items selected, or no attachments,
  *                                or no attachmentBucket.
  */
-function attachmentsSelectionGetSortOrder(){
+function attachmentsSelectionGetSortOrder() {
   return attachmentsGetSortOrder(true);
 }
 
 /**
  * Returns a string representing the current sort order of attachment items
  * by their names.
  *
  * @param aSelectedOnly {boolean}: true: return sort order of selected items only.
@@ -5299,17 +5077,17 @@ function attachmentsSelectionGetSortOrde
  *
  * @return {string} "ascending" : Sort order is ascending.
  *                  "descending": Sort order is descending.
  *                  "equivalent": The names of the items are equivalent.
  *                  ""          : There's no sort order, or no attachments,
  *                                or no attachmentBucket; or (with aSelectedOnly),
  *                                only 1 item selected, or no items selected.
  */
-function attachmentsGetSortOrder(aSelectedOnly = false){
+function attachmentsGetSortOrder(aSelectedOnly = false) {
   let listItems;
   if (aSelectedOnly) {
     if (attachmentsSelectedCount() <= 1)
       return "";
 
     listItems = attachmentsSelectionGetSortedArray();
   } else { // aSelectedOnly == false
     if (attachmentsCount() < 1)
@@ -5350,17 +5128,17 @@ function reorderAttachmentsPanelOnPopupS
   let panel = document.getElementById("reorderAttachmentsPanel");
   let buttonsNodeList = panel.querySelectorAll(".panelButton");
   let buttons = [...buttonsNodeList]; // convert NodeList to Array
   // Let's add some pretty keyboard shortcuts to the buttons.
   buttons.forEach(btn => {
     if (btn.hasAttribute("key")) {
       btn.setAttribute("prettykey", getPrettyKey(btn.getAttribute("key")));
     }
-  })
+  });
   // Focus attachment bucket to activate attachmentBucketController, which is
   // required for updating the reorder commands.
   document.getElementById("attachmentBucket").focus();
   // We're updating commands before showing the panel so that button states
   // don't change after the panel is shown, and also because focus is still
   // in attachment bucket right now, which is required for updating them.
   updateReorderAttachmentsItems();
 }
@@ -5447,18 +5225,17 @@ function attachmentBucketOnKeyPress(aEve
       goDoCommand("cmd_toggleAttachmentPane");
   }
 }
 
 function attachmentBucketOnDragStart(aEvent) {
   nsDragAndDrop.startDrag(aEvent, attachmentBucketDNDObserver);
 }
 
-function attachmentBucketOnClick(aEvent)
-{
+function attachmentBucketOnClick(aEvent) {
   // Handle click on attachment pane whitespace:
   // - With selected attachments, clear selection first.
   // - Otherwise, e.g. on a plain empty bucket, show 'Attach File(s)' dialog.
   if (attachmentsSelectedCount() == 0) {
     let boundTarget = document.getBindingParent(aEvent.originalTarget);
     if (aEvent.button == 0 && boundTarget && boundTarget.localName == "scrollbox")
       goDoCommand("cmd_attachFile");
   }
@@ -5466,24 +5243,23 @@ function attachmentBucketOnClick(aEvent)
 
 function attachmentBucketOnSelect() {
   attachmentBucketUpdateTooltips();
   updateAttachmentItems();
 }
 
 function attachmentBucketUpdateTooltips() {
   let bucket = GetMsgAttachmentElement();
-  let bucketHeader = document.getElementById("attachments-header-box");
 
   // Attachment pane whitespace tooltip
   if (attachmentsSelectedCount() > 0) {
-    bucket.tooltipText=
+    bucket.tooltipText =
       getComposeBundle().getString("attachmentBucketClearSelectionTooltip");
   } else {
-    bucket.tooltipText=
+    bucket.tooltipText =
       getComposeBundle().getString("attachmentBucketAttachFilesTooltip");
   }
 }
 
 function attachmentBucketHeaderOnClick(aEvent) {
   if (aEvent.button == 0) {
     // Left click
     goDoCommand("cmd_toggleAttachmentPane");
@@ -5497,169 +5273,150 @@ function attachmentBucketCloseButtonOnCo
 function attachmentBucketSizerOnMouseUp() {
   updateViewItems();
   if (document.getElementById("attachments-box").collapsed) {
     // If user collapsed the attachment pane, move focus to message body.
     SetMsgBodyFrameFocus();
   }
 }
 
-function AttachmentElementHasItems()
-{
+function AttachmentElementHasItems() {
   var element = document.getElementById("attachmentBucket");
   return element ? (element.getRowCount() > 0) : false;
 }
 
 function attachmentBucketMarkEmptyBucket() {
   let attachmentBucket = GetMsgAttachmentElement();
   let attachmentsBox = document.getElementById("attachments-box");
   if (attachmentBucket.itemCount > 0) {
     attachmentsBox.removeAttribute("empty");
   } else {
     attachmentsBox.setAttribute("empty", "true");
   }
 }
 
-function OpenSelectedAttachment()
-{
+function OpenSelectedAttachment() {
   let bucket = document.getElementById("attachmentBucket");
-  if (bucket.selectedItems.length == 1)
-  {
+  if (bucket.selectedItems.length == 1) {
     let attachmentUrl = bucket.getSelectedItem(0).attachment.url;
 
     let messagePrefix = /^mailbox-message:|^imap-message:|^news-message:/i;
-    if (messagePrefix.test(attachmentUrl))
-    {
+    if (messagePrefix.test(attachmentUrl)) {
       // we must be dealing with a forwarded attachment, treat this special
       let msgHdr = gMessenger.messageServiceFromURI(attachmentUrl).messageURIToMsgHdr(attachmentUrl);
       if (msgHdr)
         MailUtils.openMessageInNewWindow(msgHdr);
-    }
-    else
-    {
+    } else {
       // Turn the URL into a nsIURI object then open it.
       let uri = Services.io.newURI(attachmentUrl);
-      if (uri)
-      {
+      if (uri) {
         let channel = Services.io.newChannelFromURI2(uri,
                                                      null,
                                                      Services.scriptSecurityManager.getSystemPrincipal(),
                                                      null,
                                                      Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
                                                      Ci.nsIContentPolicy.TYPE_OTHER);
-        if (channel)
-        {
+        if (channel) {
           let uriLoader = Cc["@mozilla.org/uriloader;1"].getService(Ci.nsIURILoader);
           uriLoader.openURI(channel, true, new nsAttachmentOpener());
         }
       }
     }
   } // if one attachment selected
 }
 
-function nsAttachmentOpener()
-{
-}
-
-nsAttachmentOpener.prototype =
-{
+function nsAttachmentOpener() {
+}
+
+nsAttachmentOpener.prototype = {
   QueryInterface: ChromeUtils.generateQI(["nsIURIContentListener",
                                           "nsIInterfaceRequestor"]),
 
-  onStartURIOpen: function(uri)
-  {
+  onStartURIOpen(uri) {
     return false;
   },
 
-  doContent: function(contentType, isContentPreferred, request, contentHandler)
-  {
+  doContent(contentType, isContentPreferred, request, contentHandler) {
     // If we came here to display an attached message, make sure we provide a type.
     if (/[?&]part=/i.test(request.URI.query)) {
       let newQuery = request.URI.query + "&type=message/rfc822";
       request.URI = request.URI.mutate().setQuery(newQuery).finalize();
     }
     let newHandler = Cc["@mozilla.org/uriloader/content-handler;1?type=application/x-message-display"]
                        .createInstance(Ci.nsIContentHandler);
     newHandler.handleContent("application/x-message-display", this, request);
     return true;
   },
 
-  isPreferred: function(contentType, desiredContentType)
-  {
+  isPreferred(contentType, desiredContentType) {
     if (contentType == "message/rfc822")
       return true;
     return false;
   },
 
-  canHandleContent: function(contentType, isContentPreferred, desiredContentType)
-  {
+  canHandleContent(contentType, isContentPreferred, desiredContentType) {
     return false;
   },
 
-  getInterface: function(iid)
-  {
+  getInterface(iid) {
     if (iid.equals(Ci.nsIDOMWindow)) {
       return window;
-    } else if (iid.equals(Ci.nsIDocShell)) {
+    }
+    if (iid.equals(Ci.nsIDocShell)) {
       return window.docShell;
-    } else {
-      return this.QueryInterface(iid);
     }
+    return this.QueryInterface(iid);
   },
 
   loadCookie: null,
-  parentContentListener: null
-}
+  parentContentListener: null,
+};
 
 /**
  * Check what to do with HTML message according to what preference we have
  * stored for the recipients.
  *
  * @param convertible  An nsIMsgCompConvertible constant describing
  *                     message convertibility to plain text.
  */
-function DetermineHTMLAction(convertible)
-{
+function DetermineHTMLAction(convertible) {
   if (!gMsgCompose.composeHTML)
-    return nsIMsgCompSendFormat.PlainText;
-
-  if (gSendFormat == nsIMsgCompSendFormat.AskUser)
+    return Ci.nsIMsgCompSendFormat.PlainText;
+
+  if (gSendFormat == Ci.nsIMsgCompSendFormat.AskUser)
     return gMsgCompose.determineHTMLAction(convertible);
 
   return gSendFormat;
 }
 
 /**
  * Expands mailinglists found in the recipient fields.
  */
-function expandRecipients()
-{
+function expandRecipients() {
   gMsgCompose.expandMailingLists();
 }
 
-function DetermineConvertibility()
-{
-    if (!gMsgCompose.composeHTML)
-        return nsIMsgCompConvertible.Plain;
-
-    try {
-        return gMsgCompose.bodyConvertible();
-    } catch(ex) {}
-    return nsIMsgCompConvertible.No;
+function DetermineConvertibility() {
+  if (!gMsgCompose.composeHTML)
+    return Ci.nsIMsgCompConvertible.Plain;
+
+  try {
+    return gMsgCompose.bodyConvertible();
+  } catch (ex) {}
+  return Ci.nsIMsgCompConvertible.No;
 }
 
 /**
  * Hides addressing options (To, CC, Bcc, Newsgroup, Followup-To, etc.)
  * that are not relevant for the account type used for sending.
  *
  * @param aAccountKey  Key of the account that is currently selected
  *                     as the sending account.
  */
-function hideIrrelevantAddressingOptions(aAccountKey)
-{
+function hideIrrelevantAddressingOptions(aAccountKey) {
   let hideNews = true;
   for (let account of fixIterator(MailServices.accounts.accounts,
                                   Ci.nsIMsgAccount)) {
     if (account.incomingServer.type == "nntp")
       hideNews = false;
   }
   // If there is no News (NNTP) account existing then
   // hide the Newsgroup and Followup-To recipient type in all the menulists.
@@ -5669,44 +5426,41 @@ function hideIrrelevantAddressingOptions
     .querySelectorAll('menuitem[value="addr_newsgroups"], menuitem[value="addr_followup"]');
   // Collapsing the menuitem only prevents it getting chosen, it does not
   // affect the menulist widget display when Newsgroup is already selected.
   for (let item of newsTypes) {
     item.collapsed = hideNews;
   }
 }
 
-function LoadIdentity(startup)
-{
+function LoadIdentity(startup) {
     var identityElement = document.getElementById("msgIdentity");
     var prevIdentity = gCurrentIdentity;
 
     if (identityElement) {
         var idKey = identityElement.selectedItem.getAttribute("identitykey");
         gCurrentIdentity = MailServices.accounts.getIdentity(idKey);
 
         let accountKey = null;
         // Set the account key value on the menu list.
         if (identityElement.selectedItem) {
           accountKey = identityElement.selectedItem.getAttribute("accountkey");
           identityElement.setAttribute("accountkey", accountKey);
           hideIrrelevantAddressingOptions(accountKey);
         }
 
         let maxRecipients = awGetMaxRecipients();
-        for (let i = 1; i <= maxRecipients; i++)
-        {
+        for (let i = 1; i <= maxRecipients; i++) {
           let params = JSON.parse(awGetInputElement(i).searchParam);
           params.idKey = idKey;
           params.accountKey = accountKey;
           awGetInputElement(i).searchParam = JSON.stringify(params);
         }
 
-        if (!startup && prevIdentity && idKey != prevIdentity.key)
-        {
+        if (!startup && prevIdentity && idKey != prevIdentity.key) {
           var prevReplyTo = prevIdentity.replyTo;
           var prevCc = "";
           var prevBcc = "";
           var prevReceipt = prevIdentity.requestReturnReceipt;
           var prevDSN = prevIdentity.DSN;
           var prevAttachVCard = prevIdentity.attachVCard;
 
           if (prevIdentity.doCc)
@@ -5728,67 +5482,61 @@ function LoadIdentity(startup)
           if (gCurrentIdentity.doBcc)
             newBcc += gCurrentIdentity.doBccList;
 
           var needToCleanUp = false;
           var msgCompFields = gMsgCompose.compFields;
 
           if (!gReceiptOptionChanged &&
               prevReceipt == msgCompFields.returnReceipt &&
-              prevReceipt != newReceipt)
-          {
+              prevReceipt != newReceipt) {
             msgCompFields.returnReceipt = newReceipt;
-            document.getElementById("returnReceiptMenu").setAttribute('checked',msgCompFields.returnReceipt);
+            document.getElementById("returnReceiptMenu").setAttribute("checked", msgCompFields.returnReceipt);
           }
 
           if (!gDSNOptionChanged &&
               prevDSN == msgCompFields.DSN &&
-              prevDSN != newDSN)
-          {
+              prevDSN != newDSN) {
             msgCompFields.DSN = newDSN;
-            document.getElementById("dsnMenu").setAttribute('checked',msgCompFields.DSN);
+            document.getElementById("dsnMenu").setAttribute("checked", msgCompFields.DSN);
           }
 
           if (!gAttachVCardOptionChanged &&
               prevAttachVCard == msgCompFields.attachVCard &&
-              prevAttachVCard != newAttachVCard)
-          {
+              prevAttachVCard != newAttachVCard) {
             msgCompFields.attachVCard = newAttachVCard;
-            document.getElementById("cmd_attachVCard").setAttribute('checked',msgCompFields.attachVCard);
+            document.getElementById("cmd_attachVCard").setAttribute("checked", msgCompFields.attachVCard);
           }
 
-          if (newReplyTo != prevReplyTo)
-          {
+          if (newReplyTo != prevReplyTo) {
             needToCleanUp = true;
             if (prevReplyTo != "")
               awRemoveRecipients(msgCompFields, "addr_reply", prevReplyTo);
             if (newReplyTo != "")
               awAddRecipients(msgCompFields, "addr_reply", newReplyTo);
           }
 
           let toAddrs = new Set(msgCompFields.splitRecipients(
             msgCompFields.to, true, {}));
           let ccAddrs = new Set(msgCompFields.splitRecipients(
             msgCompFields.cc, true, {}));
 
-          if (newCc != prevCc)
-          {
+          if (newCc != prevCc) {
             needToCleanUp = true;
             if (prevCc)
               awRemoveRecipients(msgCompFields, "addr_cc", prevCc);
             if (newCc) {
               // Ensure none of the Ccs are already in To.
               let cc2 = msgCompFields.splitRecipients(newCc, true, {});
               newCc = cc2.filter(x => !toAddrs.has(x)).join(", ");
               awAddRecipients(msgCompFields, "addr_cc", newCc);
             }
           }
 
-          if (newBcc != prevBcc)
-          {
+          if (newBcc != prevBcc) {
             needToCleanUp = true;
             if (prevBcc)
               awRemoveRecipients(msgCompFields, "addr_bcc", prevBcc);
             if (newBcc) {
               // Ensure none of the Bccs are already in To or Cc.
               let bcc2 = msgCompFields.splitRecipients(newBcc, true, {});
               let toCcAddrs = new Set([...toAddrs, ...ccAddrs]);
               newBcc = bcc2.filter(x => !toCcAddrs.has(x)).join(", ");
@@ -5796,92 +5544,91 @@ function LoadIdentity(startup)
             }
           }
 
           if (needToCleanUp)
             awCleanupRows();
 
           try {
             gMsgCompose.identity = gCurrentIdentity;
-          } catch (ex) { dump("### Cannot change the identity: " + ex + "\n");}
-
-          var event = document.createEvent('Events');
-          event.initEvent('compose-from-changed', false, true);
+          } catch (ex) {
+            dump("### Cannot change the identity: " + ex + "\n");
+          }
+
+          var event = document.createEvent("Events");
+          event.initEvent("compose-from-changed", false, true);
           document.getElementById("msgcomposeWindow").dispatchEvent(event);
 
           gComposeNotificationBar.clearIdentityWarning();
         }
 
       if (!startup) {
           if (getPref("mail.autoComplete.highlightNonMatches"))
-            document.getElementById('addressCol2#1').highlightNonMatches = true;
+            document.getElementById("addressCol2#1").highlightNonMatches = true;
 
           // Only do this if we aren't starting up...
           // It gets done as part of startup already.
           addRecipientsToIgnoreList(gCurrentIdentity.fullAddress);
 
           // If the From field is editable, reset the address from the identity.
-          if (identityElement.editable)
-          {
+          if (identityElement.editable) {
             identityElement.value = identityElement.selectedItem.value;
-            identityElement.inputField.placeholder = getComposeBundle().getFormattedString("msgIdentityPlaceholder", [identityElement.selectedItem.value]);
+            identityElement.inputField.placeholder = getComposeBundle().getFormattedString(
+              "msgIdentityPlaceholder", [identityElement.selectedItem.value]
+            );
           }
       }
     }
 }
 
-function MakeFromFieldEditable(ignoreWarning)
-{
-  if (!ignoreWarning && !getPref("mail.compose.warned_about_customize_from"))
-  {
+function MakeFromFieldEditable(ignoreWarning) {
+  let bundle = getComposeBundle();
+  if (!ignoreWarning && !getPref("mail.compose.warned_about_customize_from")) {
     var check = { value: false };
     if (Services.prompt.confirmEx(window,
-          getComposeBundle().getString("customizeFromAddressTitle"),
-          getComposeBundle().getString("customizeFromAddressWarning"),
+          bundle.getString("customizeFromAddressTitle"),
+          bundle.getString("customizeFromAddressWarning"),
           Services.prompt.BUTTON_POS_0 * Services.prompt.BUTTON_TITLE_OK +
           Services.prompt.BUTTON_POS_1 * Services.prompt.BUTTON_TITLE_CANCEL +
           Services.prompt.BUTTON_POS_1_DEFAULT,
           null, null, null,
-          getComposeBundle().getString("customizeFromAddressIgnore"),
+          bundle.getString("customizeFromAddressIgnore"),
           check) != 0)
       return;
     Services.prefs.setBoolPref("mail.compose.warned_about_customize_from", check.value);
   }
 
   var customizeMenuitem = document.getElementById("cmd_customizeFromAddress");
   customizeMenuitem.setAttribute("disabled", "true");
   var identityElement = document.getElementById("msgIdentity");
   identityElement.removeAttribute("type");
   identityElement.setAttribute("editable", "true");
   identityElement.focus();
   identityElement.value = identityElement.selectedItem.value;
   identityElement.select();
-  identityElement.inputField.placeholder = getComposeBundle().getFormattedString("msgIdentityPlaceholder", [identityElement.selectedItem.value]);
-}
-
-function setupAutocomplete()
-{
+  identityElement.inputField.placeholder = bundle.getFormattedString("msgIdentityPlaceholder", [identityElement.selectedItem.value]);
+}
+
+function setupAutocomplete() {
   var autoCompleteWidget = document.getElementById("addressCol2#1");
   try {
     // Request that input that isn't matched be highlighted.
     // This element then gets cloned for subsequent rows, so they should
     // honor it as well.
     if (getPref("mail.autoComplete.highlightNonMatches"))
       autoCompleteWidget.highlightNonMatches = true;
   } catch (ex) {}
 }
 
-function fromKeyPress(event)
-{
+function fromKeyPress(event) {
   if (event.keyCode == KeyEvent.DOM_VK_RETURN)
     awSetFocus(1, awGetInputElement(1));
 }
 
-function subjectKeyPress(event)
-{
+function subjectKeyPress(event) {
   gSubjectChanged = true;
   if (event.keyCode == KeyEvent.DOM_VK_RETURN)
     SetMsgBodyFrameFocus();
 }
 
 // we can drag and drop addresses, files, messages and urls into the compose envelope
 var envelopeDragObserver = {
 
@@ -5895,18 +5642,17 @@ var envelopeDragObserver = {
    * @param aEvent the drag-and-drop event being performed
    * @return {attachmentitem|string} the adjusted drop target:
    *                                 - an attachmentitem node for inserting
    *                                   *before*
    *                                 - "none" if this isn't a valid insertion point
    *                                 - "afterLastItem" for appending at the
    *                                   bottom of the list.
    */
-  _adjustDropTarget: function(aEvent)
-  {
+  _adjustDropTarget(aEvent) {
     let target = aEvent.target;
     let bucket = document.getElementById("attachmentBucket");
 
     if (target == bucket) {
       // Dragging or dropping at top/bottom border of the listbox
       let box = target.boxObject;
       if ((aEvent.screenY - box.screenY) / box.height < 0.5) {
         target = bucket.firstChild;
@@ -5928,17 +5674,17 @@ var envelopeDragObserver = {
       }
     }
 
     // Target is an attachmentitem.
     if (target.tagName == "attachmentitem") {
       // If we're dragging/dropping in bottom half of attachmentitem,
       // adjust target to target.nextSibling (to show dropmarker above that).
       let box = target.boxObject;
-      if((aEvent.screenY - box.screenY) / box.height >= 0.5) {
+      if ((aEvent.screenY - box.screenY) / box.height >= 0.5) {
         target = target.nextSibling;
 
         // If there's no target.nextSibling, we're dragging/dropping
         // to the bottom of the list.
         if (!target) {
           // We can't move a bottom block selection to the bottom.
           if (attachmentsSelectionIsBlock("bottom"))
             return "none";
@@ -5961,44 +5707,41 @@ var envelopeDragObserver = {
           return "none";
       }
       return target;
     }
 
     return "none";
   },
 
-  _showDropMarker: function(targetItem)
-  {
+  _showDropMarker(targetItem) {
     let bucket = document.getElementById("attachmentBucket");
 
     let oldDropMarkerItem =
       bucket.querySelector("attachmentitem[dropOn]");
     if (oldDropMarkerItem)
       oldDropMarkerItem.removeAttribute("dropOn");
 
     if (targetItem == "afterLastItem") {
       targetItem = bucket.lastChild;
       targetItem.setAttribute("dropOn", "bottom");
     } else {
       targetItem.setAttribute("dropOn", "top");
     }
   },
 
-  _hideDropMarker: function()
-  {
+  _hideDropMarker() {
    let oldDropMarkerItem =
      document.getElementById("attachmentBucket")
              .querySelector("attachmentitem[dropOn]");
     if (oldDropMarkerItem)
       oldDropMarkerItem.removeAttribute("dropOn");
   },
 
-  onDrop: function (aEvent, aData, aDragSession)
-  {
+  onDrop(aEvent, aData, aDragSession) {
     let bucket = document.getElementById("attachmentBucket");
     let dragSourceNode = aDragSession.sourceNode;
     if (dragSourceNode && dragSourceNode.parentNode == bucket) {
       // We dragged from the attachment pane onto itself, so instead of
       // attaching a new object, we're just reordering them.
 
       // Adjust the drop target according to mouse position on list (items).
       let target = this._adjustDropTarget(aEvent);
@@ -6067,30 +5810,28 @@ var envelopeDragObserver = {
       bucket.currentItem = focus;
       this._hideDropMarker();
       return;
     }
 
     let dataList = aData.dataList;
     let attachments = [];
 
-    for (let dataListObj of dataList)
-    {
+    for (let dataListObj of dataList) {
       let item = dataListObj.first;
       let rawData = item.data;
       let isValidAttachment = false;
       let prettyName;
       let size;
 
       // We could be dropping an attachment of various flavours OR an address;
       // check and do the right thing.
       // Note that case blocks {...} are recommended to avoid redeclaration errors
       // when using 'let'.
-      switch (item.flavour.contentType)
-      {
+      switch (item.flavour.contentType) {
         // Process attachments.
         case "application/x-moz-file": {
           let fileHandler = Services.io
                                     .getProtocolHandler("file")
                                     .QueryInterface(Ci.nsIFileProtocolHandler);
           if (!rawData.exists() || !rawData.isReadable()) {
             // For some reason we couldn't read the file just dragged. Permission problem?
             Cu.reportError("Couldn't access the dragged file " + rawData.leafName);
@@ -6126,18 +5867,17 @@ var envelopeDragObserver = {
 
           // If this is a URL (or selected text), check if it's a valid URL
           // by checking if we can extract a scheme using Services.io.
           // Don't attach invalid or mailto: URLs.
           try {
             let scheme = Services.io.extractScheme(rawData);
             if (scheme != "mailto")
               isValidAttachment = true;
-          }
-          catch (ex) {}
+          } catch (ex) {}
           break;
         }
 
         // Process address: Drop it into recipient field.
         case "text/x-moz-address": {
           if (rawData) {
             DropRecipient(aEvent.target, rawData);
 
@@ -6166,18 +5906,17 @@ var envelopeDragObserver = {
       }
     }
 
     // Add attachments if any.
     if (attachments.length > 0)
       AddAttachments(attachments);
   },
 
-  onDragOver: function (aEvent, aFlavour, aDragSession)
-  {
+  onDragOver(aEvent, aFlavour, aDragSession) {
     let bucket = document.getElementById("attachmentBucket");
     let dragSourceNode = aDragSession.sourceNode;
     if (dragSourceNode && dragSourceNode.parentNode == bucket) {
       // If we're dragging from the attachment bucket onto itself, we need to
       // show a drop marker.
 
       let target = this._adjustDropTarget(aEvent);
 
@@ -6196,145 +5935,124 @@ var envelopeDragObserver = {
     if (aFlavour.contentType != "text/x-moz-address") {
       // Make sure the attachment pane is visible during drag over.
       toggleAttachmentPane("show");
     } else {
       DragAddressOverTargetControl(aEvent);
     }
   },
 
-  onDragExit: function (aEvent, aDragSession)
-  {
+  onDragExit(aEvent, aDragSession) {
     this._hideDropMarker();
   },
 
-  getSupportedFlavours: function ()
-  {
+  getSupportedFlavours() {
     let flavourSet = new FlavourSet();
     // Prefer "text/x-moz-address", so when an address from the address book
     // is dragged, this flavour is tested first. Otherwise the attachment
     // bucket would open since the addresses also carry the
     // "application/x-moz-file" flavour.
     flavourSet.appendFlavour("text/x-moz-address");
     flavourSet.appendFlavour("text/x-moz-message");
     flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
     flavourSet.appendFlavour("text/x-moz-url");
     return flavourSet;
-  }
+  },
 };
 
 var attachmentBucketDNDObserver = {
-  onDragStart: function (aEvent, aAttachmentData, aDragAction)
-  {
+  onDragStart(aEvent, aAttachmentData, aDragAction) {
     var target = aEvent.target;
 
     if (target.localName == "attachmentitem")
       aAttachmentData.data = CreateAttachmentTransferData(target.attachment);
-  }
+  },
 };
 
-function DisplaySaveFolderDlg(folderURI)
-{
-  try
-  {
+function DisplaySaveFolderDlg(folderURI) {
+  try {
     var showDialog = gCurrentIdentity.showSaveMsgDlg;
-  }
-  catch (e)
-  {
+  } catch (e) {
     return;
   }
 
-  if (showDialog){
+  if (showDialog) {
     let msgfolder = MailUtils.getFolderForURI(folderURI, true);
     if (!msgfolder)
       return;
-    let checkbox = {value:0};
-    let SaveDlgTitle = getComposeBundle().getString("SaveDialogTitle");
+    let checkbox = {value: 0};
+    let bundle = getComposeBundle();
+    let SaveDlgTitle = bundle.getString("SaveDialogTitle");
     let dlgMsg = bundle.getFormattedString("SaveDialogMsg",
                                            [msgfolder.name,
                                             msgfolder.server.prettyName]);
 
-    let CheckMsg = bundle.getString("CheckMsg");
-    Services.prompt
-            .alertCheck(window, SaveDlgTitle, dlgMsg,
-                        getComposeBundle().getString("CheckMsg"), checkbox);
+    Services.prompt.alertCheck(window, SaveDlgTitle, dlgMsg,
+                               bundle.getString("CheckMsg"), checkbox);
     try {
-          gCurrentIdentity.showSaveMsgDlg = !checkbox.value;
-    }//try
-    catch (e) {
-    return;
-    }//catch
-
-  }//if
-  return;
-}
-
-function SetMsgAddressingWidgetTreeElementFocus()
-{
+      gCurrentIdentity.showSaveMsgDlg = !checkbox.value;
+    } catch (e) {
+    }
+  }
+}
+
+function SetMsgAddressingWidgetTreeElementFocus() {
   let lastRecipientInputElement = awGetInputElement(awGetNumberOfRecipients());
   awSetFocus(awGetNumberOfRecipients(), lastRecipientInputElement);
 }
 
-function SetMsgIdentityElementFocus()
-{
+function SetMsgIdentityElementFocus() {
   GetMsgIdentityElement().focus();
 }
 
-function SetMsgSubjectElementFocus()
-{
+function SetMsgSubjectElementFocus() {
   GetMsgSubjectElement().focus();
 }
 
-function SetMsgAttachmentElementFocus()
-{
+function SetMsgAttachmentElementFocus() {
   // Caveat: Callers must ensure that attachment pane is visible.
   GetMsgAttachmentElement().focus();
 }
 
 /**
  * Focus the people search input in contacts side bar.
  */
 function focusContactsSidebarSearchInput() {
   // Caveat: Callers must ensure that contacts side bar is visible.
   sidebarDocumentGetElementById("peopleSearchInput", "abContactsPanel").focus();
 }
 
-function SetMsgBodyFrameFocus()
-{
+function SetMsgBodyFrameFocus() {
   // window.content.focus() fails to blur the currently focused element
   document.commandDispatcher
           .advanceFocusIntoSubtree(document.getElementById("appcontent"));
 }
 
-function GetMsgAddressingWidgetTreeElement()
-{
+function GetMsgAddressingWidgetTreeElement() {
   if (!gMsgAddressingWidgetTreeElement)
     gMsgAddressingWidgetTreeElement = document.getElementById("addressingWidget");
 
   return gMsgAddressingWidgetTreeElement;
 }
 
-function GetMsgIdentityElement()
-{
+function GetMsgIdentityElement() {
   if (!gMsgIdentityElement)
     gMsgIdentityElement = document.getElementById("msgIdentity");
 
   return gMsgIdentityElement;
 }
 
-function GetMsgSubjectElement()
-{
+function GetMsgSubjectElement() {
   if (!gMsgSubjectElement)
     gMsgSubjectElement = document.getElementById("msgSubject");
 
   return gMsgSubjectElement;
 }
 
-function GetMsgAttachmentElement()
-{
+function GetMsgAttachmentElement() {
   if (!gMsgAttachmentElement)
     gMsgAttachmentElement = document.getElementById("attachmentBucket");
 
   return gMsgAttachmentElement;
 }
 
 /**
  * Get an element by ID in the current sidebar browser document.
@@ -6355,41 +6073,39 @@ function sidebarDocumentGetElementById(a
     if (sidebarDocument.getElementById(aPageId)) {
       return sidebarDocument.getElementById(aId);
     }
     return null;
   }
   return sidebarDocument.getElementById(aId);
 }
 
-function GetMsgHeadersToolbarElement()
-{
+function GetMsgHeadersToolbarElement() {
   if (!gMsgHeadersToolbarElement)
     gMsgHeadersToolbarElement = document.getElementById("MsgHeadersToolbar");
 
   return gMsgHeadersToolbarElement;
 }
 
 /**
  * Determine which element of the fast-track focus ring has focus.
  * Note that only elements of the fast-track focus ring will be returned.
  *
  * @return an element node of the fast-track focus ring if the node or one of
  *         its descendants has focus, otherwise null.
  */
-function WhichElementHasFocus()
-{
+function WhichElementHasFocus() {
   let msgIdentityElement = GetMsgIdentityElement();
   let msgAddressingWidgetTreeElement = GetMsgAddressingWidgetTreeElement();
   let msgSubjectElement = GetMsgSubjectElement();
   let msgAttachmentElement = GetMsgAttachmentElement();
   let abContactsPanelElement = sidebarDocumentGetElementById("abContactsPanel");
 
-  if (top.document.commandDispatcher.focusedWindow == content)
-    return content;
+  if (top.document.commandDispatcher.focusedWindow == window.content)
+    return window.content;
 
   let currentNode = top.document.commandDispatcher.focusedElement;
   while (currentNode) {
     if (currentNode == msgIdentityElement ||
         currentNode == msgAddressingWidgetTreeElement ||
         currentNode == msgSubjectElement ||
         currentNode == msgAttachmentElement ||
         currentNode == abContactsPanelElement) {
@@ -6406,18 +6122,17 @@ function WhichElementHasFocus()
  * in the message compose window. Ctrl+[Shift+]Tab | [Shift+]F6 on Windows.
  *
  * The default element to switch to when going in either direction (with or
  * without shift key pressed) is the AddressingWidgetTreeElement.
  *
  * The only exception is when the MsgHeadersToolbar is collapsed,
  * then the focus will always be on the body of the message.
  */
-function SwitchElementFocus(event)
-{
+function SwitchElementFocus(event) {
   let focusedElement = WhichElementHasFocus();
 
   if (!focusedElement) {
     // None of the pre-defined focus ring elements has focus: This should never
     // happen with the default installation, but might happen with add-ons.
     // In that case, default to focusing the address widget as the first element
     // of the focus ring.
     SetMsgAddressingWidgetTreeElementFocus();
@@ -6436,17 +6151,17 @@ function SwitchElementFocus(event)
             sidebarDocumentGetElementById("abContactsPanel"))
           focusContactsSidebarSearchInput();
         else
           SetMsgBodyFrameFocus();
         break;
       case sidebarDocumentGetElementById("abContactsPanel"):
         SetMsgBodyFrameFocus();
         break;
-      case content: // message body
+      case window.content: // message body
         // Only set focus to the attachment element if it is shown.
         if (!document.getElementById("attachments-box").collapsed)
           SetMsgAttachmentElementFocus();
         else
           SetMsgSubjectElementFocus();
         break;
       case gMsgAttachmentElement:
         SetMsgSubjectElementFocus();
@@ -6466,17 +6181,17 @@ function SwitchElementFocus(event)
         if (!document.getElementById("attachments-box").collapsed)
           SetMsgAttachmentElementFocus();
         else
           SetMsgBodyFrameFocus();
         break;
       case gMsgAttachmentElement:
         SetMsgBodyFrameFocus();
         break;
-      case content:
+      case window.content:
         // Only set focus to the contacts side bar (search box) if it is shown.
         if (!sidebar_is_hidden() &&
             sidebarDocumentGetElementById("abContactsPanel"))
           focusContactsSidebarSearchInput();
         else
           SetMsgIdentityElementFocus();
         break;
       case sidebarDocumentGetElementById("abContactsPanel"):
@@ -6488,33 +6203,32 @@ function SwitchElementFocus(event)
     }
   }
 }
 
 function sidebarCloseButtonOnCommand() {
   toggleAddressPicker();
 }
 
-function toggleAddressPicker()
-{
+function toggleAddressPicker() {
   // Caveat: This function erroneously assumes that only abContactsPanel can
   // be shown in the sidebar browser, so it will fail if any other src is shown
   // as we do not reliably enforce abContactsPanel.xul as src of the sidebar
   // <browser>. Currently we don't show anything else in the sidebar, but
   // add-ons might.
   let sidebarBox = document.getElementById("sidebar-box");
   let sidebarSplitter = document.getElementById("sidebar-splitter");
   let sidebar = document.getElementById("sidebar");
   let viewAddressPicker = document.getElementById("viewAddressPicker");
 
   if (sidebarBox.hidden) {
     // Show contacts sidebar.
     sidebarBox.hidden = false;
     sidebarSplitter.hidden = false;
-    viewAddressPicker.setAttribute("checked","true");
+    viewAddressPicker.setAttribute("checked", "true");
 
     let sidebarUrl = sidebar.getAttribute("src");
     // If we have yet to initialize the src URL on the sidebar, then go ahead
     // and do so now... We do this lazily here, so we don't spend time when
     // bringing up the compose window loading the address book data sources.
     // Only when the user opens the address picker, do we set the src URL
     // for the sidebar.
     if (sidebarUrl == "")
@@ -6543,96 +6257,87 @@ function toggleAddressPicker()
     // otherwise the body. If we didn't do that, focus may stay inside the closed
     // Contacts sidebar and then the main window/frame does not respond to accesskeys.
     // This may be fixed by bug 570835.
     let composerBox = document.getElementById("headers-parent");
     let focusedElement = composerBox.querySelector(":focus") ||
                          composerBox.querySelector('[focused="true"]');
     if (focusedElement) {
       focusedElement.focus();
+    } else if (!GetMsgSubjectElement().value) {
+      SetMsgSubjectElementFocus();
     } else {
-      if (!GetMsgSubjectElement().value)
-        SetMsgSubjectElementFocus();
-      else
-        SetMsgBodyFrameFocus();
+      SetMsgBodyFrameFocus();
     }
   }
 }
 
 // Public method called by addons.
-function AddRecipient(aRecipientType, aAddress)
-{
+function AddRecipient(aRecipientType, aAddress) {
   awAddRecipientsArray(aRecipientType, [aAddress]);
 }
 
 // Public method called by the contants sidebar.
-function AddRecipientsArray(aRecipientType, aAddressArray)
-{
+function AddRecipientsArray(aRecipientType, aAddressArray) {
   awAddRecipientsArray(aRecipientType, aAddressArray);
 }
 
-function loadHTMLMsgPrefs()
-{
+function loadHTMLMsgPrefs() {
   var fontFace;
   var fontSize;
   var textColor;
   var bgColor;
 
   try {
     fontFace = getPref("msgcompose.font_face", true);
-    doStatefulCommand('cmd_fontFace', fontFace);
+    doStatefulCommand("cmd_fontFace", fontFace);
   } catch (e) {}
 
   try {
     fontSize = getPref("msgcompose.font_size");
     EditorSetFontSize(fontSize);
   } catch (e) {}
 
   var bodyElement = GetBodyElement();
 
   try {
     textColor = getPref("msgcompose.text_color");
-    if (!bodyElement.getAttribute("text"))
-    {
-    bodyElement.setAttribute("text", textColor);
-    gDefaultTextColor = textColor;
-    document.getElementById("cmd_fontColor").setAttribute("state", textColor);
-    onFontColorChange();
+    if (!bodyElement.getAttribute("text")) {
+      bodyElement.setAttribute("text", textColor);
+      gDefaultTextColor = textColor;
+      document.getElementById("cmd_fontColor").setAttribute("state", textColor);
+      onFontColorChange();
     }
   } catch (e) {}
 
   try {
     bgColor = getPref("msgcompose.background_color");
-    if (!bodyElement.getAttribute("bgcolor"))
-    {
-    bodyElement.setAttribute("bgcolor", bgColor);
-    gDefaultBackgroundColor = bgColor;
-    document.getElementById("cmd_backgroundColor").setAttribute("state", bgColor);
-    onBackgroundColorChange();
+    if (!bodyElement.getAttribute("bgcolor")) {
+      bodyElement.setAttribute("bgcolor", bgColor);
+      gDefaultBackgroundColor = bgColor;
+      document.getElementById("cmd_backgroundColor").setAttribute("state", bgColor);
+      onBackgroundColorChange();
     }
   } catch (e) {}
 }
 
-function AutoSave()
-{
+function AutoSave() {
   if (gMsgCompose.editor && (gContentChanged || gMsgCompose.bodyModified) &&
-      !gSendOperationInProgress && !gSaveOperationInProgress)
-  {
-    GenericSendMessage(nsIMsgCompDeliverMode.AutoSaveAsDraft);
+      !gSendOperationInProgress && !gSaveOperationInProgress) {
+    GenericSendMessage(Ci.nsIMsgCompDeliverMode.AutoSaveAsDraft);
     gAutoSaveKickedIn = true;
   }
 
   gAutoSaveTimeout = setTimeout(AutoSave, gAutoSaveInterval);
 }
 
 /**
  * Periodically check for keywords in the message.
  */
-var gAttachmentNotifier =
-{
+var gAttachmentNotifier = {
   _obs: null,
 
   enabled: false,
 
   init: function gAN_init(aDocument) {
     if (this._obs)
       this.shutdown();
 
@@ -6671,34 +6376,33 @@ var gAttachmentNotifier =
                                                Ci.nsITimer.TYPE_ONE_SHOT);
   },
 
   /**
    * Checks for new keywords synchronously and run the usual handler.
    *
    * @param aManage  Determines whether to manage the notification according to keywords found.
    */
-  redetectKeywords: function(aManage) {
+  redetectKeywords(aManage) {
     if (!this.enabled)
       return;
 
     attachmentWorker.onmessage({ data: this._checkForAttachmentKeywords(false) }, aManage);
   },
 
   /**
    * Check if there are any keywords in the message.
    *
    * @param async  Whether we should run the regex checker asynchronously or not.
    *
    * @return  If async is true, attachmentWorker.message is called with the array
    *          of found keywords and this function returns null.
    *          If it is false, the array is returned from this function immediately.
    */
-  _checkForAttachmentKeywords: function(async)
-  {
+  _checkForAttachmentKeywords(async) {
     if (!this.enabled)
       return (async ? null : []);
 
     if (attachmentNotificationSupressed()) {
       // If we know we don't need to show the notification,
       // we can skip the expensive checking of keywords in the message.
       // but mark it in the .lastMessage that the keywords are unknown.
       attachmentWorker.lastMessage = null;
@@ -6760,23 +6464,23 @@ var gAttachmentNotifier =
     if (fwdIndex > 0)
       mailData = mailData.substring(0, fwdIndex);
 
     // Prepend the subject to see if the subject contains any attachment
     // keywords too, after making sure that the subject has changed.
     let subject = GetMsgSubjectElement().value;
     if (subject && (gSubjectChanged ||
        (gEditingDraft &&
-         (gComposeType == nsIMsgCompType.New ||
-         gComposeType == nsIMsgCompType.NewsPost ||
-         gComposeType == nsIMsgCompType.Draft ||
-         gComposeType == nsIMsgCompType.Template ||
-         gComposeType == nsIMsgCompType.EditTemplate ||
-         gComposeType == nsIMsgCompType.EditAsNew ||
-         gComposeType == nsIMsgCompType.MailToUrl))))
+         (gComposeType == Ci.nsIMsgCompType.New ||
+          gComposeType == Ci.nsIMsgCompType.NewsPost ||
+          gComposeType == Ci.nsIMsgCompType.Draft ||
+          gComposeType == Ci.nsIMsgCompType.Template ||
+          gComposeType == Ci.nsIMsgCompType.EditTemplate ||
+          gComposeType == Ci.nsIMsgCompType.EditAsNew ||
+          gComposeType == Ci.nsIMsgCompType.MailToUrl))))
       mailData = subject + " " + mailData;
 
     if (!async)
       return GetAttachmentKeywords(mailData, keywordsInCsv);
 
     attachmentWorker.postMessage([mailData, keywordsInCsv]);
     return null;
   },
@@ -6785,60 +6489,56 @@ var gAttachmentNotifier =
     if (this._obs)
       this._obs.disconnect();
     gAttachmentNotifier.timer.cancel();
 
     this._obs = null;
   },
 
   event: {
-    notify: function(timer)
-    {
+    notify(timer) {
       // Only run the checker if the compose window is initialized
       // and not shutting down.
       if (gMsgCompose) {
         // This runs the attachmentWorker asynchronously so if keywords are found
         // manageAttachmentNotification is run from attachmentWorker.onmessage.
         gAttachmentNotifier._checkForAttachmentKeywords(true);
       }
-    }
+    },
   },
 
-  timer: Cc["@mozilla.org/timer;1"]
-           .createInstance(Ci.nsITimer)
+  timer: Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer),
 };
 
 /**
  * Helper function to remove a query part from a URL, so for example:
  * ...?remove=xx&other=yy becomes ...?other=yy.
  *
  * @param aURL    the URL from which to remove the query part
  * @param aQuery  the query part to remove
  * @return        the URL with the query part removed
  */
-function removeQueryPart(aURL, aQuery)
-{
+function removeQueryPart(aURL, aQuery) {
   // Quick pre-check.
-  if (aURL.indexOf(aQuery) < 0)
+  if (!aURL.includes(aQuery))
     return aURL;
 
   let indexQM = aURL.indexOf("?");
   if (indexQM < 0)
     return aURL;
 
   let queryParts = aURL.substr(indexQM + 1).split("&");
   let indexPart = queryParts.indexOf(aQuery);
   if (indexPart < 0)
     return aURL;
   queryParts.splice(indexPart, 1);
   return aURL.substr(0, indexQM + 1) + queryParts.join("&");
 }
 
-function InitEditor()
-{
+function InitEditor() {
   var editor = GetCurrentEditor();
 
   // Set eEditorMailMask flag to avoid using content prefs for spell checker,
   // otherwise dictionary setting in preferences is ignored and dictionary is
   // inconsistent in subject and message body.
   let eEditorMailMask = Ci.nsIPlaintextEditor.eEditorMailMask;
   editor.flags |= eEditorMailMask;
   GetMsgSubjectElement().editor.flags |= eEditorMailMask;
@@ -6852,36 +6552,36 @@ function InitEditor()
                                "p" : "br");
   if (gMsgCompose.composeHTML) {
     // Re-enable table/image resizers.
     editor.QueryInterface(Ci.nsIHTMLAbsPosEditor).absolutePositioningEnabled = true;
     editor.QueryInterface(Ci.nsIHTMLInlineTableEditor).inlineTableEditingEnabled = true;
     editor.QueryInterface(Ci.nsIHTMLObjectResizer).objectResizingEnabled = true;
   }
 
-  editor.QueryInterface(nsIEditorStyleSheets);
+  editor.QueryInterface(Ci.nsIEditorStyleSheets);
   // We use addOverrideStyleSheet rather than addStyleSheet so that we get
   // a synchronous load, rather than having a late-finishing async load
   // mark our editor as modified when the user hasn't typed anything yet,
   // but that means the sheet must not @import slow things, especially
   // not over the network.
   editor.addOverrideStyleSheet("chrome://messenger/content/composerOverlay.css");
   gMsgCompose.initEditor(editor, window.content);
 
   // We always go through this function every time we init an editor.
   // First step is making sure we can spell check.
   gSpellChecker.init(editor);
-  document.getElementById('menu_inlineSpellCheck')
-          .setAttribute('disabled', !gSpellChecker.canSpellCheck);
-  document.getElementById('spellCheckEnable')
-          .setAttribute('disabled', !gSpellChecker.canSpellCheck);
+  document.getElementById("menu_inlineSpellCheck")
+          .setAttribute("disabled", !gSpellChecker.canSpellCheck);
+  document.getElementById("spellCheckEnable")
+          .setAttribute("disabled", !gSpellChecker.canSpellCheck);
   // If canSpellCheck = false, then hidden = false, i.e. show it so that we can
   // still add dictionaries. Else, hide that.
-  document.getElementById('spellCheckAddDictionariesMain')
-          .setAttribute('hidden', gSpellChecker.canSpellCheck);
+  document.getElementById("spellCheckAddDictionariesMain")
+          .setAttribute("hidden", gSpellChecker.canSpellCheck);
   // Then, we enable related UI entries.
   enableInlineSpellCheck(getPref("mail.spellcheck.inline"));
   gAttachmentNotifier.init(editor.document);
 
   // Listen for spellchecker changes, set document language to
   // dictionary picked by the user via the right-click menu in the editor.
   document.addEventListener("spellcheck-changed", updateDocumentLanguage);
 
@@ -6926,23 +6626,21 @@ function InitEditor()
         // now.
         event.target.classList.add("loading-internal");
         try {
           loadBlockedImage(src);
         } catch (e) {
           // Couldn't load the referenced image.
           Cu.reportError(e);
         }
-      }
-      else {
+      } else {
         // Appears to reference a random message. Notify and keep blocking.
         gComposeNotificationBar.setBlockedContent(src);
       }
-    }
-    else {
+    } else {
       // For file:, and references to parts of random messages, show the
       // blocked content notification.
       gComposeNotificationBar.setBlockedContent(src);
     }
   }, true);
 
   // Convert mailnews URL back to data: URL.
   let background = editor.document.body.background;
@@ -6963,43 +6661,40 @@ function InitEditor()
         Cu.reportError(e);
       }
     }
   }
 }
 
 // This is used as event listener to spellcheck-changed event to update
 // document language.
-function updateDocumentLanguage(e)
-{
+function updateDocumentLanguage(e) {
   document.documentElement.setAttribute("lang", e.detail.dictionary);
 }
 
 // This function modifies gSpellChecker and updates the UI accordingly. It's
 // called either at startup (see InitEditor above), or when the user clicks on
 // one of the two menu items that allow them to toggle the spellcheck feature
 // (either context menu or Options menu).
-function enableInlineSpellCheck(aEnableInlineSpellCheck)
-{
+function enableInlineSpellCheck(aEnableInlineSpellCheck) {
   if (gSpellChecker.enabled != aEnableInlineSpellCheck) {
     // If state of spellchecker is about to change, clear any pending observer.
     spellCheckReadyObserver.removeObserver();
   }
   gSpellChecker.enabled = aEnableInlineSpellCheck;
-  document.getElementById('msgSubject').setAttribute('spellcheck', aEnableInlineSpellCheck);
+  document.getElementById("msgSubject").setAttribute("spellcheck", aEnableInlineSpellCheck);
   document.getElementById("menu_inlineSpellCheck")
-          .setAttribute('checked', aEnableInlineSpellCheck);
+          .setAttribute("checked", aEnableInlineSpellCheck);
   document.getElementById("spellCheckEnable")
-          .setAttribute('checked', aEnableInlineSpellCheck);
-  document.getElementById('spellCheckDictionaries')
-          .setAttribute('hidden', !aEnableInlineSpellCheck);
-}
-
-function getMailToolbox()
-{
+          .setAttribute("checked", aEnableInlineSpellCheck);
+  document.getElementById("spellCheckDictionaries")
+          .setAttribute("hidden", !aEnableInlineSpellCheck);
+}
+
+function getMailToolbox() {
   return document.getElementById("compose-toolbox");
 }
 
 function getPref(aPrefName, aIsComplex) {
   if (aIsComplex) {
     return Services.prefs.getStringPref(aPrefName);
   }
   switch (Services.prefs.getPrefType(aPrefName)) {
@@ -7033,25 +6728,22 @@ function UpdateFullZoomMenu() {
   menuItem.setAttribute("checked", !ZoomManager.useFullZoom);
 }
 
 /**
  * Return the <editor> element of the mail compose window. The name is somewhat
  * unfortunate; we need to maintain it since the zoom manager, view source and
  * other functions still rely on it.
  */
-function getBrowser()
-{
+function getBrowser() {
   return document.getElementById("content-frame");
 }
 
-function goUpdateMailMenuItems(commandset)
-{
-  for (let i = 0; i < commandset.childNodes.length; i++)
-  {
+function goUpdateMailMenuItems(commandset) {
+  for (let i = 0; i < commandset.childNodes.length; i++) {
     let commandID = commandset.childNodes[i].getAttribute("id");
     if (commandID)
       goUpdateCommand(commandID);
   }
 }
 
 /**
  * Object to handle message related notifications that are showing in a
@@ -7063,85 +6755,84 @@ var gComposeNotificationBar = {
     return this.brandBundle = document.getElementById("brandBundle");
   },
 
   get notificationBar() {
     delete this.notificationBar;
     return this.notificationBar = document.getElementById("attachmentNotificationBox");
   },
 
-  setBlockedContent: function(aBlockedURI) {
+  setBlockedContent(aBlockedURI) {
     let brandName = this.brandBundle.getString("brandShortName");
     let buttonLabel = getComposeBundle().getString((AppConstants.platform == "win") ?
       "blockedContentPrefLabel" : "blockedContentPrefLabelUnix");
     let buttonAccesskey = getComposeBundle().getString((AppConstants.platform == "win") ?
       "blockedContentPrefAccesskey" : "blockedContentPrefAccesskeyUnix");
 
     let buttons = [{
       label: buttonLabel,
       accessKey: buttonAccesskey,
       popup: "blockedContentOptions",
-      callback: function(aNotification, aButton) {
+      callback(aNotification, aButton) {
         return true; // keep notification open
-      }
+      },
     }];
 
     // The popup value is a space separated list of all the blocked urls.
     let popup = document.getElementById("blockedContentOptions");
     let urls = popup.value ? popup.value.split(" ") : [];
     if (!urls.includes(aBlockedURI))
       urls.push(aBlockedURI);
     popup.value = urls.join(" ");
 
     let msg = getComposeBundle().getFormattedString(
       "blockedContentMessage", [brandName, brandName]);
     msg = PluralForm.get(urls.length, msg);
 
     if (!this.isShowingBlockedContentNotification()) {
       this.notificationBar.appendNotification(msg, "blockedContent",
         null, this.notificationBar.PRIORITY_WARNING_MEDIUM, buttons);
-    }
-    else {
+    } else {
       this.notificationBar.getNotificationWithValue("blockedContent")
         .setAttribute("label", msg);
     }
   },
 
-  isShowingBlockedContentNotification: function() {
+  isShowingBlockedContentNotification() {
     return !!this.notificationBar.getNotificationWithValue("blockedContent");
   },
 
-  clearBlockedContentNotification: function() {
+  clearBlockedContentNotification() {
     this.notificationBar.removeNotification(
       this.notificationBar.getNotificationWithValue("blockedContent"));
   },
 
-  clearNotifications: function(aValue) {
+  clearNotifications(aValue) {
     this.notificationBar.removeAllNotifications(true);
   },
 
-  setIdentityWarning: function(aIdentityName) {
+  setIdentityWarning(aIdentityName) {
     if (!this.notificationBar.getNotificationWithValue("identityWarning")) {
       let text = getComposeBundle().getString("identityWarning")
                                    .split("%S");
       let label = new DocumentFragment();
       label.appendChild(document.createTextNode(text[0]));
       label.appendChild(document.createElement("b"));
       label.lastChild.appendChild(document.createTextNode(aIdentityName));
       label.appendChild(document.createTextNode(text[1]));
       this.notificationBar.appendNotification(label, "identityWarning", null,
         this.notificationBar.PRIORITY_WARNING_HIGH, null);
     }
   },
 
-  clearIdentityWarning: function() {
+  clearIdentityWarning() {
     let idWarning = this.notificationBar.getNotificationWithValue("identityWarning");
     if (idWarning)
       this.notificationBar.removeNotification(idWarning);
-  }
+  },
 };
 
 /**
  * Populate the menuitems of what blocked content to unblock.
  */
 function onBlockedContentOptionsShowing(aEvent) {
   let urls = aEvent.target.value ? aEvent.target.value.split(" ") : [];
 
@@ -7200,18 +6891,17 @@ function onUnblockResource(aURL, aNode) 
  * @param {Bool}    aReturnDataURL - return data: URL instead of processing image
  * @return {String} the image as data: URL.
  * @throw Error()   if reading the data failed
  */
 function loadBlockedImage(aURL, aReturnDataURL = false) {
   let filename;
   if (/^(file|chrome):/i.test(aURL)) {
     filename = aURL.substr(aURL.lastIndexOf("/") + 1);
-  }
-  else {
+  } else {
     let fnMatch = /[?&;]filename=([^?&]+)/.exec(aURL);
     filename = (fnMatch && fnMatch[1]) || "";
   }
   filename = decodeURIComponent(filename);
   let uri = Services.io.newURI(aURL);
   let contentType;
   if (filename) {
     try {
@@ -7222,18 +6912,17 @@ function loadBlockedImage(aURL, aReturnD
       contentType = "image/png";
     }
 
     if (!contentType.startsWith("image/")) {
       // Unsafe to unblock this. It would just be garbage either way.
       throw new Error("Won't unblock; URL=" + aURL +
                       ", contentType=" + contentType);
     }
-  }
-  else {
+  } else {
     // Assuming image/png is the best we can do.
     contentType = "image/png";
   }
   let channel = Services.io.newChannelFromURI2(uri,
     null,
     Services.scriptSecurityManager.getSystemPrincipal(),
     null,
     Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
@@ -7242,19 +6931,19 @@ function loadBlockedImage(aURL, aReturnD
   let stream = Cc["@mozilla.org/binaryinputstream;1"]
     .createInstance(Ci.nsIBinaryInputStream);
   stream.setInputStream(inputStream);
   let streamData = "";
   try {
     while (stream.available() > 0) {
       streamData += stream.readBytes(stream.available());
     }
-  } catch(e) {
+  } catch (e) {
     stream.close();
-    throw new Error("Couln't read all data from URL=" + aURL + " (" + e +")");
+    throw new Error("Couln't read all data from URL=" + aURL + " (" + e + ")");
   }
   stream.close();
   let encoded = btoa(streamData);
   let dataURL = "data:" + contentType +
     (filename ? ";filename=" + encodeURIComponent(filename) : "") +
     ";base64," + encoded;
 
   if (aReturnDataURL)
@@ -7262,9 +6951,11 @@ function loadBlockedImage(aURL, aReturnD
 
   let editor = GetCurrentEditor();
   for (let img of editor.document.images) {
     if (img.src == aURL) {
       img.src = dataURL; // Swap to data URL.
       img.classList.remove("loading-internal");
     }
   }
-}
+
+  return null;
+}
--- a/mail/components/compose/content/addressingWidgetOverlay.js
+++ b/mail/components/compose/content/addressingWidgetOverlay.js
@@ -1,59 +1,52 @@
 /* -*- Mode: Javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * 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/. */
 
-ChromeUtils.import("resource://gre/modules/Services.jsm");
-ChromeUtils.import("resource:///modules/MailServices.jsm");
+/* import-globals-from MsgComposeCommands.js */
 
 top.MAX_RECIPIENTS = 1; /* for the initial listitem created in the XUL */
 
 var inputElementType = "";
 var selectElementType = "";
 var selectElementIndexTable = null;
 
 var gNumberOfCols = 0;
 
 var gDragService = Cc["@mozilla.org/widget/dragservice;1"]
                      .getService(Ci.nsIDragService);
 
 var test_addresses_sequence = false;
 
-try {
-  if (sPrefs)
-    test_addresses_sequence = sPrefs.getBoolPref("mail.debug.test_addresses_sequence");
+if (Services.prefs.getPrefType("mail.debug.test_addresses_sequence") == Ci.nsIPrefBranch.PREF_BOOL) {
+  test_addresses_sequence = Services.prefs.getBoolPref("mail.debug.test_addresses_sequence");
 }
-catch (ex) {}
 
-function awGetMaxRecipients()
-{
+function awGetMaxRecipients() {
   return top.MAX_RECIPIENTS;
 }
 
-function awGetNumberOfCols()
-{
-  if (gNumberOfCols == 0)
-  {
+function awGetNumberOfCols() {
+  if (gNumberOfCols == 0) {
     var listbox = document.getElementById("addressingWidget");
     var listCols = listbox.getElementsByTagName("treecol");
     gNumberOfCols = listCols.length;
     if (!gNumberOfCols)
       gNumberOfCols = 1;  /* if no cols defined, that means we have only one! */
   }
 
   return gNumberOfCols;
 }
 
 /**
  * Adjust the default and minimum number of visible recipient rows for addressingWidget
  */
-function awInitializeNumberOfRowsShown()
-{
+function awInitializeNumberOfRowsShown() {
   let msgHeadersToolbar = document.getElementById("MsgHeadersToolbar");
   let addressingWidget = document.getElementById("addressingWidget");
   let awNumRowsShownDefault =
     Services.prefs.getIntPref("mail.compose.addresswidget.numRowsShownDefault");
 
   // Work around bug 966655: extraHeight 2 pixels for msgHeadersToolbar ensures
   // visibility of recipient rows per awNumRowsShownDefault and prevents scrollbar
   // on empty Address Widget, depending on OS screen resolution dpi scaling
@@ -71,54 +64,48 @@ function awInitializeNumberOfRowsShown()
   msgHeadersToolbar.height = msgHeadersToolbar.boxObject.height +
     addressingWidget.boxObject.height * (awNumRowsShownDefault - 1) +
     extraHeight;
 
   // Update addressingWidget internals.
   awCreateOrRemoveDummyRows();
 }
 
-function awInputElementName()
-{
+function awInputElementName() {
   if (inputElementType == "")
     inputElementType = document.getElementById("addressCol2#1").localName;
   return inputElementType;
 }
 
-function awSelectElementName()
-{
+function awSelectElementName() {
   if (selectElementType == "")
       selectElementType = document.getElementById("addressCol1#1").localName;
   return selectElementType;
 }
 
 // TODO: replace awGetSelectItemIndex with recipient type index constants
 
-function awGetSelectItemIndex(itemData)
-{
-  if (selectElementIndexTable == null)
-  {
-    selectElementIndexTable = new Object();
+function awGetSelectItemIndex(itemData) {
+  if (selectElementIndexTable == null) {
+    selectElementIndexTable = {};
     var selectElem = document.getElementById("addressCol1#1");
-    for (var i = 0; i < selectElem.childNodes[0].childNodes.length; i ++)
-    {
+    for (var i = 0; i < selectElem.childNodes[0].childNodes.length; i++) {
       var aData = selectElem.childNodes[0].childNodes[i].getAttribute("value");
       selectElementIndexTable[aData] = i;
     }
   }
 
   return selectElementIndexTable[itemData];
 }
 
-function Recipients2CompFields(msgCompFields)
-{
+function Recipients2CompFields(msgCompFields) {
   if (!msgCompFields) {
     throw new Error("Message Compose Error: msgCompFields is null (ExtractRecipients)");
-    return;
   }
+
     var i = 1;
     var addrTo = "";
     var addrCc = "";
     var addrBcc = "";
     var addrReply = "";
     var addrNg = "";
     var addrFollow = "";
     var to_Sep = "";
@@ -127,71 +114,84 @@ function Recipients2CompFields(msgCompFi
     var reply_Sep = "";
     var ng_Sep = "";
     var follow_Sep = "";
 
     var recipientType;
     var inputField;
     var fieldValue;
     var recipient;
-    while ((inputField = awGetInputElement(i)))
-    {
+    while ((inputField = awGetInputElement(i))) {
       fieldValue = inputField.value;
-      if (fieldValue != "")
-      {
+      if (fieldValue != "") {
         recipientType = awGetPopupElement(i).value;
         recipient = null;
 
-        switch (recipientType)
-        {
-          case "addr_to"    :
-          case "addr_cc"    :
-          case "addr_bcc"   :
-          case "addr_reply" :
+        switch (recipientType) {
+          case "addr_to":
+          case "addr_cc":
+          case "addr_bcc":
+          case "addr_reply":
             try {
               let headerParser = MailServices.headerParser;
               recipient =
                 headerParser.makeFromDisplayAddress(fieldValue, {})
                             .map(fullValue => headerParser.makeMimeAddress(fullValue.name,
                                                                            fullValue.email))
                             .join(", ");
             } catch (ex) {
               recipient = fieldValue;
             }
             break;
         }
 
-        switch (recipientType)
-        {
-          case "addr_to"          : addrTo += to_Sep + recipient; to_Sep = ",";               break;
-          case "addr_cc"          : addrCc += cc_Sep + recipient; cc_Sep = ",";               break;
-          case "addr_bcc"         : addrBcc += bcc_Sep + recipient; bcc_Sep = ",";            break;
-          case "addr_reply"       : addrReply += reply_Sep + recipient; reply_Sep = ",";      break;
-          case "addr_newsgroups"  : addrNg += ng_Sep + fieldValue; ng_Sep = ",";              break;
-          case "addr_followup"    : addrFollow += follow_Sep + fieldValue; follow_Sep = ",";  break;
+        switch (recipientType) {
+          case "addr_to":
+            addrTo += to_Sep + recipient;
+            to_Sep = ",";
+            break;
+          case "addr_cc":
+            addrCc += cc_Sep + recipient;
+            cc_Sep = ",";
+            break;
+          case "addr_bcc":
+            addrBcc += bcc_Sep + recipient;
+            bcc_Sep = ",";
+            break;
+          case "addr_reply":
+            addrReply += reply_Sep + recipient;
+            reply_Sep = ",";
+            break;
+          case "addr_newsgroups":
+            addrNg += ng_Sep + fieldValue;
+            ng_Sep = ",";
+            break;
+          case "addr_followup":
+            addrFollow += follow_Sep + fieldValue;
+            follow_Sep = ",";
+            break;
           case "addr_other":
             let headerName = awGetPopupElement(i).label;
-            headerName = headerName.substring(0, headerName.indexOf(':'));
+            headerName = headerName.substring(0, headerName.indexOf(":"));
             msgCompFields.setRawHeader(headerName, fieldValue, null);
             break;
         }
       }
-      i ++;
+      i++;
     }
 
     msgCompFields.to = addrTo;
     msgCompFields.cc = addrCc;
     msgCompFields.bcc = addrBcc;
     msgCompFields.replyTo = addrReply;
     msgCompFields.newsgroups = addrNg;
     msgCompFields.followupTo = addrFollow;
 }
 
-function CompFields2Recipients(msgCompFields)
-{
+function CompFields2Recipients(msgCompFields) {
   if (msgCompFields) {
     let listbox = document.getElementById("addressingWidget");
     let newListBoxNode = listbox.cloneNode(false);
     let listBoxColsClone = listbox.firstChild.cloneNode(true);
     newListBoxNode.appendChild(listBoxColsClone);
     let templateNode = listbox.getElementsByTagName("richlistitem")[0];
     // dump("replacing child in comp fields 2 recips \n");
     listbox.parentNode.replaceChild(newListBoxNode, listbox);
@@ -202,53 +202,49 @@ function CompFields2Recipients(msgCompFi
     let msgCC = msgCompFields.cc;
     let msgBCC = msgCompFields.bcc;
     let msgNewsgroups = msgCompFields.newsgroups;
     let msgFollowupTo = msgCompFields.followupTo;
     let havePrimaryRecipient = false;
     if (msgReplyTo)
       awSetInputAndPopupFromArray(msgCompFields.splitRecipients(msgReplyTo, false, {}),
                                   "addr_reply", newListBoxNode, templateNode);
-    if (msgTo)
-    {
+    if (msgTo) {
       let rcp = msgCompFields.splitRecipients(msgTo, false, {});
-      if (rcp.length)
-      {
+      if (rcp.length) {
         awSetInputAndPopupFromArray(rcp, "addr_to", newListBoxNode, templateNode);
         havePrimaryRecipient = true;
       }
     }
     if (msgCC)
       awSetInputAndPopupFromArray(msgCompFields.splitRecipients(msgCC, false, {}),
                                   "addr_cc", newListBoxNode, templateNode);
     if (msgBCC)
       awSetInputAndPopupFromArray(msgCompFields.splitRecipients(msgBCC, false, {}),
                                   "addr_bcc", newListBoxNode, templateNode);
-    if (msgNewsgroups)
-    {
+    if (msgNewsgroups) {
       awSetInputAndPopup(msgNewsgroups, "addr_newsgroups", newListBoxNode, templateNode);
       havePrimaryRecipient = true;
     }
     if (msgFollowupTo)
       awSetInputAndPopup(msgFollowupTo, "addr_followup", newListBoxNode, templateNode);
 
     // If it's a new message, we need to add an extra empty recipient.
     if (!havePrimaryRecipient)
       _awSetInputAndPopup("", "addr_to", newListBoxNode, templateNode);
     awFitDummyRows(2);
 
     // CompFields2Recipients is called whenever a user replies or edits an existing message. We want to
     // add all of the non-empty recipients for this message to the ignore list for spell check
     let currentAddress = gCurrentIdentity ? gCurrentIdentity.fullAddress : "";
-    addRecipientsToIgnoreList([currentAddress,msgTo,msgCC,msgBCC].filter(adr => adr).join(", "));
+    addRecipientsToIgnoreList([currentAddress, msgTo, msgCC, msgBCC].filter(adr => adr).join(", "));
   }
 }
 
-function awSetInputAndPopupId(inputElem, popupElem, rowNumber)
-{
+function awSetInputAndPopupId(inputElem, popupElem, rowNumber) {
   popupElem.id = "addressCol1#" + rowNumber;
   inputElem.id = "addressCol2#" + rowNumber;
   inputElem.setAttribute("aria-labelledby", popupElem.id);
 }
 
 /**
  * Set value of the recipient input field at row rowNumber and set up
  * the recipient type menulist.
@@ -257,143 +253,125 @@ function awSetInputAndPopupId(inputElem,
  * @param inputValue                recipient value (address)
  * @param popupElem                 recipient type menulist element
  * @param popupValue
  * @param aNotifyRecipientsChanged  Notify that the recipients have changed.
  *                                  Generally we notify unless recipients are
  *                                  added in batch when the caller takes care
  *                                  of the notification.
  */
-function awSetInputAndPopupValue(inputElem, inputValue, popupElem, popupValue, rowNumber, aNotifyRecipientsChanged = true)
-{
+function awSetInputAndPopupValue(inputElem, inputValue, popupElem, popupValue, rowNumber, aNotifyRecipientsChanged = true) {
   inputElem.value = inputValue.trimLeft();
 
   popupElem.selectedItem = popupElem.childNodes[0].childNodes[awGetSelectItemIndex(popupValue)];
   // TODO: can there be a row without ID yet?
   if (rowNumber >= 0)
     awSetInputAndPopupId(inputElem, popupElem, rowNumber);
 
   _awSetAutoComplete(popupElem, inputElem);
 
   if (aNotifyRecipientsChanged)
     onRecipientsChanged(true);
 }
 
-function _awSetInputAndPopup(inputValue, popupValue, parentNode, templateNode)
-{
+function _awSetInputAndPopup(inputValue, popupValue, parentNode, templateNode) {
     top.MAX_RECIPIENTS++;
 
     var newNode = templateNode.cloneNode(true);
     parentNode.appendChild(newNode); // we need to insert the new node before we set the value of the select element!
 
     var input = newNode.getElementsByTagName(awInputElementName());
     var select = newNode.getElementsByTagName(awSelectElementName());
 
     if (input && input.length == 1 && select && select.length == 1)
-      awSetInputAndPopupValue(input[0], inputValue, select[0], popupValue, top.MAX_RECIPIENTS)
+      awSetInputAndPopupValue(input[0], inputValue, select[0], popupValue, top.MAX_RECIPIENTS);
 }
 
-function awSetInputAndPopup(inputValue, popupValue, parentNode, templateNode)
-{
-  if ( inputValue && popupValue )
-  {
+function awSetInputAndPopup(inputValue, popupValue, parentNode, templateNode) {
+  if (inputValue && popupValue) {
     var addressArray = inputValue.split(",");
 
-    for ( var index = 0; index < addressArray.length; index++ )
-        _awSetInputAndPopup(addressArray[index], popupValue, parentNode, templateNode);
+    for (var index = 0; index < addressArray.length; index++)
+      _awSetInputAndPopup(addressArray[index], popupValue, parentNode, templateNode);
   }
 }
 
-function awSetInputAndPopupFromArray(inputArray, popupValue, parentNode, templateNode)
-{
-  if (popupValue)
-  {
+function awSetInputAndPopupFromArray(inputArray, popupValue, parentNode, templateNode) {
+  if (popupValue) {
     for (let recipient of inputArray)
       _awSetInputAndPopup(recipient, popupValue, parentNode, templateNode);
   }
 }
 
-function awRemoveRecipients(msgCompFields, recipientType, recipientsList)
-{
+function awRemoveRecipients(msgCompFields, recipientType, recipientsList) {
   if (!msgCompFields || !recipientsList)
     return;
 
   var recipientArray = msgCompFields.splitRecipients(recipientsList, false, {});
 
   for (var index = 0; index < recipientArray.length; index++)
-    for (var row = 1; row <= top.MAX_RECIPIENTS; row ++)
-    {
+    for (var row = 1; row <= top.MAX_RECIPIENTS; row++) {
       var popup = awGetPopupElement(row);
-      if (popup.value == recipientType)
-      {
+      if (popup.value == recipientType) {
         var input = awGetInputElement(row);
-        if (input.value == recipientArray[index])
-        {
+        if (input.value == recipientArray[index]) {
           awSetInputAndPopupValue(input, "", popup, "addr_to", -1);
           break;
         }
       }
     }
 }
 
 /**
  * Adds a batch of new rows matching recipientType and drops in the list of addresses.
  *
  * @param msgCompFields  A nsIMsgCompFields object that is only used as a helper,
  *                       it will not get the addresses appended.
  * @param recipientType  Type of recipient, e.g. "addr_to".
  * @param recipientList  A string of addresses to add.
  */
-function awAddRecipients(msgCompFields, recipientType, recipientsList)
-{
+function awAddRecipients(msgCompFields, recipientType, recipientsList) {
   if (!msgCompFields || !recipientsList)
     return;
 
   var recipientArray = msgCompFields.splitRecipients(recipientsList, false, {});
   awAddRecipientsArray(recipientType, recipientArray);
 }
 
 /**
  * Adds a batch of new rows matching recipientType and drops in the array of addresses.
  *
  * @param aRecipientType  Type of recipient, e.g. "addr_to".
  * @param aAddressArray   An array of recipient addresses (strings) to add.
  */
-function awAddRecipientsArray(aRecipientType, aAddressArray)
-{
+function awAddRecipientsArray(aRecipientType, aAddressArray) {
   // Find rows that are empty so that we can fill them.
   let emptyRows = [];
-  for (let row = 1; row <= top.MAX_RECIPIENTS; row ++)
-  {
+  for (let row = 1; row <= top.MAX_RECIPIENTS; row++) {
     if (awGetInputElement(row).value == "")
       emptyRows.push(row);
   }
 
   // Push the new recipients into the found empty rows or append new rows when needed.
   let row = 1;
-  for (let address of aAddressArray)
-  {
-    if (emptyRows.length > 0)
-    {
+  for (let address of aAddressArray) {
+    if (emptyRows.length > 0) {
       row = emptyRows.shift();
-    }
-    else
-    {
+    } else {
       awAppendNewRow(false);
       row = top.MAX_RECIPIENTS;
     }
 
     awSetInputAndPopupValue(awGetInputElement(row), address,
                             awGetPopupElement(row), aRecipientType,
                             row, false);
   }
 
   // Be sure we still have an empty row left.
-  if ((emptyRows.length == 0) && (awGetInputElement(top.MAX_RECIPIENTS).value != ""))
-  {
+  if ((emptyRows.length == 0) && (awGetInputElement(top.MAX_RECIPIENTS).value != "")) {
     // Insert empty row at the end and focus.
     awAppendNewRow(true);
     awSetInputAndPopupValue(awGetInputElement(top.MAX_RECIPIENTS), "",
                             awGetPopupElement(top.MAX_RECIPIENTS), "addr_to",
                             top.MAX_RECIPIENTS, false);
   } else {
     // Focus the next empty row, if any, or the pre-existing empty last row.
     row = (emptyRows.length > 0) ? emptyRows.shift() : top.MAX_RECIPIENTS;
@@ -409,190 +387,169 @@ function awAddRecipientsArray(aRecipient
 /**
  * Adds a new row matching recipientType and drops in the single address.
  *
  * This is mostly used by addons, even though they should use AddRecipient().
  *
  * @param aRecipientType  Type of recipient, e.g. addr_to.
  * @param aAddress        A string with recipient address.
  */
-function awAddRecipient(aRecipientType, aAddress)
-{
+function awAddRecipient(aRecipientType, aAddress) {
   awAddRecipientsArray(aRecipientType, [aAddress]);
 }
 
-function awTestRowSequence()
-{
+function awTestRowSequence() {
   /*
     This function is for debug and testing purpose only, normal user should not run it!
 
     Every time we insert or delete a row, we must be sure we didn't break the ID sequence of
     the addressing widget rows. This function will run a quick test to see if the sequence still ok
 
     You need to define the pref mail.debug.test_addresses_sequence to true in order to activate it
   */
 
   if (!test_addresses_sequence)
     return true;
 
   /* debug code to verify the sequence still good */
 
   let listbox = document.getElementById("addressingWidget");
   let listitems = listbox.getElementsByTagName("richlistitem");
-  if (listitems.length >= top.MAX_RECIPIENTS )
-  {
-    for (let i = 1; i <= listitems.length; i ++)
-    {
-      let item = listitems [i - 1];
+  if (listitems.length >= top.MAX_RECIPIENTS) {
+    for (let i = 1; i <= listitems.length; i++) {
+      let item = listitems[i - 1];
       let inputID = item.querySelector(awInputElementName()).id.split("#")[1];
       let popupID = item.querySelector(awSelectElementName()).id.split("#")[1];
-      if (inputID != i || popupID != i)
-      {
+      if (inputID != i || popupID != i) {
         dump("#ERROR: sequence broken at row " + i + ", inputID=" + inputID + ", popupID=" + popupID + "\n");
         return false;
       }
       dump("---SEQUENCE OK---\n");
       return true;
     }
+  } else {
+    dump("#ERROR: listitems.length(" + listitems.length + ") < top.MAX_RECIPIENTS(" + top.MAX_RECIPIENTS + ")\n");
   }
-  else
-    dump("#ERROR: listitems.length(" + listitems.length + ") < top.MAX_RECIPIENTS(" + top.MAX_RECIPIENTS + ")\n");
 
   return false;
 }
 
-function awCleanupRows()
-{
+function awCleanupRows() {
   var maxRecipients = top.MAX_RECIPIENTS;
   var rowID = 1;
 
-  for (var row = 1; row <= maxRecipients; row ++)
-  {
+  for (var row = 1; row <= maxRecipients; row++) {
     var inputElem = awGetInputElement(row);
-    if (inputElem.value == "" && row < maxRecipients)
+    if (inputElem.value == "" && row < maxRecipients) {
       awRemoveRow(awGetRowByInputElement(inputElem));
-    else
-    {
+    } else {
       awSetInputAndPopupId(inputElem, awGetPopupElement(row), rowID);
-      rowID ++;
+      rowID++;
     }
   }
 
   awTestRowSequence();
 }
 
-function awDeleteRow(rowToDelete)
-{
+function awDeleteRow(rowToDelete) {
   // When we delete a row, we must reset the id of other rows in order to not break the sequence.
   var maxRecipients = top.MAX_RECIPIENTS;
   awRemoveRow(rowToDelete);
 
   // assume 2 column update (input and popup)
-  for (var row = rowToDelete + 1; row <= maxRecipients; row ++)
-    awSetInputAndPopupId(awGetInputElement(row), awGetPopupElement(row), (row-1));
+  for (var row = rowToDelete + 1; row <= maxRecipients; row++)
+    awSetInputAndPopupId(awGetInputElement(row), awGetPopupElement(row), (row - 1));
 
   awTestRowSequence();
 }
 
-function awClickEmptySpace(target, setFocus)
-{
+function awClickEmptySpace(target, setFocus) {
   if (document.getElementById("addressCol2#1").disabled ||
       target == null ||
       target.localName != "hbox")
     return;
 
   var lastInput = awGetInputElement(top.MAX_RECIPIENTS);
 
-  if ( lastInput && lastInput.value )
+  if (lastInput && lastInput.value)
     awAppendNewRow(setFocus);
-  else
-    if (setFocus)
-      awSetFocus(top.MAX_RECIPIENTS, lastInput);
+  else if (setFocus)
+    awSetFocus(top.MAX_RECIPIENTS, lastInput);
 }
 
-function awReturnHit(inputElement)
-{
+function awReturnHit(inputElement) {
   var row = awGetRowByInputElement(inputElement);
-  var nextInput = awGetInputElement(row+1);
+  var nextInput = awGetInputElement(row + 1);
 
-  if ( !nextInput )
-  {
-    if ( inputElement.value )
+  if (!nextInput) {
+    if (inputElement.value) {
       awAppendNewRow(true);
-    else // No address entered, switch to Subject field
-    {
-      var subjectField = document.getElementById( 'msgSubject' );
+    } else {
+      // No address entered, switch to Subject field
+      var subjectField = document.getElementById("msgSubject");
       subjectField.select();
       subjectField.focus();
     }
-  }
-  else
-  {
+  } else {
     nextInput.select();
-    awSetFocus(row+1, nextInput);
+    awSetFocus(row + 1, nextInput);
   }
 
   // be sure to add the user add recipient to our ignore list
   // when the user hits enter in an autocomplete widget...
   addRecipientsToIgnoreList(inputElement.value);
 }
 
-function awDeleteHit(inputElement)
-{
+function awDeleteHit(inputElement) {
   var row = awGetRowByInputElement(inputElement);
 
   /* 1. don't delete the row if it's the last one remaining, just reset it! */
-  if (top.MAX_RECIPIENTS <= 1)
-  {
+  if (top.MAX_RECIPIENTS <= 1) {
     inputElement.value = "";
     return;
   }
 
   /* 2. Set the focus to the previous field if possible */
   if (row > 1)
-    awSetFocus(row - 1, awGetInputElement(row - 1))
+    awSetFocus(row - 1, awGetInputElement(row - 1));
   else
-    awSetFocus(1, awGetInputElement(2))   /* We have to cheat a little bit because the focus will */
+    awSetFocus(1, awGetInputElement(2));  /* We have to cheat a little bit because the focus will */
                                           /* be set asynchronusly after we delete the current row, */
                                           /* therefore the row number still the same! */
 
   /* 3. Delete the row */
   awDeleteRow(row);
 }
 
-function awInputChanged(inputElement)
-{
-  //Do we need to add a new row?
+function awInputChanged(inputElement) {
+  // Do we need to add a new row?
   var lastInput = awGetInputElement(top.MAX_RECIPIENTS);
-  if ( lastInput && lastInput.value && !top.doNotCreateANewRow)
+  if (lastInput && lastInput.value && !top.doNotCreateANewRow)
     awAppendNewRow(false);
   top.doNotCreateANewRow = false;
 }
 
-function awAppendNewRow(setFocus)
-{
-  var listbox = document.getElementById('addressingWidget');
+function awAppendNewRow(setFocus) {
+  var listbox = document.getElementById("addressingWidget");
   var listitem1 = awGetListItem(1);
 
-  if ( listbox && listitem1 )
-  {
+  if (listbox && listitem1) {
     var lastRecipientType = awGetPopupElement(top.MAX_RECIPIENTS).value;
 
     var nextDummy = awGetNextDummyRow();
     var newNode = listitem1.cloneNode(true);
     if (nextDummy)
       listbox.replaceChild(newNode, nextDummy);
     else
       listbox.appendChild(newNode);
 
     top.MAX_RECIPIENTS++;
 
     var input = newNode.getElementsByTagName(awInputElementName());
-    if ( input && input.length == 1 )
-    {
+    if (input && input.length == 1) {
       input[0].value = "";
 
       // We always clone the first row.  The problem is that the first row
       // could be focused.  When we clone that row, we end up with a cloned
       // XUL textbox that has a focused attribute set.  Therefore we think
       // we're focused and don't properly refocus.  The best solution to this
       // would be to clone a template row that didn't really have any presentation,
       // rather than using the real visible first row of the listbox.
@@ -601,28 +558,26 @@ function awAppendNewRow(setFocus)
       // is never copied when the node is cloned.
       input[0].removeAttribute("focused");
 
       // Reset autocomplete attribute "nomatch" so we don't cause red addresses
       // on a cloned row.
       input[0].removeAttribute("nomatch");
     }
     var select = newNode.getElementsByTagName(awSelectElementName());
-    if ( select && select.length == 1 )
-    {
+    if (select && select.length == 1) {
       // It only makes sense to clone some field types; others
       // should not be cloned, since it just makes the user have
       // to go to the trouble of selecting something else. In such
       // cases let's default to 'To' (a reasonable default since
       // we already default to 'To' on the first dummy field of
       // a new message).
-      switch (lastRecipientType)
-      {
-        case  "addr_reply":
-        case  "addr_other":
+      switch (lastRecipientType) {
+        case "addr_reply":
+        case "addr_other":
           select[0].selectedIndex = awGetSelectItemIndex("addr_to");
           break;
         case "addr_followup":
           select[0].selectedIndex = awGetSelectItemIndex("addr_newsgroups");
           break;
         default:
         // e.g. "addr_to","addr_cc","addr_bcc","addr_newsgroups":
           select[0].selectedIndex = awGetSelectItemIndex(lastRecipientType);
@@ -630,332 +585,299 @@ function awAppendNewRow(setFocus)
 
       awSetInputAndPopupId(input[0], select[0], top.MAX_RECIPIENTS);
 
       if (input)
         _awSetAutoComplete(select[0], input[0]);
     }
 
     // focus on new input widget
-    if (setFocus && input[0] )
+    if (setFocus && input[0])
       awSetFocus(top.MAX_RECIPIENTS, input[0]);
   }
 }
 
 // functions for accessing the elements in the addressing widget
 
 /**
  * Returns the recipient type popup for a row.
  *
  * @param row  Index of the recipient row to return. Starts at 1.
  * @return     This returns the menulist (not its child menupopup), despite the function name.
  */
-function awGetPopupElement(row)
-{
+function awGetPopupElement(row) {
 
     return document.getElementById("addressCol1#" + row);
 }
 
 /**
  * Returns the recipient inputbox for a row.
  *
  * @param row  Index of the recipient row to return. Starts at 1.
  * @return     This returns the textbox element.
  */
-function awGetInputElement(row)
-{
+function awGetInputElement(row) {
     return document.getElementById("addressCol2#" + row);
 }
 
-function awGetElementByCol(row, col)
-{
+function awGetElementByCol(row, col) {
   var colID = "addressCol" + col + "#" + row;
   return document.getElementById(colID);
 }
 
-function awGetListItem(row)
-{
+function awGetListItem(row) {
   var listbox = document.getElementById("addressingWidget");
 
-  if ( listbox && row > 0)
-  {
+  if (listbox && row > 0) {
     var listitems = listbox.getElementsByTagName("richlistitem");
-    if ( listitems && listitems.length >= row )
-      return listitems[row-1];
+    if (listitems && listitems.length >= row)
+      return listitems[row - 1];
   }
   return 0;
 }
 
-function awGetRowByInputElement(inputElement)
-{
+function awGetRowByInputElement(inputElement) {
   var row = 0;
   if (inputElement) {
     var listitem = inputElement.parentNode.parentNode;
     while (listitem) {
       if (listitem.localName == "richlistitem") {
         ++row;
       }
       listitem = listitem.previousSibling;
     }
   }
   return row;
 }
 
-
 // Copy Node - copy this node and insert ahead of the (before) node.  Append to end if before=0
-function awCopyNode(node, parentNode, beforeNode)
-{
+function awCopyNode(node, parentNode, beforeNode) {
   var newNode = node.cloneNode(true);
 
-  if ( beforeNode )
+  if (beforeNode)
     parentNode.insertBefore(newNode, beforeNode);
   else
     parentNode.appendChild(newNode);
 
-    return newNode;
+  return newNode;
 }
 
-// remove row
-
-function awRemoveRow(row)
-{
+function awRemoveRow(row) {
   awGetListItem(row).remove();
   awFitDummyRows();
 
-  top.MAX_RECIPIENTS --;
+  top.MAX_RECIPIENTS--;
 }
 
-
-function awSetFocus(row, inputElement)
-{
+function awSetFocus(row, inputElement) {
   top.awRow = row;
   top.awInputElement = inputElement;
   setTimeout(_awSetFocus, 0);
 }
 
-function _awSetFocus()
-{
-  var listbox = document.getElementById('addressingWidget');
+function _awSetFocus() {
+  var listbox = document.getElementById("addressingWidget");
   var theNewRow = awGetListItem(top.awRow);
   listbox.ensureElementIsVisible(theNewRow);
   top.awInputElement.focus();
 }
 
-function awTabFromRecipient(element, event)
-{
+function awTabFromRecipient(element, event) {
   // If we are the last element in the listbox, we don't want to create a new row.
   if (element == awGetInputElement(top.MAX_RECIPIENTS))
     top.doNotCreateANewRow = true;
 
   var row = awGetRowByInputElement(element);
   if (!event.shiftKey && row < top.MAX_RECIPIENTS) {
     var listBoxRow = row - 1; // listbox row indices are 0-based, ours are 1-based.
     var listBox = document.getElementById("addressingWidget");
     listBox.listBoxObject.ensureIndexIsVisible(listBoxRow + 1);
   }
 
   // be sure to add the user add recipient to our ignore list
   // when the user tabs out of an autocomplete line...
   addRecipientsToIgnoreList(element.value);
 }
 
-function awTabFromMenulist(element, event)
-{
+function awTabFromMenulist(element, event) {
   var row = awGetRowByInputElement(element);
   if (event.shiftKey && row > 1) {
     var listBoxRow = row - 1; // listbox row indices are 0-based, ours are 1-based.
     var listBox = document.getElementById("addressingWidget");
     listBox.listBoxObject.ensureIndexIsVisible(listBoxRow - 1);
   }
 }
 
-function awGetNumberOfRecipients()
-{
-    return top.MAX_RECIPIENTS;
+function awGetNumberOfRecipients() {
+  return top.MAX_RECIPIENTS;
 }
 
-function DragOverAddressingWidget(event)
-{
+function DragOverAddressingWidget(event) {
   var validFlavor = false;
   var dragSession = dragSession = gDragService.getCurrentSession();
 
   if (dragSession.isDataFlavorSupported("text/x-moz-address"))
     validFlavor = true;
 
   if (validFlavor)
     dragSession.canDrop = true;
 }
 
-function DropOnAddressingWidget(event)
-{
+function DropOnAddressingWidget(event) {
   var dragSession = gDragService.getCurrentSession();
 
   var trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
   trans.init(getLoadContext());
   trans.addDataFlavor("text/x-moz-address");
 
-  for ( var i = 0; i < dragSession.numDropItems; ++i )
-  {
-    dragSession.getData ( trans, i );
-    var dataObj = new Object();
-    var bestFlavor = new Object();
-    var len = new Object();
-    trans.getAnyTransferData ( bestFlavor, dataObj, len );
-    if ( dataObj )
+  for (var i = 0; i < dragSession.numDropItems; ++i) {
+    dragSession.getData(trans, i);
+    var dataObj = {};
+    var bestFlavor = {};
+    var len = {};
+    trans.getAnyTransferData(bestFlavor, dataObj, len);
+    if (dataObj)
       dataObj = dataObj.value.QueryInterface(Ci.nsISupportsString);
-    if ( !dataObj )
+    if (!dataObj)
       continue;
 
     // pull the address out of the data object
     var address = dataObj.data.substring(0, len.value);
     if (!address)
       continue;
 
     DropRecipient(event.target, address);
   }
 }
 
-function DropRecipient(target, recipient)
-{
+function DropRecipient(target, recipient) {
   // break down and add each address
   return parseAndAddAddresses(recipient, awGetPopupElement(top.MAX_RECIPIENTS).value);
 }
 
-function _awSetAutoComplete(selectElem, inputElem)
-{
-  let params = JSON.parse(inputElem.getAttribute('autocompletesearchparam'));
+function _awSetAutoComplete(selectElem, inputElem) {
+  let params = JSON.parse(inputElem.getAttribute("autocompletesearchparam"));
   params.type = selectElem.value;
-  inputElem.setAttribute('autocompletesearchparam', JSON.stringify(params));
+  inputElem.setAttribute("autocompletesearchparam", JSON.stringify(params));
 }
 
-function awSetAutoComplete(rowNumber)
-{
-    var inputElem = awGetInputElement(rowNumber);
-    var selectElem = awGetPopupElement(rowNumber);
-    _awSetAutoComplete(selectElem, inputElem)
+function awSetAutoComplete(rowNumber) {
+  var inputElem = awGetInputElement(rowNumber);
+  var selectElem = awGetPopupElement(rowNumber);
+  _awSetAutoComplete(selectElem, inputElem);
 }
 
-function awRecipientTextCommand(enterEvent, element)
-{
+function awRecipientTextCommand(enterEvent, element) {
   // Only add new row when enter was hit (not for tab/autocomplete select).
   if (enterEvent)
     awReturnHit(element);
 }
 
-function awRecipientKeyPress(event, element)
-{
-  switch(event.keyCode) {
+function awRecipientKeyPress(event, element) {
+  switch (event.keyCode) {
   case KeyEvent.DOM_VK_RETURN:
   case KeyEvent.DOM_VK_TAB:
     // if the user text contains a comma or a line return, ignore
-    if (element.value.includes(','))
-    {
+    if (element.value.includes(",")) {
       var addresses = element.value;
       element.value = ""; // clear out the current line so we don't try to autocomplete it..
       parseAndAddAddresses(addresses, awGetPopupElement(awGetRowByInputElement(element)).value);
+    } else if (event.keyCode == KeyEvent.DOM_VK_TAB) {
+      awTabFromRecipient(element, event);
     }
-    else if (event.keyCode == KeyEvent.DOM_VK_TAB)
-      awTabFromRecipient(element, event);
 
     break;
   }
 }
 
-function awRecipientKeyDown(event, element)
-{
-  switch(event.keyCode) {
+function awRecipientKeyDown(event, element) {
+  switch (event.keyCode) {
   case KeyEvent.DOM_VK_DELETE:
   case KeyEvent.DOM_VK_BACK_SPACE:
     if (!element.value)
       awDeleteHit(element);
 
     // We need to stop the event else the listbox will receive it and the
     // function awKeyDown will be executed!
     event.stopPropagation();
     break;
   }
 }
 
-function awKeyDown(event, listboxElement)
-{
-  switch(event.keyCode) {
+function awKeyDown(event, listboxElement) {
+  switch (event.keyCode) {
   case KeyEvent.DOM_VK_DELETE:
   case KeyEvent.DOM_VK_BACK_SPACE:
     /* Warning, the listboxElement.selectedItems will change every time we delete a row */
     var length = listboxElement.selectedCount;
     for (var i = 1; i <= length; i++) {
       var inputs = listboxElement.selectedItem.getElementsByTagName(awInputElementName());
       if (inputs && inputs.length == 1)
         awDeleteHit(inputs[0]);
     }
     break;
   }
 }
 
-function awMenulistKeyPress(event, element)
-{
-  switch(event.keyCode) {
+function awMenulistKeyPress(event, element) {
+  switch (event.keyCode) {
   case KeyEvent.DOM_VK_TAB:
     awTabFromMenulist(element, event);
     break;
   }
 }
 
 /* ::::::::::: addressing widget dummy rows ::::::::::::::::: */
 
 var gAWContentHeight = 0;
 var gAWRowHeight = 0;
 
-function awFitDummyRows()
-{
+function awFitDummyRows() {
   awCalcContentHeight();
   awCreateOrRemoveDummyRows();
 }
 
-function awCreateOrRemoveDummyRows()
-{
+function awCreateOrRemoveDummyRows() {
   let listbox = document.getElementById("addressingWidget");
   let listboxHeight = listbox.boxObject.height;
 
   // remove rows to remove scrollbar
-  let kids = listbox.querySelectorAll('[_isDummyRow]');
+  let kids = listbox.querySelectorAll("[_isDummyRow]");
   for (let i = kids.length - 1; gAWContentHeight > listboxHeight && i >= 0; --i) {
     gAWContentHeight -= gAWRowHeight;
     kids[i].remove();
   }
 
   // add rows to fill space
   if (gAWRowHeight) {
     while (gAWContentHeight + gAWRowHeight < listboxHeight) {
       awCreateDummyItem(listbox);
       gAWContentHeight += gAWRowHeight;
     }
   }
 }
 
-function awCalcContentHeight()
-{
+function awCalcContentHeight() {
   var listbox = document.getElementById("addressingWidget");
   var items = listbox.getElementsByTagName("richlistitem");
 
   gAWContentHeight = 0;
   if (items.length > 0) {
     // all rows are forced to a uniform height in xul listboxes, so
     // find the first listitem with a boxObject and use it as precedent
     var i = 0;
     do {
       gAWRowHeight = items[i].boxObject.height;
       ++i;
     } while (i < items.length && !gAWRowHeight);
-    gAWContentHeight = gAWRowHeight*items.length;
+    gAWContentHeight = gAWRowHeight * items.length;
   }
 }
 
-function awCreateDummyItem(aParent)
-{
+function awCreateDummyItem(aParent) {
   var listbox = document.getElementById("addressingWidget");
   var item = listbox.getElementsByTagName("richlistitem")[0];
 
   var titem = document.createElement("richlistitem");
   titem.setAttribute("_isDummyRow", "true");
   titem.setAttribute("class", "dummy-row");
   titem.style.height = item.boxObject.height + "px";
 
@@ -971,86 +893,77 @@ function awCreateDummyItem(aParent)
 
   if (aParent) {
     aParent.appendChild(titem);
   }
 
   return titem;
 }
 
-function awCreateDummyCell(aParent)
-{
+function awCreateDummyCell(aParent) {
   var cell = document.createElement("hbox");
   cell.setAttribute("class", "addressingWidgetCell dummy-row-cell");
   if (aParent)
     aParent.appendChild(cell);
 
   return cell;
 }
 
-function awGetNextDummyRow()
-{
+function awGetNextDummyRow() {
   // gets the next row from the top down
-  return document.querySelector('#addressingWidget > [_isDummyRow]');
+  return document.querySelector("#addressingWidget > [_isDummyRow]");
 }
 
-function awSizerListen()
-{
+function awSizerListen() {
   // when splitter is clicked, fill in necessary dummy rows each time the mouse is moved
   awCalcContentHeight(); // precalculate
   document.addEventListener("mousemove", awSizerMouseMove, true);
   document.addEventListener("mouseup", awSizerMouseUp, {capture: false, once: true});
 }
 
-function awSizerMouseMove()
-{
+function awSizerMouseMove() {
   awCreateOrRemoveDummyRows(2);
 }
 
-function awSizerMouseUp()
-{
+function awSizerMouseUp() {
   document.removeEventListener("mousemove", awSizerMouseMove, true);
 }
 
-function awDocumentKeyPress(event)
-{
+function awDocumentKeyPress(event) {
   try {
     var id = event.target.id;
-    if (id.startsWith('addressCol1'))
+    if (id.startsWith("addressCol1"))
       awMenulistKeyPress(event, event.target);
   } catch (e) { }
 }
 
 // Given an arbitrary block of text like a comma delimited list of names or a names separated by spaces,
 // we will try to autocomplete each of the names and then take the FIRST match for each name, adding it the
 // addressing widget on the compose window.
 
 var gAutomatedAutoCompleteListener = null;
 
-function parseAndAddAddresses(addressText, recipientType)
-{
+function parseAndAddAddresses(addressText, recipientType) {
   // strip any leading >> characters inserted by the autocomplete widget
   var strippedAddresses = addressText.replace(/.* >> /, "");
 
   let addresses = MailServices.headerParser
                               .makeFromDisplayAddress(strippedAddresses);
 
-  if (addresses.length > 0)
-  {
+  if (addresses.length > 0) {
     // we need to set up our own autocomplete session and search for results
     if (!gAutomatedAutoCompleteListener)
       gAutomatedAutoCompleteListener = new AutomatedAutoCompleteHandler();
 
     gAutomatedAutoCompleteListener.init(addresses.map(addr => addr.toString()),
                                         recipientType);
   }
 }
 
-function AutomatedAutoCompleteHandler()
-{
+function AutomatedAutoCompleteHandler() {
 }
 
 // state driven self contained object which will autocomplete a block of addresses without any UI.
 // force picks the first match and adds it to the addressing widget, then goes on to the next
 // name to complete.
 
 AutomatedAutoCompleteHandler.prototype =
 {
@@ -1061,39 +974,35 @@ AutomatedAutoCompleteHandler.prototype =
   indexIntoNames: 0,
   finalAddresses: null,
 
   numSessionsToSearch: 0,
   numSessionsSearched: 0,
   recipientType: null,
   searchResults: null,
 
-  init:function(namesToComplete, recipientType)
-  {
+  init(namesToComplete, recipientType) {
     this.indexIntoNames = 0;
     this.numNamesToComplete = namesToComplete.length;
     this.namesToComplete = namesToComplete;
     this.finalAddresses = [];
 
     this.recipientType = recipientType ? recipientType : "addr_to";
 
     // set up the auto complete sessions to use
     this.autoCompleteNextAddress();
   },
 
-  autoCompleteNextAddress:function()
-  {
+  autoCompleteNextAddress() {
     this.numSessionsToSearch = 0;
     this.numSessionsSearched = 0;
     this.searchResults = [];
 
-    if (this.indexIntoNames < this.numNamesToComplete)
-    {
-      if (this.namesToComplete[this.indexIntoNames])
-      {
+    if (this.indexIntoNames < this.numNamesToComplete) {
+      if (this.namesToComplete[this.indexIntoNames]) {
       /* XXX This is used to work, until switching to the new toolkit broke it
          We should fix it see bug 456550.
       if (!this.namesToComplete[this.indexIntoNames].includes('@')) // don't autocomplete if address has an @ sign in it
       {
         // make sure total session count is updated before we kick off ANY actual searches
         if (gAutocompleteSession)
           this.numSessionsToSearch++;
 
@@ -1118,70 +1027,59 @@ AutomatedAutoCompleteHandler.prototype =
         if (gLDAPSession && gCurrentAutocompleteDirectory)
           gLDAPSession.onStartLookup(this.namesToComplete[this.indexIntoNames], null, this);
       }
       */
 
         if (!this.numSessionsToSearch)
           this.processAllResults(); // ldap and ab are turned off, so leave text alone.
       }
-    }
-    else
-    {
+    } else {
       this.finish();
     }
   },
 
-  onStatus:function(aStatus)
-  {
-    return;
+  onStatus(aStatus) {
   },
 
-  onAutoComplete: function(aResults, aStatus)
-  {
+  onAutoComplete(aResults, aStatus) {
     // store the results until all sessions are done and have reported in
     if (aResults)
       this.searchResults[this.numSessionsSearched] = aResults;
 
     this.numSessionsSearched++; // bump our counter
 
     if (this.numSessionsToSearch <= this.numSessionsSearched)
       setTimeout(gAutomatedAutoCompleteListener.processAllResults, 0); // we are all done
   },
 
-  processAllResults: function()
-  {
+  processAllResults() {
     // Take the first result and add it to the compose window
     var addressToAdd;
 
     // loop through the results looking for the non default case (default case is the address book with only one match, the default domain)
     var sessionIndex;
 
     var searchResultsForSession;
 
-    for (sessionIndex in this.searchResults)
-    {
+    for (sessionIndex in this.searchResults) {
       searchResultsForSession = this.searchResults[sessionIndex];
-      if (searchResultsForSession && searchResultsForSession.defaultItemIndex > -1)
-      {
+      if (searchResultsForSession && searchResultsForSession.defaultItemIndex > -1) {
         addressToAdd = searchResultsForSession.items
           .queryElementAt(searchResultsForSession.defaultItemIndex,
                           Ci.nsIAutoCompleteItem).value;
         break;
       }
     }
 
     // still no match? loop through looking for the -1 default index
-    if (!addressToAdd)
-    {
-      for (sessionIndex in this.searchResults)
-      {
+    if (!addressToAdd) {
+      for (sessionIndex in this.searchResults) {
         searchResultsForSession = this.searchResults[sessionIndex];
-        if (searchResultsForSession && searchResultsForSession.defaultItemIndex == -1)
-        {
+        if (searchResultsForSession && searchResultsForSession.defaultItemIndex == -1) {
           addressToAdd = searchResultsForSession.items
             .queryElementAt(0, Ci.nsIAutoCompleteItem).value;
           break;
         }
       }
     }
 
     // no matches anywhere...just use what we were given
@@ -1189,22 +1087,21 @@ AutomatedAutoCompleteHandler.prototype =
       addressToAdd = this.namesToComplete[this.indexIntoNames];
 
     this.finalAddresses.push(addressToAdd);
 
     this.indexIntoNames++;
     this.autoCompleteNextAddress();
   },
 
-  finish: function()
-  {
+  finish() {
     // This will now append all the recipients, set the focus on a new
     // available row, and make sure it is visible.
     awAddRecipientsArray(this.recipientType, this.finalAddresses);
   },
 
   QueryInterface: ChromeUtils.generateQI(["nsIAutoCompleteListener"]),
-}
+};
 
 // Returns the load context for the current window
 function getLoadContext() {
   return window.docShell.QueryInterface(Ci.nsILoadContext);
 }
--- a/mail/components/compose/content/bigFileObserver.js
+++ b/mail/components/compose/content/bigFileObserver.js
@@ -1,11 +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/. */
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* import-globals-from MsgComposeCommands.js */
 
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource:///modules/cloudFileAccounts.js");
 
 var kUploadNotificationValue = "bigAttachmentUploading";
 var kPrivacyWarningNotificationValue = "bigAttachmentPrivacyWarning";
 
 var gBigFileObserver = {
@@ -15,221 +17,216 @@ var gBigFileObserver = {
 
   get hidden() {
     return this.sessionHidden ||
            !Services.prefs.getBoolPref("mail.cloud_files.enabled") ||
            !Services.prefs.getBoolPref("mail.compose.big_attachments.notify") ||
            Services.io.offline;
   },
 
-  hide: function(aPermanent) {
+  hide(aPermanent) {
     if (aPermanent)
       Services.prefs.setBoolPref("mail.compose.big_attachments.notify", false);
     else
       this.sessionHidden = true;
   },
 
-  init: function() {
+  init() {
     let bucket = document.getElementById("attachmentBucket");
     bucket.addEventListener("attachments-added", this);
     bucket.addEventListener("attachments-removed", this);
     bucket.addEventListener("attachments-uploading", this);
     bucket.addEventListener("attachment-uploaded", this);
     bucket.addEventListener("attachment-upload-failed", this);
     bucket.addEventListener("attachments-converted", this);
 
     this.sessionHidden = false;
     this.privacyWarned = false;
     this.bigFiles = [];
   },
 
-  handleEvent: function(event) {
+  handleEvent(event) {
     if (this.hidden)
       return;
 
     const bucketCallbacks = {
       "attachments-added": this.attachmentsAdded,
       "attachments-removed": this.attachmentsRemoved,
       "attachments-converted": this.attachmentsConverted,
       "attachments-uploading": this.attachmentsUploading,
     };
 
     const itemCallbacks = {
       "attachment-uploaded": this.attachmentUploaded,
       "attachment-upload-failed": this.attachmentUploadFailed,
-    }
+    };
 
     if (event.type in bucketCallbacks)
       bucketCallbacks[event.type].call(this, event.detail);
 
     if (event.type in itemCallbacks)
       itemCallbacks[event.type].call(this, event.target,
                                      ("detail" in event) ? event.detail : null);
 
     this.updateNotification();
   },
 
-  formatString: function (key, replacements, plural) {
+  formatString(key, replacements, plural) {
     let str = getComposeBundle().getString(key);
     if (plural !== undefined)
       str = PluralForm.get(plural, str);
     if (replacements !== undefined) {
       for (let i = 0; i < replacements.length; i++)
         str = str.replace("#" + (i + 1), replacements[i]);
     }
     return str;
   },
 
-  attachmentsAdded: function(aAttachments) {
+  attachmentsAdded(aAttachments) {
     let threshold = Services.prefs.getIntPref(
                     "mail.compose.big_attachments.threshold_kb") * 1024;
 
     for (let attachment of fixIterator(
          aAttachments, Ci.nsIMsgAttachment)) {
       if (attachment.size >= threshold && !attachment.sendViaCloud)
         this.bigFiles.push(attachment);
     }
   },
 
-  attachmentsRemoved: function(aAttachments) {
+  attachmentsRemoved(aAttachments) {
     for (let attachment of fixIterator(
          aAttachments, Ci.nsIMsgAttachment)) {
       let index = this.bigFiles.indexOf(attachment);
       if (index != -1)
         this.bigFiles.splice(index, 1);
     }
   },
 
-  attachmentsConverted: function(aAttachments) {
+  attachmentsConverted(aAttachments) {
     let uploaded = [];
 
     for (let attachment of fixIterator(
          aAttachments, Ci.nsIMsgAttachment)) {
       if (attachment.sendViaCloud) {
         this.attachmentsRemoved([attachment]);
         uploaded.push(attachment);
       }
     }
 
     if (uploaded.length)
       this.showUploadingNotification(uploaded);
   },
 
-  attachmentsUploading: function(aAttachments) {
+  attachmentsUploading(aAttachments) {
     this.showUploadingNotification(aAttachments);
   },
 
-  attachmentUploaded: function(aAttachment) {
+  attachmentUploaded(aAttachment) {
     if (!this._anyUploadsInProgress()) {
       this.hideUploadingNotification();
 
       if (!this.privacyWarned) {
         this.showPrivacyNotification();
         this.privacyWarned = true;
       }
     }
   },
 
-  attachmentUploadFailed: function(aAttachment, aStatusCode) {
+  attachmentUploadFailed(aAttachment, aStatusCode) {
     if (!this._anyUploadsInProgress())
       this.hideUploadingNotification();
   },
 
-  updateNotification: function() {
+  updateNotification() {
     let nb = document.getElementById("attachmentNotificationBox");
     let notification = nb.getNotificationWithValue("bigAttachment");
-    let numAccounts = cloudFileAccounts.accounts.length;
 
     if (this.bigFiles.length) {
       if (notification) {
         notification.label = this.formatString("bigFileDescription",
                                                [this.bigFiles.length],
                                                this.bigFiles.length);
         return;
       }
 
       let buttons = [
         {
           label: getComposeBundle().getString("learnMore.label"),
           accessKey: getComposeBundle().getString("learnMore.accesskey"),
           callback: this.openLearnMore.bind(this),
-        },
-        { label: this.formatString("bigFileShare.label",
-                                   []),
+        }, {
+          label: this.formatString("bigFileShare.label", []),
           accessKey: this.formatString("bigFileShare.accesskey"),
           callback: this.convertAttachments.bind(this),
-        },
-
-        { label: this.formatString("bigFileAttach.label",
-                                   []),
+        }, {
+          label: this.formatString("bigFileAttach.label", []),
           accessKey: this.formatString("bigFileAttach.accesskey"),
           callback: this.hideNotification.bind(this),
         },
       ];
 
       let msg = this.formatString("bigFileDescription", [this.bigFiles.length],
                                   this.bigFiles.length);
 
       notification = nb.appendNotification(msg, "bigAttachment", "null",
                                            nb.PRIORITY_WARNING_MEDIUM,
                                            buttons);
-    }
-    else {
-      if (notification)
-        nb.removeNotification(notification);
+    } else if (notification) {
+      nb.removeNotification(notification);
     }
   },
 
-  openLearnMore: function() {
+  openLearnMore() {
     let url = Services.prefs.getCharPref("mail.cloud_files.learn_more_url");
     openContentTab(url);
     return true;
   },
 
-  convertAttachments: function() {
+  convertAttachments() {
     let cloudProvider;
     let accounts = cloudFileAccounts.accounts;
 
     if (accounts.length == 1) {
       cloudProvider = accounts[0];
-    }
-    else if(accounts.length > 1) {
+    } else if (accounts.length > 1) {
       let selection = {};
       let names = accounts.map(i => cloudFileAccounts.getDisplayName(i));
       if (Services.prompt.select(window,
                                  this.formatString("bigFileChooseAccount.title"),
                                  this.formatString("bigFileChooseAccount.text"),
                                  names.length, names, selection))
         cloudProvider = accounts[selection.value];
-    }
-    else {
+    } else {
       let accountKey = cloudFileAccounts.addAccountDialog();
       if (accountKey)
         cloudProvider = cloudFileAccounts.getAccount(accountKey);
       else
         return true;
     }
 
     if (cloudProvider)
       convertToCloudAttachment(this.bigFiles, cloudProvider);
+
+    return false;
   },
 
-  hideNotification: function() {
+  hideNotification() {
     let never = {};
     if (Services.prompt.confirmCheck(window,
                                      this.formatString("bigFileHideNotification.title"),
                                      this.formatString("bigFileHideNotification.text"),
                                      this.formatString("bigFileHideNotification.check"),
-                                     never))
+                                     never)) {
       this.hide(never.value);
-    else
-      return true;
+      return false;
+    }
+    return true;
   },
 
-  showUploadingNotification: function(aAttachments) {
+  showUploadingNotification(aAttachments) {
     // We will show the uploading notification for a minimum of 2.5 seconds
     // seconds.
     const kThreshold = 2500; // milliseconds
 
     if (!aAttachments.length ||
         !Services.prefs
                  .getBoolPref("mail.compose.big_attachments.insert_notification"))
       return;
@@ -240,28 +237,27 @@ var gBigFileObserver = {
     if (notification)
       return;
 
     let message = this.formatString("cloudFileUploadingNotification");
     message = PluralForm.get(aAttachments.length, message);
     let showUploadButton = {
       accessKey: this.formatString("stopShowingUploadingNotification.accesskey"),
       label: this.formatString("stopShowingUploadingNotification.label"),
-      callback: function (aNotificationBar, aButton)
-      {
+      callback(aNotificationBar, aButton) {
         Services.prefs.setBoolPref("mail.compose.big_attachments.insert_notification", false);
-      }
+      },
     };
     notification = nb.appendNotification(message, kUploadNotificationValue,
                                          "null", nb.PRIORITY_WARNING_MEDIUM,
                                          [showUploadButton]);
     notification.timeout = Date.now() + kThreshold;
   },
 
-  hideUploadingNotification: function() {
+  hideUploadingNotification() {
     let nb = document.getElementById("attachmentNotificationBox");
     let notification = nb.getNotificationWithValue(kUploadNotificationValue);
 
     if (notification) {
       // Check the timestamp that we stashed in the timeout field of the
       // notification...
       let now = Date.now();
       if (now >= notification.timeout) {
@@ -269,35 +265,34 @@ var gBigFileObserver = {
       } else {
         setTimeout(function() {
           nb.removeNotification(notification);
         }, notification.timeout - now);
       }
     }
   },
 
-  showPrivacyNotification: function() {
+  showPrivacyNotification() {
     const kPrivacyNotificationValue = "bigAttachmentPrivacyWarning";
 
     let nb = document.getElementById("attachmentNotificationBox");
     let notification = nb.getNotificationWithValue(kPrivacyNotificationValue);
 
     if (notification)
       return;
 
     let message = this.formatString("cloudFilePrivacyNotification");
     nb.appendNotification(message, kPrivacyNotificationValue, "null",
                           nb.PRIORITY_WARNING_MEDIUM, null);
 
   },
 
-  _anyUploadsInProgress: function() {
+  _anyUploadsInProgress() {
     let bucket = document.getElementById("attachmentBucket");
-    let rowCount = bucket.getRowCount();
-    for (let i = 0; i < bucket.getRowCount(); ++i) {
+    for (let i = 0, rowCount = bucket.getRowCount(); i < rowCount; ++i) {
       let item = bucket.getItemAtIndex(i);
       if (item && item.uploading)
         return true;
     }
     return false;
   },
 
 };
--- a/mail/components/compose/content/cloudAttachmentLinkManager.js
+++ b/mail/components/compose/content/cloudAttachmentLinkManager.js
@@ -1,14 +1,16 @@
 /* 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 MsgComposeCommands.js */
+
 var gCloudAttachmentLinkManager = {
-  init: function() {
+  init() {
     this.cloudAttachments = [];
 
     let bucket = document.getElementById("attachmentBucket");
     bucket.addEventListener("attachment-uploaded", this);
     bucket.addEventListener("attachments-removed", this);
     bucket.addEventListener("attachments-converted", this);
 
     // If we're restoring a draft that has some attachments,
@@ -18,35 +20,34 @@ var gCloudAttachmentLinkManager = {
       let attachment = bucket.getItemAtIndex(i).attachment;
       if (attachment && attachment.sendViaCloud)
         this.cloudAttachments.push(attachment);
     }
 
     gMsgCompose.RegisterStateListener(this);
   },
 
-  NotifyComposeFieldsReady: function() {},
-  NotifyComposeBodyReady: function() {},
-  ComposeProcessDone: function() {},
-  SaveInFolderDone: function() {},
+  NotifyComposeFieldsReady() {},
+  NotifyComposeBodyReady() {},
+  ComposeProcessDone() {},
+  SaveInFolderDone() {},
 
-  handleEvent: function(event) {
+  handleEvent(event) {
     let mailDoc = document.getElementById("content-frame").contentDocument;
 
     if (event.type == "attachment-uploaded") {
       if (this.cloudAttachments.length == 0)
         this._insertHeader(mailDoc);
 
       let attachment = event.target.attachment;
       let provider = event.target.cloudProvider;
       this.cloudAttachments.push(attachment);
       this._insertItem(mailDoc, attachment, provider);
-    }
-    else if (event.type == "attachments-removed" ||
-             event.type == "attachments-converted") {
+    } else if (event.type == "attachments-removed" ||
+               event.type == "attachments-converted") {
       let items = [];
       let list = mailDoc.getElementById("cloudAttachmentList");
       if (list)
         items = list.getElementsByClassName("cloudAttachmentItem");
 
       for (let attachment of fixIterator(
            event.detail, Ci.nsIMsgAttachment)) {
         // Remove the attachment from the message body.
@@ -71,53 +72,53 @@ var gCloudAttachmentLinkManager = {
     }
   },
 
   /**
    * Removes the root node for an attachment list in an HTML email.
    *
    * @param aDocument the document to remove the root node from.
    */
-  _removeRoot: function(aDocument) {
+  _removeRoot(aDocument) {
     let header = aDocument.getElementById("cloudAttachmentListRoot");
     if (header)
       header.remove();
   },
 
   /**
    * Given some node, returns the textual HTML representation for the node
    * and its children.
    *
    * @param aDocument the document that the node is embedded in
    * @param aNode the node to get the textual representation from
    */
-  _getHTMLRepresentation: function(aDocument, aNode) {
+  _getHTMLRepresentation(aDocument, aNode) {
     let tmp = aDocument.createElement("p");
     tmp.appendChild(aNode);
     return tmp.innerHTML;
   },
 
   /**
    * Generates an appropriately styled link.
    *
    * @param aDocument the document to append the link to - doesn't actually
    *                  get appended, but is used to generate the anchor node.
    * @param aContent the textual content of the link
    * @param aHref the HREF attribute for the generated link
    */
-  _generateLink: function(aDocument, aContent, aHref) {
+  _generateLink(aDocument, aContent, aHref) {
     const LINK_COLOR = "#0F7EDB";
     let link = aDocument.createElement("a");
     link.href = aHref;
     link.textContent = aContent;
     link.style.cssText = "color: " + LINK_COLOR + " !important";
     return link;
   },
 
-  _findInsertionPoint: function(aDocument) {
+  _findInsertionPoint(aDocument) {
     let mailBody = aDocument.querySelector("body");
     let editor = GetCurrentEditor();
     let selection = editor.selection;
 
     let childNodes = mailBody.childNodes;
     let childToInsertAfter, childIndex;
 
     // First, search for any text nodes that are immediate children of
@@ -158,29 +159,27 @@ var gCloudAttachmentLinkManager = {
           selection.collapse(mailBody, childNodes.length - 1);
           editor.insertLineBreak();
 
           if (!gMsgCompose.composeHTML)
             editor.insertLineBreak();
 
           selection.collapse(mailBody, childNodes.length - 2);
         }
-      } else {
+      } else if (replyCitation.previousSibling) {
         // Replying above quote
-        if (replyCitation.previousSibling) {
-          let nodeIndex = Array.from(childNodes).indexOf(replyCitation.previousSibling);
-          if (nodeIndex <= 0) {
-            editor.insertLineBreak();
-            nodeIndex = 1;
-          }
-          selection.collapse(mailBody, nodeIndex);
-        } else {
-          editor.beginningOfDocument();
+        let nodeIndex = Array.from(childNodes).indexOf(replyCitation.previousSibling);
+        if (nodeIndex <= 0) {
           editor.insertLineBreak();
+          nodeIndex = 1;
         }
+        selection.collapse(mailBody, nodeIndex);
+      } else {
+        editor.beginningOfDocument();
+        editor.insertLineBreak();
       }
       return;
     }
 
     // Are we forwarding?
     let forwardBody = mailBody.querySelector(".moz-forward-container");
     if (forwardBody) {
       if (forwardBody.previousSibling) {
@@ -226,31 +225,31 @@ var gCloudAttachmentLinkManager = {
 
   /**
    * Attempts to find any elements with an id in aIDs, and sets those elements
    * id attribute to the empty string, freeing up the ids for later use.
    *
    * @param aDocument the document to search for the elements.
    * @param aIDs an array of id strings.
    */
-  _resetNodeIDs: function(aDocument, aIDs) {
+  _resetNodeIDs(aDocument, aIDs) {
     for (let id of aIDs) {
       let node = aDocument.getElementById(id);
       if (node)
         node.id = "";
     }
   },
 
   /**
    * Insert the header for the cloud attachment list, which we'll use to
    * as an insertion point for the individual cloud attachments.
    *
    * @param aDocument the document to insert the header into.
    */
-  _insertHeader: function(aDocument) {
+  _insertHeader(aDocument) {
     // If there already exists a cloudAttachmentListRoot,
     // cloudAttachmentListHeader or cloudAttachmentList in the document,
     // strip them of their IDs so that we don't conflict with them.
     this._resetNodeIDs(aDocument, ["cloudAttachmentListRoot",
                                     "cloudAttachmentListHeader",
                                     "cloudAttachmentList"]);
 
     let brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
@@ -295,25 +294,24 @@ var gCloudAttachmentLinkManager = {
                                .getCharPref("mail.cloud_files.inserted_urls.footer.link");
       let appname = this._generateLink(aDocument,
                                        brandBundle.GetStringFromName("brandFullName"),
                                        appLinkUrl);
 
       let applink = this._getHTMLRepresentation(aDocument, appname);
       let footerMessage = getComposeBundle().getFormattedString("cloudAttachmentListFooter", [applink], 1);
 
-      footer.innerHTML = footerMessage;
+      footer.innerHTML = footerMessage; // eslint-disable-line no-unsanitized/property
       footer.style.color = "#444444";
       footer.style.fontSize = "small";
       footer.style.marginTop = "15px";
       root.appendChild(footer);
 
       editor.insertElementAtSelection(root, false);
-    }
-    else {
+    } else {
       let root = editor.createElementWithDefaults("div");
       root.id = "cloudAttachmentListRoot";
 
       let header = editor.createElementWithDefaults("div");
       header.id = "cloudAttachmentListHeader";
       header.innerHTML = " ";
       root.appendChild(header);
 
@@ -332,17 +330,17 @@ var gCloudAttachmentLinkManager = {
   },
 
   /**
    * Updates the count of how many attachments have been added
    * in HTML emails.
    *
    * @aDocument the document that contains the cloudAttachmentListHeader node.
    */
-  _updateAttachmentCount: function(aDocument) {
+  _updateAttachmentCount(aDocument) {
     let header = aDocument.getElementById("cloudAttachmentListHeader");
     if (!header)
       return;
 
     let count = PluralForm.get(this.cloudAttachments.length,
                                getComposeBundle().getString("cloudAttachmentCountHeader"));
 
     header.textContent = count.replace("#1", this.cloudAttachments.length);
@@ -350,17 +348,17 @@ var gCloudAttachmentLinkManager = {
 
   /**
    * Insert the information for a cloud attachment.
    *
    * @param aDocument the document to insert the item into
    * @param aAttachment the nsIMsgAttachment to insert
    * @param aProviderType the cloud storage provider
    */
-  _insertItem: function(aDocument, aAttachment, aProvider) {
+  _insertItem(aDocument, aAttachment, aProvider) {
     let list = aDocument.getElementById("cloudAttachmentList");
 
     if (!list) {
       this._insertHeader(aDocument);
       list = aDocument.getElementById("cloudAttachmentList");
     }
 
     let node = aDocument.createElement("div");
@@ -431,18 +429,17 @@ var gCloudAttachmentLinkManager = {
 
       let downloadUrl = this._generateLink(aDocument,
                                            aAttachment.contentLocation,
                                            aAttachment.contentLocation);
       downloadUrl.style.fontSize = "small";
       downloadUrl.style.display = "block";
 
       node.appendChild(downloadUrl);
-    }
-    else {
+    } else {
       node.textContent = getComposeBundle().getFormattedString(
         "cloudAttachmentListItem",
         [aAttachment.name, gMessenger.formatFileSize(aAttachment.size),
          aProvider.displayName,
          aAttachment.contentLocation]);
     }
 
     this._updateAttachmentCount(aDocument);
@@ -450,17 +447,17 @@ var gCloudAttachmentLinkManager = {
   },
 
   /**
    * Event handler for when mail is sent.  For mail that is being sent
    * (and not saved!), find any cloudAttachmentList* nodes that we've created,
    * and strip their IDs out.  That way, if the receiving user replies by
    * sending some BigFiles, we don't run into ID conflicts.
    */
-  send: function(aEvent) {
+  send(aEvent) {
     let msgType = parseInt(aEvent.target.getAttribute("msgtype"));
 
     if (msgType == Ci.nsIMsgCompDeliverMode.Now ||
         msgType == Ci.nsIMsgCompDeliverMode.Later ||
         msgType == Ci.nsIMsgCompDeliverMode.Background) {
 
       const kIDs = ["cloudAttachmentList", "cloudAttachmentListRoot",
                     "cloudAttachmentListHeader"];