Diff
Modified: branches/chromium/1132/LayoutTests/fast/forms/datalist/datalist-child-validation-expected.txt (119624 => 119625)
--- branches/chromium/1132/LayoutTests/fast/forms/datalist/datalist-child-validation-expected.txt 2012-06-06 22:28:54 UTC (rev 119624)
+++ branches/chromium/1132/LayoutTests/fast/forms/datalist/datalist-child-validation-expected.txt 2012-06-06 22:30:26 UTC (rev 119625)
@@ -9,6 +9,7 @@
PASS e.willValidate is true
PASS e.willValidate is true
PASS document.querySelector(":invalid") is e
+PASS document.getElementById("inLegend").willValidate is false
PASS successfullyParsed is true
TEST COMPLETE
Modified: branches/chromium/1132/LayoutTests/fast/forms/datalist/datalist-child-validation.html (119624 => 119625)
--- branches/chromium/1132/LayoutTests/fast/forms/datalist/datalist-child-validation.html 2012-06-06 22:28:54 UTC (rev 119624)
+++ branches/chromium/1132/LayoutTests/fast/forms/datalist/datalist-child-validation.html 2012-06-06 22:30:26 UTC (rev 119625)
@@ -11,8 +11,12 @@
<div id=w>
<input type=text id=e required>
</div>
+ <legend>
+ <input id="inLegend" required>
+ </legend>
</datalist>
+
<script>
description('Test for child elements of a datalist element.');
@@ -28,6 +32,8 @@
shouldBeTrue('e.willValidate');
shouldBe('document.querySelector(":invalid")', 'e');
+shouldBeFalse('document.getElementById("inLegend").willValidate');
+
</script>
<script src=""
</body>
Modified: branches/chromium/1132/Source/WebCore/html/HTMLFieldSetElement.cpp (119624 => 119625)
--- branches/chromium/1132/Source/WebCore/html/HTMLFieldSetElement.cpp 2012-06-06 22:28:54 UTC (rev 119624)
+++ branches/chromium/1132/Source/WebCore/html/HTMLFieldSetElement.cpp 2012-06-06 22:30:26 UTC (rev 119625)
@@ -45,14 +45,27 @@
return adoptRef(new HTMLFieldSetElement(tagName, document, form));
}
+void HTMLFieldSetElement::invalidateDisabledStateUnder(Element* base)
+{
+ for (Node* currentNode = base->traverseNextNode(base); currentNode; currentNode = currentNode->traverseNextNode(base)) {
+ if (currentNode && currentNode->isElementNode() && toElement(currentNode)->isFormControlElement())
+ static_cast<HTMLFormControlElement*>(currentNode)->ancestorDisabledStateWasChanged();
+ }
+}
+
void HTMLFieldSetElement::disabledAttributeChanged()
{
// This element must be updated before the style of nodes in its subtree gets recalculated.
HTMLFormControlElement::disabledAttributeChanged();
+ invalidateDisabledStateUnder(this);
+}
- for (Node* currentNode = this->traverseNextNode(this); currentNode; currentNode = currentNode->traverseNextNode(this)) {
- if (currentNode && currentNode->isElementNode() && toElement(currentNode)->isFormControlElement())
- static_cast<HTMLFormControlElement*>(currentNode)->ancestorDisabledStateWasChanged();
+void HTMLFieldSetElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
+{
+ HTMLFormControlElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+ for (Element* element = firstElementChild(); element; element = element->nextElementSibling()) {
+ if (element->hasTagName(legendTag))
+ invalidateDisabledStateUnder(element);
}
}
Modified: branches/chromium/1132/Source/WebCore/html/HTMLFieldSetElement.h (119624 => 119625)
--- branches/chromium/1132/Source/WebCore/html/HTMLFieldSetElement.h 2012-06-06 22:28:54 UTC (rev 119624)
+++ branches/chromium/1132/Source/WebCore/html/HTMLFieldSetElement.h 2012-06-06 22:30:26 UTC (rev 119625)
@@ -44,6 +44,9 @@
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
virtual const AtomicString& formControlType() const;
virtual bool recalcWillValidate() const { return false; }
+ virtual void childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) OVERRIDE;
+
+ static void invalidateDisabledStateUnder(Element*);
};
} // namespace
Modified: branches/chromium/1132/Source/WebCore/html/HTMLFormControlElement.cpp (119624 => 119625)
--- branches/chromium/1132/Source/WebCore/html/HTMLFormControlElement.cpp 2012-06-06 22:28:54 UTC (rev 119624)
+++ branches/chromium/1132/Source/WebCore/html/HTMLFormControlElement.cpp 2012-06-06 22:30:26 UTC (rev 119625)
@@ -48,13 +48,11 @@
HTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
: LabelableElement(tagName, document)
- , m_fieldSetAncestor(0)
- , m_legendAncestor(0)
- , m_fieldSetAncestorValid(false)
, m_disabled(false)
, m_readOnly(false)
, m_required(false)
, m_valueMatchesRenderer(false)
+ , m_ancestorDisabledState(AncestorDisabledStateUnknown)
, m_dataListAncestorState(Unknown)
, m_willValidateInitialized(false)
, m_willValidate(true)
@@ -101,23 +99,24 @@
return fastHasAttribute(formnovalidateAttr);
}
-void HTMLFormControlElement::updateFieldSetAndLegendAncestor() const
+void HTMLFormControlElement::updateAncestorDisabledState() const
{
- m_fieldSetAncestor = 0;
- m_legendAncestor = 0;
+ HTMLFieldSetElement* fieldSetAncestor = 0;
+ ContainerNode* legendAncestor = 0;
for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
- if (!m_legendAncestor && ancestor->hasTagName(legendTag))
- m_legendAncestor = static_cast<HTMLLegendElement*>(ancestor);
+ if (!legendAncestor && ancestor->hasTagName(legendTag))
+ legendAncestor = ancestor;
if (ancestor->hasTagName(fieldsetTag)) {
- m_fieldSetAncestor = static_cast<HTMLFieldSetElement*>(ancestor);
+ fieldSetAncestor = static_cast<HTMLFieldSetElement*>(ancestor);
break;
}
}
- m_fieldSetAncestorValid = true;
+ m_ancestorDisabledState = (fieldSetAncestor && fieldSetAncestor->disabled() && !(legendAncestor && legendAncestor == fieldSetAncestor->legend())) ? AncestorDisabledStateDisabled : AncestorDisabledStateEnabled;
}
void HTMLFormControlElement::ancestorDisabledStateWasChanged()
{
+ m_ancestorDisabledState = AncestorDisabledStateUnknown;
disabledAttributeChanged();
}
@@ -230,7 +229,7 @@
Node::InsertionNotificationRequest HTMLFormControlElement::insertedInto(Node* insertionPoint)
{
- m_fieldSetAncestorValid = false;
+ m_ancestorDisabledState = AncestorDisabledStateUnknown;
m_dataListAncestorState = Unknown;
setNeedsWillValidateCheck();
HTMLElement::insertedInto(insertionPoint);
@@ -240,7 +239,7 @@
void HTMLFormControlElement::removedFrom(Node* insertionPoint)
{
- m_fieldSetAncestorValid = false;
+ m_ancestorDisabledState = AncestorDisabledStateUnknown;
m_dataListAncestorState = Unknown;
HTMLElement::removedFrom(insertionPoint);
FormAssociatedElement::removedFrom(insertionPoint);
@@ -284,13 +283,9 @@
if (m_disabled)
return true;
- if (!m_fieldSetAncestorValid)
- updateFieldSetAndLegendAncestor();
-
- // Form controls in the first legend element inside a fieldset are not affected by fieldset.disabled.
- if (m_fieldSetAncestor && m_fieldSetAncestor->disabled())
- return !(m_legendAncestor && m_legendAncestor == m_fieldSetAncestor->legend());
- return false;
+ if (m_ancestorDisabledState == AncestorDisabledStateUnknown)
+ updateAncestorDisabledState();
+ return m_ancestorDisabledState == AncestorDisabledStateDisabled;
}
void HTMLFormControlElement::setDisabled(bool b)
@@ -366,7 +361,7 @@
{
if (m_dataListAncestorState == Unknown) {
for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
- if (!m_legendAncestor && ancestor->hasTagName(datalistTag)) {
+ if (ancestor->hasTagName(datalistTag)) {
m_dataListAncestorState = InsideDataList;
break;
}
Modified: branches/chromium/1132/Source/WebCore/html/HTMLFormControlElement.h (119624 => 119625)
--- branches/chromium/1132/Source/WebCore/html/HTMLFormControlElement.h 2012-06-06 22:28:54 UTC (rev 119624)
+++ branches/chromium/1132/Source/WebCore/html/HTMLFormControlElement.h 2012-06-06 22:30:26 UTC (rev 119625)
@@ -51,7 +51,6 @@
void setFormMethod(const String&);
bool formNoValidate() const;
- void updateFieldSetAndLegendAncestor() const;
void ancestorDisabledStateWasChanged();
virtual void reset() { }
@@ -150,16 +149,16 @@
virtual bool isDefaultButtonForForm() const;
virtual bool isValidFormControlElement();
String visibleValidationMessage() const;
+ void updateAncestorDisabledState() const;
- mutable HTMLFieldSetElement* m_fieldSetAncestor;
- mutable HTMLLegendElement* m_legendAncestor;
OwnPtr<ValidationMessage> m_validationMessage;
- mutable bool m_fieldSetAncestorValid : 1;
bool m_disabled : 1;
bool m_readOnly : 1;
bool m_required : 1;
bool m_valueMatchesRenderer : 1;
+ enum AncestorDisabledState { AncestorDisabledStateUnknown, AncestorDisabledStateEnabled, AncestorDisabledStateDisabled };
+ mutable AncestorDisabledState m_ancestorDisabledState;
enum DataListAncestorState { Unknown, InsideDataList, NotInsideDataList };
mutable enum DataListAncestorState m_dataListAncestorState;