Bug 1330111 - Always attempt to autocomplete on type=password fields upon focus. r=daleharvey a=jcristau
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Tue, 07 Feb 2017 11:15:35 +0800
changeset 378289 83a5402b5472f547f133de773592120994806ff1
parent 378288 8dcc2332e280ee23815b44ba76f78c9919d9ebd0
child 378290 e22cc104ea978ac6c889c6820e20b15d31068870
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdaleharvey, jcristau
bugs1330111
milestone53.0a2
Bug 1330111 - Always attempt to autocomplete on type=password fields upon focus. r=daleharvey a=jcristau Let password manager handle opening the popup on username fields itself. MozReview-Commit-ID: FbI6CgsadEd
mobile/android/app/mobile.js
toolkit/components/satchel/nsFormFillController.cpp
--- a/mobile/android/app/mobile.js
+++ b/mobile/android/app/mobile.js
@@ -167,16 +167,17 @@ pref("browser.download.manager.flashCoun
 pref("browser.download.manager.displayedHistoryDays", 7);
 pref("browser.download.manager.addToRecentDocs", true);
 
 /* download helper */
 pref("browser.helperApps.deleteTempFileOnExit", false);
 
 /* password manager */
 pref("signon.rememberSignons", true);
+pref("signon.autofillForms.http", true);
 pref("signon.expireMasterPassword", false);
 pref("signon.debug", false);
 
 /* form helper (scroll to and optionally zoom into editable fields)  */
 pref("formhelper.mode", 2);  // 0 = disabled, 1 = enabled, 2 = dynamic depending on screen size
 pref("formhelper.autozoom", true);
 
 /* find helper */
--- a/toolkit/components/satchel/nsFormFillController.cpp
+++ b/toolkit/components/satchel/nsFormFillController.cpp
@@ -286,17 +286,16 @@ nsFormFillController::MarkAsLoginManager
   nsFocusManager *fm = nsFocusManager::GetFocusManager();
   if (fm) {
     nsCOMPtr<nsIContent> focusedContent = fm->GetFocusedContent();
     if (SameCOMIdentity(focusedContent, node)) {
       nsCOMPtr<nsIDOMHTMLInputElement> input = do_QueryInterface(node);
       if (!mFocusedInput) {
         MaybeStartControllingInput(input);
       }
-      ShowPopup();
     }
   }
 
   if (!mLoginManager)
     mLoginManager = do_GetService("@mozilla.org/login-manager;1");
 
   return NS_OK;
 }
@@ -693,25 +692,30 @@ NS_IMETHODIMP
 nsFormFillController::StartSearch(const nsAString &aSearchString, const nsAString &aSearchParam,
                                   nsIAutoCompleteResult *aPreviousResult, nsIAutoCompleteObserver *aListener)
 {
   nsresult rv;
   nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(mFocusedInputNode);
 
   // If the login manager has indicated it's responsible for this field, let it
   // handle the autocomplete. Otherwise, handle with form history.
+  // This method is sometimes called in unit tests and from XUL without a focused node.
   if (mFocusedInputNode && (mPwmgrInputs.Get(mFocusedInputNode) ||
                             formControl->GetType() == NS_FORM_INPUT_PASSWORD)) {
 
     // Handle the case where a password field is focused but
     // MarkAsLoginManagerField wasn't called because password manager is disabled.
     if (!mLoginManager) {
       mLoginManager = do_GetService("@mozilla.org/login-manager;1");
     }
 
+    if (NS_WARN_IF(!mLoginManager)) {
+      return NS_ERROR_FAILURE;
+    }
+
     // XXX aPreviousResult shouldn't ever be a historyResult type, since we're not letting
     // satchel manage the field?
     mLastListener = aListener;
     rv = mLoginManager->AutoCompleteSearchAsync(aSearchString,
                                                 aPreviousResult,
                                                 mFocusedInput,
                                                 this);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -979,18 +983,20 @@ nsFormFillController::MaybeStartControll
 
   bool autocomplete = nsContentUtils::IsAutocompleteEnabled(aInput);
 
   nsCOMPtr<nsIDOMHTMLElement> datalist;
   aInput->GetList(getter_AddRefs(datalist));
   bool hasList = datalist != nullptr;
 
   bool isPwmgrInput = false;
-  if (mPwmgrInputs.Get(inputNode))
-      isPwmgrInput = true;
+  if (mPwmgrInputs.Get(inputNode) ||
+      formControl->GetType() == NS_FORM_INPUT_PASSWORD) {
+    isPwmgrInput = true;
+  }
 
   if (isPwmgrInput || hasList || autocomplete) {
     StartControllingInput(aInput);
   }
 }
 
 nsresult
 nsFormFillController::Focus(nsIDOMEvent* aEvent)
@@ -1000,29 +1006,27 @@ nsFormFillController::Focus(nsIDOMEvent*
   MaybeStartControllingInput(input);
 
   // Bail if we didn't start controlling the input.
   if (!mFocusedInputNode) {
     mContextMenuFiredBeforeFocus = false;
     return NS_OK;
   }
 
+#ifndef ANDROID
   nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(mFocusedInputNode);
   MOZ_ASSERT(formControl);
 
   // If this focus doesn't immediately follow a contextmenu event then show
-  // the autocomplete popup
-  if (!mContextMenuFiredBeforeFocus &&
-      (mPwmgrInputs.Get(mFocusedInputNode)
-#ifndef ANDROID
-       || formControl->GetType() == NS_FORM_INPUT_PASSWORD
-#endif
-       )) {
+  // the autocomplete popup for all password fields.
+  if (!mContextMenuFiredBeforeFocus
+      && formControl->GetType() == NS_FORM_INPUT_PASSWORD) {
     ShowPopup();
   }
+#endif
 
   mContextMenuFiredBeforeFocus = false;
   return NS_OK;
 }
 
 nsresult
 nsFormFillController::KeyPress(nsIDOMEvent* aEvent)
 {