| Index: Source/core/html/HTMLFormControlElement.cpp
|
| diff --git a/Source/core/html/HTMLFormControlElement.cpp b/Source/core/html/HTMLFormControlElement.cpp
|
| index 1127f15e99516c810cab7608c47c77fdb53a1503..499ee64bb9ddf506a0e2f4539e67a9d317c90692 100644
|
| --- a/Source/core/html/HTMLFormControlElement.cpp
|
| +++ b/Source/core/html/HTMLFormControlElement.cpp
|
| @@ -58,6 +58,7 @@ HTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tagName, Doc
|
| , m_willValidateInitialized(false)
|
| , m_willValidate(true)
|
| , m_isValid(true)
|
| + , m_validityIsDirty(false)
|
| , m_wasChangedSinceLastFormControlChangeEvent(false)
|
| , m_wasFocusedByMouse(false)
|
| {
|
| @@ -283,28 +284,31 @@ void HTMLFormControlElement::removedFrom(ContainerNode* insertionPoint)
|
| void HTMLFormControlElement::willChangeForm()
|
| {
|
| FormAssociatedElement::willChangeForm();
|
| - formOwnerSetNeedsValidityCheck(ElementRemoval, isValidElement());
|
| + formOwnerSetNeedsValidityCheck();
|
| }
|
|
|
| void HTMLFormControlElement::didChangeForm()
|
| {
|
| FormAssociatedElement::didChangeForm();
|
| - formOwnerSetNeedsValidityCheck(ElementAddition, isValidElement());
|
| + formOwnerSetNeedsValidityCheck();
|
| }
|
|
|
| -void HTMLFormControlElement::formOwnerSetNeedsValidityCheck(ValidityRecalcReason reason, bool isValid)
|
| +void HTMLFormControlElement::formOwnerSetNeedsValidityCheck()
|
| {
|
| - HTMLFormElement* form = formOwner();
|
| - if (form)
|
| - form->setNeedsValidityCheck(reason, isValid);
|
| + if (HTMLFormElement* form = formOwner()) {
|
| + form->pseudoStateChanged(CSSSelector::PseudoValid);
|
| + form->pseudoStateChanged(CSSSelector::PseudoInvalid);
|
| + }
|
| }
|
|
|
| void HTMLFormControlElement::fieldSetAncestorsSetNeedsValidityCheck(Node* node)
|
| {
|
| if (!node)
|
| return;
|
| - for (HTMLFieldSetElement* fieldSet = Traversal<HTMLFieldSetElement>::firstAncestorOrSelf(*node); fieldSet; fieldSet = Traversal<HTMLFieldSetElement>::firstAncestor(*fieldSet))
|
| - fieldSet->setNeedsValidityCheck();
|
| + for (HTMLFieldSetElement* fieldSet = Traversal<HTMLFieldSetElement>::firstAncestorOrSelf(*node); fieldSet; fieldSet = Traversal<HTMLFieldSetElement>::firstAncestor(*fieldSet)) {
|
| + fieldSet->pseudoStateChanged(CSSSelector::PseudoValid);
|
| + fieldSet->pseudoStateChanged(CSSSelector::PseudoInvalid);
|
| + }
|
| }
|
|
|
| void HTMLFormControlElement::setChangedSinceLastFormControlChangeEvent(bool changed)
|
| @@ -508,7 +512,7 @@ ValidationMessageClient* HTMLFormControlElement::validationMessageClient() const
|
|
|
| bool HTMLFormControlElement::checkValidity(WillBeHeapVector<RefPtrWillBeMember<HTMLFormControlElement>>* unhandledInvalidControls, CheckValidityEventBehavior eventBehavior)
|
| {
|
| - if (!willValidate() || isValidElement())
|
| + if (isValidElement())
|
| return true;
|
| if (eventBehavior != CheckValidityDispatchInvalidEvent)
|
| return false;
|
| @@ -559,21 +563,23 @@ bool HTMLFormControlElement::matchesValidityPseudoClasses() const
|
|
|
| bool HTMLFormControlElement::isValidElement()
|
| {
|
| - // If the following assertion fails, setNeedsValidityCheck() is not called
|
| - // correctly when something which changes validity is updated.
|
| - ASSERT(m_isValid == valid());
|
| + if (m_validityIsDirty) {
|
| + m_isValid = !willValidate() || valid();
|
| + m_validityIsDirty = false;
|
| + } else {
|
| + // If the following assertion fails, setNeedsValidityCheck() is not
|
| + // called correctly when something which changes validity is updated.
|
| + ASSERT(m_isValid == (!willValidate() || valid()));
|
| + }
|
| return m_isValid;
|
| }
|
|
|
| void HTMLFormControlElement::setNeedsValidityCheck()
|
| {
|
| - bool newIsValid = valid();
|
| - bool changed = newIsValid != m_isValid;
|
| - m_isValid = newIsValid;
|
| - if (changed) {
|
| - formOwnerSetNeedsValidityCheck(ElementModification, newIsValid);
|
| + if (!m_validityIsDirty) {
|
| + m_validityIsDirty = true;
|
| + formOwnerSetNeedsValidityCheck();
|
| fieldSetAncestorsSetNeedsValidityCheck(parentNode());
|
| - // Update style for pseudo classes such as :valid :invalid.
|
| pseudoStateChanged(CSSSelector::PseudoValid);
|
| pseudoStateChanged(CSSSelector::PseudoInvalid);
|
| }
|
|
|