Index: Source/core/html/HTMLFormElement.cpp |
diff --git a/Source/core/html/HTMLFormElement.cpp b/Source/core/html/HTMLFormElement.cpp |
index 6504dbf561d24d60aba8a1d4d529e6c5dc57f1bc..4ea622e713450da5cc45fe5381cca5395930cea4 100644 |
--- a/Source/core/html/HTMLFormElement.cpp |
+++ b/Source/core/html/HTMLFormElement.cpp |
@@ -77,6 +77,7 @@ HTMLFormElement::HTMLFormElement(Document& document) |
, m_shouldSubmit(false) |
, m_isInResetFunction(false) |
, m_wasDemoted(false) |
+ , m_invalidControlsCount(0) |
, m_pendingAutocompleteEventsQueue(GenericEventQueue::create(this)) |
{ |
} |
@@ -716,12 +717,27 @@ HTMLFormControlElement* HTMLFormElement::defaultButton() const |
return 0; |
} |
-void HTMLFormElement::setNeedsValidityCheck() |
-{ |
- // For now unconditionally order style recalculation, which triggers |
- // validity recalculation. In the near future, implement validity cache and |
- // recalculate style only if it changed. |
- setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::createWithExtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Invalid)); |
+void HTMLFormElement::setNeedsValidityCheck(ValidityRecalcReason reason, bool isValid) |
+{ |
+ bool formWasInvalid = m_invalidControlsCount > 0; |
+ switch (reason) { |
+ case ElementRemoval: |
+ if (!isValid) |
+ --m_invalidControlsCount; |
+ break; |
+ case ElementAddition: |
+ if (!isValid) |
+ ++m_invalidControlsCount; |
+ break; |
+ case ElementModification: |
+ if (isValid) |
+ --m_invalidControlsCount; |
+ else |
+ ++m_invalidControlsCount; |
+ break; |
+ } |
+ if (formWasInvalid != (m_invalidControlsCount > 0)) |
+ setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::createWithExtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Invalid)); |
} |
bool HTMLFormElement::checkValidity() |
@@ -731,6 +747,9 @@ bool HTMLFormElement::checkValidity() |
bool HTMLFormElement::checkInvalidControlsAndCollectUnhandled(WillBeHeapVector<RefPtrWillBeMember<HTMLFormControlElement> >* unhandledInvalidControls, CheckValidityEventBehavior eventBehavior) |
{ |
+ if (!unhandledInvalidControls && eventBehavior == CheckValidityDispatchNoEvent) |
+ return m_invalidControlsCount; |
+ |
RefPtrWillBeRawPtr<HTMLFormElement> protector(this); |
// Copy associatedElements because event handlers called from |
// HTMLFormControlElement::checkValidity() might change associatedElements. |
@@ -739,15 +758,17 @@ bool HTMLFormElement::checkInvalidControlsAndCollectUnhandled(WillBeHeapVector<R |
elements.reserveCapacity(associatedElements.size()); |
for (unsigned i = 0; i < associatedElements.size(); ++i) |
elements.append(associatedElements[i]); |
- bool hasInvalidControls = false; |
+ int invalidControlsCount = 0; |
for (unsigned i = 0; i < elements.size(); ++i) { |
if (elements[i]->form() == this && elements[i]->isFormControlElement()) { |
HTMLFormControlElement* control = toHTMLFormControlElement(elements[i].get()); |
if (!control->checkValidity(unhandledInvalidControls, eventBehavior) && control->formOwner() == this) |
- hasInvalidControls = true; |
+ ++invalidControlsCount; |
} |
} |
- return hasInvalidControls; |
+ if (eventBehavior == CheckValidityDispatchNoEvent) |
+ ASSERT(invalidControlsCount == m_invalidControlsCount); |
+ return invalidControlsCount; |
} |
bool HTMLFormElement::reportValidity() |