Bug 1304634 - Part 1: Introduce MarkAsAutofillField API and necessary logic changes in controller, r=MattN
MozReview-Commit-ID: BeZXuWMvcQg
--- 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);
};