summaryrefslogtreecommitdiffstats
path: root/toolkit/components/satchel/nsFormFillController.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/satchel/nsFormFillController.cpp')
-rw-r--r--toolkit/components/satchel/nsFormFillController.cpp249
1 files changed, 45 insertions, 204 deletions
diff --git a/toolkit/components/satchel/nsFormFillController.cpp b/toolkit/components/satchel/nsFormFillController.cpp
index 61d23d157c..342e1d29b7 100644
--- a/toolkit/components/satchel/nsFormFillController.cpp
+++ b/toolkit/components/satchel/nsFormFillController.cpp
@@ -23,7 +23,6 @@
#include "mozilla/Services.h"
#include "mozilla/StaticPrefs_ui.h"
#include "nsCRT.h"
-#include "nsIFormHistoryAutoComplete.h"
#include "nsString.h"
#include "nsPIDOMWindow.h"
#include "nsIAutoCompleteResult.h"
@@ -47,25 +46,8 @@ using mozilla::LogLevel;
static mozilla::LazyLogModule sLogger("satchel");
-static nsIFormHistoryAutoComplete* GetFormHistoryAutoComplete() {
- static nsCOMPtr<nsIFormHistoryAutoComplete> sInstance;
- static bool sInitialized = false;
- if (!sInitialized) {
- nsresult rv;
- sInstance =
- do_GetService("@mozilla.org/satchel/form-history-autocomplete;1", &rv);
-
- if (NS_SUCCEEDED(rv)) {
- ClearOnShutdown(&sInstance);
- sInitialized = true;
- }
- }
- return sInstance;
-}
-
-NS_IMPL_CYCLE_COLLECTION(nsFormFillController, mController, mLoginManagerAC,
- mFocusedPopup, mPopups, mLastListener,
- mLastFormHistoryAutoComplete)
+NS_IMPL_CYCLE_COLLECTION(nsFormFillController, mController, mFocusedPopup,
+ mLastListener)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsFormFillController)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIFormFillController)
@@ -205,8 +187,7 @@ void nsFormFillController::ARIAAttributeDefaultChanged(
MOZ_CAN_RUN_SCRIPT_BOUNDARY
void nsFormFillController::NodeWillBeDestroyed(nsINode* aNode) {
MOZ_LOG(sLogger, LogLevel::Verbose, ("NodeWillBeDestroyed: %p", aNode));
- mPwmgrInputs.Remove(aNode);
- mAutofillInputs.Remove(aNode);
+ mAutoCompleteInputs.Remove(aNode);
MaybeRemoveMutationObserver(aNode);
if (aNode == mListNode) {
mListNode = nullptr;
@@ -217,9 +198,9 @@ void nsFormFillController::NodeWillBeDestroyed(nsINode* aNode) {
}
void nsFormFillController::MaybeRemoveMutationObserver(nsINode* aNode) {
- // Nodes being tracked in mPwmgrInputs will have their observers removed when
- // they stop being tracked.
- if (!mPwmgrInputs.Get(aNode) && !mAutofillInputs.Get(aNode)) {
+ // Nodes being tracked in mAutoCompleteInputs will have their observers
+ // removed when they stop being tracked.
+ if (!mAutoCompleteInputs.Get(aNode)) {
aNode->RemoveMutationObserver(this);
}
}
@@ -228,84 +209,7 @@ void nsFormFillController::MaybeRemoveMutationObserver(nsINode* aNode) {
//// nsIFormFillController
NS_IMETHODIMP
-nsFormFillController::AttachPopupElementToDocument(Document* aDocument,
- dom::Element* aPopupEl) {
- if (!xpc::IsInAutomation()) {
- return NS_ERROR_NOT_AVAILABLE;
- }
-
- MOZ_LOG(sLogger, LogLevel::Debug,
- ("AttachPopupElementToDocument for document %p with popup %p",
- aDocument, aPopupEl));
- NS_ENSURE_TRUE(aDocument && aPopupEl, NS_ERROR_ILLEGAL_VALUE);
-
- nsCOMPtr<nsIAutoCompletePopup> popup = aPopupEl->AsAutoCompletePopup();
- NS_ENSURE_STATE(popup);
-
- mPopups.InsertOrUpdate(aDocument, popup);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFormFillController::DetachFromDocument(Document* aDocument) {
- if (!xpc::IsInAutomation()) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- mPopups.Remove(aDocument);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFormFillController::MarkAsLoginManagerField(HTMLInputElement* aInput) {
- /*
- * The Login Manager can supply autocomplete results for username fields,
- * when a user has multiple logins stored for a site. It uses this
- * interface to indicate that the form manager shouldn't handle the
- * autocomplete. The form manager also checks for this tag when saving
- * form history (so it doesn't save usernames).
- */
- NS_ENSURE_STATE(aInput);
-
- // If the field was already marked, we don't want to show the popup again.
- if (mPwmgrInputs.Get(aInput)) {
- return NS_OK;
- }
-
- mPwmgrInputs.InsertOrUpdate(aInput, true);
- aInput->AddMutationObserverUnlessExists(this);
-
- nsFocusManager* fm = nsFocusManager::GetFocusManager();
- if (fm) {
- nsCOMPtr<nsIContent> focusedContent = fm->GetFocusedElement();
- if (focusedContent == aInput) {
- if (!mFocusedInput) {
- MaybeStartControllingInput(aInput);
- } else {
- // If we change who is responsible for searching the autocomplete
- // result, notify the controller that the previous result is not valid
- // anymore.
- nsCOMPtr<nsIAutoCompleteController> controller = mController;
- controller->ResetInternalState();
- }
- }
- }
-
- if (!mLoginManagerAC) {
- mLoginManagerAC =
- do_GetService("@mozilla.org/login-manager/autocompletesearch;1");
- }
-
- return NS_OK;
-}
-
-MOZ_CAN_RUN_SCRIPT NS_IMETHODIMP nsFormFillController::IsLoginManagerField(
- HTMLInputElement* aInput, bool* isLoginManagerField) {
- *isLoginManagerField = mPwmgrInputs.Get(aInput);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFormFillController::MarkAsAutofillField(HTMLInputElement* aInput) {
+nsFormFillController::MarkAsAutoCompletableField(HTMLInputElement* aInput) {
/*
* Support other components implementing form autofill and handle autocomplete
* for the field.
@@ -313,13 +217,13 @@ nsFormFillController::MarkAsAutofillField(HTMLInputElement* aInput) {
NS_ENSURE_STATE(aInput);
MOZ_LOG(sLogger, LogLevel::Verbose,
- ("MarkAsAutofillField: aInput = %p", aInput));
+ ("MarkAsAutoCompletableField: aInput = %p", aInput));
- if (mAutofillInputs.Get(aInput)) {
+ if (mAutoCompleteInputs.Get(aInput)) {
return NS_OK;
}
- mAutofillInputs.InsertOrUpdate(aInput, true);
+ mAutoCompleteInputs.InsertOrUpdate(aInput, true);
aInput->AddMutationObserverUnlessExists(this);
aInput->EnablePreview();
@@ -522,18 +426,15 @@ nsFormFillController::GetSearchCount(uint32_t* aSearchCount) {
NS_IMETHODIMP
nsFormFillController::GetSearchAt(uint32_t index, nsACString& _retval) {
- if (mAutofillInputs.Get(mFocusedInput)) {
- MOZ_LOG(sLogger, LogLevel::Debug, ("GetSearchAt: autofill-profiles field"));
- nsCOMPtr<nsIAutoCompleteSearch> profileSearch = do_GetService(
- "@mozilla.org/autocomplete/search;1?name=autofill-profiles");
- if (profileSearch) {
- _retval.AssignLiteral("autofill-profiles");
- return NS_OK;
- }
- }
-
- MOZ_LOG(sLogger, LogLevel::Debug, ("GetSearchAt: form-history field"));
- _retval.AssignLiteral("form-history");
+ MOZ_LOG(sLogger, LogLevel::Debug,
+ ("GetSearchAt: form-fill-controller field"));
+
+ // The better solution should be AutoCompleteController gets the
+ // nsIAutoCompleteSearch interface from AutoCompletePopup and invokes the
+ // StartSearch without going through FormFillController. Currently
+ // FormFillController acts as the proxy to find the AutoCompletePopup for
+ // AutoCompleteController.
+ _retval.AssignLiteral("form-fill-controller");
return NS_OK;
}
@@ -636,13 +537,12 @@ nsFormFillController::GetNoRollupOnCaretMove(bool* aNoRollupOnCaretMove) {
NS_IMETHODIMP
nsFormFillController::GetNoRollupOnEmptySearch(bool* aNoRollupOnEmptySearch) {
- if (mFocusedInput && (mPwmgrInputs.Get(mFocusedInput) ||
- mFocusedInput->HasBeenTypePassword())) {
- // Don't close the login popup when the field is cleared (bug 1534896).
- *aNoRollupOnEmptySearch = true;
- } else {
- *aNoRollupOnEmptySearch = false;
+ if (mFocusedInput && mFocusedPopup) {
+ return mFocusedPopup->GetNoRollupOnEmptySearch(mFocusedInput,
+ aNoRollupOnEmptySearch);
}
+
+ *aNoRollupOnEmptySearch = false;
return NS_OK;
}
@@ -669,61 +569,32 @@ nsFormFillController::StartSearch(const nsAString& aSearchString,
nsIAutoCompleteObserver* aListener) {
MOZ_LOG(sLogger, LogLevel::Debug, ("StartSearch for %p", mFocusedInput));
- nsresult rv;
-
- // 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 (mFocusedInput && (mPwmgrInputs.Get(mFocusedInput) ||
- mFocusedInput->HasBeenTypePassword())) {
- MOZ_LOG(sLogger, LogLevel::Debug, ("StartSearch: login field"));
-
- // Handle the case where a password field is focused but
- // MarkAsLoginManagerField wasn't called because password manager is
- // disabled.
- if (!mLoginManagerAC) {
- mLoginManagerAC =
- do_GetService("@mozilla.org/login-manager/autocompletesearch;1");
- }
-
- if (NS_WARN_IF(!mLoginManagerAC)) {
- return NS_ERROR_FAILURE;
- }
+ mLastListener = aListener;
- // XXX aPreviousResult shouldn't ever be a historyResult type, since we're
- // not letting satchel manage the field?
- mLastListener = aListener;
- rv = mLoginManagerAC->StartSearch(aSearchString, aPreviousResult,
- mFocusedInput, this);
- NS_ENSURE_SUCCESS(rv, rv);
- } else {
- MOZ_LOG(sLogger, LogLevel::Debug, ("StartSearch: non-login field"));
- mLastListener = aListener;
+ if (mFocusedInput && mFocusedPopup) {
+ if (mAutoCompleteInputs.Get(mFocusedInput) ||
+ mFocusedInput->HasBeenTypePassword()) {
+ MOZ_LOG(sLogger, LogLevel::Debug,
+ ("StartSearch: formautofill or login field"));
- bool addDataList = IsTextControl(mFocusedInput);
- if (addDataList) {
- MaybeObserveDataListMutations();
+ return mFocusedPopup->StartSearch(aSearchString, mFocusedInput, this);
}
+ }
- auto* formHistoryAutoComplete = GetFormHistoryAutoComplete();
- NS_ENSURE_TRUE(formHistoryAutoComplete, NS_ERROR_FAILURE);
+ MOZ_LOG(sLogger, LogLevel::Debug, ("StartSearch: form history field"));
- formHistoryAutoComplete->AutoCompleteSearchAsync(
- aSearchParam, aSearchString, mFocusedInput, aPreviousResult,
- addDataList, this);
- mLastFormHistoryAutoComplete = formHistoryAutoComplete;
+ bool addDataList = IsTextControl(mFocusedInput);
+ if (addDataList) {
+ MaybeObserveDataListMutations();
}
- return NS_OK;
+ return mFocusedPopup->StartSearch(aSearchString, mFocusedInput, this);
}
void nsFormFillController::MaybeObserveDataListMutations() {
// If an <input> is focused, check if it has a list="<datalist>" which can
// provide the list of suggestions.
- MOZ_ASSERT(!mPwmgrInputs.Get(mFocusedInput));
-
if (mFocusedInput) {
Element* list = mFocusedInput->GetList();
@@ -760,16 +631,10 @@ void nsFormFillController::RevalidateDataList() {
NS_IMETHODIMP
nsFormFillController::StopSearch() {
- // Make sure to stop and clear this, otherwise the controller will prevent
- // mLastFormHistoryAutoComplete from being deleted.
- if (mLastFormHistoryAutoComplete) {
- mLastFormHistoryAutoComplete->StopAutoCompleteSearch();
- mLastFormHistoryAutoComplete = nullptr;
+ if (mFocusedPopup) {
+ mFocusedPopup->StopSearch();
}
- if (mLoginManagerAC) {
- mLoginManagerAC->StopSearch();
- }
return NS_OK;
}
@@ -927,19 +792,8 @@ void nsFormFillController::AttachListeners(EventTarget* aEventTarget) {
void nsFormFillController::RemoveForDocument(Document* aDoc) {
MOZ_LOG(sLogger, LogLevel::Verbose, ("RemoveForDocument: %p", aDoc));
- for (auto iter = mPwmgrInputs.Iter(); !iter.Done(); iter.Next()) {
- const nsINode* key = iter.Key();
- if (key && (!aDoc || key->OwnerDoc() == aDoc)) {
- // mFocusedInput's observer is tracked separately, so don't remove it
- // here.
- if (key != mFocusedInput) {
- const_cast<nsINode*>(key)->RemoveMutationObserver(this);
- }
- iter.Remove();
- }
- }
- for (auto iter = mAutofillInputs.Iter(); !iter.Done(); iter.Next()) {
+ for (auto iter = mAutoCompleteInputs.Iter(); !iter.Done(); iter.Next()) {
const nsINode* key = iter.Key();
if (key && (!aDoc || key->OwnerDoc() == aDoc)) {
// mFocusedInput's observer is tracked separately, so don't remove it
@@ -975,19 +829,8 @@ void nsFormFillController::MaybeStartControllingInput(
return;
}
- bool autocomplete = nsContentUtils::IsAutocompleteEnabled(aInput);
-
- bool isPwmgrInput = false;
- if (mPwmgrInputs.Get(aInput) || aInput->HasBeenTypePassword()) {
- isPwmgrInput = true;
- }
-
- bool isAutofillInput = false;
- if (mAutofillInputs.Get(aInput)) {
- isAutofillInput = true;
- }
-
- if (isAutofillInput || isPwmgrInput || hasList || autocomplete) {
+ if (mAutoCompleteInputs.Get(aInput) || aInput->HasBeenTypePassword() ||
+ hasList || nsContentUtils::IsAutocompleteEnabled(aInput)) {
StartControllingInput(aInput);
}
}
@@ -1228,12 +1071,10 @@ void nsFormFillController::StartControllingInput(HTMLInputElement* aInput) {
return;
}
- nsCOMPtr<nsIAutoCompletePopup> popup = mPopups.Get(aInput->OwnerDoc());
+ nsCOMPtr<nsIAutoCompletePopup> popup =
+ do_QueryActor("AutoComplete", aInput->OwnerDoc());
if (!popup) {
- popup = do_QueryActor("AutoComplete", aInput->OwnerDoc());
- if (!popup) {
- return;
- }
+ return;
}
mFocusedPopup = popup;