Bug 1110557. r=mak, r=gavin
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user