155 lines
5.6 KiB
Diff
155 lines
5.6 KiB
Diff
|
From 0922145c255bf2503d3b2dd5f8f1e813338ba990 Mon Sep 17 00:00:00 2001
|
||
|
From: Mats Palmgren <mats@mozilla.com>
|
||
|
Date: Sat, 24 Jan 2015 12:37:47 -0500
|
||
|
Subject: [PATCH] Bug 1110557. r=mak, r=gavin, a=bkerensa
|
||
|
|
||
|
---
|
||
|
.../components/satchel/nsFormFillController.cpp | 67 +++++++++++++++-------
|
||
|
toolkit/components/satchel/nsFormFillController.h | 5 ++
|
||
|
2 files changed, 52 insertions(+), 20 deletions(-)
|
||
|
|
||
|
diff --git a/toolkit/components/satchel/nsFormFillController.cpp b/toolkit/components/satchel/nsFormFillController.cpp
|
||
|
index 315fc68..676ad84 100644
|
||
|
--- a/toolkit/components/satchel/nsFormFillController.cpp
|
||
|
+++ b/toolkit/components/satchel/nsFormFillController.cpp
|
||
|
@@ -61,6 +61,7 @@ nsFormFillController::nsFormFillController() :
|
||
|
mSuppressOnInput(false)
|
||
|
{
|
||
|
mController = do_GetService("@mozilla.org/autocomplete/controller;1");
|
||
|
+ MOZ_ASSERT(mController);
|
||
|
}
|
||
|
|
||
|
struct PwmgrInputsEnumData
|
||
|
@@ -104,6 +105,21 @@ nsFormFillController::AttributeChanged(nsIDocument* aDocument,
|
||
|
int32_t aNameSpaceID,
|
||
|
nsIAtom* aAttribute, int32_t aModType)
|
||
|
{
|
||
|
+ if ((aAttribute == nsGkAtoms::type || aAttribute == nsGkAtoms::readonly ||
|
||
|
+ aAttribute == nsGkAtoms::autocomplete) &&
|
||
|
+ aNameSpaceID == kNameSpaceID_None) {
|
||
|
+ nsCOMPtr<nsIDOMHTMLInputElement> focusedInput(mFocusedInput);
|
||
|
+ // Reset the current state of the controller, unconditionally.
|
||
|
+ StopControllingInput();
|
||
|
+ // Then restart based on the new values. We have to delay this
|
||
|
+ // to avoid ending up in an endless loop due to re-registering our
|
||
|
+ // mutation observer (which would notify us again for *this* event).
|
||
|
+ nsCOMPtr<nsIRunnable> event =
|
||
|
+ NS_NewRunnableMethodWithArg<nsCOMPtr<nsIDOMHTMLInputElement>>
|
||
|
+ (this, &nsFormFillController::MaybeStartControllingInput, focusedInput);
|
||
|
+ NS_DispatchToCurrentThread(event);
|
||
|
+ }
|
||
|
+
|
||
|
if (mListNode && mListNode->Contains(aElement)) {
|
||
|
RevalidateDataList();
|
||
|
}
|
||
|
@@ -841,28 +857,26 @@ nsFormFillController::RemoveForDocumentEnumerator(const nsINode* aKey,
|
||
|
return PL_DHASH_NEXT;
|
||
|
}
|
||
|
|
||
|
-nsresult
|
||
|
-nsFormFillController::Focus(nsIDOMEvent* aEvent)
|
||
|
+void
|
||
|
+nsFormFillController::MaybeStartControllingInput(nsIDOMHTMLInputElement* aInput)
|
||
|
{
|
||
|
- nsCOMPtr<nsIDOMHTMLInputElement> input = do_QueryInterface(
|
||
|
- aEvent->InternalDOMEvent()->GetTarget());
|
||
|
- nsCOMPtr<nsINode> inputNode = do_QueryInterface(input);
|
||
|
+ nsCOMPtr<nsINode> inputNode = do_QueryInterface(aInput);
|
||
|
if (!inputNode)
|
||
|
- return NS_OK;
|
||
|
+ return;
|
||
|
|
||
|
- nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(input);
|
||
|
+ nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(aInput);
|
||
|
if (!formControl || !formControl->IsSingleLineTextControl(true))
|
||
|
- return NS_OK;
|
||
|
+ return;
|
||
|
|
||
|
bool isReadOnly = false;
|
||
|
- input->GetReadOnly(&isReadOnly);
|
||
|
+ aInput->GetReadOnly(&isReadOnly);
|
||
|
if (isReadOnly)
|
||
|
- return NS_OK;
|
||
|
+ return;
|
||
|
|
||
|
- bool autocomplete = nsContentUtils::IsAutocompleteEnabled(input);
|
||
|
+ bool autocomplete = nsContentUtils::IsAutocompleteEnabled(aInput);
|
||
|
|
||
|
nsCOMPtr<nsIDOMHTMLElement> datalist;
|
||
|
- input->GetList(getter_AddRefs(datalist));
|
||
|
+ aInput->GetList(getter_AddRefs(datalist));
|
||
|
bool hasList = datalist != nullptr;
|
||
|
|
||
|
bool dummy;
|
||
|
@@ -871,9 +885,16 @@ nsFormFillController::Focus(nsIDOMEvent* aEvent)
|
||
|
isPwmgrInput = true;
|
||
|
|
||
|
if (isPwmgrInput || hasList || autocomplete) {
|
||
|
- StartControllingInput(input);
|
||
|
+ StartControllingInput(aInput);
|
||
|
}
|
||
|
+}
|
||
|
|
||
|
+nsresult
|
||
|
+nsFormFillController::Focus(nsIDOMEvent* aEvent)
|
||
|
+{
|
||
|
+ nsCOMPtr<nsIDOMHTMLInputElement> input = do_QueryInterface(
|
||
|
+ aEvent->InternalDOMEvent()->GetTarget());
|
||
|
+ MaybeStartControllingInput(input);
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
@@ -1087,6 +1108,10 @@ nsFormFillController::StartControllingInput(nsIDOMHTMLInputElement *aInput)
|
||
|
// Make sure we're not still attached to an input
|
||
|
StopControllingInput();
|
||
|
|
||
|
+ if (!mController) {
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
// Find the currently focused docShell
|
||
|
nsCOMPtr<nsIDocShell> docShell = GetDocShellForInput(aInput);
|
||
|
int32_t index = GetIndexOfDocShell(docShell);
|
||
|
@@ -1129,13 +1154,15 @@ nsFormFillController::StopControllingInput()
|
||
|
mListNode = nullptr;
|
||
|
}
|
||
|
|
||
|
- // Reset the controller's input, but not if it has been switched
|
||
|
- // to another input already, which might happen if the user switches
|
||
|
- // focus by clicking another autocomplete textbox
|
||
|
- nsCOMPtr<nsIAutoCompleteInput> input;
|
||
|
- mController->GetInput(getter_AddRefs(input));
|
||
|
- if (input == this)
|
||
|
- mController->SetInput(nullptr);
|
||
|
+ if (mController) {
|
||
|
+ // Reset the controller's input, but not if it has been switched
|
||
|
+ // to another input already, which might happen if the user switches
|
||
|
+ // focus by clicking another autocomplete textbox
|
||
|
+ nsCOMPtr<nsIAutoCompleteInput> input;
|
||
|
+ mController->GetInput(getter_AddRefs(input));
|
||
|
+ if (input == this)
|
||
|
+ mController->SetInput(nullptr);
|
||
|
+ }
|
||
|
|
||
|
if (mFocusedInputNode) {
|
||
|
MaybeRemoveMutationObserver(mFocusedInputNode);
|
||
|
diff --git a/toolkit/components/satchel/nsFormFillController.h b/toolkit/components/satchel/nsFormFillController.h
|
||
|
index b60d28d..8c3ba26 100644
|
||
|
--- a/toolkit/components/satchel/nsFormFillController.h
|
||
|
+++ b/toolkit/components/satchel/nsFormFillController.h
|
||
|
@@ -62,6 +62,11 @@ protected:
|
||
|
|
||
|
void StartControllingInput(nsIDOMHTMLInputElement *aInput);
|
||
|
void StopControllingInput();
|
||
|
+ /**
|
||
|
+ * Checks that aElement is a type of element we want to fill, then calls
|
||
|
+ * StartControllingInput on it.
|
||
|
+ */
|
||
|
+ void MaybeStartControllingInput(nsIDOMHTMLInputElement* aElement);
|
||
|
|
||
|
nsresult PerformInputListAutoComplete(nsIAutoCompleteResult* aPreviousResult);
|
||
|
|
||
|
--
|
||
|
2.2.1
|
||
|
|