Commit 90db5815 authored by bartekn@chromium.org's avatar bartekn@chromium.org

Fix a problem where a control's willValidate change wouldn't trigger the...

Fix a problem where a control's willValidate change wouldn't trigger the containing form's or fieldset's style change. Cache form validity while at it to avoid style recalculation

BUG=360466
TEST=Added cases to layout tests that toggle controls disabled and readonly in form and fieldset

Review URL: https://codereview.chromium.org/703473003

git-svn-id: svn://svn.chromium.org/blink/trunk@185347 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 35cac119
...@@ -4,7 +4,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE ...@@ -4,7 +4,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
PASS getComputedStyle(fieldset, '').backgroundColor is transparent PASS getComputedStyle(fieldset, '').backgroundColor is transparent
PASS internals.updateStyleAndReturnAffectedElementCount() is 7 PASS internals.updateStyleAndReturnAffectedElementCount() is 2
PASS getComputedStyle(fieldset, '').backgroundColor is green PASS getComputedStyle(fieldset, '').backgroundColor is green
PASS successfullyParsed is true PASS successfullyParsed is true
......
...@@ -35,7 +35,7 @@ fieldset.disabled = true; ...@@ -35,7 +35,7 @@ fieldset.disabled = true;
if (window.internals) { if (window.internals) {
// There are still instances of SubtreeStyleChange left when updating // There are still instances of SubtreeStyleChange left when updating
// disabled state. This count should become lower. // disabled state. This count should become lower.
shouldBe("internals.updateStyleAndReturnAffectedElementCount()", "7"); shouldBe("internals.updateStyleAndReturnAffectedElementCount()", "2");
} }
shouldBe("getComputedStyle(fieldset, '').backgroundColor", "green"); shouldBe("getComputedStyle(fieldset, '').backgroundColor", "green");
......
...@@ -3,7 +3,7 @@ Check if :valid/:invalid CSS pseudo selectors are lively applied for fieldsets ...@@ -3,7 +3,7 @@ Check if :valid/:invalid CSS pseudo selectors are lively applied for fieldsets
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
Removing and adding required text inputs and modifying ther value by a DOM tree mutation: Removing and adding required text inputs and modifying their value by a DOM tree mutation:
PASS backgroundOf(fieldset1) is invalidColor PASS backgroundOf(fieldset1) is invalidColor
PASS backgroundOf(sub1) is subInvalidColor PASS backgroundOf(sub1) is subInvalidColor
PASS fieldset1.removeChild(input1); backgroundOf(fieldset1) is validColor PASS fieldset1.removeChild(input1); backgroundOf(fieldset1) is validColor
...@@ -15,6 +15,16 @@ PASS backgroundOf(sub1) is subValidColor ...@@ -15,6 +15,16 @@ PASS backgroundOf(sub1) is subValidColor
PASS input2.setAttribute("value", ""); backgroundOf(fieldset1) is invalidColor PASS input2.setAttribute("value", ""); backgroundOf(fieldset1) is invalidColor
PASS backgroundOf(sub1) is subInvalidColor PASS backgroundOf(sub1) is subInvalidColor
Disabling and marking inputs readonly by a DOM tree mutation:
PASS backgroundOf(fieldset1) is invalidColor
PASS backgroundOf(sub1) is subInvalidColor
PASS input1.disabled=1; backgroundOf(fieldset1) is validColor
PASS backgroundOf(sub1) is subValidColor
PASS input1.disabled=0; backgroundOf(fieldset1) is invalidColor
PASS backgroundOf(sub1) is subInvalidColor
PASS input1.setAttribute("readonly", "1"); backgroundOf(fieldset1) is validColor
PASS backgroundOf(sub1) is subValidColor
Adding a required text input that is not a direct child of the fieldset: Adding a required text input that is not a direct child of the fieldset:
PASS backgroundOf(fieldset1) is validColor PASS backgroundOf(fieldset1) is validColor
PASS div1.appendChild(input1); backgroundOf(fieldset1) is invalidColor PASS div1.appendChild(input1); backgroundOf(fieldset1) is invalidColor
......
...@@ -29,7 +29,7 @@ var subValidColor = 'rgb(0, 127, 0)'; ...@@ -29,7 +29,7 @@ var subValidColor = 'rgb(0, 127, 0)';
var parent = document.createElement('div'); var parent = document.createElement('div');
document.body.appendChild(parent); document.body.appendChild(parent);
debug('Removing and adding required text inputs and modifying ther value by a DOM tree mutation:'); debug('Removing and adding required text inputs and modifying their value by a DOM tree mutation:');
parent.innerHTML = '<fieldset id=fieldset1><input type=text id=input1 required><input type=text id=input2 required value=a><input type=submit id=sub1></fieldset>'; parent.innerHTML = '<fieldset id=fieldset1><input type=text id=input1 required><input type=text id=input2 required value=a><input type=submit id=sub1></fieldset>';
var fieldset1 = $('fieldset1'); var fieldset1 = $('fieldset1');
var input1 = $('input1'); var input1 = $('input1');
...@@ -47,6 +47,21 @@ shouldBe('input2.setAttribute("value", ""); backgroundOf(fieldset1)', 'invalidCo ...@@ -47,6 +47,21 @@ shouldBe('input2.setAttribute("value", ""); backgroundOf(fieldset1)', 'invalidCo
shouldBe('backgroundOf(sub1)', 'subInvalidColor'); shouldBe('backgroundOf(sub1)', 'subInvalidColor');
debug('') debug('')
debug('Disabling and marking inputs readonly by a DOM tree mutation:');
parent.innerHTML = '<fieldset id=fieldset1><input type=text id=input1 required><input type=text id=input2 required value=a><input type=submit id=sub1></fieldset>';
var fieldset1 = $('fieldset1');
var input1 = $('input1');
var sub1 = $('sub1');
shouldBe('backgroundOf(fieldset1)', 'invalidColor');
shouldBe('backgroundOf(sub1)', 'subInvalidColor');
shouldBe('input1.disabled=1; backgroundOf(fieldset1)', 'validColor');
shouldBe('backgroundOf(sub1)', 'subValidColor');
shouldBe('input1.disabled=0; backgroundOf(fieldset1)', 'invalidColor');
shouldBe('backgroundOf(sub1)', 'subInvalidColor');
shouldBe('input1.setAttribute("readonly", "1"); backgroundOf(fieldset1)', 'validColor');
shouldBe('backgroundOf(sub1)', 'subValidColor');
debug('')
debug('Adding a required text input that is not a direct child of the fieldset:'); debug('Adding a required text input that is not a direct child of the fieldset:');
parent.innerHTML = '<fieldset id=fieldset1></fieldset>'; parent.innerHTML = '<fieldset id=fieldset1></fieldset>';
var fieldset1 = $('fieldset1'); var fieldset1 = $('fieldset1');
......
...@@ -3,7 +3,7 @@ Check if :valid/:invalid CSS pseudo selectors are lively applied for forms ...@@ -3,7 +3,7 @@ Check if :valid/:invalid CSS pseudo selectors are lively applied for forms
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
Removing and adding required text inputs and modifying ther value by a DOM tree mutation: Removing and adding required text inputs and modifying their value by a DOM tree mutation:
PASS backgroundOf(form1) is invalidColor PASS backgroundOf(form1) is invalidColor
PASS backgroundOf(sub1) is subInvalidColor PASS backgroundOf(sub1) is subInvalidColor
PASS form1.removeChild(input1); backgroundOf(form1) is validColor PASS form1.removeChild(input1); backgroundOf(form1) is validColor
...@@ -15,6 +15,22 @@ PASS backgroundOf(sub1) is subValidColor ...@@ -15,6 +15,22 @@ PASS backgroundOf(sub1) is subValidColor
PASS input2.setAttribute("value", ""); backgroundOf(form1) is invalidColor PASS input2.setAttribute("value", ""); backgroundOf(form1) is invalidColor
PASS backgroundOf(sub1) is subInvalidColor PASS backgroundOf(sub1) is subInvalidColor
Disabling and marking inputs readonly by a DOM tree mutation:
PASS backgroundOf(form1) is invalidColor
PASS backgroundOf(sub1) is subInvalidColor
PASS input1.disabled=1; backgroundOf(form1) is validColor
PASS backgroundOf(sub1) is subValidColor
PASS input1.disabled=0; backgroundOf(form1) is invalidColor
PASS backgroundOf(sub1) is subInvalidColor
PASS input1.setAttribute("readonly", "1"); backgroundOf(form1) is validColor
PASS backgroundOf(sub1) is subValidColor
Move element under datalist by a DOM tree mutation:
PASS backgroundOf(form1) is invalidColor
PASS parent.removeChild(input1); backgroundOf(form1) is validColor
PASS dl1.appendChild(input1); backgroundOf(form1) is validColor
PASS parent.appendChild(input1); backgroundOf(form1) is invalidColor
Adding a required text input that is not a direct child of the form: Adding a required text input that is not a direct child of the form:
PASS backgroundOf(form1) is validColor PASS backgroundOf(form1) is validColor
PASS div1.appendChild(input1); backgroundOf(form1) is invalidColor PASS div1.appendChild(input1); backgroundOf(form1) is invalidColor
......
...@@ -29,7 +29,7 @@ var subValidColor = 'rgb(0, 127, 0)'; ...@@ -29,7 +29,7 @@ var subValidColor = 'rgb(0, 127, 0)';
var parent = document.createElement('div'); var parent = document.createElement('div');
document.body.appendChild(parent); document.body.appendChild(parent);
debug('Removing and adding required text inputs and modifying ther value by a DOM tree mutation:'); debug('Removing and adding required text inputs and modifying their value by a DOM tree mutation:');
parent.innerHTML = '<form id=form1><input type=text id=input1 required><input type=text id=input2 required value=a><input type=submit id=sub1></form>'; parent.innerHTML = '<form id=form1><input type=text id=input1 required><input type=text id=input2 required value=a><input type=submit id=sub1></form>';
var form1 = $('form1'); var form1 = $('form1');
var input1 = $('input1'); var input1 = $('input1');
...@@ -47,6 +47,32 @@ shouldBe('input2.setAttribute("value", ""); backgroundOf(form1)', 'invalidColor' ...@@ -47,6 +47,32 @@ shouldBe('input2.setAttribute("value", ""); backgroundOf(form1)', 'invalidColor'
shouldBe('backgroundOf(sub1)', 'subInvalidColor'); shouldBe('backgroundOf(sub1)', 'subInvalidColor');
debug('') debug('')
debug('Disabling and marking inputs readonly by a DOM tree mutation:');
parent.innerHTML = '<form id=form1><input type=text id=input1 required><input type=text id=input2 required value=a><input type=submit id=sub1></form>';
var form1 = $('form1');
var input1 = $('input1');
var sub1 = $('sub1');
shouldBe('backgroundOf(form1)', 'invalidColor');
shouldBe('backgroundOf(sub1)', 'subInvalidColor');
shouldBe('input1.disabled=1; backgroundOf(form1)', 'validColor');
shouldBe('backgroundOf(sub1)', 'subValidColor');
shouldBe('input1.disabled=0; backgroundOf(form1)', 'invalidColor');
shouldBe('backgroundOf(sub1)', 'subInvalidColor');
shouldBe('input1.setAttribute("readonly", "1"); backgroundOf(form1)', 'validColor');
shouldBe('backgroundOf(sub1)', 'subValidColor');
debug('')
debug('Move element under datalist by a DOM tree mutation:');
parent.innerHTML = '<form id=form1></form><datalist id=dl1></datalist><input type=text id=input1 required form=form1>';
var form1 = $('form1');
var input1 = $('input1');
var dl1 = $('dl1');
shouldBe('backgroundOf(form1)', 'invalidColor');
shouldBe('parent.removeChild(input1); backgroundOf(form1)', 'validColor');
shouldBe('dl1.appendChild(input1); backgroundOf(form1)', 'validColor');
shouldBe('parent.appendChild(input1); backgroundOf(form1)', 'invalidColor');
debug('')
debug('Adding a required text input that is not a direct child of the form:'); debug('Adding a required text input that is not a direct child of the form:');
parent.innerHTML = '<form id=form1></form>'; parent.innerHTML = '<form id=form1></form>';
var form1 = $('form1'); var form1 = $('form1');
......
...@@ -263,27 +263,28 @@ void HTMLFormControlElement::removedFrom(ContainerNode* insertionPoint) ...@@ -263,27 +263,28 @@ void HTMLFormControlElement::removedFrom(ContainerNode* insertionPoint)
m_hasValidationMessage = false; m_hasValidationMessage = false;
m_ancestorDisabledState = AncestorDisabledStateUnknown; m_ancestorDisabledState = AncestorDisabledStateUnknown;
m_dataListAncestorState = Unknown; m_dataListAncestorState = Unknown;
setNeedsWillValidateCheck();
HTMLElement::removedFrom(insertionPoint); HTMLElement::removedFrom(insertionPoint);
FormAssociatedElement::removedFrom(insertionPoint); FormAssociatedElement::removedFrom(insertionPoint);
} }
void HTMLFormControlElement::willChangeForm() void HTMLFormControlElement::willChangeForm()
{ {
formOwnerSetNeedsValidityCheck();
FormAssociatedElement::willChangeForm(); FormAssociatedElement::willChangeForm();
formOwnerSetNeedsValidityCheck(ElementRemoval, isValidElement());
} }
void HTMLFormControlElement::didChangeForm() void HTMLFormControlElement::didChangeForm()
{ {
formOwnerSetNeedsValidityCheck();
FormAssociatedElement::didChangeForm(); FormAssociatedElement::didChangeForm();
formOwnerSetNeedsValidityCheck(ElementAddition, isValidElement());
} }
void HTMLFormControlElement::formOwnerSetNeedsValidityCheck() void HTMLFormControlElement::formOwnerSetNeedsValidityCheck(ValidityRecalcReason reason, bool isValid)
{ {
HTMLFormElement* form = formOwner(); HTMLFormElement* form = formOwner();
if (form) if (form)
form->setNeedsValidityCheck(); form->setNeedsValidityCheck(reason, isValid);
} }
void HTMLFormControlElement::fieldSetAncestorsSetNeedsValidityCheck(Node* node) void HTMLFormControlElement::fieldSetAncestorsSetNeedsValidityCheck(Node* node)
...@@ -406,12 +407,7 @@ bool HTMLFormControlElement::recalcWillValidate() const ...@@ -406,12 +407,7 @@ bool HTMLFormControlElement::recalcWillValidate() const
bool HTMLFormControlElement::willValidate() const bool HTMLFormControlElement::willValidate() const
{ {
if (!m_willValidateInitialized || m_dataListAncestorState == Unknown) { if (!m_willValidateInitialized || m_dataListAncestorState == Unknown) {
m_willValidateInitialized = true; const_cast<HTMLFormControlElement*>(this)->setNeedsWillValidateCheck();
bool newWillValidate = recalcWillValidate();
if (m_willValidate != newWillValidate) {
m_willValidate = newWillValidate;
const_cast<HTMLFormControlElement*>(this)->setNeedsValidityCheck();
}
} else { } else {
// If the following assertion fails, setNeedsWillValidateCheck() is not // If the following assertion fails, setNeedsWillValidateCheck() is not
// called correctly when something which changes recalcWillValidate() result // called correctly when something which changes recalcWillValidate() result
...@@ -430,7 +426,10 @@ void HTMLFormControlElement::setNeedsWillValidateCheck() ...@@ -430,7 +426,10 @@ void HTMLFormControlElement::setNeedsWillValidateCheck()
m_willValidateInitialized = true; m_willValidateInitialized = true;
m_willValidate = newWillValidate; m_willValidate = newWillValidate;
setNeedsValidityCheck(); setNeedsValidityCheck();
setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::Validate)); // No need to trigger style recalculation here because
// setNeedsValidityCheck() does it in the right away. This relies on
// the assumption that valid() is always true if willValidate() is false.
if (!m_willValidate) if (!m_willValidate)
hideVisibleValidationMessage(); hideVisibleValidationMessage();
} }
...@@ -557,14 +556,15 @@ bool HTMLFormControlElement::isValidElement() ...@@ -557,14 +556,15 @@ bool HTMLFormControlElement::isValidElement()
void HTMLFormControlElement::setNeedsValidityCheck() void HTMLFormControlElement::setNeedsValidityCheck()
{ {
bool newIsValid = valid(); bool newIsValid = valid();
if (willValidate() && newIsValid != m_isValid) { bool changed = newIsValid != m_isValid;
formOwnerSetNeedsValidityCheck(); m_isValid = newIsValid;
if (changed) {
formOwnerSetNeedsValidityCheck(ElementModification, newIsValid);
fieldSetAncestorsSetNeedsValidityCheck(parentNode()); fieldSetAncestorsSetNeedsValidityCheck(parentNode());
// Update style for pseudo classes such as :valid :invalid. // Update style for pseudo classes such as :valid :invalid.
pseudoStateChanged(CSSSelector::PseudoValid); pseudoStateChanged(CSSSelector::PseudoValid);
pseudoStateChanged(CSSSelector::PseudoInvalid); pseudoStateChanged(CSSSelector::PseudoInvalid);
} }
m_isValid = newIsValid;
// Updates only if this control already has a validation message. // Updates only if this control already has a validation message.
if (isValidationMessageVisible()) { if (isValidationMessageVisible()) {
......
...@@ -34,6 +34,7 @@ class HTMLFormElement; ...@@ -34,6 +34,7 @@ class HTMLFormElement;
class ValidationMessageClient; class ValidationMessageClient;
enum CheckValidityEventBehavior { CheckValidityDispatchNoEvent, CheckValidityDispatchInvalidEvent }; enum CheckValidityEventBehavior { CheckValidityDispatchNoEvent, CheckValidityDispatchInvalidEvent };
enum ValidityRecalcReason { ElementAddition, ElementRemoval, ElementModification };
// HTMLFormControlElement is the default implementation of FormAssociatedElement, // HTMLFormControlElement is the default implementation of FormAssociatedElement,
// and form-associated element implementations should use HTMLFormControlElement // and form-associated element implementations should use HTMLFormControlElement
...@@ -168,7 +169,9 @@ private: ...@@ -168,7 +169,9 @@ private:
ValidationMessageClient* validationMessageClient() const; ValidationMessageClient* validationMessageClient() const;
// Requests validity recalc for the form owner, if one exists. // Requests validity recalc for the form owner, if one exists.
void formOwnerSetNeedsValidityCheck(); // In case of removal, isValid specifies element validity upon removal.
// In case of addition and modification, it specifies new validity.
void formOwnerSetNeedsValidityCheck(ValidityRecalcReason, bool isValid);
// Requests validity recalc for all ancestor fieldsets, if exist. // Requests validity recalc for all ancestor fieldsets, if exist.
void fieldSetAncestorsSetNeedsValidityCheck(Node*); void fieldSetAncestorsSetNeedsValidityCheck(Node*);
......
...@@ -78,6 +78,7 @@ HTMLFormElement::HTMLFormElement(Document& document) ...@@ -78,6 +78,7 @@ HTMLFormElement::HTMLFormElement(Document& document)
, m_shouldSubmit(false) , m_shouldSubmit(false)
, m_isInResetFunction(false) , m_isInResetFunction(false)
, m_wasDemoted(false) , m_wasDemoted(false)
, m_invalidControlsCount(0)
, m_pendingAutocompleteEventsQueue(GenericEventQueue::create(this)) , m_pendingAutocompleteEventsQueue(GenericEventQueue::create(this))
{ {
} }
...@@ -715,13 +716,29 @@ HTMLFormControlElement* HTMLFormElement::defaultButton() const ...@@ -715,13 +716,29 @@ HTMLFormControlElement* HTMLFormElement::defaultButton() const
return 0; return 0;
} }
void HTMLFormElement::setNeedsValidityCheck() void HTMLFormElement::setNeedsValidityCheck(ValidityRecalcReason reason, bool isValid)
{ {
// For now unconditionally order style recalculation, which triggers bool formWasInvalid = m_invalidControlsCount > 0;
// validity recalculation. In the near future, implement validity cache and switch (reason) {
// recalculate style only if it changed. case ElementRemoval:
pseudoStateChanged(CSSSelector::PseudoValid); if (!isValid)
pseudoStateChanged(CSSSelector::PseudoInvalid); --m_invalidControlsCount;
break;
case ElementAddition:
if (!isValid)
++m_invalidControlsCount;
break;
case ElementModification:
if (isValid)
--m_invalidControlsCount;
else
++m_invalidControlsCount;
break;
}
if (formWasInvalid && !m_invalidControlsCount)
pseudoStateChanged(CSSSelector::PseudoValid);
if (!formWasInvalid && m_invalidControlsCount)
pseudoStateChanged(CSSSelector::PseudoInvalid);
} }
bool HTMLFormElement::checkValidity() bool HTMLFormElement::checkValidity()
...@@ -731,6 +748,9 @@ bool HTMLFormElement::checkValidity() ...@@ -731,6 +748,9 @@ bool HTMLFormElement::checkValidity()
bool HTMLFormElement::checkInvalidControlsAndCollectUnhandled(WillBeHeapVector<RefPtrWillBeMember<HTMLFormControlElement>>* unhandledInvalidControls, CheckValidityEventBehavior eventBehavior) bool HTMLFormElement::checkInvalidControlsAndCollectUnhandled(WillBeHeapVector<RefPtrWillBeMember<HTMLFormControlElement>>* unhandledInvalidControls, CheckValidityEventBehavior eventBehavior)
{ {
if (!unhandledInvalidControls && eventBehavior == CheckValidityDispatchNoEvent)
return m_invalidControlsCount;
RefPtrWillBeRawPtr<HTMLFormElement> protector(this); RefPtrWillBeRawPtr<HTMLFormElement> protector(this);
// Copy associatedElements because event handlers called from // Copy associatedElements because event handlers called from
// HTMLFormControlElement::checkValidity() might change associatedElements. // HTMLFormControlElement::checkValidity() might change associatedElements.
...@@ -739,15 +759,17 @@ bool HTMLFormElement::checkInvalidControlsAndCollectUnhandled(WillBeHeapVector<R ...@@ -739,15 +759,17 @@ bool HTMLFormElement::checkInvalidControlsAndCollectUnhandled(WillBeHeapVector<R
elements.reserveCapacity(associatedElements.size()); elements.reserveCapacity(associatedElements.size());
for (unsigned i = 0; i < associatedElements.size(); ++i) for (unsigned i = 0; i < associatedElements.size(); ++i)
elements.append(associatedElements[i]); elements.append(associatedElements[i]);
bool hasInvalidControls = false; int invalidControlsCount = 0;
for (unsigned i = 0; i < elements.size(); ++i) { for (unsigned i = 0; i < elements.size(); ++i) {
if (elements[i]->form() == this && elements[i]->isFormControlElement()) { if (elements[i]->form() == this && elements[i]->isFormControlElement()) {
HTMLFormControlElement* control = toHTMLFormControlElement(elements[i].get()); HTMLFormControlElement* control = toHTMLFormControlElement(elements[i].get());
if (!control->checkValidity(unhandledInvalidControls, eventBehavior) && control->formOwner() == this) 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() bool HTMLFormElement::reportValidity()
......
...@@ -48,7 +48,7 @@ public: ...@@ -48,7 +48,7 @@ public:
virtual ~HTMLFormElement(); virtual ~HTMLFormElement();
virtual void trace(Visitor*) override; virtual void trace(Visitor*) override;
void setNeedsValidityCheck(); void setNeedsValidityCheck(ValidityRecalcReason, bool isValid);
PassRefPtrWillBeRawPtr<HTMLFormControlsCollection> elements(); PassRefPtrWillBeRawPtr<HTMLFormControlsCollection> elements();
void getNamedElements(const AtomicString&, WillBeHeapVector<RefPtrWillBeMember<Element>>&); void getNamedElements(const AtomicString&, WillBeHeapVector<RefPtrWillBeMember<Element>>&);
...@@ -186,6 +186,10 @@ private: ...@@ -186,6 +186,10 @@ private:
bool m_wasDemoted : 1; bool m_wasDemoted : 1;
// Number of invalid elements associated to the form that are candidates
// for constraint validation (their willValidate state is true).
int m_invalidControlsCount;
OwnPtrWillBeMember<GenericEventQueue> m_pendingAutocompleteEventsQueue; OwnPtrWillBeMember<GenericEventQueue> m_pendingAutocompleteEventsQueue;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment