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