Bug 1209035. Fix incorrect "is this control focused?" checks in form code. r=smaug

For number controls, nsContentUtils::IsFocusedContent doesn't really do the
right thing, because the thing it thinks is focused is the anonymous text
element inside the number control.  As a result, we weren't properly updating
the state of the currently-focused number control when hitting enter in it to
submit the form.

The HTMLFormElement change is enough on its own to fix the bug.  The constraint
validation change is a just-in-case.

I haven't figured out a sane way to write a reftest for this, unfortunately:
the enter key press needs to look like a real user event to trigger the
submission behavior.
This commit is contained in:
Boris Zbarsky 2018-06-27 12:04:26 -04:00
parent 3ef9fe1263
commit e2386da2d1
3 changed files with 20 additions and 9 deletions

View File

@ -1953,7 +1953,12 @@ HTMLFormElement::CheckValidFormSubmission()
// Input elements can trigger a form submission and we want to
// update the style in that case.
if (mControls->mElements[i]->IsHTMLElement(nsGkAtoms::input) &&
nsContentUtils::IsFocusedContent(mControls->mElements[i])) {
// We don't use nsContentUtils::IsFocusedContent here, because it
// doesn't really do what we want for number controls: it's true
// for the anonymous textnode inside, but not the number control
// itself. We can use the focus state, though, because that gets
// synced to the number control by the anonymous text control.
mControls->mElements[i]->State().HasState(NS_EVENT_STATE_FOCUS)) {
static_cast<HTMLInputElement*>(mControls->mElements[i])
->UpdateValidityUIBits(true);
}

View File

@ -6435,6 +6435,7 @@ HTMLInputElement::AddStates(EventStates aStates)
if (!focusStates.IsEmpty()) {
HTMLInputElement* ownerNumberControl = GetOwnerNumberControl();
if (ownerNumberControl) {
// If this code changes, audit existing places that check for NS_EVENT_STATE_FOCUS.
ownerNumberControl->AddStates(focusStates);
}
}
@ -6451,6 +6452,7 @@ HTMLInputElement::RemoveStates(EventStates aStates)
if (!focusStates.IsEmpty()) {
HTMLInputElement* ownerNumberControl = GetOwnerNumberControl();
if (ownerNumberControl) {
// If this code changes, audit existing places that check for NS_EVENT_STATE_FOCUS.
ownerNumberControl->RemoveStates(focusStates);
}
}

View File

@ -132,11 +132,11 @@ nsIConstraintValidation::ReportValidity()
return true;
}
nsCOMPtr<nsIContent> content = do_QueryInterface(this);
MOZ_ASSERT(content, "This class should be inherited by HTML elements only!");
nsCOMPtr<Element> element = do_QueryInterface(this);
MOZ_ASSERT(element, "This class should be inherited by HTML elements only!");
bool defaultAction = true;
nsContentUtils::DispatchTrustedEvent(content->OwnerDoc(), content,
nsContentUtils::DispatchTrustedEvent(element->OwnerDoc(), element,
NS_LITERAL_STRING("invalid"),
CanBubble::eNo,
Cancelable::eYes,
@ -164,7 +164,7 @@ nsIConstraintValidation::ReportValidity()
nsCOMPtr<nsIMutableArray> invalidElements =
do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
invalidElements->AppendElement(content);
invalidElements->AppendElement(element);
NS_ENSURE_SUCCESS(rv, true);
nsCOMPtr<nsISupports> inst;
@ -179,13 +179,17 @@ nsIConstraintValidation::ReportValidity()
}
}
if (content->IsHTMLElement(nsGkAtoms::input) &&
nsContentUtils::IsFocusedContent(content)) {
HTMLInputElement* inputElement = HTMLInputElement::FromNode(content);
if (element->IsHTMLElement(nsGkAtoms::input) &&
// We don't use nsContentUtils::IsFocusedContent here, because it doesn't
// really do what we want for number controls: it's true for the
// anonymous textnode inside, but not the number control itself. We can
// use the focus state, though, because that gets synced to the number
// control by the anonymous text control.
element->State().HasState(NS_EVENT_STATE_FOCUS)) {
HTMLInputElement* inputElement = HTMLInputElement::FromNode(element);
inputElement->UpdateValidityUIBits(true);
}
dom::Element* element = content->AsElement();
element->UpdateState(true);
return false;
}