Bug 1330111 - Always attempt to autocomplete on type=password fields upon focus. r=daleharvey draft
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Fri, 03 Feb 2017 17:19:02 -0800
changeset 478917 07980abd1af8ec1f06d35f01965fbb045b46c3dc
parent 468862 70e19926d22bc7ad68fc64825a869ab65afde184
child 478918 667dc91d72b35a27d377aae37d42b8470ef2e430
push id44090
push usermozilla@noorenberghe.ca
push dateSat, 04 Feb 2017 01:25:53 +0000
reviewersdaleharvey
bugs1330111
milestone54.0a1
Bug 1330111 - Always attempt to autocomplete on type=password fields upon focus. r=daleharvey 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;
 }
@@ -697,29 +696,37 @@ nsFormFillController::GetUserContextId(u
 ////////////////////////////////////////////////////////////////////////
 //// nsIAutoCompleteSearch
 
 NS_IMETHODIMP
 nsFormFillController::StartSearch(const nsAString &aSearchString, const nsAString &aSearchParam,
                                   nsIAutoCompleteResult *aPreviousResult, nsIAutoCompleteObserver *aListener)
 {
   nsresult rv;
+  if (!mFocusedInputNode) {
+    return NS_ERROR_FAILURE;
+  }
+
   nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(mFocusedInputNode);
+  MOZ_ASSERT(formControl);
 
   // If the login manager has indicated it's responsible for this field, let it
   // handle the autocomplete. Otherwise, handle with form history.
-  if (mFocusedInputNode && (mPwmgrInputs.Get(mFocusedInputNode) ||
-                            formControl->GetType() == NS_FORM_INPUT_PASSWORD)) {
+  if (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);
@@ -987,18 +994,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)
@@ -1008,29 +1017,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)
 {