Bug 1584211 - Fix mailing list edit dialog bugs. r=mkmelin a=jorgk
authorPaul Morris <paul@thunderbird.net>
Sun, 13 Oct 2019 11:38:58 +0200
changeset 36694 1f623ce59de43a442e87cd9ea2e2757d40be6e93
parent 36693 d0b0f5b31baefecfcacd501a24723a0ab451c83a
child 36695 2ecd5527f4bd2043d89e37010bd5ab952cc00e60
push id394
push userclokep@gmail.com
push dateMon, 21 Oct 2019 20:22:01 +0000
reviewersmkmelin, jorgk
bugs1584211
Bug 1584211 - Fix mailing list edit dialog bugs. r=mkmelin a=jorgk
mailnews/addrbook/content/abMailListDialog.js
--- a/mailnews/addrbook/content/abMailListDialog.js
+++ b/mailnews/addrbook/content/abMailListDialog.js
@@ -13,17 +13,17 @@ var { AppConstants } = ChromeUtils.impor
   "resource://gre/modules/AppConstants.jsm"
 );
 
 top.MAX_RECIPIENTS = 1;
 var inputElementType = "";
 
 var gListCard;
 var gEditList;
-var oldListName = "";
+var gOldListName = "";
 var gLoadListeners = [];
 var gSaveListeners = [];
 
 try {
   var gDragService = Cc["@mozilla.org/widget/dragservice;1"].getService(
     Ci.nsIDragService
   );
 } catch (e) {}
@@ -40,102 +40,86 @@ function mailingListExists(listname) {
       gAddressBookBundle.getString("mailListNameExistsTitle"),
       gAddressBookBundle.getString("mailListNameExistsMessage")
     );
     return true;
   }
   return false;
 }
 
-function GetListValue(mailList, doAdd) {
-  var listname = document.getElementById("ListName").value.trim();
+/**
+ * Get the new inputs from the create/edit mailing list dialog and use them to
+ * update the mailing list that was passed in as an argument.
+ *
+ * @param {XPCWrappedNative_NoHelper} mailList - The mailing list object to
+ *   update. When creating a new list it will be newly created and empty.
+ * @param {boolean} isNewList - Whether we are populating a new list.
+ * @return {boolean} - Whether the operation succeeded or not.
+ */
+function updateMailList(mailList, isNewList) {
+  let listname = document.getElementById("ListName").value.trim();
 
   if (listname.length == 0) {
-    var alertText = gAddressBookBundle.getString("emptyListName");
-    alert(alertText);
+    alert(gAddressBookBundle.getString("emptyListName"));
     return false;
   }
 
-  var canonicalNewListName = listname.toLowerCase();
-  var canonicalOldListName = oldListName.toLowerCase();
-  if (doAdd) {
-    if (mailingListExists(canonicalNewListName)) {
-      return false;
-    }
-  } else if (canonicalOldListName != canonicalNewListName) {
+  let canonicalNewListName = listname.toLowerCase();
+  let canonicalOldListName = gOldListName.toLowerCase();
+  if (isNewList || canonicalOldListName != canonicalNewListName) {
     if (mailingListExists(canonicalNewListName)) {
       return false;
     }
   }
 
   mailList.isMailList = true;
   mailList.dirName = listname;
   mailList.listNickName = document.getElementById("ListNickName").value;
   mailList.description = document.getElementById("ListDescription").value;
 
-  var oldTotal = mailList.addressLists.length;
-  var i = 1;
-  var pos = 0;
-  var inputField, fieldValue, cardproperty;
-  while ((inputField = awGetInputElement(i))) {
-    fieldValue = inputField.value;
+  // Gather email address inputs into a single string (comma-separated).
+  let addresses = Array.from(
+    document.querySelectorAll(".textbox-addressingWidget"),
+    element => element.value
+  )
+    .filter(value => value.trim())
+    .join();
+
+  // Convert the addresses string into address objects.
+  let addressObjects = MailServices.headerParser.makeFromDisplayAddress(
+    addresses
+  );
 
-    if (doAdd || pos >= oldTotal) {
-      cardproperty = Cc[
-        "@mozilla.org/addressbook/cardproperty;1"
-      ].createInstance();
-    } else {
-      cardproperty = mailList.addressLists.queryElementAt(pos, Ci.nsIAbCard);
-    }
+  // Update the list by updating existing entries/cards or adding new ones.
+  let oldAddressCount = isNewList ? 0 : mailList.addressLists.length;
+  let addressCounter = 0;
+
+  for (let { email, name } of addressObjects) {
+    let addNewCard = addressCounter >= oldAddressCount;
 
-    if (fieldValue == "") {
-      if (!doAdd && cardproperty) {
-        try {
-          mailList.addressLists.removeElementAt(pos);
-          --oldTotal;
-        } catch (ex) {
-          // Ignore attempting to remove an item
-          // at a position greater than the number
-          // of elements in the addressLists attribute
-        }
+    let card = addNewCard
+      ? Cc["@mozilla.org/addressbook/cardproperty;1"].createInstance()
+      : mailList.addressLists.queryElementAt(addressCounter, Ci.nsIAbCard);
+
+    card = card && card.QueryInterface(Ci.nsIAbCard);
+
+    if (card) {
+      card.primaryEmail = email;
+      card.displayName = name || email;
+
+      if (addNewCard) {
+        mailList.addressLists.appendElement(card);
       }
-    } else if (cardproperty) {
-      cardproperty = cardproperty.QueryInterface(Ci.nsIAbCard);
-      if (cardproperty) {
-        let addrObjects = MailServices.headerParser.makeFromDisplayAddress(
-          fieldValue,
-          {}
-        );
-        for (let j = 0; j < addrObjects.length; j++) {
-          if (j > 0) {
-            cardproperty = Cc[
-              "@mozilla.org/addressbook/cardproperty;1"
-            ].createInstance();
-            cardproperty = cardproperty.QueryInterface(Ci.nsIAbCard);
-          }
-          cardproperty.primaryEmail = addrObjects[j].email;
-          cardproperty.displayName =
-            addrObjects[j].name || addrObjects[j].email;
-
-          if (doAdd || pos >= oldTotal) {
-            mailList.addressLists.appendElement(cardproperty);
-          }
-        }
-        pos++;
-      }
+      addressCounter += 1;
     }
-    i++;
   }
 
-  --i;
-
-  if (!doAdd && i < oldTotal) {
-    for (var j = i; j < oldTotal; j++) {
-      mailList.addressLists.removeElementAt(j);
-    }
+  // Remove any remaining unneeded entries.
+  while (mailList.addressLists.length > addressCounter) {
+    mailList.addressLists.removeElementAt(addressCounter);
   }
   return true;
 }
 
 function MailListOKButton(event) {
   var popup = document.getElementById("abPopup");
   if (popup) {
     var uri = popup.getAttribute("value");
@@ -149,17 +133,17 @@ function MailListOKButton(event) {
     // -----
 
     // Add mailing list to database
     var mailList = Cc[
       "@mozilla.org/addressbook/directoryproperty;1"
     ].createInstance();
     mailList = mailList.QueryInterface(Ci.nsIAbDirectory);
 
-    if (GetListValue(mailList, true)) {
+    if (updateMailList(mailList, true)) {
       var parentDirectory = GetDirectoryFromURI(uri);
       mailList = parentDirectory.addMailList(mailList);
       NotifySaveListeners(mailList);
     } else {
       event.preventDefault();
     }
   }
 }
@@ -214,51 +198,50 @@ function OnLoadNewMailList() {
     );
   }
 
   NotifyLoadListeners(directory);
 }
 
 function EditListOKButton(event) {
   // edit mailing list in database
-  if (GetListValue(gEditList, false)) {
+  if (updateMailList(gEditList, false)) {
     if (gListCard) {
       // modify the list card (for the results pane) from the mailing list
       gListCard.displayName = gEditList.dirName;
       gListCard.lastName = gEditList.dirName;
       gListCard.setProperty("NickName", gEditList.listNickName);
       gListCard.setProperty("Notes", gEditList.description);
     }
 
     NotifySaveListeners(gEditList);
     gEditList.editMailListToDatabase(gListCard);
 
     window.arguments[0].refresh = true;
     return; // close the window
   }
-
   event.preventDefault();
 }
 
 function OnLoadEditList() {
   InitCommonJS();
 
   gListCard = window.arguments[0].abCard;
   var listUri = window.arguments[0].listURI;
 
   gEditList = GetDirectoryFromURI(listUri);
 
   document.getElementById("ListName").value = gEditList.dirName;
   document.getElementById("ListNickName").value = gEditList.listNickName;
   document.getElementById("ListDescription").value = gEditList.description;
-  oldListName = gEditList.dirName;
+  gOldListName = gEditList.dirName;
 
   document.title = gAddressBookBundle.getFormattedString(
     "mailingListTitleEdit",
-    [oldListName]
+    [gOldListName]
   );
 
   if (gEditList.addressLists) {
     let total = gEditList.addressLists.length;
     if (total) {
       let listbox = document.getElementById("addressingWidget");
       let newListBoxNode = listbox.cloneNode(false);
       let templateNode = listbox.querySelector("richlistitem");