Bug 1110557. r=mak, r=gavin

This commit is contained in:
Mats Palmgren
2015-01-24 12:37:47 -05:00
parent ee102e519c
commit 07bba9f488
2 changed files with 52 additions and 20 deletions

View File

@@ -74,6 +74,7 @@ nsFormFillController::nsFormFillController() :
mSuppressOnInput(false)
{
mController = do_GetService("@mozilla.org/autocomplete/controller;1");
MOZ_ASSERT(mController);
}
struct PwmgrInputsEnumData
@@ -117,6 +118,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();
}
@@ -861,28 +877,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;
@@ -891,9 +905,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;
}
@@ -1137,6 +1158,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);
@@ -1179,13 +1204,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);