Bug 325458 - Recipient Autocomplete: Nickname should get highest precedence for matching address book entries; r=mkmelin, a=mkmelin
authorSuyash Agarwal <syshagarwal@gmail.com>
Wed, 04 Feb 2015 20:56:01 +1300
changeset 25716 13f0f38594621fa463104400bddb7b760c603694
parent 25715 b7895b1370659516d240cf64a428dbb0c3142966
child 25717 fae7fa18f2339784b871212e889bf66f8d8f5829
push id1850
push userclokep@gmail.com
push dateWed, 08 Mar 2017 19:29:12 +0000
treeherdercomm-esr52@028df196b2d9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin, mkmelin
bugs325458
Bug 325458 - Recipient Autocomplete: Nickname should get highest precedence for matching address book entries; r=mkmelin, a=mkmelin
mailnews/addrbook/src/nsAbAutoCompleteSearch.js
mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch1.js
mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch6.js
--- a/mailnews/addrbook/src/nsAbAutoCompleteSearch.js
+++ b/mailnews/addrbook/src/nsAbAutoCompleteSearch.js
@@ -124,27 +124,37 @@ nsAbAutoCompleteSearch.prototype = {
     return popularityIndex;
   },
 
   /**
    * Gets the score of the (full) address, given the search input. We want
    * results that match the beginning of a "word" in the result to score better
    * than a result that matches only in the middle of the word.
    *
+   * @param aCard - the card whose score is being decided
    * @param aAddress - full lower-cased address, including display name and address
    * @param aSearchString - search string provided by user
    * @return a score; a higher score is better than a lower one
    */
-  _getScore: function(aAddress, aSearchString) {
+  _getScore: function(aCard, aAddress, aSearchString) {
     const BEST = 100;
+
+    // We will firstly check if the search term provided by the user
+    // is the nick name for the card or at least in the beginning of it.
+    let nick = aCard.getProperty("NickName", "").toLocaleLowerCase();
+    aSearchString = aSearchString.toLocaleLowerCase();
+    if (nick == aSearchString)
+      return BEST + 1;
+    if (nick.indexOf(aSearchString) == 0)
+      return BEST;
+
     // We'll do this case-insensitively and ignore the domain.
     let atIdx = aAddress.lastIndexOf("@");
     if (atIdx != -1) // mail lists don't have an @
       aAddress = aAddress.substr(0, atIdx);
-    aSearchString = aSearchString.toLocaleLowerCase();
     let idx = aAddress.indexOf(aSearchString);
     if (idx == 0)
       return BEST;
     if (idx == -1)
       return 0;
 
     // We want to treat firstname, lastname and word boundary(ish) parts of
     // the email address the same. E.g. for "John Doe (:xx) <jd.who@example.com>"
@@ -291,17 +301,17 @@ nsAbAutoCompleteSearch.prototype = {
 
     result._collectedValues.set(lcEmailAddress, {
       value: emailAddress,
       comment: commentColumn,
       card: card,
       isPrimaryEmail: isPrimaryEmail,
       emailToUse: emailToUse,
       popularity: this._getPopularityIndex(directory, card),
-      score: this._getScore(lcEmailAddress, result.searchString)
+      score: this._getScore(card, lcEmailAddress, result.searchString)
     });
   },
 
   // nsIAutoCompleteSearch
 
   /**
    * Starts a search based on the given parameters.
    *
--- a/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch1.js
+++ b/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch1.js
@@ -41,21 +41,21 @@ const lastNames = [ { search: "l",      
 
 const displayNames = [ { search: "d",      expected: [5, 0, 1, 2, 3, 4, 9] },
                        { search: "di",     expected: [5, 1, 2, 3, 4] },
                        { search: "dis",    expected: [5, 2, 3, 4] },
                        { search: "disp",   expected: [5, 3, 4]},
                        { search: "displ",  expected: [5, 4]},
                        { search: "displa", expected: [5]} ];
 
-const nickNames = [ { search: "n",      expected: [5, 0, 1, 2, 3, 4] },
-                    { search: "ni",     expected: [5, 0, 1, 2, 3] },
-                    { search: "nic",    expected: [5, 1, 2, 3] },
-                    { search: "nick",   expected: [5, 2, 3] },
-                    { search: "nickn",  expected: [5, 3] },
+const nickNames = [ { search: "n",      expected: [4, 5, 0, 1, 2, 3] },
+                    { search: "ni",     expected: [0, 5, 1, 2, 3] },
+                    { search: "nic",    expected: [1, 5, 2, 3] },
+                    { search: "nick",   expected: [2, 5, 3] },
+                    { search: "nickn",  expected: [3, 5] },
                     { search: "nickna", expected: [5] } ];
 
 const emails = [ { search: "e",     expected: [0, 1, 2, 3, 4, 5, 7, 8, 9] },
                  { search: "em",    expected: [0, 1, 2, 4, 5] },
                  { search: "ema",   expected: [0, 1, 2, 5] },
                  { search: "emai",  expected: [1, 2, 5] },
                  { search: "email", expected: [2, 5] } ];
 
--- a/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch6.js
+++ b/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch6.js
@@ -72,31 +72,50 @@ const cards = [
     popularityIndex: 0, firstName: "paul", lastName: "mary meyer",
     value: "paul meyer <12@example.com>"
   },
 
   { // 13
     email: "13@example.com", displayName: "mr iron man (exp dev)",
     popularityIndex: 0, firstName: "iron", lastName: "man",
     value: "mr iron man (exp dev) <13@example.com>"
+  },
+
+  { // 14
+    email: "14@example.com", displayName: "michael",
+    popularityIndex: 0, nickName: "short",
+    value: "michael <14@example.com>"
+  },
+
+  { // 15
+    email: "15@example.com", displayName: "good boy",
+    popularityIndex: 0, nickName: "sh",
+    value: "good boy <15@example.com>"
+  },
+
+  { // 16
+    email: "16@example.com", displayName: "sherlock holmes",
+    popularityIndex: 0, value: "sherlock holmes <16@example.com>"
   }
 ];
 
 const inputs = [
   { search: "john", expected: [0, 9] },
   { search: "doe", expected: [1, 0] },
   { search: "jd", expected: [0, 4] },
   { search: "who", expected: [1, 0, 6] },
   { search: "xx", expected: [0, 5] },
   { search: "jan", expected: [1, 3] },
-  { search: "sh", expected: [2, 10, 7] },
+  // expecting nickname to score highest.
+  { search: "sh", expected: [15, 14, 16, 2, 10, 7] },
   { search: "st", expected: [3,8] },
   { search: "paul mary", expected: [11, 12] },
   { search: "\"paul mary\"", expected: [11] },
-  { search: "\"iron man\" mr \"exp dev\"", expected: [13] }
+  { search: "\"iron man\" mr \"exp dev\"", expected: [13] },
+  { search: "short", expected: [14] }
 ];
 
 function acObserver() {}
 
 acObserver.prototype = {
   _search: null,
   _result: null,
 
@@ -120,16 +139,17 @@ function run_test()
     var card = Cc["@mozilla.org/addressbook/cardproperty;1"]
                  .createInstance(Ci.nsIAbCard);
 
     card.primaryEmail = element.email;
     card.displayName = element.displayName;
     card.setProperty("PopularityIndex", element.popularityIndex);
     card.firstName = element.firstName;
     card.lastName = element.lastName;
+    card.setProperty("NickName", element.nickName);
 
     ab.addCard(card);
   }
 
   cards.forEach(createAndAddCard);
 
   // Test - duplicate elements