Bug 1478572 - Turn on ESLint in mail/components/addrbook; r=aceman
authorGeoff Lankow <geoff@darktrojan.net>
Mon, 27 Aug 2018 21:49:35 +1200
changeset 32909 dc872eb2bea05fa96959f3d3e4f0693789d16204
parent 32908 9289d8a37eb2dae82f2ecc0076ec8396126a5526
child 32910 1cf799b1afa82d114fbb543925074d1f754543d4
push id386
push userclokep@gmail.com
push dateTue, 23 Oct 2018 00:48:12 +0000
reviewersaceman
bugs1478572
Bug 1478572 - Turn on ESLint in mail/components/addrbook; r=aceman
.eslintignore
mail/components/addrbook/content/.eslintrc.js
mail/components/addrbook/content/abCard.js
mail/components/addrbook/content/abCardView.js
mail/components/addrbook/content/abCommon.js
mail/components/addrbook/content/abContactsPanel.js
mail/components/addrbook/content/abTrees.js
mail/components/addrbook/content/addressbook.js
--- a/.eslintignore
+++ b/.eslintignore
@@ -37,16 +37,17 @@ mail/installer/**
 mail/locales/**
 mail/test/**
 mail/themes/**
 
 # mail/components exclusions
 mail/components/*
 !mail/components/about-support
 !mail/components/accountcreation
+!mail/components/addrbook
 !mail/components/devtools
 !mail/components/downloads
 !mail/components/extensions
 
 # calendar/ exclusions
 
 # prefs files
 calendar/lightning/content/lightning.js
new file mode 100644
--- /dev/null
+++ b/mail/components/addrbook/content/.eslintrc.js
@@ -0,0 +1,54 @@
+"use strict";
+
+module.exports = { // eslint-disable-line no-undef
+  "globals": {
+    // abCommon.js
+    "AbEditCard": true,
+    "AbNewMessage": true,
+    "ChangeDirectoryByURI": true,
+    "DirPaneController": true,
+    "GenerateAddressFromCard": true,
+    "GetDirectoryFromURI": true,
+    "GetParentDirectoryFromMailingListURI": true,
+    "InitCommonJS": true,
+    "SelectFirstAddressBook": true,
+    "abList": true,
+    "defaultPhotoURI": true,
+    "gAbResultsTree": true,
+    "gAbView": true,
+    "gAddressBookBundle": true,
+    "gDirTree": true,
+    "gImageDownloader": true,
+    "gShowAbColumnInComposeSidebar": true,
+    "getPhotoURI": true,
+    "getPhotosDir": true,
+    "getSelectedDirectory": true,
+    "getSelectedDirectoryURI": true,
+    "goNewCardDialog": true,
+    "goNewListDialog": true,
+    "kAllDirectoryRoot": true,
+    "kCollectedAddressbookURI": true,
+    "kDefaultAscending": true,
+    "kDefaultDescending": true,
+    "kDefaultSortColumn": true,
+    "kDefaultYear": true,
+    "kLdapUrlPrefix": true,
+    "kMaxYear": true,
+    "kMinYear": true,
+    "kPersonalAddressbookURI": true,
+    "saneBirthYear": true,
+    "selectStartupViewDirectory": true,
+
+    // mailnews/addrbook/content/abResultsPane.js
+    "AbEditSelectedCard": true,
+    "CloseAbView": true,
+    "GetSelectedAbCards": true,
+    "GetSelectedAddresses": true,
+    "GetSelectedCardIndex": true,
+    "GetSelectedCardTypes": true,
+    "ResultsPaneController": true,
+    "SelectFirstCard": true,
+    "SetAbView": true,
+    "SortAndUpdateIndicators": true,
+  }
+};
--- a/mail/components/addrbook/content/abCard.js
+++ b/mail/components/addrbook/content/abCard.js
@@ -1,15 +1,15 @@
 /* -*- 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.js");
+var { MailServices } = ChromeUtils.import("resource:///modules/mailServices.js", null);
 
 var kNonVcardFields =
         ["NickNameContainer", "SecondaryEmailContainer", "ScreenNameContainer",
          "customFields", "preferDisplayName"];
 
 var kPhoneticFields =
         ["PhoneticLastName", "PhoneticLabel1", "PhoneticSpacer1",
          "PhoneticFirstName", "PhoneticLabel2", "PhoneticSpacer2"];
@@ -64,58 +64,56 @@ var kVcardFields =
          ["QQ", "_QQ"],
          ["MSN", "_MSN"],
          ["ICQ", "_ICQ"],
          ["XMPP", "_JabberId"],
          ["IRC", "_IRC"]
         ];
 
 var gEditCard;
-var gOnSaveListeners = new Array();
-var gOnLoadListeners = new Array();
+var gOnSaveListeners = [];
+var gOnLoadListeners = [];
 var gOkCallback = null;
 var gHideABPicker = false;
 var gPhotoHandlers = {};
 // If any new photos were added to the card, this stores the name of the original
 // and any temporary new filenames used to store photos of the card.
 // 'null' is a valid value when there was no photo (e.g. the generic photo).
 var gOldPhotos = [];
 // If a new photo was added, the name is stored here.
 var gNewPhoto = null;
 
-function OnLoadNewCard()
-{
+function OnLoadNewCard() {
   InitEditCard();
 
   gEditCard.card =
     (("arguments" in window) && (window.arguments.length > 0) &&
      (window.arguments[0] instanceof Ci.nsIAbCard))
     ? window.arguments[0]
     : Cc["@mozilla.org/addressbook/cardproperty;1"]
         .createInstance(Ci.nsIAbCard);
   gEditCard.titleProperty = "newContactTitle";
   gEditCard.selectedAB = "";
 
-  if ("arguments" in window && window.arguments[0])
-  {
+  if ("arguments" in window && window.arguments[0]) {
     gEditCard.selectedAB = kPersonalAddressbookURI;
 
     if ("selectedAB" in window.arguments[0] &&
         (window.arguments[0].selectedAB != kAllDirectoryRoot + "?")) {
       // check if selected ab is a mailing list
       var abURI = window.arguments[0].selectedAB;
 
       var directory = GetDirectoryFromURI(abURI);
       if (directory.isMailList) {
         var parentURI = GetParentDirectoryFromMailingListURI(abURI);
         if (parentURI)
           gEditCard.selectedAB = parentURI;
+      } else if (!directory.readOnly) {
+        gEditCard.selectedAB = window.arguments[0].selectedAB;
       }
-      else if (!directory.readOnly)
-        gEditCard.selectedAB = window.arguments[0].selectedAB;
     }
 
     // we may have been given properties to pre-initialize the window with....
     // we'll fill these in here...
     if ("primaryEmail" in window.arguments[0])
       gEditCard.card.primaryEmail = window.arguments[0].primaryEmail;
     if ("displayName" in window.arguments[0]) {
       gEditCard.card.displayName = window.arguments[0].displayName;
@@ -142,17 +140,17 @@ function OnLoadNewCard()
     if ("titleProperty" in window.arguments[0])
       gEditCard.titleProperty = window.arguments[0].titleProperty;
 
     if ("hideABPicker" in window.arguments[0])
       gHideABPicker = window.arguments[0].hideABPicker;
   }
 
   // set popup with address book names
-  var abPopup = document.getElementById('abPopup');
+  var abPopup = document.getElementById("abPopup");
   abPopup.value = gEditCard.selectedAB || kPersonalAddressbookURI;
 
   if (gHideABPicker && abPopup) {
     abPopup.hidden = true;
     document.getElementById("abPopupLabel").hidden = true;
   }
 
   SetCardDialogTitle(gEditCard.card.displayName);
@@ -182,18 +180,17 @@ function getContainingDirectory() {
     let dirId =
       gEditCard.card.directoryId
                     .substring(0, gEditCard.card.directoryId.indexOf("&"));
     directory = MailServices.ab.getDirectoryFromId(dirId);
   }
   return directory;
 }
 
-function EditCardOKButton()
-{
+function EditCardOKButton() {
   if (!CheckCardRequiredDataPresence(document))
     return false;  // don't close window
 
   // See if this card is in any mailing list
   // if so then we need to update the addresslists of those mailing lists
   let directory = getContainingDirectory();
 
   // if the directory is a mailing list we need to search all the mailing lists
@@ -214,17 +211,17 @@ function EditCardOKButton()
       // See if any card in this list is the one we edited.
       // Must compare card contents using .equals() instead of .indexOf()
       // because gEditCard is not really a member of the .addressLists array.
       let listCardsCount = subdir.addressLists.length;
       for (let index = 0; index < listCardsCount; index++) {
         let card = subdir.addressLists
                          .queryElementAt(index, Ci.nsIAbCard);
         if (card.equals(gEditCard.card))
-          foundDirectories.push({directory:subdir, cardIndex:index});
+          foundDirectories.push({directory: subdir, cardIndex: index});
       }
     }
   }
 
   CheckAndSetCardValues(gEditCard.card, document, false);
 
   directory.modifyCard(gEditCard.card);
 
@@ -240,62 +237,56 @@ function EditCardOKButton()
 
   // callback to allow caller to update
   if (gOkCallback)
     gOkCallback();
 
   return true;  // close the window
 }
 
-function EditCardCancelButton()
-{
+function EditCardCancelButton() {
   // If a new photo was created, remove it now as it won't be used.
   purgeOldPhotos(false);
 }
 
-function OnLoadEditCard()
-{
+function OnLoadEditCard() {
   InitEditCard();
 
   gEditCard.titleProperty = "editContactTitle";
 
-  if (window.arguments && window.arguments[0])
-  {
+  if (window.arguments && window.arguments[0]) {
     if (window.arguments[0].card)
       gEditCard.card = window.arguments[0].card;
     if (window.arguments[0].okCallback)
       gOkCallback = window.arguments[0].okCallback;
     if (window.arguments[0].abURI)
       gEditCard.abURI = window.arguments[0].abURI;
   }
 
   // set global state variables
   // if first or last name entered, disable generateDisplayName
   if (gEditCard.generateDisplayName &&
       (gEditCard.card.firstName.length +
        gEditCard.card.lastName.length +
-       gEditCard.card.displayName.length > 0))
-  {
+       gEditCard.card.displayName.length > 0)) {
     gEditCard.generateDisplayName = false;
   }
 
   GetCardValues(gEditCard.card, document);
 
   SetCardDialogTitle(gEditCard.card.displayName);
 
   // check if selectedAB is a writeable
   // if not disable all the fields
-  if ("arguments" in window && window.arguments[0])
-  {
+  if ("arguments" in window && window.arguments[0]) {
     if ("abURI" in window.arguments[0]) {
       var abURI = window.arguments[0].abURI;
       var directory = GetDirectoryFromURI(abURI);
 
-      if (directory.readOnly)
-      {
+      if (directory.readOnly) {
         // Set all the editable vcard fields to read only
         for (var i = kVcardFields.length; i-- > 0; )
           document.getElementById(kVcardFields[i][0]).readOnly = true;
 
         // the birthday fields
         document.getElementById("Birthday").readOnly = true;
         document.getElementById("BirthYear").readOnly = true;
         document.getElementById("Age").readOnly = true;
@@ -325,155 +316,139 @@ function OnLoadEditCard()
   }
 }
 
 /* Registers functions that are called when loading the card
  * values into the contact editor dialog.  This is useful if
  * extensions have added extra fields to the nsIAbCard, and
  * need to display them in the contact editor.
  */
-function RegisterLoadListener(aFunc)
-{
+function RegisterLoadListener(aFunc) {
   gOnLoadListeners[gOnLoadListeners.length] = aFunc;
 }
 
-function UnregisterLoadListener(aFunc)
-{
+function UnregisterLoadListener(aFunc) {
   var fIndex = gOnLoadListeners.indexOf(aFunc);
   if (fIndex != -1)
     gOnLoadListeners.splice(fIndex, 1);
 }
 
 // Notifies load listeners that an nsIAbCard is being loaded.
-function NotifyLoadListeners(aCard, aDoc)
-{
+function NotifyLoadListeners(aCard, aDoc) {
   if (!gOnLoadListeners.length)
     return;
 
   for (var i = 0; i < gOnLoadListeners.length; i++)
     gOnLoadListeners[i](aCard, aDoc);
 }
 
 /* Registers functions that are called when saving the card
  * values.  This is useful if extensions have added extra
  * fields to the user interface, and need to set those values
  * in their nsIAbCard.
  */
-function RegisterSaveListener(func)
-{
+function RegisterSaveListener(func) {
   gOnSaveListeners[gOnSaveListeners.length] = func;
 }
 
-function UnregisterSaveListener(aFunc)
-{
+function UnregisterSaveListener(aFunc) {
   var fIndex = gOnSaveListeners.indexOf(aFunc);
   if (fIndex != -1)
     gOnSaveListeners.splice(fIndex, 1);
 }
 
 // Notifies save listeners that an nsIAbCard is being saved.
-function NotifySaveListeners(directory)
-{
+function NotifySaveListeners(directory) {
   if (!gOnSaveListeners.length)
     return;
 
   for (var i = 0; i < gOnSaveListeners.length; i++)
     gOnSaveListeners[i](gEditCard.card, document);
 
   // the save listeners might have tweaked the card
   // in which case we need to commit it.
   directory.modifyCard(gEditCard.card);
 }
 
-function InitPhoneticFields()
-{
+function InitPhoneticFields() {
   var showPhoneticFields =
     Services.prefs.getComplexValue("mail.addr_book.show_phonetic_fields",
       Ci.nsIPrefLocalizedString).data;
 
   // show phonetic fields if indicated by the pref
-  if (showPhoneticFields == "true")
-  {
+  if (showPhoneticFields == "true") {
     for (var i = kPhoneticFields.length; i-- > 0; )
       document.getElementById(kPhoneticFields[i]).hidden = false;
   }
 }
 
-function InitEditCard()
-{
+function InitEditCard() {
   InitPhoneticFields();
 
   InitCommonJS();
 
   // Create gEditCard object that contains global variables for the current js
   //   file.
-  gEditCard = new Object();
+  gEditCard = {};
 
   // get specific prefs that gEditCard will need
   try {
     var displayLastNameFirst =
       Services.prefs.getComplexValue("mail.addr_book.displayName.lastnamefirst",
         Ci.nsIPrefLocalizedString).data;
     gEditCard.displayLastNameFirst = (displayLastNameFirst == "true");
     gEditCard.generateDisplayName =
       Services.prefs.getBoolPref("mail.addr_book.displayName.autoGeneration");
-  }
-  catch (ex) {
+  } catch (ex) {
     dump("ex: failed to get pref" + ex + "\n");
   }
 }
 
-function NewCardOKButton()
-{
-  if (gOkCallback)
-  {
+function NewCardOKButton() {
+  if (gOkCallback) {
     if (!CheckAndSetCardValues(gEditCard.card, document, true))
       return false;  // don't close window
 
     gOkCallback(gEditCard.card.translateTo("vcard"));
     return true;  // close the window
   }
 
-  var popup = document.getElementById('abPopup');
-  if (popup)
-  {
+  var popup = document.getElementById("abPopup");
+  if (popup) {
     var uri = popup.value;
 
     // FIX ME - hack to avoid crashing if no ab selected because of blank option bug from template
     // should be able to just remove this if we are not seeing blank lines in the ab popup
     if (!uri)
       return false;  // don't close window
     // -----
 
-    if (gEditCard.card)
-    {
+    if (gEditCard.card) {
       if (!CheckAndSetCardValues(gEditCard.card, document, true))
         return false;  // don't close window
 
       // replace gEditCard.card with the card we added
       // so that save listeners can get / set attributes on
       // the card that got created.
       var directory = GetDirectoryFromURI(uri);
       gEditCard.card = directory.addCard(gEditCard.card);
       NotifySaveListeners(directory);
     }
   }
 
   return true;  // close the window
 }
 
-function NewCardCancelButton()
-{
+function NewCardCancelButton() {
   // If a new photo was created, remove it now as it won't be used.
   purgeOldPhotos(false);
 }
 
 // Move the data from the cardproperty to the dialog
-function GetCardValues(cardproperty, doc)
-{
+function GetCardValues(cardproperty, doc) {
   if (!cardproperty)
     return;
 
   // Pass the nsIAbCard and the Document through the listeners
   // to give extensions a chance to populate custom fields.
   NotifyLoadListeners(cardproperty, doc);
 
   for (var i = kVcardFields.length; i-- > 0; ) {
@@ -518,52 +493,49 @@ function GetCardValues(cardproperty, doc
 
   var popup = document.getElementById("PreferMailFormatPopup");
   if (popup)
     popup.value = cardproperty.getProperty("PreferMailFormat", "");
 
   var preferDisplayNameEl = document.getElementById("preferDisplayName");
   if (preferDisplayNameEl)
     // getProperty may return a "1" or "0" string, we want a boolean
-    preferDisplayNameEl.checked = cardproperty.getProperty("PreferDisplayName", true) != false;
+    preferDisplayNameEl.checked = !cardproperty.getProperty("PreferDisplayName", true);
 
   // get phonetic fields if exist
   try {
     doc.getElementById("PhoneticFirstName").value = cardproperty.getProperty("PhoneticFirstName", "");
     doc.getElementById("PhoneticLastName").value = cardproperty.getProperty("PhoneticLastName", "");
-  }
-  catch (ex) {}
+  } catch (ex) {}
 
   // Select the type if there is a valid value stored for that type, otherwise
   // select the generic photo
   loadPhoto(cardproperty);
 
   updateChatName();
 }
 
 // when the ab card dialog is being loaded to show a vCard,
 // hide the fields which aren't supported
 // by vCard so the user does not try to edit them.
-function HideNonVcardFields()
-{
+function HideNonVcardFields() {
   document.getElementById("homeTabButton").hidden = true;
   document.getElementById("chatTabButton").hidden = true;
   document.getElementById("photoTabButton").hidden = true;
   var i;
   for (i = kNonVcardFields.length; i-- > 0; )
     document.getElementById(kNonVcardFields[i]).collapsed = true;
   for (i = kPhoneticFields.length; i-- > 0; )
     document.getElementById(kPhoneticFields[i]).collapsed = true;
 }
 
 // Move the data from the dialog to the cardproperty to be stored in the database
 // @Returns false - Some required data are missing (card values were not set);
 //          true - Card values were set, or there is no card to set values on.
-function CheckAndSetCardValues(cardproperty, doc, check)
-{
+function CheckAndSetCardValues(cardproperty, doc, check) {
   // If requested, check the required data presence.
   if (check && !CheckCardRequiredDataPresence(document))
     return false;
 
   if (!cardproperty)
     return true;
 
   for (var i = kVcardFields.length; i-- > 0; )
@@ -588,124 +560,112 @@ function CheckAndSetCardValues(cardprope
   var preferDisplayNameEl = document.getElementById("preferDisplayName");
   if (preferDisplayNameEl)
     cardproperty.setProperty("PreferDisplayName", preferDisplayNameEl.checked);
 
   // set phonetic fields if exist
   try {
     cardproperty.setProperty("PhoneticFirstName", doc.getElementById("PhoneticFirstName").value);
     cardproperty.setProperty("PhoneticLastName", doc.getElementById("PhoneticLastName").value);
-  }
-  catch (ex) {}
+  } catch (ex) {}
 
   let photoType = doc.getElementById("PhotoType").value;
   if (gPhotoHandlers[photoType]) {
     if (!gPhotoHandlers[photoType].onSave(cardproperty, doc)) {
       photoType = "generic";
       onSwitchPhotoType("generic");
       gPhotoHandlers[photoType].onSave(cardproperty, doc);
     }
   }
   cardproperty.setProperty("PhotoType", photoType);
   purgeOldPhotos(true);
 
   return true;
 }
 
-function CleanUpWebPage(webPage)
-{
+function CleanUpWebPage(webPage) {
   // no :// yet so we should add something
-  if (webPage.length && !webPage.includes("://"))
-  {
+  if (webPage.length && !webPage.includes("://")) {
     // check for missing / on http://
     if (webPage.startsWith("http:/"))
-      return("http://" + webPage.substr(6));
-    else
-      return("http://" + webPage);
+      return ("http://" + webPage.substr(6));
+    return ("http://" + webPage);
   }
-  else
-    return(webPage);
+  return (webPage);
 }
 
 // @Returns false - Some required data are missing;
 //          true - All required data are present.
-function CheckCardRequiredDataPresence(doc)
-{
+function CheckCardRequiredDataPresence(doc) {
   // Bug 314995 We require at least one of the following fields to be
   // filled in: email address, first name, last name, display name,
   //            organization (company name).
   var primaryEmail = doc.getElementById("PrimaryEmail");
   if (primaryEmail.textLength == 0 &&
     doc.getElementById("FirstName").textLength == 0 &&
     doc.getElementById("LastName").textLength == 0 &&
     doc.getElementById("DisplayName").textLength == 0 &&
-    doc.getElementById("Company").textLength == 0)
-  {
+    doc.getElementById("Company").textLength == 0) {
     Services.prompt.alert(
       window,
       gAddressBookBundle.getString("cardRequiredDataMissingTitle"),
       gAddressBookBundle.getString("cardRequiredDataMissingMessage"));
 
     return false;
   }
 
   // Simple checks that the primary email should be of the form |user@host|.
   // Note: if the length of the primary email is 0 then we skip the check
   // as some other field must have something as per the check above.
-  if (primaryEmail.textLength != 0 && !/.@./.test(primaryEmail.value))
-  {
+  if (primaryEmail.textLength != 0 && !/.@./.test(primaryEmail.value)) {
     Services.prompt.alert(
       window,
       gAddressBookBundle.getString("incorrectEmailAddressFormatTitle"),
       gAddressBookBundle.getString("incorrectEmailAddressFormatMessage"));
 
     // Focus the dialog field, to help the user.
     document.getElementById("abTabs").selectedIndex = 0;
     primaryEmail.focus();
 
     return false;
   }
 
   return true;
 }
 
-function GenerateDisplayName()
-{
+function GenerateDisplayName() {
   if (!gEditCard.generateDisplayName)
     return;
 
   var displayName;
 
   var firstNameValue = document.getElementById("FirstName").value;
   var lastNameValue = document.getElementById("LastName").value;
   if (lastNameValue && firstNameValue) {
     displayName = (gEditCard.displayLastNameFirst)
       ? gAddressBookBundle.getFormattedString("lastFirstFormat", [lastNameValue, firstNameValue])
       : gAddressBookBundle.getFormattedString("firstLastFormat", [firstNameValue, lastNameValue]);
-  }
-  else {
+  } else {
     // one (or both) of these is empty, so this works.
     displayName = firstNameValue + lastNameValue;
   }
 
   document.getElementById("DisplayName").value = displayName;
 
   SetCardDialogTitle(displayName);
 }
 
-function DisplayNameChanged()
-{
+function DisplayNameChanged() {
   // turn off generateDisplayName if the user changes the display name
   gEditCard.generateDisplayName = false;
 
   SetCardDialogTitle(document.getElementById("DisplayName").value);
 }
 
-function SetCardDialogTitle(displayName)
-{
+function SetCardDialogTitle(displayName) {
   document.title = displayName
     ? gAddressBookBundle.getFormattedString(gEditCard.titleProperty + "WithDisplayName", [displayName])
     : gAddressBookBundle.getString(gEditCard.titleProperty);
 }
 
 /**
  * Calculates the duration of time between an event and now and updates the year
  * of whichever element did not call this function.
@@ -731,31 +691,29 @@ function calculateAge(aEvent, aElement) 
 
   var year = yearElem.value;
   // if the year element's value is invalid set the year and age elements to null
   if (isNaN(year) || year < kMinYear || year > kMaxYear) {
     yearElem.value = null;
     ageElem.value = null;
     datepicker.year = kDefaultYear;
     return;
-  }
-  else if (aElement == yearElem)
+  } else if (aElement == yearElem)
     datepicker.year = year;
   // calculate the length of time between the event and now
   try {
     var event = new Date(datepicker.year, datepicker.month, datepicker.date);
     // if the year is only 2 digits, then the year won't be set correctly
     // using setFullYear fixes this issue
     event.setFullYear(datepicker.year);
     // get the difference between today and the event
     var age = new Date(new Date() - event);
     // get the number of years of the difference and subtract 1970 (epoch)
     ageElem.value = age.getFullYear() - 1970;
-  }
-  catch(e) {
+  } catch (e) {
     datepicker.year = kDefaultYear;
     // if there was an error (like invalid year) set the year and age to null
     yearElem.value = null;
     ageElem.value = null;
   }
 }
 
 /**
@@ -785,20 +743,19 @@ function calculateYear(aEvent, aElement)
   }
   var today = new Date();
   try {
     var date = new Date(aElement.value, datepicker.month, datepicker.date);
     date.setFullYear(aElement.value);
     // get the difference between today and the age (the year is offset by 1970)
     var difference = new Date(today - date);
     datepicker.year = yearElem.value = difference.getFullYear() - 1970;
-  }
-  // the above code may throw an invalid year exception.  If that happens, set
-  // the year to kDefaultYear and set the year element's value to 0
-  catch (e) {
+  } catch (e) {
+    // The above code may throw an invalid year exception. If that happens, set
+    // the year to kDefaultYear and set the year element's value to 0.
     datepicker.year = kDefaultYear;
     // if there was an error (like invalid year) set the year and age to null
     yearElem.value = null;
     let ageElem = document.getElementById("Age");
     if (ageElem)
       ageElem.value = null;
   }
 }
@@ -844,96 +801,93 @@ function modifyDatepicker(aDatepicker) {
     if (aNoWrap && aField == this.monthField)
       aValue--;
     // make sure the date is valid for the given month
     if (aField == this.dateField) {
       var currentMonth = this.month;
       var dt = new Date(this.year, currentMonth, aValue);
       return dt.getMonth() != currentMonth ? 1 : aValue;
     }
+    var min = (aField == this.monthField) ? 0 : 1;
     var max = (aField == this.monthField) ? 11 : kMaxYear;
     // make sure the value isn't too high
     if (aValue > max)
       return aNoWrap ? max : min;
     return aValue;
-  }
+  };
   // sets the specified field to the given value, but allows blank fields
   // from: mozilla/toolkit/content/widgets/datetimepicker.xml#698
   aDatepicker._setFieldValue = function setValue(aField, aValue) {
     if (aField == this.yearField && aValue >= kMinYear && aValue <= kMaxYear) {
-      var oldDate = this._dateValue;
+      let oldDate = this._dateValue;
       this._dateValue.setFullYear(aValue);
       if (oldDate != this._dateValue) {
         this._dateValue.setDate(0);
         this._updateUI(this.dateField, this.date);
       }
-    }
-    // update the month if the value isn't null
-    else if (aField == this.monthField && aValue != null) {
-      var oldDate = this.date;
+    } else if (aField == this.monthField && aValue != null) {
+      // update the month if the value isn't null
+      let oldDate = this.date;
       this._dateValue.setMonth(aValue);
       if (oldDate != this.date)
         this._dateValue.setDate(0);
       this._updateUI(this.dateField, this.date);
-      var date = this._dateValue.getDate();
+      let date = this._dateValue.getDate();
       this.dateField.value = date < 10 && this.dateLeadingZero ? "0" + date : date;
-      var month = this._dateValue.getMonth() + 1;
+      let month = this._dateValue.getMonth() + 1;
       this.monthField.value = month < 10 && this.monthLeadingZero ? "0" + month : month;
-    }
-    // update the date if the value isn't null
-    else if (aField == this.dateField && aValue != null) {
+    } else if (aField == this.dateField && aValue != null) {
+      // update the date if the value isn't null
       this._dateValue.setDate(aValue);
       this._updateUI(this.dateField, this.date);
-      var date = this._dateValue.getDate();
+      let date = this._dateValue.getDate();
       this.dateField.value = date < 10 && this.dateLeadingZero ? "0" + date : date;
-      var month = this._dateValue.getMonth() + 1;
+      let month = this._dateValue.getMonth() + 1;
       this.monthField.value = month < 10 && this.monthLeadingZero ? "0" + month : month;
     }
     this.setAttribute("value", this.value);
 
     if (this.attachedControl)
       this.attachedControl._setValueNoSync(this._dateValue);
     // if the aField's value is null or 0, set both field's values to null
     if (!aField.value && aField != this.yearField) {
       this.dateField.value = null;
       this.monthField.value = null;
     }
     // make the field's value null if aValue is null and the field's value isn't
     if (aValue == null && aField.value != null)
       aField.value = null;
-  }
+  };
 }
 
 var chatNameFieldIds =
   ["Gtalk", "AIM", "Yahoo", "Skype", "QQ", "MSN", "ICQ", "XMPP", "IRC"];
 
 /**
  * Show the 'Chat' tab and focus the first field that has a value, or
  * the first field if none of them has a value.
  */
-function showChat()
-{
-  document.getElementById('abTabPanels').parentNode.selectedTab =
-    document.getElementById('chatTabButton');
+function showChat() {
+  document.getElementById("abTabPanels").parentNode.selectedTab =
+    document.getElementById("chatTabButton");
   for (let id of chatNameFieldIds) {
     let elt = document.getElementById(id);
     if (elt.value) {
       elt.focus();
       return;
     }
   }
   document.getElementById(chatNameFieldIds[0]).focus();
 }
 
 /**
  * Fill in the value of the ChatName readonly field with the first
  * value of the fields in the Chat tab.
  */
-function updateChatName()
-{
+function updateChatName() {
   let value = "";
   for (let id of chatNameFieldIds) {
     let val = document.getElementById(id).value;
     if (val) {
       value = val;
       break;
     }
   }
@@ -1007,18 +961,17 @@ function removePhoto(aName) {
     return false;
   // Get the directory with all the photos
   var file = getPhotosDir();
   // Get the photo (throws an exception for invalid names)
   try {
     file.append(aName);
     file.remove(false);
     return true;
-  }
-  catch (e) {}
+  } catch (e) {}
   return false;
 }
 
 /**
  * Remove previous and temporary photo files from the Photos directory.
  *
  * @param aSaved {boolean}  Whether the new card is going to be saved/committed.
  */
@@ -1056,17 +1009,17 @@ function browsePhoto(aEvent) {
   if (aEvent)
     aEvent.stopPropagation();
 
   var fp = Cc["@mozilla.org/filepicker;1"]
              .createInstance(Ci.nsIFilePicker);
   fp.init(window, gAddressBookBundle.getString("browsePhoto"), Ci.nsIFilePicker.modeOpen);
 
   // Open the directory of the currently chosen photo (if any)
-  let currentPhotoFile = document.getElementById("PhotoFile").file
+  let currentPhotoFile = document.getElementById("PhotoFile").file;
   if (currentPhotoFile) {
     fp.displayDirectory = currentPhotoFile.parent;
   }
 
   // Add All Files & Image Files filters and select the latter
   fp.appendFilters(Ci.nsIFilePicker.filterImages);
   fp.appendFilters(Ci.nsIFilePicker.filterAll);
 
@@ -1132,17 +1085,17 @@ var gPhotoDownloadUI = (function() {
     if (!elProgressbar)
       elProgressbar = document.getElementById("PhotoDownloadProgress");
     if (!elProgressLabel)
       elProgressLabel = document.getElementById("PhotoStatus");
     if (!elPhotoType)
       elPhotoType = document.getElementById("PhotoType");
     if (!elProgressContainer)
       elProgressContainer = document.getElementById("ProgressContainer");
-  }, false);
+  });
 
   function onStart() {
     elProgressContainer.setAttribute("class", "expanded");
     elProgressLabel.value = "";
     elProgressbar.hidden = false;
     elProgressbar.value = 3; // Start with a tiny visible progress
   }
 
@@ -1175,21 +1128,21 @@ var gPhotoDownloadUI = (function() {
   }
 
   function onProgress(state, percent) {
     elProgressbar.value = percent;
     elProgressLabel.value = gAddressBookBundle.getString("stateImageSave");
   }
 
   return {
-    onStart: onStart,
-    onSuccess: onSuccess,
-    onError: onError,
-    onProgress: onProgress
-  }
+    onStart,
+    onSuccess,
+    onError,
+    onProgress
+  };
 })();
 
 /* A photo handler defines the behaviour of the contact editor
  * for a particular photo type. Each photo handler must implement
  * the following interface:
  *
  * onLoad: function(aCard, aDocument):
  *   Called when the editor wants to populate the contact editor
@@ -1218,50 +1171,50 @@ var gPhotoDownloadUI = (function() {
  *   be called.
  *
  * onSave: function(aCard, aDocument)
  *   Called when the editor wants to save this photo type to the card.
  *   Returns true on success.
  */
 
 var genericPhotoHandler = {
-  onLoad: function(aCard, aDocument) {
+  onLoad(aCard, aDocument) {
     return true;
   },
 
-  onShow: function(aCard, aDocument, aTargetID) {
+  onShow(aCard, aDocument, aTargetID) {
     // XXX TODO: this ignores any other value from the generic photos
     // menulist than "default".
     aDocument.getElementById(aTargetID)
              .setAttribute("src", defaultPhotoURI);
     return true;
   },
 
-  onRead: function(aCard, aDocument) {
+  onRead(aCard, aDocument) {
     gPhotoDownloadUI.onSuccess();
 
     newPhotoAdded("", aCard);
 
     genericPhotoHandler.onShow(aCard, aDocument, "photo");
     return true;
   },
 
-  onSave: function(aCard, aDocument) {
+  onSave(aCard, aDocument) {
     // XXX TODO: this ignores any other value from the generic photos
     // menulist than "default".
 
     // Update contact
     aCard.setProperty("PhotoName", "");
     aCard.setProperty("PhotoURI", "");
     return true;
   }
-}
+};
 
 var filePhotoHandler = {
-  onLoad: function(aCard, aDocument) {
+  onLoad(aCard, aDocument) {
     let photoURI = aCard.getProperty("PhotoURI", "");
     let file;
     try {
       // The original file may not exist anymore, but we still display it.
       file = Services.io.newURI(photoURI)
                         .QueryInterface(Ci.nsIFileURL)
                         .file;
     } catch (e) {}
@@ -1269,24 +1222,24 @@ var filePhotoHandler = {
     if (!file)
       return false;
 
     aDocument.getElementById("PhotoFile").file = file;
     this._showFilename(aCard, aDocument);
     return true;
   },
 
-  onShow: function(aCard, aDocument, aTargetID) {
+  onShow(aCard, aDocument, aTargetID) {
     let photoName = gNewPhoto || aCard.getProperty("PhotoName", null);
     let photoURI = getPhotoURI(photoName);
     aDocument.getElementById(aTargetID).setAttribute("src", photoURI);
     return true;
   },
 
-  onRead: function(aCard, aDocument) {
+  onRead(aCard, aDocument) {
     let file = aDocument.getElementById("PhotoFile").file;
     filePhotoHandler._showFilename(aCard, aDocument);
     if (!file)
       return false;
 
     // If the local file has been removed/renamed, keep the current photo as is.
     if (!file.exists() || !file.isFile())
       return false;
@@ -1306,109 +1259,108 @@ var filePhotoHandler = {
     };
 
     gImageDownloader.savePhoto(photoURI, cbSuccess,
                                gPhotoDownloadUI.onError,
                                gPhotoDownloadUI.onProgress);
     return true;
   },
 
-  onSave: function(aCard, aDocument) {
+  onSave(aCard, aDocument) {
     // Update contact
     if (gNewPhoto) {
       // The file may not be valid unless the photo has changed.
       let photoURI = aDocument.getElementById("PhotoFile").getAttribute("PhotoURI");
       aCard.setProperty("PhotoName", gNewPhoto);
       aCard.setProperty("PhotoURI", photoURI);
     }
     return true;
   },
 
-  _showFilename: function(aCard, aDocument) {
+  _showFilename(aCard, aDocument) {
     let photoElem = aDocument.getElementById("PhotoFile");
     let photoFile = photoElem.file ? photoElem.file : null;
     let photoSpec = Services.io.getProtocolHandler("file")
                             .QueryInterface(Ci.nsIFileProtocolHandler)
                             .getURLSpecFromFile(photoFile);
     if (photoFile) {
       photoElem.style.backgroundImage = "url(moz-icon://" + photoSpec + "?size=16)";
       photoElem.value = photoFile.leafName;
     } else {
       photoElem.value = "";
     }
   }
-}
+};
 
 var webPhotoHandler = {
-  onLoad: function(aCard, aDocument) {
+  onLoad(aCard, aDocument) {
     let photoURI = aCard.getProperty("PhotoURI", null);
 
     if (!photoURI)
       return false;
 
     aDocument.getElementById("PhotoURI").value = photoURI;
     return true;
   },
 
-  onShow: function(aCard, aDocument, aTargetID) {
+  onShow(aCard, aDocument, aTargetID) {
     let photoName = gNewPhoto || aCard.getProperty("PhotoName", null);
     if (!photoName)
       return false;
 
     let photoURI = getPhotoURI(photoName);
 
     aDocument.getElementById(aTargetID).setAttribute("src", photoURI);
     return true;
   },
 
-  onRead: function(aCard, aDocument) {
+  onRead(aCard, aDocument) {
     let photoURI = aDocument.getElementById("PhotoURI").value;
     if (!photoURI)
       return false;
 
     gPhotoDownloadUI.onStart();
 
     let cbSuccess = function(newPhotoName) {
       gPhotoDownloadUI.onSuccess();
 
       newPhotoAdded(newPhotoName, aCard);
 
       webPhotoHandler.onShow(aCard, aDocument, "photo");
 
-    }
+    };
 
     gImageDownloader.savePhoto(photoURI, cbSuccess,
                                gPhotoDownloadUI.onError,
                                gPhotoDownloadUI.onProgress);
     return true;
   },
 
-  onSave: function(aCard, aDocument) {
+  onSave(aCard, aDocument) {
     // Update contact
     if (gNewPhoto) {
       let photoURI = aDocument.getElementById("PhotoURI").value;
       aCard.setProperty("PhotoName", gNewPhoto);
       aCard.setProperty("PhotoURI", photoURI);
     }
     return true;
   }
-}
+};
 
 function newPhotoAdded(aPhotoName, aCard) {
   // If we had the photo saved locally, shedule it for removal if card is saved.
   gOldPhotos.push(gNewPhoto !== null ? gNewPhoto : aCard.getProperty("PhotoName", null));
   gNewPhoto = aPhotoName;
 }
 
 /* In order for other photo handlers to be recognized for
  * a particular type, they must be registered through this
  * function.
  * @param aType the type of photo to handle
  * @param aPhotoHandler the photo handler to register
  */
-function registerPhotoHandler(aType, aPhotoHandler)
-{
+function registerPhotoHandler(aType, aPhotoHandler) {
   gPhotoHandlers[aType] = aPhotoHandler;
 }
 
 registerPhotoHandler("generic", genericPhotoHandler);
 registerPhotoHandler("web", webPhotoHandler);
 registerPhotoHandler("file", filePhotoHandler);
--- a/mail/components/addrbook/content/abCardView.js
+++ b/mail/components/addrbook/content/abCardView.js
@@ -1,14 +1,14 @@
 /* -*- 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/. */
 
-//NOTE: gAddressBookBundle must be defined and set or this Overlay won't work
+// NOTE: gAddressBookBundle must be defined and set or this Overlay won't work
 
 ChromeUtils.import("resource://gre/modules/PlacesUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 var gProfileDirURL;
 var gFileHandler = Services.io.getProtocolHandler("file")
   .QueryInterface(Ci.nsIFileProtocolHandler);
 var gPhotoDisplayHandlers = {};
@@ -35,18 +35,17 @@ var zSkype;
 var zQQ;
 var zMSN;
 var zICQ;
 var zXMPP;
 var zIRC;
 
 var cvData;
 
-function OnLoadCardView()
-{
+function OnLoadCardView() {
   zPrimaryEmail = gAddressBookBundle.getString("propertyPrimaryEmail");
   zSecondaryEmail = gAddressBookBundle.getString("propertySecondaryEmail");
   zNickname = gAddressBookBundle.getString("propertyNickname");
   zDisplayName = gAddressBookBundle.getString("propertyDisplayName");
   zListName = gAddressBookBundle.getString("propertyListName");
   zWork = gAddressBookBundle.getString("propertyWork");
   zHome = gAddressBookBundle.getString("propertyHome");
   zFax = gAddressBookBundle.getString("propertyFax");
@@ -67,17 +66,17 @@ function OnLoadCardView()
   zXMPP = gAddressBookBundle.getString("propertyXMPP");
   zIRC = gAddressBookBundle.getString("propertyIRC");
 
   var doc = document;
 
   /* data for address book, prefixes: "cvb" = card view box
                     "cvh" = crad view header
                     "cv"  = card view (normal fields) */
-  cvData = new Object;
+  cvData = {};
 
   // Card View Box
   cvData.CardViewBox    = doc.getElementById("CardViewInnerBox");
   // Title
   cvData.CardTitle    = doc.getElementById("CardTitle");
   // Name section
   cvData.cvbContact = doc.getElementById("cvbContact");
   cvData.cvhContact = doc.getElementById("cvhContact");
@@ -154,47 +153,46 @@ function OnLoadCardView()
   cvData.cvICQ        = doc.getElementById("cvICQ");
   cvData.cvXMPP       = doc.getElementById("cvXMPP");
   cvData.cvIRC        = doc.getElementById("cvIRC");
 }
 
 // XXX todo
 // some similar code (in spirit) already exists, see OnLoadEditList()
 // perhaps we could combine and put in abCommon.js?
-function GetAddressesFromURI(uri)
-{
+function GetAddressesFromURI(uri) {
   var addresses = "";
 
   var editList = GetDirectoryFromURI(uri);
   var addressList = editList.addressLists;
   if (addressList) {
     var total = addressList.length;
     if (total > 0)
       addresses = addressList.queryElementAt(0, Ci.nsIAbCard).primaryEmail;
-    for (var i = 1;  i < total; i++ ) {
+    for (let i = 1; i < total; i++) {
       addresses += ", " + addressList.queryElementAt(i, Ci.nsIAbCard).primaryEmail;
     }
   }
   return addresses;
 }
 
-function DisplayCardViewPane(realCard)
-{
+/* eslint-disable complexity */
+function DisplayCardViewPane(realCard) {
   let generatedName = realCard.generateName(
     Services.prefs.getIntPref("mail.addr_book.lastnamefirst"));
 
   // This will become neater when bug 312116 is fixed...
   // (card.property instead of card.getProperty("Property"))
-  var card = { getProperty : function (prop) {
+  var card = { getProperty(prop) {
                  return realCard.getProperty(prop, "");
                },
-               primaryEmail : realCard.primaryEmail,
-               displayName : realCard.displayName,
-               isMailList : realCard.isMailList,
-               mailListURI : realCard.mailListURI
+               primaryEmail: realCard.primaryEmail,
+               displayName: realCard.displayName,
+               isMailList: realCard.isMailList,
+               mailListURI: realCard.mailListURI
   };
 
   var data = top.cvData;
   var visible;
 
   // Contact photo
   displayPhoto(card, cvData.cvPhoto);
 
@@ -214,18 +212,17 @@ function DisplayCardViewPane(realCard)
   cvSetNodeWithLabel(data.cvNickname, zNickname, card.getProperty("NickName"));
 
   if (card.isMailList) {
     // email1 and display name always hidden when a mailing list.
     cvSetVisible(data.cvDisplayName, false);
     cvSetVisible(data.cvEmail1Box, false);
 
     visible = HandleLink(data.cvListName, zListName, card.displayName, data.cvListNameBox, "mailto:" + encodeURIComponent(GenerateAddressFromCard(card))) || visible;
-  }
-  else {
+  } else {
     // listname always hidden if not a mailing list
     cvSetVisible(data.cvListNameBox, false);
 
     cvSetNodeWithLabel(data.cvDisplayName, zDisplayName, card.displayName);
 
     visible = HandleLink(data.cvEmail1, zPrimaryEmail, card.primaryEmail, data.cvEmail1Box, "mailto:" + card.primaryEmail) || visible;
   }
 
@@ -253,55 +250,53 @@ function DisplayCardViewPane(realCard)
   visible = HandleLink(data.cvHomeWebPage, "", card.getProperty("WebPage2"),
                        data.cvHomeWebPageBox, card.getProperty("WebPage2")) ||
             visible;
 
   cvSetVisible(data.cvhHome, visible);
   cvSetVisible(data.cvbHome, visible);
   if (card.isMailList) {
     // Description section
-    visible = cvSetNode(data.cvDescription, card.getProperty("Notes"))
+    visible = cvSetNode(data.cvDescription, card.getProperty("Notes"));
     cvSetVisible(data.cvbDescription, visible);
 
     // Addresses section
     visible = cvAddAddressNodes(data.cvAddresses, card.mailListURI);
     cvSetVisible(data.cvbAddresses, visible);
 
     // Other and Chat sections, not shown for mailing lists.
     cvSetVisible(data.cvbOther, false);
     cvSetVisible(data.cvbChat, false);
-  }
-  else {
+  } else {
     // Other section
     // setup the birthday information
     var day = card.getProperty("BirthDay", null);
     var month = card.getProperty("BirthMonth", null);
     var year = card.getProperty("BirthYear", null);
     var dateStr;
     if (day > 0 && day < 32 && month > 0 && month < 13) {
       var date;
       var formatter;
       if (year) {
         // use UTC-based calculations to avoid off-by-one day
         // due to time zone/dst discontinuity
         date = new Date(Date.UTC(year, month - 1, day));
         date.setUTCFullYear(year); // to handle two-digit years properly
         formatter = new Services.intl.DateTimeFormat(undefined,
                       { dateStyle: "long", timeZone: "UTC" });
-      }
-      // if the year doesn't exist, display Month DD (ex. January 01)
-      else {
+      } else {
+        // if the year doesn't exist, display Month DD (ex. January 01)
         date = new Date(Date.UTC(saneBirthYear(year), month - 1, day));
         formatter = new Services.intl.DateTimeFormat(undefined,
                       { month: "long", day: "numeric", timeZone: "UTC" });
       }
       dateStr = formatter.format(date);
+    } else if (year) {
+      dateStr = year;
     }
-    else if (year)
-      dateStr = year;
     visible = cvSetNodeWithLabel(data.cvBirthday, zBirthday, dateStr);
 
     visible = cvSetNodeWithLabel(data.cvCustom1, zCustom1,
                                  card.getProperty("Custom1")) || visible;
     visible = cvSetNodeWithLabel(data.cvCustom2, zCustom2,
                                  card.getProperty("Custom2")) || visible;
     visible = cvSetNodeWithLabel(data.cvCustom3, zCustom3,
                                  card.getProperty("Custom3")) || visible;
@@ -387,19 +382,19 @@ function DisplayCardViewPane(realCard)
                              visible;
 
   cvSetVisible(data.cvhWork, visible);
   cvSetVisible(data.cvbWork, visible);
 
   // make the card view box visible
   cvSetVisible(top.cvData.CardViewBox, true);
 }
+/* eslint-enable complexity */
 
-function setBuddyIcon(card, buddyIcon)
-{
+function setBuddyIcon(card, buddyIcon) {
   try {
     let myScreenName = Services.prefs.getCharPref("aim.session.screenname");
     if (myScreenName && card.primaryEmail) {
       if (!gProfileDirURL) {
         // lazily create these file urls, and keep them around
         let profileDir = Services.dirsvc.get("ProfD", Ci.nsIFile);
         gProfileDirURL = Services.io.newFileURI(profileDir);
       }
@@ -412,44 +407,38 @@ function setBuddyIcon(card, buddyIcon)
 
       // check if the file exists
       // is this a perf hit?  (how expensive is stat()?)
       if (file.exists()) {
         buddyIcon.setAttribute("src", iconURLStr);
         return true;
       }
     }
-  }
-  catch (ex) {
+  } catch (ex) {
     // can get here if no screenname
   }
 
   buddyIcon.setAttribute("src", "");
   return false;
 }
 
-function ClearCardViewPane()
-{
+function ClearCardViewPane() {
   cvSetVisible(top.cvData.CardViewBox, false);
 }
 
-function cvSetNodeWithLabel(node, label, text)
-{
+function cvSetNodeWithLabel(node, label, text) {
   if (text) {
     if (label)
       return cvSetNode(node, label + ": " + text);
-    else
-      return cvSetNode(node, text);
+    return cvSetNode(node, text);
   }
-  else
-    return cvSetNode(node, "");
+  return cvSetNode(node, "");
 }
 
-function cvSetCityStateZip(node, city, state, zip)
-{
+function cvSetCityStateZip(node, city, state, zip) {
   let text = "";
 
   if (city && state && zip)
     text = gAddressBookBundle.getFormattedString("cityAndStateAndZip",
                                                  [city, state, zip]);
   else if (city && state && !zip)
     text = gAddressBookBundle.getFormattedString("cityAndStateNoZip",
                                                  [city, state]);
@@ -459,43 +448,41 @@ function cvSetCityStateZip(node, city, s
   else {
     // Only one of the strings is non-empty so contatenating them produces that string.
     text = city + state + zip;
   }
 
   return cvSetNode(node, text);
 }
 
-function cvSetNode(node, text)
-{
+function cvSetNode(node, text) {
   if (!node)
     return false;
 
   node.textContent = text;
   let visible = !!text;
   cvSetVisible(node, visible);
 
   return visible;
 }
 
-function cvAddAddressNodes(node, uri)
-{
+function cvAddAddressNodes(node, uri) {
   var visible = false;
 
   if (node) {
     var editList = GetDirectoryFromURI(uri);
     var addressList = editList.addressLists;
 
     if (addressList) {
       var total = addressList.length;
       if (total > 0) {
         while (node.hasChildNodes()) {
           node.lastChild.remove();
         }
-        for (i = 0;  i < total; i++ ) {
+        for (let i = 0; i < total; i++) {
           var descNode = document.createElement("description");
           var card = addressList.queryElementAt(i, Ci.nsIAbCard);
 
           descNode.setAttribute("class", "CardViewLink");
           node.appendChild(descNode);
 
           var linkNode = document.createElementNS("http://www.w3.org/1999/xhtml", "a");
           linkNode.setAttribute("id", "addr#" + i);
@@ -508,76 +495,70 @@ function cvAddAddressNodes(node, uri)
         visible = true;
       }
     }
     cvSetVisible(node, visible);
   }
   return visible;
 }
 
-function cvSetVisible(node, visible)
-{
-  if ( visible )
+function cvSetVisible(node, visible) {
+  if (visible)
     node.removeAttribute("collapsed");
   else
     node.setAttribute("collapsed", "true");
 }
 
-function HandleLink(node, label, value, box, link)
-{
+function HandleLink(node, label, value, box, link) {
   var visible = cvSetNodeWithLabel(node, label, value);
   if (visible)
-    node.setAttribute('href', link);
+    node.setAttribute("href", link);
   cvSetVisible(box, visible);
 
   return visible;
 }
 
-function OpenURLWithHistory(url)
-{
+function OpenURLWithHistory(url) {
   PlacesUtils.history.insert({
     url,
     visits: [{
       date: new Date()
     }]
   }).catch(Cu.reportError);
   try {
     var messenger = Cc["@mozilla.org/messenger;1"].createInstance();
     messenger = messenger.QueryInterface(Ci.nsIMessenger);
     messenger.launchExternalURL(url);
   } catch (ex) {}
 }
 
-function openLink(id)
-{
+function openLink(id) {
   OpenURLWithHistory(document.getElementById(id).getAttribute("href"));
 
   // return false, so we don't load the href in the addressbook window
   return false;
 }
 
-function openLinkWithUrl(aUrl)
-{
+function openLinkWithUrl(aUrl) {
   if (aUrl)
     OpenURLWithHistory(aUrl);
 
   // return false, so we don't load the href in the addressbook window
   return false;
 }
 
 /* Display the contact photo from the nsIAbCard in the IMG element.
  * If the photo cannot be displayed, show the generic contact
  * photo.
  */
-function displayPhoto(aCard, aImg)
-{
+function displayPhoto(aCard, aImg) {
   var type = aCard.getProperty("PhotoType", "");
   if (!gPhotoDisplayHandlers[type] ||
       !gPhotoDisplayHandlers[type](aCard, aImg))
-    gPhotoDisplayHandlers["generic"](aCard, aImg);
+    gPhotoDisplayHandlers.generic(aCard, aImg);
 }
 
 /* In order to display the contact photos in the card view, there
  * must be a registered photo display handler for the card photo
  * type.  The generic, file, and web photo types are handled
  * by default.
  *
  * A photo display handler is a function that behaves as follows:
@@ -587,34 +568,31 @@ function displayPhoto(aCard, aImg)
  *    the photo from nsIAbCard aCard, and for displaying it in img
  *    img element aImg.  Returns true if successful.  If it returns
  *    false, the generic photo display handler will be called.
  *
  * The following display handlers are for the generic, file and
  * web photo types.
  */
 
-var genericPhotoDisplayHandler = function(aCard, aImg)
-{
+function genericPhotoDisplayHandler(aCard, aImg) {
   aImg.setAttribute("src", defaultPhotoURI);
   return true;
 }
 
-var photoNameDisplayHandler = function(aCard, aImg)
-{
+function photoNameDisplayHandler(aCard, aImg) {
   var photoSrc = getPhotoURI(aCard.getProperty("PhotoName"));
   aImg.setAttribute("src", photoSrc);
   return true;
 }
 
 /* In order for a photo display handler to be registered for
  * a particular photo type, it must be registered here.
  */
-function registerPhotoDisplayHandler(aType, aPhotoDisplayHandler)
-{
+function registerPhotoDisplayHandler(aType, aPhotoDisplayHandler) {
   if (!gPhotoDisplayHandlers[aType])
     gPhotoDisplayHandlers[aType] = aPhotoDisplayHandler;
 }
 
 registerPhotoDisplayHandler("generic", genericPhotoDisplayHandler);
 // File and Web are treated the same, and therefore use the
 // same handler.
 registerPhotoDisplayHandler("file", photoNameDisplayHandler);
--- a/mail/components/addrbook/content/abCommon.js
+++ b/mail/components/addrbook/content/abCommon.js
@@ -1,15 +1,29 @@
 /* -*- Mode: javascript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 ; js-indent-level: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-ChromeUtils.import("resource:///modules/mailServices.js");
+// addressbook.js
+/* globals PluralForm, ResultsPaneSelectionChanged, gPreviousDirTreeIndex, onEnterInSearchBar */
+// abTrees.js
+/* globals gDirectoryTreeView */
+
+// mail/base/content/utilityOverlay.js
+/* globals goSetMenuValue */
+
+// mailnews/addrbook/content/abResultsPane.js
+/* globals kCardsOnly, kListsAndCards, kMultipleListsOnly, kNothingSelected, kSingleListOnly */
+
+// toolkit/content/globalOverlay.js
+/* globals goUpdateCommand */
+
+var { MailServices } = ChromeUtils.import("resource:///modules/mailServices.js", null);
 ChromeUtils.import("resource:///modules/IOUtils.js");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/FileUtils.jsm");
 ChromeUtils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
 
 var gDirTree;
 var abList = null;
 var gAbResultsTree = null;
@@ -35,36 +49,34 @@ var kCollectedAddressbookURI = "moz-abmd
 // blank.
 var defaultPhotoURI = "";
 
 var PERMS_DIRECTORY = parseInt("0755", 8);
 
 // Controller object for Dir Pane
 var DirPaneController =
 {
-  supportsCommand: function(command)
-  {
+  supportsCommand(command) {
     switch (command) {
       case "cmd_selectAll":
       case "cmd_delete":
       case "button_delete":
       case "cmd_properties":
       case "cmd_abToggleStartupDir":
       case "cmd_printcard":
       case "cmd_printcardpreview":
       case "cmd_newlist":
       case "cmd_newCard":
         return true;
       default:
         return false;
     }
   },
 
-  isCommandEnabled: function(command)
-  {
+  isCommandEnabled(command) {
     switch (command) {
       case "cmd_selectAll":
         // The gDirTree pane only handles single selection, but normally we
         // enable cmd_selectAll as it will get forwarded to the results pane.
         // But if there is no gAbView, disable as we can't forward to anywhere.
         return (gAbView != null);
       case "cmd_delete":
       case "button_delete": {
@@ -91,24 +103,22 @@ var DirPaneController =
         // If the directory is a mailing list, and it is read-only,
         // return false to disable deletion.
         if (selectedDir.isMailList && selectedDir.readOnly)
           return false;
 
         // If the selected directory is an ldap directory,
         // and if the prefs for this directory are locked,
         // return false to disable deletion.
-        if (selectedDirURI.startsWith(kLdapUrlPrefix))
-        {
+        if (selectedDirURI.startsWith(kLdapUrlPrefix)) {
           let disable = false;
           try {
             let prefName = selectedDirURI.substr(kLdapUrlPrefix.length);
             disable = Services.prefs.getBoolPref(prefName + ".disable_delete");
-          }
-          catch(ex) {
+          } catch (ex) {
             // If this preference is not set, that's ok.
           }
           if (disable)
             return false;
         }
 
         // Else return true to enable deletion (default).
         return true;
@@ -144,18 +154,17 @@ var DirPaneController =
       case "cmd_newlist":
       case "cmd_newCard":
         return true;
       default:
         return false;
     }
   },
 
-  doCommand: function(command)
-  {
+  doCommand(command) {
     switch (command) {
       case "cmd_printcard":
       case "cmd_printcardpreview":
       case "cmd_selectAll":
         SendCommandToResultsPane(command);
         break;
       case "cmd_delete":
       case "button_delete":
@@ -172,51 +181,46 @@ var DirPaneController =
         AbNewList();
         break;
       case "cmd_newCard":
         AbNewCard();
         break;
     }
   },
 
-  onEvent: function(event)
-  {
+  onEvent(event) {
     // on blur events set the menu item texts back to the normal values
     if (event == "blur")
       goSetMenuValue("cmd_delete", "valueDefault");
   }
 };
 
-function SendCommandToResultsPane(command)
-{
+function SendCommandToResultsPane(command) {
   ResultsPaneController.doCommand(command);
 
   // if we are sending the command so the results pane
   // we should focus the results pane
   gAbResultsTree.focus();
 }
 
-function AbNewLDAPDirectory()
-{
+function AbNewLDAPDirectory() {
   window.openDialog("chrome://messenger/content/addressbook/pref-directory-add.xul",
                     "",
                     "chrome,modal,resizable=no,centerscreen",
                     null);
 }
 
-function AbNewAddressBook()
-{
+function AbNewAddressBook() {
   window.openDialog("chrome://messenger/content/addressbook/abAddressBookNameDialog.xul",
                     "",
                     "chrome,modal,resizable=no,centerscreen",
                     null);
 }
 
-function AbEditSelectedDirectory()
-{
+function AbEditSelectedDirectory() {
   let selectedDir = getSelectedDirectory();
   if (!selectedDir)
     return;
 
   if (selectedDir.isMailList) {
     goEditListDialog(null, selectedDir.URI);
   } else {
     window.openDialog(selectedDir.propertiesChromeURI,
@@ -232,18 +236,17 @@ function updateDirTreeContext() {
     let startupURI = Services.prefs.getCharPref("mail.addr_book.view.startupURI");
     let selectedDirURI = getSelectedDirectoryURI();
     startupItem.setAttribute("checked", (startupURI == selectedDirURI));
   } else {
     startupItem.setAttribute("checked", "false");
   }
 }
 
-function abToggleSelectedDirStartup()
-{
+function abToggleSelectedDirStartup() {
   let selectedDirURI = getSelectedDirectoryURI();
   if (!selectedDirURI)
     return;
 
   let isDefault = Services.prefs.getBoolPref("mail.addr_book.view.startupURIisDefault");
   let startupURI = Services.prefs.getCharPref("mail.addr_book.view.startupURI");
 
   if (isDefault && (startupURI == selectedDirURI)) {
@@ -256,59 +259,54 @@ function abToggleSelectedDirStartup()
     Services.prefs.setCharPref("mail.addr_book.view.startupURI", selectedDirURI);
     Services.prefs.setBoolPref("mail.addr_book.view.startupURIisDefault", true);
   }
 
   // Update the checkbox in the menuitem.
   goUpdateCommand("cmd_abToggleStartupDir");
 }
 
-function AbDeleteSelectedDirectory()
-{
+function AbDeleteSelectedDirectory() {
   let selectedDirURI = getSelectedDirectoryURI();
   if (!selectedDirURI)
     return;
 
   AbDeleteDirectory(selectedDirURI);
 }
 
-function AbDeleteDirectory(aURI)
-{
+function AbDeleteDirectory(aURI) {
   // Determine strings for smart and context-sensitive user prompts
   // for confirming deletion.
   let directory = GetDirectoryFromURI(aURI);
   let confirmDeleteTitleID;
   let confirmDeleteTitle;
   let confirmDeleteMessageID;
   let confirmDeleteMessage;
   let brandShortName;
   let clearCollectionPrefs = false;
 
   if (directory.isMailList) {
     // It's a mailing list.
     confirmDeleteMessageID = "confirmDeleteThisMailingList";
     confirmDeleteTitleID = "confirmDeleteThisMailingListTitle";
+  } else if (Services.prefs.getCharPref("mail.collect_addressbook") == aURI &&
+      Services.prefs.getBoolPref("mail.collect_email_address_outgoing")) {
+    // It's a collection address book: let's be clear about the consequences.
+    brandShortName = document.getElementById("bundle_brand").getString("brandShortName");
+    confirmDeleteMessageID = "confirmDeleteThisCollectionAddressbook";
+    confirmDeleteTitleID = "confirmDeleteThisCollectionAddressbookTitle";
+    clearCollectionPrefs = true;
+  } else if (directory.URI.startsWith(kLdapUrlPrefix)) {
+    // It's an LDAP directory, so we only delete our offline copy.
+    confirmDeleteMessageID = "confirmDeleteThisLDAPDir";
+    confirmDeleteTitleID = "confirmDeleteThisLDAPDirTitle";
   } else {
-    // It's an address book: check which type.
-    if (Services.prefs.getCharPref("mail.collect_addressbook") == aURI &&
-        Services.prefs.getBoolPref("mail.collect_email_address_outgoing")) {
-      // It's a collection address book: let's be clear about the consequences.
-      brandShortName = document.getElementById("bundle_brand").getString("brandShortName");
-      confirmDeleteMessageID = "confirmDeleteThisCollectionAddressbook";
-      confirmDeleteTitleID = "confirmDeleteThisCollectionAddressbookTitle";
-      clearCollectionPrefs = true;
-    } else if (directory.URI.startsWith(kLdapUrlPrefix)) {
-      // It's an LDAP directory, so we only delete our offline copy.
-      confirmDeleteMessageID = "confirmDeleteThisLDAPDir";
-      confirmDeleteTitleID = "confirmDeleteThisLDAPDirTitle";
-    } else {
-      // It's a normal personal address book: we'll delete its contacts, too.
-      confirmDeleteMessageID = "confirmDeleteThisAddressbook";
-      confirmDeleteTitleID = "confirmDeleteThisAddressbookTitle";
-    }
+    // It's a normal personal address book: we'll delete its contacts, too.
+    confirmDeleteMessageID = "confirmDeleteThisAddressbook";
+    confirmDeleteTitleID = "confirmDeleteThisAddressbookTitle";
   }
 
   // Get the raw strings with placeholders.
   confirmDeleteTitle   = gAddressBookBundle.getString(confirmDeleteTitleID);
   confirmDeleteMessage = gAddressBookBundle.getString(confirmDeleteMessageID);
 
   // Substitute placeholders as required.
   // Replace #1 with the name of the selected address book or mailing list.
@@ -332,55 +330,52 @@ function AbDeleteDirectory(aURI)
     // Change the collection AB pref to "Personal Address Book" so that we
     // don't get a blank item in prefs dialog when collection is re-enabled.
     Services.prefs.setCharPref("mail.collect_addressbook", kPersonalAddressbookURI);
   }
 
   MailServices.ab.deleteAddressBook(aURI);
 }
 
-function GetParentRow(aTree, aRow)
-{
+function GetParentRow(aTree, aRow) {
   var row = aRow;
   var level = aTree.view.getLevel(row);
   var parentLevel = level;
   while (parentLevel >= level) {
     row--;
     if (row == -1)
       return row;
     parentLevel = aTree.view.getLevel(row);
   }
   return row;
 }
 
-function InitCommonJS()
-{
+function InitCommonJS() {
   gDirTree = document.getElementById("dirTree");
   abList = document.getElementById("addressbookList");
   gAddressBookBundle = document.getElementById("bundle_addressBook");
 }
 
-function AbDelete()
-{
+function AbDelete() {
   let types = GetSelectedCardTypes();
   if (types == kNothingSelected)
     return;
 
   // Determine strings for smart and context-sensitive user prompts
   // for confirming deletion.
   let confirmDeleteTitleID;
   let confirmDeleteTitle;
   let confirmDeleteMessageID;
   let confirmDeleteMessage;
   let itemName;
   let containingListName;
   let selectedDir = getSelectedDirectory();
   let numSelectedItems = gAbView.selection.count;
 
-  switch(types) {
+  switch (types) {
     case kListsAndCards:
       confirmDeleteMessageID = "confirmDelete2orMoreContactsAndLists";
       confirmDeleteTitleID   = "confirmDelete2orMoreContactsAndListsTitle";
       break;
     case kSingleListOnly:
       // Set item name for single mailing list.
       let theCard = GetSelectedAbCards()[0];
       itemName = theCard.displayName;
@@ -398,25 +393,23 @@ function AbDelete()
           confirmDeleteMessageID = "confirmRemoveThisContact";
           confirmDeleteTitleID = "confirmRemoveThisContactTitle";
         } else {
           confirmDeleteMessageID = "confirmRemove2orMoreContacts";
           confirmDeleteTitleID   = "confirmRemove2orMoreContactsTitle";
         }
         // For removing contacts from mailing list, set placeholder value
         containingListName = selectedDir.dirName;
-      } else {
+      } else if (numSelectedItems == 1) {
         // Contact(s) in address books will be deleted.
-        if (numSelectedItems == 1) {
-          confirmDeleteMessageID = "confirmDeleteThisContact";
-          confirmDeleteTitleID   = "confirmDeleteThisContactTitle";
-        } else {
-          confirmDeleteMessageID = "confirmDelete2orMoreContacts";
-          confirmDeleteTitleID   = "confirmDelete2orMoreContactsTitle";
-        }
+        confirmDeleteMessageID = "confirmDeleteThisContact";
+        confirmDeleteTitleID   = "confirmDeleteThisContactTitle";
+      } else {
+        confirmDeleteMessageID = "confirmDelete2orMoreContacts";
+        confirmDeleteTitleID   = "confirmDelete2orMoreContactsTitle";
       }
       if (numSelectedItems == 1) {
         // Set item name for single contact.
         let theCard = GetSelectedAbCards()[0];
         let nameFormatFromPref = Services.prefs.getIntPref("mail.addr_book.lastnamefirst");
         itemName = theCard.generateName(nameFormatFromPref);
       }
       break;
@@ -467,55 +460,51 @@ function AbDelete()
     }
     SetAbView(kAllDirectoryRoot + "?");
   } else {
     // Delete cards from address books or mailing lists.
     gAbView.deleteSelectedCards();
   }
 }
 
-function AbNewCard()
-{
+function AbNewCard() {
   goNewCardDialog(getSelectedDirectoryURI());
 }
 
-function AbEditCard(card)
-{
+function AbEditCard(card) {
   // Need a card,
   // but not allowing AOL special groups to be edited.
   if (!card)
     return;
 
   if (card.isMailList) {
     goEditListDialog(card, card.mailListURI);
-  }
-  else {
+  } else {
     goEditCardDialog(getSelectedDirectoryURI(), card);
   }
 }
 
-function AbNewMessage()
-{
+function AbNewMessage() {
   let msgComposeType = Ci.nsIMsgCompType;
   let msgComposeFormat = Ci.nsIMsgCompFormat;
 
   let params = Cc["@mozilla.org/messengercompose/composeparams;1"].createInstance(Ci.nsIMsgComposeParams);
   if (params) {
     params.type = msgComposeType.New;
     params.format = msgComposeFormat.Default;
     let composeFields = Cc["@mozilla.org/messengercompose/composefields;1"].createInstance(Ci.nsIMsgCompFields);
     if (composeFields) {
       if (DirPaneHasFocus()) {
         let selectedDir = getSelectedDirectory();
         let hidesRecipients = false;
         try {
           // This is a bit of hackery so that extensions can have mailing lists
           // where recipients are sent messages via BCC.
           hidesRecipients = selectedDir.getBoolValue("HidesRecipients", false);
-        } catch(e) {
+        } catch (e) {
           // Standard Thunderbird mailing lists do not have preferences
           // associated with them, so we'll silently eat the error.
         }
 
         if (selectedDir && selectedDir.isMailList && hidesRecipients)
           // Bug 669301 (https://bugzilla.mozilla.org/show_bug.cgi?id=669301)
           // We're using BCC right now to hide recipients from one another.
           // We should probably use group syntax, but that's broken
@@ -547,259 +536,237 @@ function InitViewLayoutMenuPopup(event) 
   cardPaneMenuItem.setAttribute("checked", document.getElementById(
     "results-splitter").getAttribute("state") != "collapsed");
 }
 
 // Generate a list of cards from the selected mailing list
 // and get a comma separated list of card addresses. If the
 // item selected in the directory pane is not a mailing list,
 // an empty string is returned.
-function GetSelectedAddressesFromDirTree()
-{
+function GetSelectedAddressesFromDirTree() {
   let selectedDir = getSelectedDirectory();
 
   if (!selectedDir || !selectedDir.isMailList)
     return "";
 
   let listCardsCount = selectedDir.addressLists.length;
   let cards = new Array(listCardsCount);
   for (let i = 0; i < listCardsCount; ++i)
     cards[i] = selectedDir.addressLists
                  .queryElementAt(i, Ci.nsIAbCard);
   return GetAddressesForCards(cards);
 }
 
 // Generate a comma separated list of addresses from a given
 // set of cards.
-function GetAddressesForCards(cards)
-{
+function GetAddressesForCards(cards) {
   var addresses = "";
 
   if (!cards) {
     Cu.reportError("GetAddressesForCards: |cards| is null.");
     return addresses;
   }
 
-  var count = cards.length;
-
   // We do not handle the case where there is one or more null-ish
   // element in the Array.  Always non-null element is pushed into
   // cards[] array.
 
   let generatedAddresses = cards.map(GenerateAddressFromCard)
     .filter(function(aAddress) {
       return aAddress;
     });
-  return generatedAddresses.join(',');
+  return generatedAddresses.join(",");
 }
 
-function SelectFirstAddressBook()
-{
+function SelectFirstAddressBook() {
   if (gDirTree.view.selection.currentIndex != 0) {
     gDirTree.view.selection.select(0);
     // If gPreviousDirTreeIndex == 0 then DirPaneSelectionChange() and
     // ChangeDirectoryByURI() have already been run
     // (e.g. by the onselect event on the tree) so skip the call.
     if (gPreviousDirTreeIndex != 0)
       ChangeDirectoryByURI(getSelectedDirectoryURI());
   }
   gAbResultsTree.focus();
 }
 
 /**
  * Get the startup view directory from pref and select it in the
  * directory tree so that it gets shown.
  */
-function selectStartupViewDirectory()
-{
+function selectStartupViewDirectory() {
   let startupURI = Services.prefs.getCharPref("mail.addr_book.view.startupURI");
   if (!startupURI) {
     // If pref is empty, fall back to "All Address Books" root directory.
-    startupURI = kAllDirectoryRoot + "?"
+    startupURI = kAllDirectoryRoot + "?";
   }
   let startupDirTreeIndex = gDirectoryTreeView.getIndexForId(startupURI);
   // XXX TODO: If directory of startupURI is collapsed, we fail to find and
   // select it, so getIndexForId returns -1; for now, fall back to "All Address
   // Books" root directory.
   // We also end up here and redirect to "All ABs" root when default directory
   // is not found because it has been deleted; after fixing the collapsed case,
   // deletion will be the only case to end up here, then we could reset the pref
   // here (somewhat lazy and fuzzy).
   if (startupDirTreeIndex == -1) {
     startupDirTreeIndex = gDirectoryTreeView.getIndexForId(kAllDirectoryRoot + "?");
   }
   gDirectoryTreeView.selection.select(startupDirTreeIndex);
 }
 
-function DirPaneClick(event)
-{
+function DirPaneClick(event) {
   // we only care about left button events
   if (event.button != 0)
     return;
 
   // if the user clicks on the header / trecol, do nothing
   if (event.originalTarget.localName == "treecol") {
     event.stopPropagation();
-    return;
+
   }
 }
 
-function DirPaneDoubleClick(event)
-{
+function DirPaneDoubleClick(event) {
   // We only care about left button events.
   if (event.button != 0)
     return;
 
   // Ignore double clicking on invalid rows.
   let row = gDirTree.treeBoxObject.getRowAt(event.clientX, event.clientY);
-  if (row == -1 || row > gDirTree.view.rowCount-1)
+  if (row == -1 || row > gDirTree.view.rowCount - 1)
     return;
 
   // Default action for double click is expand/collapse which ships with the tree.
   // For convenience, allow double-click to edit the properties of mailing
   // lists in directory tree.
   if (gDirTree && gDirTree.view.selection &&
       gDirTree.view.selection.count == 1 &&
       getSelectedDirectory().isMailList) {
     AbEditSelectedDirectory();
   }
 }
 
-function DirPaneSelectionChange()
-{
+function DirPaneSelectionChange() {
   let uri = getSelectedDirectoryURI();
   // clear out the search box when changing folders...
   onAbClearSearch(false);
   if (gDirTree && gDirTree.view.selection && gDirTree.view.selection.count == 1) {
-    gPreviousDirTreeIndex = gDirTree.currentIndex;
+    gPreviousDirTreeIndex = gDirTree.currentIndex; // eslint-disable-line no-native-reassign
     ChangeDirectoryByURI(uri);
     document.getElementById("localResultsOnlyMessage")
             .setAttribute("hidden",
                           !gDirectoryTreeView.hasRemoteAB ||
                           uri != kAllDirectoryRoot + "?");
   }
 
-  goUpdateCommand('cmd_newlist');
-  goUpdateCommand('cmd_newCard');
+  goUpdateCommand("cmd_newlist");
+  goUpdateCommand("cmd_newCard");
 }
 
-function ChangeDirectoryByURI(uri = kPersonalAddressbookURI)
-{
+function ChangeDirectoryByURI(uri = kPersonalAddressbookURI) {
   SetAbView(uri);
 
   // Actively de-selecting if there are any pre-existing selections
   // in the results list.
   if (gAbView && gAbView.getCardFromRow(0))
     gAbView.selection.clearSelection();
   else
     // the selection changes if we were switching directories.
-    ResultsPaneSelectionChanged()
+    ResultsPaneSelectionChanged();
 }
 
-function AbNewList()
-{
+function AbNewList() {
   goNewListDialog(getSelectedDirectoryURI());
 }
 
-function goNewListDialog(selectedAB)
-{
+function goNewListDialog(selectedAB) {
   window.openDialog("chrome://messenger/content/addressbook/abMailListDialog.xul",
                     "",
                     "chrome,modal,resizable=no,centerscreen",
-                    {selectedAB:selectedAB});
+                    {selectedAB});
 }
 
-function goEditListDialog(abCard, listURI)
-{
+function goEditListDialog(abCard, listURI) {
   let params = {
-    abCard: abCard,
-    listURI: listURI,
+    abCard,
+    listURI,
     refresh: false, // This is an out param, true if OK in dialog is clicked.
   };
   window.openDialog("chrome://messenger/content/addressbook/abEditListDialog.xul",
                     "",
                     "chrome,modal,resizable=no,centerscreen",
                     params);
   if (params.refresh) {
     ChangeDirectoryByURI(listURI); // force refresh
   }
 }
 
-function goNewCardDialog(selectedAB)
-{
+function goNewCardDialog(selectedAB) {
   window.openDialog("chrome://messenger/content/addressbook/abNewCardDialog.xul",
                     "",
                     "chrome,modal,resizable=no,centerscreen",
-                    {selectedAB:selectedAB});
+                    {selectedAB});
 }
 
-function goEditCardDialog(abURI, card)
-{
+function goEditCardDialog(abURI, card) {
   window.openDialog("chrome://messenger/content/addressbook/abEditCardDialog.xul",
                     "",
                     "chrome,modal,resizable=no,centerscreen",
-                    {abURI:abURI, card:card});
+                    {abURI, card});
 }
 
-function setSortByMenuItemCheckState(id, value)
-{
-    var menuitem = document.getElementById(id);
-    if (menuitem) {
-      menuitem.setAttribute("checked", value);
-    }
+function setSortByMenuItemCheckState(id, value) {
+  var menuitem = document.getElementById(id);
+  if (menuitem)
+    menuitem.setAttribute("checked", value);
 }
 
-function InitViewSortByMenu()
-{
-    var sortColumn = kDefaultSortColumn;
-    var sortDirection = kDefaultAscending;
+function InitViewSortByMenu() {
+  var sortColumn = kDefaultSortColumn;
+  var sortDirection = kDefaultAscending;
 
-    if (gAbView) {
-      sortColumn = gAbView.sortColumn;
-      sortDirection = gAbView.sortDirection;
-    }
+  if (gAbView) {
+    sortColumn = gAbView.sortColumn;
+    sortDirection = gAbView.sortDirection;
+  }
 
-    // this approach is necessary to support generic columns that get overlaid.
-    let elements = document.querySelectorAll('[name="sortas"]');
-    for (let i = 0; i < elements.length; i++) {
-      let cmd = elements[i].id;
-      let columnForCmd = cmd.substr(10); // everything right of cmd_SortBy
-      setSortByMenuItemCheckState(cmd, (sortColumn == columnForCmd));
-    }
+  // this approach is necessary to support generic columns that get overlaid.
+  let elements = document.querySelectorAll('[name="sortas"]');
+  for (let i = 0; i < elements.length; i++) {
+    let cmd = elements[i].id;
+    let columnForCmd = cmd.substr(10); // everything right of cmd_SortBy
+    setSortByMenuItemCheckState(cmd, (sortColumn == columnForCmd));
+  }
 
-    setSortByMenuItemCheckState("sortAscending", (sortDirection == kDefaultAscending));
-    setSortByMenuItemCheckState("sortDescending", (sortDirection == kDefaultDescending));
+  setSortByMenuItemCheckState("sortAscending", (sortDirection == kDefaultAscending));
+  setSortByMenuItemCheckState("sortDescending", (sortDirection == kDefaultDescending));
 }
 
-function GenerateAddressFromCard(card)
-{
+function GenerateAddressFromCard(card) {
   if (!card)
     return "";
 
   var email;
 
-  if (card.isMailList)
-  {
+  if (card.isMailList) {
     var directory = GetDirectoryFromURI(card.mailListURI);
     email = directory.description || card.displayName;
+  } else {
+    email = card.primaryEmail;
   }
-  else
-    email = card.primaryEmail;
 
   return MailServices.headerParser.makeMimeAddress(card.displayName, email);
 }
 
-function GetDirectoryFromURI(uri)
-{
+function GetDirectoryFromURI(uri) {
   return MailServices.ab.getDirectory(uri);
 }
 
 // returns null if abURI is not a mailing list URI
-function GetParentDirectoryFromMailingListURI(abURI)
-{
+function GetParentDirectoryFromMailingListURI(abURI) {
   var abURIArr = abURI.split("/");
   /*
    turn turn "moz-abmdbdirectory://abook.mab/MailList6"
    into ["moz-abmdbdirectory:","","abook.mab","MailList6"]
    then, turn ["moz-abmdbdirectory:","","abook.mab","MailList6"]
    into "moz-abmdbdirectory://abook.mab"
   */
   if (abURIArr.length == 4 && abURIArr[0] == "moz-abmdbdirectory:" && abURIArr[3] != "") {
@@ -807,86 +774,80 @@ function GetParentDirectoryFromMailingLi
   }
 
   return null;
 }
 
 /**
  * Return true if the directory pane has focus, otherwise false.
  */
-function DirPaneHasFocus()
-{
+function DirPaneHasFocus() {
   return (top.document.commandDispatcher.focusedElement == gDirTree);
 }
 
 /**
  * Get the selected directory object.
  *
  * @return The object of the currently selected directory
  */
-function getSelectedDirectory()
-{
+function getSelectedDirectory() {
   // Contacts Sidebar
   if (abList)
     return MailServices.ab.getDirectory(abList.value);
 
   // Main Address Book
   if (gDirTree.currentIndex < 0)
     return null;
   return gDirectoryTreeView.getDirectoryAtIndex(gDirTree.currentIndex);
 }
 
 /**
  * Get the URI of the selected directory.
  *
  * @return The URI of the currently selected directory
  */
-function getSelectedDirectoryURI()
-{
+function getSelectedDirectoryURI() {
   // Contacts Sidebar
   if (abList)
     return abList.value;
 
   // Main Address Book
   if (gDirTree.currentIndex < 0)
     return null;
   return gDirectoryTreeView.getDirectoryAtIndex(gDirTree.currentIndex).URI;
 }
 
 /**
  * DEPRECATED legacy function wrapper for addon compatibility;
  * use getSelectedDirectoryURI() instead!
  * Return the URI of the selected directory.
  */
-function GetSelectedDirectory()
-{
+function GetSelectedDirectory() {
   return getSelectedDirectoryURI();
 }
 
 /**
  * Clears the contents of the search input field,
  * possibly causing refresh of results.
  *
  * @param aRefresh  Set to false if the refresh isn't needed,
  *                  e.g. window/AB is going away so user will not see anything.
  */
-function onAbClearSearch(aRefresh = true)
-{
+function onAbClearSearch(aRefresh = true) {
   let searchInput = document.getElementById("peopleSearchInput");
   if (!searchInput || !searchInput.value)
     return;
 
   searchInput.value = "";
   if (aRefresh)
     onEnterInSearchBar();
 }
 
 // sets focus into the quick search box
-function QuickSearchFocus()
-{
+function QuickSearchFocus() {
   let searchInput = document.getElementById("peopleSearchInput");
   if (searchInput) {
     searchInput.focus();
     searchInput.select();
   }
 }
 
 /**
@@ -912,18 +873,17 @@ function getPhotosDir() {
  * @return A URI pointing to a photo.
  */
 function getPhotoURI(aPhotoName) {
   if (!aPhotoName)
     return defaultPhotoURI;
   var file = getPhotosDir();
   try {
     file.append(aPhotoName);
-  }
-  catch (e) {
+  } catch (e) {
     return defaultPhotoURI;
   }
   if (!file.exists())
     return defaultPhotoURI;
   return Services.io.newFileURI(file).spec;
 }
 
 /**
@@ -933,17 +893,17 @@ function getPhotoURI(aPhotoName) {
  * @param aExtension The file extension of the photo.
  *
  * @return A unique filename in the given path.
  */
 function makePhotoFile(aDir, aExtension) {
   var filename, newFile;
   // Find a random filename for the photo that doesn't exist yet
   do {
-    filename = new String(Math.random()).replace("0.", "") + "." + aExtension;
+    filename = Math.random().toString().replace("0.", "") + "." + aExtension;
     newFile = aDir.clone();
     newFile.append(filename);
   } while (newFile.exists());
   return newFile;
 }
 
 /**
  * Public self-contained object for image transfers.
@@ -1014,49 +974,47 @@ var gImageDownloader = (function() {
     }
 
     downloader = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
                    .createInstance(Ci.nsIWebBrowserPersist);
     downloader.persistFlags = Ci.nsIWebBrowserPersist.PERSIST_FLAGS_BYPASS_CACHE
                             | Ci.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES
                             | Ci.nsIWebBrowserPersist.PERSIST_FLAGS_CLEANUP_ON_FAILURE;
     downloader.progressListener = {
-      onProgressChange: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress,
+      onProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress,
                                  aCurTotalProgress, aMaxTotalProgress) {
         if (aMaxTotalProgress > -1 && callbackProgress) {
           // Download progress is 0-90%, 90-100% is verifying and scaling the image.
           let percent = Math.round(initProgress + (aCurTotalProgress / aMaxTotalProgress) * (90 - initProgress));
           callbackProgress(STATE_TRANSFERRING, percent);
         }
       },
-      onStateChange: function(aWebProgress, aRequest, aStateFlag, aStatus) {
+      onStateChange(aWebProgress, aRequest, aStateFlag, aStatus) {
         // Check if the download successfully finished.
         if ((aStateFlag & Ci.nsIWebProgressListener.STATE_STOP) &&
             !(aStateFlag & Ci.nsIWebProgressListener.STATE_IS_REQUEST)) {
           try {
             // Check the response code in case of an HTTP request to catch 4xx errors
             let http = aRequest.QueryInterface(Ci.nsIHttpChannel);
             if (http.responseStatus == 200) {
               verifyImage();
-            } else {
-              if (callbackError) {
-                callbackError(ERROR_UNAVAILABLE);
-              }
+            } else if (callbackError) {
+              callbackError(ERROR_UNAVAILABLE);
             }
           } catch (err) {
             // The nsIHttpChannel interface is not available - just proceed
             verifyImage();
           }
         }
       }
     };
 
     let source;
     try {
-      source = Services.io.newURI(aURI, null, null);
+      source = Services.io.newURI(aURI);
     } catch (err) {
       if (callbackError) {
         callbackError(ERROR_INVALID_URI);
       }
       return;
     }
 
     // Start the transfer to a temporary file.
@@ -1082,17 +1040,17 @@ var gImageDownloader = (function() {
    */
   function verifyImage() {
     let img = new Image();
     img.onerror = function() {
       cleanup();
       if (callbackError) {
         callbackError(ERROR_INVALID_IMG);
       }
-    }
+    };
     img.onload = function() {
       if (callbackProgress) {
         callbackProgress(STATE_RESIZING, 95);
       }
 
       // Images are scaled down in two steps to improve quality. Resizing ratios
       // larger than 2 use a different interpolation algorithm than small ratios.
       // Resize three times (instead of just two steps) to improve the final quality.
@@ -1103,17 +1061,17 @@ var gImageDownloader = (function() {
       saveCanvas(canvas);
 
       if (callbackProgress) {
         callbackProgress(STATE_OK, 100);
       }
 
       // Remove the temporary file.
       cleanup();
-    }
+    };
 
     if (callbackProgress) {
       callbackProgress(92);
     }
 
     img.src = Services.io.newFileURI(tempFile).spec;
   }
 
@@ -1182,26 +1140,26 @@ var gImageDownloader = (function() {
    * Save the contents of a canvas to the photos directory of the profile.
    */
   function saveCanvas(aCanvas) {
     // Get the photos directory and check that it exists
     let file = getPhotosDir();
     file = makePhotoFile(file, "png");
 
     // Create a data url from the canvas and then create URIs of the source and targets
-    let source = Services.io.newURI(aCanvas.toDataURL("image/png", ""), "UTF8", null);
+    let source = Services.io.newURI(aCanvas.toDataURL("image/png", ""), "UTF8");
     let target = Services.io.newFileURI(file);
 
     downloader = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
                    .createInstance(Ci.nsIWebBrowserPersist);
     downloader.persistFlags = Ci.nsIWebBrowserPersist.PERSIST_FLAGS_BYPASS_CACHE
                             | Ci.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES
                             | Ci.nsIWebBrowserPersist.PERSIST_FLAGS_CLEANUP_ON_FAILURE;
     downloader.progressListener = {
-      onStateChange: function(aWebProgress, aRequest, aFlag, aStatus) {
+      onStateChange(aWebProgress, aRequest, aFlag, aStatus) {
         if ((aFlag & Ci.nsIWebProgressListener.STATE_STOP) &&
             !(aFlag & Ci.nsIWebProgressListener.STATE_IS_REQUEST)) {
           if (callbackSuccess) {
             callbackSuccess(file.leafName);
           }
         }
       }
     };
@@ -1210,26 +1168,26 @@ var gImageDownloader = (function() {
     // we are downloading comes from. If, and only if, the URL is not
     // related to a window, null should be used instead.
     let privacy = PrivateBrowsingUtils.privacyContextFromWindow(window);
     downloader.saveURI(source, null, null, null, null, null, target, privacy);
   }
 
   // Publicly accessible methods.
   return {
-    cancelSave: cancelSave,
-    savePhoto: savePhoto,
-    STATE_TRANSFERRING: STATE_TRANSFERRING,
-    STATE_RESIZING: STATE_RESIZING,
-    STATE_OK: STATE_OK,
-    ERROR_UNAVAILABLE: ERROR_UNAVAILABLE,
-    ERROR_INVALID_URI: ERROR_INVALID_URI,
-    ERROR_INVALID_IMG: ERROR_INVALID_IMG,
-    ERROR_SAVE: ERROR_SAVE
-  }
+    cancelSave,
+    savePhoto,
+    STATE_TRANSFERRING,
+    STATE_RESIZING,
+    STATE_OK,
+    ERROR_UNAVAILABLE,
+    ERROR_INVALID_URI,
+    ERROR_INVALID_IMG,
+    ERROR_SAVE
+  };
 })();
 
 
 /**
  * Validates the given year and returns it, if it looks sane.
  * Returns kDefaultYear (a leap year), if no valid date is given.
  * This ensures that month/day calculations still work.
  */
@@ -1266,18 +1224,17 @@ function nearestLeap(aYear) {
  * goSetLabelAccesskeyTooltiptext("cmd_foo", "", "", "valueFlavorTooltiptext");
  *
  * @param aID                    the ID of an XUL element (attribute source and target)
  * @param aLabelAttribute        (optional) the name of a custom label attribute of aID, or ""
  * @param aAccessKeyAttribute    (optional) the name of a custom accesskey attribute of aID, or ""
  * @param aTooltipTextAttribute  (optional) the name of a custom tooltiptext attribute of aID, or ""
  */
 function goSetLabelAccesskeyTooltiptext(aID, aLabelAttribute, aAccessKeyAttribute,
-                                             aTooltipTextAttribute)
-{
+                                             aTooltipTextAttribute) {
   let node = top.document.getElementById(aID);
   if (!node) {
     // tweak for composition's abContactsPanel
     node = document.getElementById(aID);
   }
   if (!node)
     return;
 
@@ -1288,15 +1245,15 @@ function goSetLabelAccesskeyTooltiptext(
       // In XUL (DOM Level 3), getAttribute() on non-existing attributes returns
       // "" (instead of null), which is indistinguishable from existing valid
       // attributes with value="", so we have to check using hasAttribute().
       if (node.hasAttribute(customAttr)) {
         let value = node.getAttribute(customAttr);
         node.setAttribute(attr, value);
       } else {  // missing custom attribute
         dump('Something wrong here: goSetLabelAccesskeyTooltiptext("' + aID + '", ...): ' +
-             'Missing custom attribute: ' + customAttr + '\n');
+             "Missing custom attribute: " + customAttr + "\n");
       }
     } else if (customAttr === "") {
       node.removeAttribute(attr);
     }
   }
 }
--- a/mail/components/addrbook/content/abContactsPanel.js
+++ b/mail/components/addrbook/content/abContactsPanel.js
@@ -1,18 +1,28 @@
 /* -*- Mode: javascript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 ; js-indent-level: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+// addressbook.js
+/* globals gQueryURIFormat */
+
+// mailnews/addrbook/content/abResultsPane.js
+/* globals GetNumSelectedCards */
+// mailnews/base/util/ABQueryUtils.jsm
+/* globals getModelQuery, getSearchTokens, generateQueryURI */
+
+// toolkit/content/globalOverlay.js
+/* globals goUpdateCommand */
+
 ChromeUtils.import("resource:///modules/ABQueryUtils.jsm");
 
-function GetAbViewListener()
-{
+function GetAbViewListener() {
   // the ab panel doesn't care if the total changes, or if the selection changes
   return null;
 }
 
 /**
  * Handle the context menu event of results tree (right-click, context menu key
  * press, etc.). Show the respective context menu for selected contact(s) or
  * results tree blank space (work around for XUL tree bug 1331377).
@@ -46,18 +56,17 @@ function contactsListOnContextMenu(aEven
 }
 
 /**
  * Handle the click event of the results tree (workaround for XUL tree
  * bug 1331377).
  *
  * @param aEvent  a click event
  */
-function contactsListOnClick(aEvent)
-{
+function contactsListOnClick(aEvent) {
   CommandUpdate_AddressBook();
 
   let target = aEvent.originalTarget;
 
   // Left click on column header: Change sort direction.
   if (target.localName == "treecol" && aEvent.button == 0) {
     let sortDirection = target.getAttribute("sortDirection") == kDefaultDescending ?
                         kDefaultAscending : kDefaultDescending;
@@ -71,50 +80,45 @@ function contactsListOnClick(aEvent)
       // Any click on results tree whitespace.
       if ((aEvent.detail == 1 && aEvent.button == 0) || aEvent.button == 2) {
         // Single left click or any right click on results tree blank space:
         // Clear selection. This also triggers on the first click of any
         // double-click, but that's ok. MAC OS X doesn't return event.detail==1
         // for single right click, so we also let this trigger for the second
         // click of right double-click.
         gAbView.selection.clearSelection();
-        return;
+
       }
-    } else {
+    } else if (aEvent.button == 0 && aEvent.detail == 2) {
       // Any click on results tree rows.
-      if (aEvent.button == 0 && aEvent.detail == 2) {
-        // Double-click on a row: Go ahead and add the entry.
-        addSelectedAddresses("addr_to");
-        return;
-      }
+      // Double-click on a row: Go ahead and add the entry.
+      addSelectedAddresses("addr_to");
     }
   }
 }
 
 /**
  * Appends the currently selected cards as new recipients in the composed message.
  *
  * @param aRecipientType  Type of recipient, e.g. "addr_to".
  */
-function addSelectedAddresses(aRecipientType)
-{
+function addSelectedAddresses(aRecipientType) {
   var cards = GetSelectedAbCards();
 
   // Turn each card into a properly formatted address.
   var addressArray = cards.map(GenerateAddressFromCard).filter(addr => (addr != ""));
   parent.AddRecipientsArray(aRecipientType, addressArray);
 }
 
-function AddressBookMenuListChange()
-{
+function AddressBookMenuListChange() {
   let searchInput = document.getElementById("peopleSearchInput");
   if (searchInput.value && !searchInput.showingSearchCriteria)
     onEnterInSearchBar();
   else
-    ChangeDirectoryByURI(document.getElementById('addressbookList').value);
+    ChangeDirectoryByURI(document.getElementById("addressbookList").value);
 
   // Hide the addressbook column if the selected addressbook isn't
   // "All address books". Since the column is redundant in all other cases.
   let addrbookColumn = document.getElementById("addrbook");
   if (abList.value.startsWith(kAllDirectoryRoot + "?")) {
     addrbookColumn.hidden = !gShowAbColumnInComposeSidebar;
     addrbookColumn.removeAttribute("ignoreincolumnpicker");
   } else {
@@ -122,23 +126,22 @@ function AddressBookMenuListChange()
     addrbookColumn.setAttribute("ignoreincolumnpicker", "true");
   }
 
   CommandUpdate_AddressBook();
 }
 
 var mutationObs = null;
 
-function AbPanelLoad()
-{
+function AbPanelLoad() {
   InitCommonJS();
 
   document.title = parent.document.getElementById("sidebar-title").value;
 
-  var abPopup = document.getElementById('addressbookList');
+  var abPopup = document.getElementById("addressbookList");
 
   // Reselect the persisted address book if possible, if not just select the
   // first in the list.
   var temp = abPopup.value;
   abPopup.selectedItem = null;
   abPopup.value = temp;
   if (!abPopup.selectedItem)
     abPopup.selectedIndex = 0;
@@ -157,72 +160,65 @@ function AbPanelLoad()
   });
 
   document.getElementById("addrbook").hidden = !gShowAbColumnInComposeSidebar;
 
   mutationObs.observe(document.getElementById("addrbook"),
                       { attributes: true, childList: true });
 }
 
-function AbPanelUnload()
-{
+function AbPanelUnload() {
   mutationObs.disconnect();
 
   CloseAbView();
 }
 
-function AbPanelNewCard()
-{
+function AbPanelNewCard() {
   goNewCardDialog(abList.value);
 }
 
-function AbPanelNewList()
-{
+function AbPanelNewList() {
   goNewListDialog(abList.value);
 }
 
-function ResultsPaneSelectionChanged()
-{
+function ResultsPaneSelectionChanged() {
   // do nothing for ab panel
 }
 
-function OnClickedCard()
-{
+function OnClickedCard() {
   // do nothing for ab panel
 }
 
-function AbResultsPaneDoubleClick(card)
-{
+function AbResultsPaneDoubleClick(card) {
   // double click for ab panel means "send mail to this person / list"
   AbNewMessage();
 }
 
-function UpdateCardView()
-{
+function UpdateCardView() {
   // do nothing for ab panel
 }
 
-function CommandUpdate_AddressBook()
-{
+function CommandUpdate_AddressBook() {
   // Toggle disable state of to,cc,bcc buttons.
   let disabled = (GetNumSelectedCards() == 0) ? "true" : "false";
   document.getElementById("cmd_addrTo").setAttribute("disabled", disabled);
   document.getElementById("cmd_addrCc").setAttribute("disabled", disabled);
   document.getElementById("cmd_addrBcc").setAttribute("disabled", disabled);
 
-  goUpdateCommand('cmd_delete');
-  goUpdateCommand('cmd_properties');
+  goUpdateCommand("cmd_delete");
+  goUpdateCommand("cmd_properties");
 }
 
-function onEnterInSearchBar()
-{
+function onEnterInSearchBar() {
   if (!gQueryURIFormat) {
     // Get model query from pref. We don't want the query starting with "?"
     // as we have to prefix "?and" to this format.
+    /* eslint-disable no-native-reassign */
     gQueryURIFormat = getModelQuery("mail.addr_book.quicksearchquery.format");
+    /* eslint-enable no-native-reassign */
   }
 
   let searchURI = getSelectedDirectoryURI();
   let searchInput = document.getElementById("peopleSearchInput");
 
   // Use helper method to split up search query to multi-word search
   // query against multiple fields.
   if (searchInput) {
--- a/mail/components/addrbook/content/abTrees.js
+++ b/mail/components/addrbook/content/abTrees.js
@@ -1,19 +1,24 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+// mailnews/addrbook/content/abDragDrop.js
+/* globals abDirTreeObserver */
+// mailnews/base/content/jsTreeView.js
+/* globals PROTO_TREE_VIEW */
+
 /**
  * This file contains our implementation for various addressbook trees.  It
  * depends on jsTreeView.js being loaded before this script is loaded.
  */
 
 ChromeUtils.import("resource://gre/modules/Services.jsm");
-ChromeUtils.import("resource:///modules/mailServices.js");
+var { MailServices } = ChromeUtils.import("resource:///modules/mailServices.js", null);
 ChromeUtils.import("resource:///modules/IOUtils.js");
 
 // Tree Sort helper methods.
 var AB_ORDER = ["aab", "pab", "mork", "ldap", "mapi+other", "anyab", "cab"];
 
 function getDirectoryValue(aDir, aKey) {
   if (aKey == "ab_type") {
     if (aDir._directory.URI == kAllDirectoryRoot + "?")
@@ -104,17 +109,17 @@ abDirTreeItem.prototype = {
       if (this._directory.URI == (kAllDirectoryRoot + "?"))
         myEnum = MailServices.ab.directories;
       else
         myEnum = this._directory.childNodes;
 
       while (myEnum.hasMoreElements()) {
         var abItem = new abDirTreeItem(myEnum.getNext()
                                        .QueryInterface(Ci.nsIAbDirectory));
-        if (gDirectoryTreeView&&
+        if (gDirectoryTreeView &&
             this.id == kAllDirectoryRoot + "?" &&
             getDirectoryValue(abItem, "ab_type") == "ldap")
           gDirectoryTreeView.hasRemoteAB = true;
 
         this._children.push(abItem);
         this._children[this._children.length - 1]._level = this._level + 1;
         this._children[this._children.length - 1]._parent = this;
       }
@@ -190,46 +195,44 @@ directoryTreeView.prototype = {
    * NOTE: This function will result in indeterminate rows being selected.
    *       Callers should take care to re-select a desired row after calling
    *       this function.
    */
   _rebuild: function dtv__rebuild() {
     var oldCount = this._rowMap.length;
     this._rowMap = [];
 
-    var dirEnum = MailServices.ab.directories;
-
     // Make an entry for All Address Books.
     let rootAB = MailServices.ab.getDirectory(kAllDirectoryRoot + "?");
     rootAB.dirName = gAddressBookBundle.getString("allAddressBooks");
     this._rowMap.push(new abDirTreeItem(rootAB));
 
     // Sort our addressbooks now
     this._rowMap.sort(abSort);
 
     if (this._tree)
       this._tree.rowCountChanged(0, this._rowMap.length - oldCount);
 
     this._restoreOpenStates();
   },
 
-  getIndexForId: function(aId) {
+  getIndexForId(aId) {
     for (let i = 0; i < this._rowMap.length; i++) {
       if (this._rowMap[i].id == aId)
         return i;
     }
 
     return -1;
   },
 
   // nsIAbListener interfaces
   onItemAdded: function dtv_onItemAdded(aParent, aItem) {
     if (!(aItem instanceof Ci.nsIAbDirectory))
       return;
-    //xxx we can optimize this later
+    // XXX we can optimize this later
     this._rebuild();
 
     if (!this._tree)
       return;
 
     // Now select this new item
     for (var [i, row] of this._rowMap.entries()) {
       if (row.id == aItem.URI) {
@@ -237,17 +240,17 @@ directoryTreeView.prototype = {
         break;
       }
     }
   },
 
   onItemRemoved: function dtv_onItemRemoved(aParent, aItem) {
     if (!(aItem instanceof Ci.nsIAbDirectory))
       return;
-    //xxx we can optimize this later
+    // XXX we can optimize this later
     this._rebuild();
 
     if (!this._tree)
       return;
 
     // If we're deleting a top-level address-book, just select the first book
     if (aParent.URI == kAllDirectoryRoot ||
         aParent.URI == kAllDirectoryRoot + "?") {
@@ -263,17 +266,17 @@ directoryTreeView.prototype = {
       }
     }
   },
 
   onItemPropertyChanged: function dtv_onItemProp(aItem, aProp, aOld, aNew) {
     if (!(aItem instanceof Ci.nsIAbDirectory))
       return;
 
-    for (var i in this._rowMap)  {
+    for (let i in this._rowMap) {
       if (this._rowMap[i]._directory == aItem) {
         this._tree.invalidateRow(i);
         break;
       }
     }
   }
 };
 
--- a/mail/components/addrbook/content/addressbook.js
+++ b/mail/components/addrbook/content/addressbook.js
@@ -1,20 +1,40 @@
 /* -*- Mode: javascript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 ; js-indent-level: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /*
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+// abCardView.js
+/* globals ClearCardViewPane, DisplayCardViewPane, OnLoadCardView */
+// abTrees.js
+/* globals gDirectoryTreeView */
+
+// mail/base/content/mail-compacttheme.js
+/* globals CompactTheme */
+// mail/base/content/mailCore.js
+/* globals MailToolboxCustomizeDone */
+// mail/base/content/toolbarIconColor.js
+/* globals ToolbarIconColor */
+// mailnews/base/content/msgPrintEngine.js
+/* globals printEngineWindow */
+// mailnews/base/util/ABQueryUtils.jsm
+/* globals getModelQuery, getSearchTokens, generateQueryURI */
+
+// toolkit/content/globalOverlay.js
+/* globals goUpdateCommand */
+
 // Ensure the activity modules are loaded for this window.
 ChromeUtils.import("resource:///modules/activity/activityModules.js");
 ChromeUtils.import("resource:///modules/ABQueryUtils.jsm");
-ChromeUtils.import("resource:///modules/mailServices.js");
+var { MailServices } = ChromeUtils.import("resource:///modules/mailServices.js", null);
 ChromeUtils.import("resource://gre/modules/PluralForm.jsm");
+ChromeUtils.import("resource://gre/modules/Preferences.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   LightweightThemeManager: "resource://gre/modules/LightweightThemeManager.jsm",
 });
 
 var nsIAbListener = Ci.nsIAbListener;
@@ -47,70 +67,65 @@ var kPABDirectory  = 2; // defined in ns
 // that contact (assuming that the user has added that value to their list
 // of IM contacts).
 var kChatProperties = ["_GoogleTalk", "_JabberId"];
 
 // Note: We need to keep this listener as it does not just handle dir
 // pane deletes but also deletes of address books and lists from places like
 // the sidebar and LDAP preference pane.
 var gAddressBookAbListener = {
-  onItemAdded: function(parentDir, item) {
+  onItemAdded(parentDir, item) {
     // will not be called
   },
-  onItemRemoved: function(parentDir, item) {
+  onItemRemoved(parentDir, item) {
     // will only be called when an addressbook is deleted
     try {
       // If we don't have a record of the previous selection, the only
       // option is to select the first.
       if (gPreviousDirTreeIndex == -1) {
         SelectFirstAddressBook();
-      }
-      else {
+      } else if (gDirTree.currentIndex == -1) {
         // Don't reselect if we already have a valid selection, this may be
         // the case if items are being removed via other methods, e.g. sidebar,
         // LDAP preference pane etc.
-        if (gDirTree.currentIndex == -1) {
-          var directory = item.QueryInterface(Ci.nsIAbDirectory);
+        var directory = item.QueryInterface(Ci.nsIAbDirectory);
 
-          // If we are a mail list, move the selection up the list before
-          // trying to find the parent. This way we'll end up selecting the
-          // parent address book when we remove a mailing list.
-          //
-          // For simple address books we don't need to move up the list, as
-          // we want to select the next one upon removal.
-          if (directory.isMailList && gPreviousDirTreeIndex > 0)
-            --gPreviousDirTreeIndex;
+        // If we are a mail list, move the selection up the list before
+        // trying to find the parent. This way we'll end up selecting the
+        // parent address book when we remove a mailing list.
+        //
+        // For simple address books we don't need to move up the list, as
+        // we want to select the next one upon removal.
+        if (directory.isMailList && gPreviousDirTreeIndex > 0)
+          --gPreviousDirTreeIndex;
 
-          // Now get the parent of the row.
-          var newRow = gDirTree.view.getParentIndex(gPreviousDirTreeIndex);
+        // Now get the parent of the row.
+        var newRow = gDirTree.view.getParentIndex(gPreviousDirTreeIndex);
 
-          // if we have no parent (i.e. we are an address book), use the
-          // previous index.
-          if (newRow == -1)
-            newRow = gPreviousDirTreeIndex;
+        // if we have no parent (i.e. we are an address book), use the
+        // previous index.
+        if (newRow == -1)
+          newRow = gPreviousDirTreeIndex;
 
-          // Fall back to the first address book if we're not in a valid range
-          if (newRow >= gDirTree.view.rowCount)
-            newRow = 0;
+        // Fall back to the first address book if we're not in a valid range
+        if (newRow >= gDirTree.view.rowCount)
+          newRow = 0;
 
-          // Now select the new item.
-          gDirTree.view.selection.select(newRow);
-        }
+        // Now select the new item.
+        gDirTree.view.selection.select(newRow);
       }
-    }
-    catch (ex) {
+    } catch (ex) {
     }
   },
-  onItemPropertyChanged: function(item, property, oldValue, newValue) {
+  onItemPropertyChanged(item, property, oldValue, newValue) {
     // will not be called
   }
 };
 
-function OnUnloadAddressBook()
-{
+function OnUnloadAddressBook() {
   // If there's no default startupURI, save the last used URI as new startupURI.
   let saveLastURIasStartupURI = !Services.prefs.getBoolPref("mail.addr_book.view.startupURIisDefault");
   if (saveLastURIasStartupURI) {
     let selectedDirURI = getSelectedDirectoryURI();
     Services.prefs.setCharPref("mail.addr_book.view.startupURI", selectedDirURI);
   }
 
   MailServices.ab.removeAddressBookListener(gAddressBookAbListener);
@@ -124,37 +139,34 @@ function OnUnloadAddressBook()
 
   ToolbarIconColor.uninit();
   CompactTheme.uninit();
 
   CloseAbView();
 }
 
 var gAddressBookAbViewListener = {
-  onSelectionChanged: function() {
+  onSelectionChanged() {
     ResultsPaneSelectionChanged();
   },
-  onCountChanged: function(total) {
+  onCountChanged(total) {
     SetStatusText(total);
   }
 };
 
-function GetAbViewListener()
-{
+function GetAbViewListener() {
   return gAddressBookAbViewListener;
 }
 
 // we won't show the window until the onload() handler is finished
 // so we do this trick (suggested by hyatt / blaker)
-function OnLoadAddressBook()
-{
+function OnLoadAddressBook() {
   // 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 860xfull height.
     let defaultHeight = screen.availHeight;
     let defaultWidth = (screen.availWidth >= 860) ? 860 : screen.availWidth;
 
     // On small screens, default to maximized state.
     if (defaultHeight <= 600)
       document.documentElement.setAttribute("sizemode", "maximized");
 
@@ -169,18 +181,17 @@ function OnLoadAddressBook()
   ToolbarIconColor.init();
 
   if (!chatHandler.ChatCore.initialized)
     chatHandler.ChatCore.init();
 
   setTimeout(delayedOnLoadAddressBook, 0); // when debugging, set this to 5000, so you can see what happens after the window comes up.
 }
 
-function delayedOnLoadAddressBook()
-{
+function delayedOnLoadAddressBook() {
   InitCommonJS();
 
   GetCurrentPrefs();
 
   // FIX ME - later we will be able to use onload from the overlay
   OnLoadCardView();
 
   // Initialize the Address Book tree view
@@ -213,142 +224,131 @@ function delayedOnLoadAddressBook()
   // Force command update for the benefit of DirPaneController and
   // abResultsController
   CommandUpdate_AddressBook();
 
   // initialize the customizeDone method on the customizeable toolbar
   var toolbox = document.getElementById("ab-toolbox");
   toolbox.customizeDone = function(aEvent) { MailToolboxCustomizeDone(aEvent, "CustomizeABToolbar"); };
 
-  var toolbarset = document.getElementById('customToolbars');
+  var toolbarset = document.getElementById("customToolbars");
   toolbox.toolbarset = toolbarset;
 
   // Ensure we don't load xul error pages into the main window
   window.docShell.useErrorPages = false;
 
   MailServices.mailSession.AddMsgWindow(msgWindow);
 
   // Focus the searchbox as we think the user will want to do that
   // with the highest probability.
   // Bug 1143812: This is disabled for now to keep the New Contact command enabled.
   // QuickSearchFocus();
 }
 
 
-function GetCurrentPrefs()
-{
+function GetCurrentPrefs() {
   // check "Show Name As" menu item based on pref
   var menuitemID;
-  switch (Services.prefs.getIntPref(kPrefMailAddrBookLastNameFirst))
-  {
+  switch (Services.prefs.getIntPref(kPrefMailAddrBookLastNameFirst)) {
     case kFirstNameFirst:
-      menuitemID = 'firstLastCmd';
+      menuitemID = "firstLastCmd";
       break;
     case kLastNameFirst:
-      menuitemID = 'lastFirstCmd';
+      menuitemID = "lastFirstCmd";
       break;
     case kDisplayName:
     default:
-      menuitemID = 'displayNameCmd';
+      menuitemID = "displayNameCmd";
       break;
   }
 
   var menuitem = top.document.getElementById(menuitemID);
   if (menuitem)
-    menuitem.setAttribute('checked', 'true');
+    menuitem.setAttribute("checked", "true");
 
   // initialize phonetic
   var showPhoneticFields =
     Services.prefs.getComplexValue("mail.addr_book.show_phonetic_fields",
       Ci.nsIPrefLocalizedString).data;
   // show phonetic fields if indicated by the pref
   if (showPhoneticFields == "true")
     document.getElementById("cmd_SortBy_PhoneticName")
             .setAttribute("hidden", "false");
 
 }
 
-function SetNameColumn(cmd)
-{
+function SetNameColumn(cmd) {
   var prefValue;
 
-  switch ( cmd )
-  {
-    case 'firstLastCmd':
+  switch (cmd) {
+    case "firstLastCmd":
       prefValue = kFirstNameFirst;
       break;
-    case 'lastFirstCmd':
+    case "lastFirstCmd":
       prefValue = kLastNameFirst;
       break;
-    case 'displayNameCmd':
+    case "displayNameCmd":
       prefValue = kDisplayName;
       break;
   }
 
   Services.prefs.setIntPref(kPrefMailAddrBookLastNameFirst, prefValue);
 }
 
-function onOSXFileMenuInit()
-{
-  document.getElementById('menu_osxAddressBook')
+function onOSXFileMenuInit() {
+  document.getElementById("menu_osxAddressBook")
           .setAttribute("checked", AbOSXAddressBookExists());
 }
 
-function CommandUpdate_AddressBook()
-{
-  goUpdateCommand('cmd_delete');
-  goUpdateCommand('button_delete');
-  goUpdateCommand('cmd_printcardpreview');
-  goUpdateCommand('cmd_printcard');
-  goUpdateCommand('cmd_properties');
+function CommandUpdate_AddressBook() {
+  goUpdateCommand("cmd_delete");
+  goUpdateCommand("button_delete");
+  goUpdateCommand("cmd_printcardpreview");
+  goUpdateCommand("cmd_printcard");
+  goUpdateCommand("cmd_properties");
   goUpdateCommand("cmd_abToggleStartupDir");
-  goUpdateCommand('cmd_newlist');
-  goUpdateCommand('cmd_newCard');
-  goUpdateCommand('cmd_chatWithCard');
+  goUpdateCommand("cmd_newlist");
+  goUpdateCommand("cmd_newCard");
+  goUpdateCommand("cmd_chatWithCard");
 }
 
-function ResultsPaneSelectionChanged()
-{
+function ResultsPaneSelectionChanged() {
   UpdateCardView();
 }
 
-function UpdateCardView()
-{
+function UpdateCardView() {
   var cards = GetSelectedAbCards();
 
   if (!cards) {
     ClearCardViewPane();
     return;
   }
 
   // display the selected card, if exactly one card is selected.
   // either no cards, or more than one card is selected, clear the pane.
   // We do not need to check cards[0] any more since GetSelectedAbCards() only
   // push non-null entity to the list.
   if (cards.length == 1)
-    OnClickedCard(cards[0])
+    OnClickedCard(cards[0]);
   else
     ClearCardViewPane();
 }
 
-function OnClickedCard(card)
-{
+function OnClickedCard(card) {
   if (card)
     DisplayCardViewPane(card);
   else
     ClearCardViewPane();
 }
 
-function AbClose()
-{
+function AbClose() {
   top.close();
 }
 
-function AbPrintCardInternal(doPrintPreview, msgType)
-{
+function AbPrintCardInternal(doPrintPreview, msgType) {
   var selectedItems = GetSelectedAbCards();
   var numSelected = selectedItems.length;
 
   if (!numSelected)
     return;
 
   let statusFeedback;
   statusFeedback = Cc["@mozilla.org/messenger/statusfeedback;1"].createInstance();
@@ -359,120 +359,113 @@ function AbPrintCardInternal(doPrintPrev
   for (let i = 0; i < numSelected; i++) {
     let card = selectedItems[i];
     let printCardUrl = CreatePrintCardUrl(card);
     if (printCardUrl) {
       selectionArray.push(printCardUrl);
     }
   }
 
+  /* eslint-disable no-native-reassign */
   printEngineWindow = window.openDialog("chrome://messenger/content/msgPrintEngine.xul",
                                          "",
                                          "chrome,dialog=no,all",
                                          selectionArray.length, selectionArray,
                                          statusFeedback, doPrintPreview, msgType);
-
-  return;
+  /* eslint-enable no-native-reassign */
 }
 
-function AbPrintCard()
-{
+function AbPrintCard() {
   AbPrintCardInternal(false, Ci.nsIMsgPrintEngine.MNAB_PRINT_AB_CARD);
 }
 
-function AbPrintPreviewCard()
-{
+function AbPrintPreviewCard() {
   AbPrintCardInternal(true, Ci.nsIMsgPrintEngine.MNAB_PRINTPREVIEW_AB_CARD);
 }
 
-function CreatePrintCardUrl(card)
-{
+function CreatePrintCardUrl(card) {
   return "data:application/xml;base64," + card.translateTo("base64xml");
 }
 
-function AbPrintAddressBookInternal(doPrintPreview, msgType)
-{
+function AbPrintAddressBookInternal(doPrintPreview, msgType) {
   let uri = getSelectedDirectoryURI();
   if (!uri)
     return;
 
   var statusFeedback;
   statusFeedback = Cc["@mozilla.org/messenger/statusfeedback;1"].createInstance();
   statusFeedback = statusFeedback.QueryInterface(Ci.nsIMsgStatusFeedback);
 
   /*
     turn "moz-abmdbdirectory://abook.mab" into
     "addbook://moz-abmdbdirectory/abook.mab?action=print"
    */
 
   var abURIArr = uri.split("://");
-  var printUrl = "addbook://" + abURIArr[0] + "/" + abURIArr[1] + "?action=print"
+  var printUrl = "addbook://" + abURIArr[0] + "/" + abURIArr[1] + "?action=print";
 
+  /* eslint-disable no-native-reassign */
   printEngineWindow = window.openDialog("chrome://messenger/content/msgPrintEngine.xul",
                     "",
                     "chrome,dialog=no,all",
                     1, [printUrl], statusFeedback, doPrintPreview, msgType);
-
-  return;
+  /* eslint-enable no-native-reassign */
 }
 
-function AbPrintAddressBook()
-{
+function AbPrintAddressBook() {
   AbPrintAddressBookInternal(false, Ci.nsIMsgPrintEngine.MNAB_PRINT_ADDRBOOK);
 }
 
-function AbPrintPreviewAddressBook()
-{
+function AbPrintPreviewAddressBook() {
   AbPrintAddressBookInternal(true, Ci.nsIMsgPrintEngine.MNAB_PRINTPREVIEW_ADDRBOOK);
 }
 
 /**
  * Export the currently selected addressbook.
  */
 function AbExportSelection() {
   let selectedDirURI = getSelectedDirectoryURI();
   if (!selectedDirURI)
     return;
 
- if (selectedDirURI == (kAllDirectoryRoot + "?"))
-   return AbExportAll();
+  if (selectedDirURI == (kAllDirectoryRoot + "?")) {
+    AbExportAll();
+    return;
+  }
 
- return AbExport(selectedDirURI);
+  AbExport(selectedDirURI);
 }
 
 /**
  * Export all found addressbooks, each in a separate file.
  */
-function AbExportAll()
-{
+function AbExportAll() {
   let directories = MailServices.ab.directories;
 
   while (directories.hasMoreElements()) {
     let directory = directories.getNext();
     // Do not export LDAP ABs.
     if (!directory.URI.startsWith(kLdapUrlPrefix))
       AbExport(directory.URI);
   }
 }
 
 /**
  * Export the specified addressbook to a file.
  *
  * @param aSelectedDirURI  The URI of the addressbook to export.
  */
-function AbExport(aSelectedDirURI)
-{
+function AbExport(aSelectedDirURI) {
   if (!aSelectedDirURI)
     return;
 
   try {
     let directory = GetDirectoryFromURI(aSelectedDirURI);
     MailServices.ab.exportAddressBook(window, directory);
-  }
-  catch (ex) {
+  } catch (ex) {
     let message;
     switch (ex.result) {
       case Cr.NS_ERROR_FILE_ACCESS_DENIED:
         message = gAddressBookBundle.getString("failedToExportMessageFileAccessDenied");
         break;
       case Cr.NS_ERROR_FILE_NO_DEVICE_SPACE:
         message = gAddressBookBundle.getString("failedToExportMessageNoDeviceSpace");
         break;
@@ -482,75 +475,68 @@ function AbExport(aSelectedDirURI)
     }
 
     Services.prompt.alert(window,
       gAddressBookBundle.getString("failedToExportTitle"),
       message);
   }
 }
 
-function SetStatusText(total)
-{
+function SetStatusText(total) {
   if (!gStatusText)
-    gStatusText = document.getElementById('statusText');
+    gStatusText = document.getElementById("statusText");
 
   try {
     let statusText;
 
     let searchInput = document.getElementById("peopleSearchInput");
     if (searchInput && searchInput.value) {
       if (total == 0) {
         statusText = gAddressBookBundle.getString("noMatchFound");
       } else {
         statusText = PluralForm
           .get(total, gAddressBookBundle.getString("matchesFound1"))
           .replace("#1", total);
       }
-    }
-    else
+    } else
       statusText =
         gAddressBookBundle.getFormattedString(
           "totalContactStatus",
           [getSelectedDirectory().dirName, total]);
 
     gStatusText.setAttribute("label", statusText);
-  }
-  catch(ex) {
+  } catch (ex) {
     Cu.reportError("ERROR: failed to set status text:  " + ex );
   }
 }
 
-function AbResultsPaneKeyPress(event)
-{
+function AbResultsPaneKeyPress(event) {
   if (event.keyCode == 13)
     AbEditSelectedCard();
 }
 
-function AbResultsPaneDoubleClick(card)
-{
+function AbResultsPaneDoubleClick(card) {
   AbEditCard(card);
 }
 
-function onAdvancedAbSearch()
-{
+function onAdvancedAbSearch() {
   let selectedDirURI = getSelectedDirectoryURI();
   if (!selectedDirURI)
     return;
 
   let existingSearchWindow = Services.wm.getMostRecentWindow("mailnews:absearch");
   if (existingSearchWindow)
     existingSearchWindow.focus();
   else
     window.openDialog("chrome://messenger/content/ABSearchDialog.xul", "",
                       "chrome,resizable,status,centerscreen,dialog=no",
                       {directory: selectedDirURI});
 }
 
-function onEnterInSearchBar()
-{
+function onEnterInSearchBar() {
   ClearCardViewPane();
   if (!gQueryURIFormat) {
     // Get model query from pref. We don't want the query starting with "?"
     // as we have to prefix "?and" to this format.
     gQueryURIFormat = getModelQuery("mail.addr_book.quicksearchquery.format");
   }
 
   let searchURI = getSelectedDirectoryURI();
@@ -580,141 +566,120 @@ function onEnterInSearchBar()
   SetAbView(searchURI);
 
   // XXX todo
   // this works for synchronous searches of local addressbooks,
   // but not for LDAP searches
   SelectFirstCard();
 }
 
-function SwitchPaneFocus(event)
-{
+function SwitchPaneFocus(event) {
   var focusedElement    = WhichPaneHasFocus();
   var cardViewBox       = GetCardViewBox();
   var cardViewBoxEmail1 = GetCardViewBoxEmail1();
-  var searchBox         = document.getElementById('search-container');
+  var searchBox         = document.getElementById("search-container");
   var dirTree           = GetDirTree();
-  var searchInput       = document.getElementById('peopleSearchInput');
+  var searchInput       = document.getElementById("peopleSearchInput");
 
-  if (event && event.shiftKey)
-  {
-    if (focusedElement == gAbResultsTree && searchBox)
+  if (event && event.shiftKey) {
+    if (focusedElement == gAbResultsTree && searchBox) {
       searchInput.focus();
-    else if ((focusedElement == gAbResultsTree || focusedElement == searchBox) && !IsDirPaneCollapsed())
+    } else if ((focusedElement == gAbResultsTree || focusedElement == searchBox) && !IsDirPaneCollapsed()) {
       dirTree.focus();
-    else if (focusedElement != cardViewBox && !IsCardViewAndAbResultsPaneSplitterCollapsed())
-    {
-      if (cardViewBoxEmail1)
+    } else if (focusedElement != cardViewBox && !IsCardViewAndAbResultsPaneSplitterCollapsed()) {
+      if (cardViewBoxEmail1) {
         cardViewBoxEmail1.focus();
-      else
+      } else {
         cardViewBox.focus();
-    }
-    else
+      }
+    } else {
       gAbResultsTree.focus();
-  }
-  else
-  {
-    if (focusedElement == searchBox)
-      gAbResultsTree.focus();
-    else if (focusedElement == gAbResultsTree && !IsCardViewAndAbResultsPaneSplitterCollapsed())
-    {
-      if (cardViewBoxEmail1)
-        cardViewBoxEmail1.focus();
-      else
-        cardViewBox.focus();
     }
-    else if (focusedElement != dirTree && !IsDirPaneCollapsed())
-      dirTree.focus();
-    else if (searchBox && searchInput)
-      searchInput.focus();
-    else
-      gAbResultsTree.focus();
+  } else if (focusedElement == searchBox) {
+    gAbResultsTree.focus();
+  } else if (focusedElement == gAbResultsTree && !IsCardViewAndAbResultsPaneSplitterCollapsed()) {
+    if (cardViewBoxEmail1) {
+      cardViewBoxEmail1.focus();
+    } else {
+      cardViewBox.focus();
+    }
+  } else if (focusedElement != dirTree && !IsDirPaneCollapsed()) {
+    dirTree.focus();
+  } else if (searchBox && searchInput) {
+    searchInput.focus();
+  } else {
+    gAbResultsTree.focus();
   }
 }
 
-function WhichPaneHasFocus()
-{
+function WhichPaneHasFocus() {
   var cardViewBox       = GetCardViewBox();
-  var searchBox         = document.getElementById('search-container');
+  var searchBox         = document.getElementById("search-container");
   var dirTree           = GetDirTree();
 
   var currentNode = top.document.commandDispatcher.focusedElement;
-  while (currentNode)
-  {
-    var nodeId = currentNode.getAttribute('id');
-
+  while (currentNode) {
     if (currentNode == gAbResultsTree ||
         currentNode == cardViewBox ||
         currentNode == searchBox ||
         currentNode == dirTree)
       return currentNode;
 
     currentNode = currentNode.parentNode;
   }
 
   return null;
 }
 
-function GetDirTree()
-{
+function GetDirTree() {
   if (!gDirTree)
-    gDirTree = document.getElementById('dirTree');
+    gDirTree = document.getElementById("dirTree");
   return gDirTree;
 }
 
-function GetCardViewBox()
-{
+function GetCardViewBox() {
   if (!gCardViewBox)
-    gCardViewBox = document.getElementById('CardViewBox');
+    gCardViewBox = document.getElementById("CardViewBox");
   return gCardViewBox;
 }
 
-function GetCardViewBoxEmail1()
-{
-  if (!gCardViewBoxEmail1)
-  {
+function GetCardViewBoxEmail1() {
+  if (!gCardViewBoxEmail1) {
     try {
-      gCardViewBoxEmail1 = document.getElementById('cvEmail1');
-    }
-    catch (ex) {
+      gCardViewBoxEmail1 = document.getElementById("cvEmail1");
+    } catch (ex) {
       gCardViewBoxEmail1 = null;
     }
   }
   return gCardViewBoxEmail1;
 }
 
-function IsDirPaneCollapsed()
-{
+function IsDirPaneCollapsed() {
   var dirPaneBox = GetDirTree().parentNode;
   return dirPaneBox.getAttribute("collapsed") == "true" ||
          dirPaneBox.getAttribute("hidden") == "true";
 }
 
-function IsCardViewAndAbResultsPaneSplitterCollapsed()
-{
-  var cardViewBox = document.getElementById('CardViewOuterBox');
+function IsCardViewAndAbResultsPaneSplitterCollapsed() {
+  var cardViewBox = document.getElementById("CardViewOuterBox");
   try {
     return (cardViewBox.getAttribute("collapsed") == "true");
-  }
-  catch (ex) {
+  } catch (ex) {
     return false;
   }
 }
 
-function LaunchUrl(url)
-{
+function LaunchUrl(url) {
   // Doesn't matter if this bit fails, window.location contains its own prompts
   try {
     window.location = url;
-  }
-  catch (ex) {}
+  } catch (ex) {}
 }
 
-function AbIMSelected()
-{
+function AbIMSelected() {
   let cards = GetSelectedAbCards();
 
   if (!cards) {
     Cu.reportError("ERROR: AbIMSelected: |cards| is null.");
     return;
   }
 
   if (cards.length != 1) {
@@ -768,18 +733,17 @@ function AbIMSelected()
     let prplConv = selectedContact.createConversation();
     let uiConv = Services.conversations.getUIConversation(prplConv);
     let win = Services.wm.getMostRecentWindow("mail:3pane");
 
     if (win) {
       win.focus();
       win.showChatTab();
       win.chatHandler.focusConversation(uiConv);
-    }
-    else {
+    } else {
       window.openDialog("chrome://messenger/content/", "_blank",
                         "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar",
                         null, {tabType: "chat",
                                tabParams: {convType: "focus", conv: uiConv}});
     }
 
     return;
   }
@@ -793,61 +757,49 @@ function AbIMSelected()
 
   // And if we got here, that means we couldn't find *any* usernames we could
   // chat with. That really shouldn't be possible, since the isEnabled for
   // cmd_chatWithCard makes checks for this sort of thing, but we'll throw
   // an exception for good measure.
   throw new Error("Couldn't find any usernames to chat with for this card.");
 }
 
-function getMailToolbox()
-{
+function getMailToolbox() {
   return document.getElementById("ab-toolbox");
 }
 
 var kOSXDirectoryURI = "moz-abosxdirectory:///";
 var kOSXPrefBase = "ldap_2.servers.osx";
 
-function AbOSXAddressBookExists()
-{
+function AbOSXAddressBookExists() {
   // I hate doing it this way - until we redo how we manage address books
   // I can't think of a better way though.
 
   // See if the pref exists, if so, then we need to delete the address book
-  var uriPresent = false;
-  var position = 1;
-  try {
-    uriPresent = Services.prefs.getCharPref(kOSXPrefBase + ".uri") == kOSXDirectoryURI;
-  }
-  catch (e) { }
-
-  try {
-    position = Services.prefs.getIntPref(kOSXPrefBase + ".position");
-  }
-  catch (e) { }
+  var uriPresent = Preferences.get(kOSXPrefBase + ".uri", null) == kOSXDirectoryURI;
+  var position = Preferences.get(kOSXPrefBase + ".position", 1);
 
   // Address book exists if the uri is correct and the position is not zero.
   return uriPresent && position != 0;
 }
 
-function AbShowHideOSXAddressBook()
-{
+function AbShowHideOSXAddressBook() {
   if (AbOSXAddressBookExists())
     MailServices.ab.deleteAddressBook(kOSXDirectoryURI);
   else {
     MailServices.ab.newAddressBook(
       gAddressBookBundle.getString(kOSXPrefBase + ".description"),
       kOSXDirectoryURI, 3, kOSXPrefBase);
   }
 }
 
 var abResultsController = {
   commands: {
     cmd_chatWithCard: {
-      isEnabled: function() {
+      isEnabled() {
         let selected = GetSelectedAbCards();
 
         if (selected.length != 1)
           return false;
 
         let selectedCard = selected[0];
         if (!selectedCard)
           return false;
@@ -862,36 +814,36 @@ var abResultsController = {
                   && chatHandler.allContacts[contactName].canSendMessage);
         });
 
         let hasAIM = selectedCard.getProperty("_AimScreenName", "");
 
         return isIMContact || hasAIM;
       },
 
-      doCommand: function() {
+      doCommand() {
         AbIMSelected();
       },
     }
   },
 
-  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;
     let cmd = this.commands[aCommand];
     if (!cmd.isEnabled())
       return;
     cmd.doCommand();
   },
 
-  onEvent: function(aEvent) {}
-}
+  onEvent(aEvent) {}
+};