Bug 1551407 - Delete login autocomplete rows using the AutocompleteItem instance. r=sfoster
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Mon, 20 May 2019 19:17:05 +0000
changeset 474585 289880efd19336feedf4dc5c3d75c799446398bb
parent 474584 801ff26b3c1de20fb8944eecd3899e49df76dd0e
child 474586 9cf745b75ebc43caf7d734ddf1526df2b803a7e2
push id36042
push userdvarga@mozilla.com
push dateTue, 21 May 2019 04:19:40 +0000
treeherdermozilla-central@ca560ff55451 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfoster
bugs1551407
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1551407 - Delete login autocomplete rows using the AutocompleteItem instance. r=sfoster Differential Revision: https://phabricator.services.mozilla.com/D31034
toolkit/components/passwordmgr/LoginAutoCompleteResult.jsm
--- a/toolkit/components/passwordmgr/LoginAutoCompleteResult.jsm
+++ b/toolkit/components/passwordmgr/LoginAutoCompleteResult.jsm
@@ -76,32 +76,36 @@ function getLocalizedString(key, formatA
 
 
 class AutocompleteItem {
   constructor(style) {
     this.comment = "";
     this.style = style;
     this.value = "";
   }
+
+  removeFromStorage() { /* Do nothing by default */ }
 }
 
 class InsecureLoginFormAutocompleteItem extends AutocompleteItem {
   constructor() {
     super("insecureWarning");
 
     XPCOMUtils.defineLazyGetter(this, "label", () => {
       let learnMoreString = getLocalizedString("insecureFieldWarningLearnMore");
       return getLocalizedString("insecureFieldWarningDescription2", [learnMoreString]);
     });
   }
 }
 
 class LoginAutocompleteItem extends AutocompleteItem {
-  constructor(login, isPasswordField, dateAndTimeFormatter, duplicateUsernames) {
+  constructor(login, isPasswordField, dateAndTimeFormatter, duplicateUsernames, messageManager) {
     super(SHOULD_SHOW_ORIGIN ? "loginWithOrigin" : "login");
+    this._login = login;
+    this._messageManager = messageManager;
 
     XPCOMUtils.defineLazyGetter(this, "label", () => {
       let username = login.username;
       // If login is empty or duplicated we want to append a modification date to it.
       if (!username || duplicateUsernames.has(username)) {
         if (!username) {
           username = getLocalizedString("noUsername");
         }
@@ -118,16 +122,26 @@ class LoginAutocompleteItem extends Auto
     });
 
     XPCOMUtils.defineLazyGetter(this, "comment", () => {
       return JSON.stringify({
         loginOrigin: login.hostname,
       });
     });
   }
+
+  removeFromStorage() {
+    if (this._messageManager) {
+      let vanilla = LoginHelper.loginToVanillaObject(this._login);
+      this._messageManager.sendAsyncMessage("PasswordManager:removeLogin",
+                                            { login: vanilla });
+    } else {
+      Services.logins.removeLogin(this._login);
+    }
+  }
 }
 
 class LoginsFooterAutocompleteItem extends AutocompleteItem {
   constructor(hostname) {
     super("loginsFooter");
 
     XPCOMUtils.defineLazyGetter(this, "label", () => {
       return JSON.stringify({
@@ -168,31 +182,32 @@ function LoginAutoCompleteResult(aSearch
     }
 
     return true;
   }
 
   this._showInsecureFieldWarning = (!isSecure && LoginHelper.showInsecureFieldWarning) ? 1 : 0;
   this._showAutoCompleteFooter = isFooterEnabled() ? 1 : 0;
 
-  this.logins = matchingLogins.sort(loginSort);
+  let logins = matchingLogins.sort(loginSort);
   this.searchString = aSearchString;
-  this._messageManager = messageManager;
   let dateAndTimeFormatter = new Services.intl.DateTimeFormat(undefined, { dateStyle: "medium" });
 
   let duplicateUsernames = findDuplicates(matchingLogins);
 
   // Build up the results array
   this.results = [];
   if (this._showInsecureFieldWarning) {
     this.results.push(new InsecureLoginFormAutocompleteItem());
   }
 
-  for (let login of this.logins) {
-    this.results.push(new LoginAutocompleteItem(login, isPasswordField, dateAndTimeFormatter, duplicateUsernames));
+  for (let login of logins) {
+    let item = new LoginAutocompleteItem(login, isPasswordField, dateAndTimeFormatter,
+                                         duplicateUsernames, messageManager);
+    this.results.push(item);
   }
 
   if (this._showAutoCompleteFooter) {
     this.results.push(new LoginsFooterAutocompleteItem(hostname));
   }
 
 
   if (this.matchCount > 0) {
@@ -206,17 +221,21 @@ function LoginAutoCompleteResult(aSearch
   }
 }
 
 LoginAutoCompleteResult.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.nsIAutoCompleteResult,
                                           Ci.nsISupportsWeakReference]),
 
   // private
-  logins: null,
+  get logins() {
+    return this.results.filter(item => {
+      return item.constructor === LoginAutocompleteItem;
+    }).map(item => item._login);
+  },
 
   // Allow autoCompleteSearch to get at the JS object so it can
   // modify some readonly properties for internal use.
   get wrappedJSObject() {
     return this;
   },
 
   // Interfaces from idl...
@@ -261,45 +280,24 @@ LoginAutoCompleteResult.prototype = {
     return this.getValueAt(index);
   },
 
   removeValueAt(index, removeFromDB) {
     if (index < 0 || index >= this.matchCount) {
       throw new Error("Index out of range.");
     }
 
-    if (this._showInsecureFieldWarning && index === 0) {
-      // Ignore the warning message item.
-      return;
-    }
-
-    if (this._showInsecureFieldWarning) {
-      index--;
-    }
+    let [removedItem] = this.results.splice(index, 1);
 
-    // The user cannot delete the autocomplete footer.
-    if (this._showAutoCompleteFooter && index === this.matchCount - 1) {
-      return;
-    }
-
-    let [removedLogin] = this.logins.splice(index, 1);
-
-    this.matchCount--;
-    if (this.defaultIndex > this.logins.length) {
+    if (this.defaultIndex > this.results.length) {
       this.defaultIndex--;
     }
 
     if (removeFromDB) {
-      if (this._messageManager) {
-        let vanilla = LoginHelper.loginToVanillaObject(removedLogin);
-        this._messageManager.sendAsyncMessage("PasswordManager:removeLogin",
-                                              { login: vanilla });
-      } else {
-        Services.logins.removeLogin(removedLogin);
-      }
+      removedItem.removeFromStorage();
     }
   },
 };
 
 function LoginAutoComplete() {}
 LoginAutoComplete.prototype = {
   classID: Components.ID("{2bdac17c-53f1-4896-a521-682ccdeef3a8}"),
   QueryInterface: ChromeUtils.generateQI([Ci.nsILoginAutoCompleteSearch]),