Bug 1304634 - Part 1: Introduce MarkAsAutofillField API and necessary logic changes in controller, r=MattN draft
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Thu, 22 Sep 2016 15:26:28 +0800
changeset 452755 b4d9f774e5aca4a1520a685bfaa1f3b68e86c0d3
parent 450924 863c2b61bd27bb6099104933134d3be7c052551a
child 452756 6ad1fc66c424950ee92737a4e39b2978c17d4fca
child 453339 87e4edbc77bb4ef0e62c4046249bd6b315568e2a
child 453415 0387edf21882360f59d04070130527dfd2ac3472
child 453977 04e068ed865a08586bdfbd37556aa618821c0756
push id39470
push userschung@mozilla.com
push dateThu, 22 Dec 2016 04:09:07 +0000
reviewersMattN
bugs1304634
milestone53.0a1
Bug 1304634 - Part 1: Introduce MarkAsAutofillField API and necessary logic changes in controller, r=MattN MozReview-Commit-ID: BeZXuWMvcQg
toolkit/components/satchel/nsFormFillController.cpp
toolkit/components/satchel/nsFormFillController.h
toolkit/components/satchel/nsIFormFillController.idl
--- a/toolkit/components/satchel/nsFormFillController.cpp
+++ b/toolkit/components/satchel/nsFormFillController.cpp
@@ -201,31 +201,32 @@ void
 nsFormFillController::ParentChainChanged(nsIContent* aContent)
 {
 }
 
 void
 nsFormFillController::NodeWillBeDestroyed(const nsINode* aNode)
 {
   mPwmgrInputs.Remove(aNode);
+  mAutofillInputs.Remove(aNode);
   if (aNode == mListNode) {
     mListNode = nullptr;
     RevalidateDataList();
   } else if (aNode == mFocusedInputNode) {
     mFocusedInputNode = nullptr;
     mFocusedInput = nullptr;
   }
 }
 
 void
 nsFormFillController::MaybeRemoveMutationObserver(nsINode* aNode)
 {
   // Nodes being tracked in mPwmgrInputs will have their observers removed when
   // they stop being tracked.
-  if (!mPwmgrInputs.Get(aNode)) {
+  if (!mPwmgrInputs.Get(aNode) && !mAutofillInputs.Get(aNode)) {
     aNode->RemoveMutationObserver(this);
   }
 }
 
 ////////////////////////////////////////////////////////////////////////
 //// nsIFormFillController
 
 NS_IMETHODIMP
@@ -289,16 +290,31 @@ nsFormFillController::MarkAsLoginManager
   }
 
   if (!mLoginManager)
     mLoginManager = do_GetService("@mozilla.org/login-manager;1");
 
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsFormFillController::MarkAsAutofillField(nsIDOMHTMLInputElement *aInput)
+{
+  /*
+   * Support other components implementing form autofill and handle autocomplete
+   * for the field.
+   */
+  nsCOMPtr<nsINode> node = do_QueryInterface(aInput);
+  NS_ENSURE_STATE(node);
+  mAutofillInputs.Put(node, true);
+  node->AddMutationObserverUnlessExists(this);
+
+  return NS_OK;
+}
+
 
 ////////////////////////////////////////////////////////////////////////
 //// nsIAutoCompleteInput
 
 NS_IMETHODIMP
 nsFormFillController::GetPopup(nsIAutoCompletePopup **aPopup)
 {
   *aPopup = mFocusedPopup;
@@ -903,16 +919,28 @@ nsFormFillController::RemoveForDocument(
       // mFocusedInputNode's observer is tracked separately, so don't remove it
       // here.
       if (key != mFocusedInputNode) {
         const_cast<nsINode*>(key)->RemoveMutationObserver(this);
       }
       iter.Remove();
     }
   }
+
+  for (auto iter = mAutofillInputs.Iter(); !iter.Done(); iter.Next()) {
+    const nsINode* key = iter.Key();
+    if (key && (!aDoc || key->OwnerDoc() == aDoc)) {
+      // mFocusedInputNode's observer is tracked separately, so don't remove it
+      // here.
+      if (key != mFocusedInputNode) {
+        const_cast<nsINode*>(key)->RemoveMutationObserver(this);
+      }
+      iter.Remove();
+    }
+  }
 }
 
 void
 nsFormFillController::MaybeStartControllingInput(nsIDOMHTMLInputElement* aInput)
 {
   nsCOMPtr<nsINode> inputNode = do_QueryInterface(aInput);
   if (!inputNode)
     return;
--- a/toolkit/components/satchel/nsFormFillController.h
+++ b/toolkit/components/satchel/nsFormFillController.h
@@ -106,16 +106,17 @@ protected:
   // complete or the data from a datalist changes.
   nsCOMPtr<nsIAutoCompleteObserver> mLastListener;
 
   // This is cleared by StopSearch().
   nsCOMPtr<nsIFormAutoComplete> mLastFormAutoComplete;
   nsString mLastSearchString;
 
   nsDataHashtable<nsPtrHashKey<const nsINode>, bool> mPwmgrInputs;
+  nsDataHashtable<nsPtrHashKey<const nsINode>, bool> mAutofillInputs;
 
   uint32_t mTimeout;
   uint32_t mMinResultsForPopup;
   uint32_t mMaxRows;
   bool mContextMenuFiredBeforeFocus;
   bool mDisableAutoComplete;
   bool mCompleteDefaultIndex;
   bool mCompleteSelectedIndex;
--- a/toolkit/components/satchel/nsIFormFillController.idl
+++ b/toolkit/components/satchel/nsIFormFillController.idl
@@ -38,9 +38,17 @@ interface nsIFormFillController : nsISup
   /*
    * Mark the specified <input> element as being managed by password manager.
    * Autocomplete requests will be handed off to the password manager, and will
    * not be stored in form history.
    *
    * @param aInput - The HTML <input> element to tag
    */
   void markAsLoginManagerField(in nsIDOMHTMLInputElement aInput);
+
+  /*
+   * Mark the specified <input> element as being managed by a form autofill component.
+   * Autocomplete requests will be handed off to the autofill component.
+   *
+   * @param aInput - The HTML <input> element to mark
+   */
+  void markAsAutofillField(in nsIDOMHTMLInputElement aInput);
 };