Title: [112515] trunk
Revision
112515
Author
[email protected]
Date
2012-03-29 03:14:32 -0700 (Thu, 29 Mar 2012)

Log Message

Fieldset disabled attribute does not work.
https://bugs.webkit.org/show_bug.cgi?id=58837

Source/WebCore:

Make HTMLFormControlElements inherit the disabled state
from HTMLFieldSetElement ancestors. Subordinates of the
first HTMLLegendElement in a fieldset will never be disabled.

Patch by Zeno Albisser <[email protected]>

Test: fast/forms/fieldset-disabled.html

Reviewed by Kent Tamura.

* html/HTMLFieldSetElement.cpp:
(WebCore::HTMLFieldSetElement::disabledAttributeChanged):
(WebCore):
(WebCore::HTMLFieldSetElement::legend):
* html/HTMLFieldSetElement.h:
(HTMLFieldSetElement):
* html/HTMLFieldSetElement.idl:
* html/HTMLFormControlElement.cpp:
(WebCore::HTMLFormControlElement::HTMLFormControlElement):
(WebCore::HTMLFormControlElement::updateFieldSetAndLegendAncestor):
(WebCore):
(WebCore::HTMLFormControlElement::parseAttribute):
(WebCore::HTMLFormControlElement::disabledAttributeChanged):
(WebCore::HTMLFormControlElement::removedFromTree):
(WebCore::HTMLFormControlElement::disabled):
* html/HTMLFormControlElement.h:
(WebCore):
(HTMLFormControlElement):

LayoutTests:

Add a test case for fieldset disabled attribute.

Reviewed by Kent Tamura.

* fast/forms/fieldset/fieldset-disabled-expected.txt: Added.
* fast/forms/fieldset/fieldset-disabled.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (112514 => 112515)


--- trunk/LayoutTests/ChangeLog	2012-03-29 10:12:12 UTC (rev 112514)
+++ trunk/LayoutTests/ChangeLog	2012-03-29 10:14:32 UTC (rev 112515)
@@ -1,3 +1,15 @@
+2012-03-29  Zeno Albisser  <[email protected]>
+
+        Fieldset disabled attribute does not work.
+        https://bugs.webkit.org/show_bug.cgi?id=58837
+
+        Add a test case for fieldset disabled attribute.
+
+        Reviewed by Kent Tamura.
+
+        * fast/forms/fieldset/fieldset-disabled-expected.txt: Added.
+        * fast/forms/fieldset/fieldset-disabled.html: Added.
+
 2012-03-29  Csaba Osztrogonác  <[email protected]>
 
         [Qt] Unreviewed gardening after r112397. Unskip tests, add new baselines.

Added: trunk/LayoutTests/fast/forms/fieldset/fieldset-disabled-expected.txt (0 => 112515)


--- trunk/LayoutTests/fast/forms/fieldset/fieldset-disabled-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/forms/fieldset/fieldset-disabled-expected.txt	2012-03-29 10:14:32 UTC (rev 112515)
@@ -0,0 +1,107 @@
+Tests for HTMLFieldSetElement.disabled behavior.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+Verifying parser generated fieldsets.
+PASS parserGeneratedInput1.value is "L"
+PASS parserGeneratedInput2.value is "M"
+PASS parserGeneratedInput3.value is "NO"
+PASS parserGeneratedInput4.value is ""
+PASS parserGeneratedInput5.value is "P"
+PASS parserGeneratedInput6.value is ""
+PASS parserGeneratedInput7.value is ""
+PASS parserGeneratedInput8.value is ""
+PASS parserGeneratedInput9.value is ""
+
+Testing a single fieldset element.
+Verifying HTMLFormControl can be disabled regardless of enclosing fieldset.
+PASS textInput.disabled is true
+PASS textInput.value is ""
+PASS fieldSet.disabled is false
+Fieldset is enabled by default. A user can insertText into the text input field.
+PASS textInput.value is "A"
+Disable fieldset.
+PASS fieldSet.disabled is true
+Once the fieldset is disabled, text cannot be inserted.
+PASS textInput.value is "A"
+Check if the style of the text element changed.
+PASS getComputedStyle(textInput).backgroundColor is 'rgb(255, 0, 0)'
+Enable fieldset.
+PASS fieldSet.disabled is false
+PASS getComputedStyle(textInput).backgroundColor is 'rgb(255, 255, 100)'
+PASS textInput.value is "AB"
+Move the textinput element out of the fieldset.
+Disable the fieldset.
+PASS fieldSet.disabled is true
+Text can be inserted, because the textinput element is outside of the disabled fieldset.
+PASS textInput.value is "ABC"
+Enable the fieldset.
+PASS fieldSet.disabled is false
+Insert a table into the fieldset.
+Move the textinput field into the table.
+PASS textInput.value is "ABCD"
+Disable the fieldset.
+PASS fieldSet.disabled is true
+Inserting text should fail.
+PASS textInput.value is "ABCD"
+Enable the fieldset.
+PASS fieldSet.disabled is false
+PASS textInput.value is "ABCDE"
+
+Testing nested fieldset elements.
+Verifying that subordinates of both fieldsets are enabled.
+PASS outerTextInput.value is "F"
+PASS innerTextInput.value is "F"
+Disabling the inner fieldset only.
+PASS innerFieldSet.disabled is true
+PASS outerTextInput.value is "FG"
+PASS innerTextInput.value is "F"
+Enabling the inner and disabling the outer fieldset.
+PASS outerFieldSet.disabled is true
+PASS innerFieldSet.disabled is false
+PASS outerTextInput.value is "FG"
+PASS innerTextInput.value is "F"
+Disabling both fieldset elements.
+PASS outerFieldSet.disabled is true
+PASS innerFieldSet.disabled is true
+PASS outerTextInput.value is "FG"
+PASS innerTextInput.value is "F"
+Enabling both fieldset elements.
+PASS outerFieldSet.disabled is false
+PASS innerFieldSet.disabled is false
+PASS outerTextInput.value is "FGH"
+PASS innerTextInput.value is "FH"
+
+Test behavior of the first legend element in a fieldset elements.
+Children of the first legend element in a fieldset should not get disabled with the fieldset.
+PASS legendFieldSet.disabled is true
+PASS firstLegendTextInput.value is "I"
+PASS secondLegendTextInput.value is ""
+Insert another legend element before the currently first one, and check again.
+PASS insertedLegendTextInput.value is "J"
+PASS firstLegendTextInput.value is "I"
+PASS secondLegendTextInput.value is ""
+Enable the fieldset again and check for sanity.
+PASS legendFieldSet.disabled is false
+PASS insertedLegendTextInput.value is "JK"
+PASS firstLegendTextInput.value is "IK"
+PASS secondLegendTextInput.value is "K"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+
+ 
+
+
+ 
+
+
+
+
+
+
+
+

Added: trunk/LayoutTests/fast/forms/fieldset/fieldset-disabled.html (0 => 112515)


--- trunk/LayoutTests/fast/forms/fieldset/fieldset-disabled.html	                        (rev 0)
+++ trunk/LayoutTests/fast/forms/fieldset/fieldset-disabled.html	2012-03-29 10:14:32 UTC (rev 112515)
@@ -0,0 +1,300 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href=""
+<script src=""
+<style type="text/css">
+input {
+    background:rgb(255,255,100);
+}
+input:disabled {
+    background:rgb(255,0,0);
+}
+</style>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<form>
+<fieldset>
+<legend><input type="text" id="parserGeneratedInput1"></legend>
+<legend><input type="text" id="parserGeneratedInput2"></legend>
+<input type="text" id="parserGeneratedInput3">
+<input type="text" id="parserGeneratedInput4" disabled>
+</fieldset>
+<fieldset disabled>
+<legend><input type="text" id="parserGeneratedInput5"></legend>
+<legend><input type="text" id="parserGeneratedInput6"></legend>
+<input type="text" id="parserGeneratedInput7">
+<input type="text" id="parserGeneratedInput8" disabled>
+</fieldset>
+<fieldset disabled>
+<input type="text" id="parserGeneratedInput9">
+</fieldset>
+</form>
+
+<script>
+description('Tests for HTMLFieldSetElement.disabled behavior.');
+
+debug('\nVerifying parser generated fieldsets.');
+var parserGeneratedInput1 = document.getElementById("parserGeneratedInput1");
+var parserGeneratedInput2 = document.getElementById("parserGeneratedInput2");
+var parserGeneratedInput3 = document.getElementById("parserGeneratedInput3");
+var parserGeneratedInput4 = document.getElementById("parserGeneratedInput4");
+var parserGeneratedInput5 = document.getElementById("parserGeneratedInput5");
+var parserGeneratedInput6 = document.getElementById("parserGeneratedInput6");
+var parserGeneratedInput7 = document.getElementById("parserGeneratedInput7");
+var parserGeneratedInput8 = document.getElementById("parserGeneratedInput8");
+var parserGeneratedInput9 = document.getElementById("parserGeneratedInput9");
+
+parserGeneratedInput1.focus();
+document.execCommand('insertText', false, 'L');
+parserGeneratedInput2.focus();
+document.execCommand('insertText', false, 'M');
+parserGeneratedInput3.focus();
+document.execCommand('insertText', false, 'N');
+parserGeneratedInput4.focus();
+document.execCommand('insertText', false, 'O');
+parserGeneratedInput5.focus();
+document.execCommand('insertText', false, 'P');
+parserGeneratedInput6.focus();
+document.execCommand('insertText', false, 'Q');
+parserGeneratedInput7.focus();
+document.execCommand('insertText', false, 'R');
+parserGeneratedInput8.focus();
+document.execCommand('insertText', false, 'S');
+parserGeneratedInput9.focus();
+document.execCommand('insertText', false, 'T');
+
+shouldBe('parserGeneratedInput1.value', '"L"');
+shouldBe('parserGeneratedInput2.value', '"M"');
+shouldBe('parserGeneratedInput3.value', '"NO"');
+shouldBe('parserGeneratedInput4.value', '""');
+shouldBe('parserGeneratedInput5.value', '"P"');
+shouldBe('parserGeneratedInput6.value', '""');
+shouldBe('parserGeneratedInput7.value', '""');
+shouldBe('parserGeneratedInput8.value', '""');
+shouldBe('parserGeneratedInput9.value', '""');
+
+
+debug('\nTesting a single fieldset element.');
+var fieldSet = document.createElement('fieldset');
+document.body.appendChild(fieldSet);
+var textInput = document.createElement('input');
+textInput.type = "text";
+fieldSet.appendChild(textInput);
+
+debug('Verifying HTMLFormControl can be disabled regardless of enclosing fieldset.');
+textInput.disabled = true;
+shouldBeTrue('textInput.disabled');
+textInput.focus();
+document.execCommand('insertText', false, 'A');
+shouldBe('textInput.value', '""');
+shouldBeFalse('fieldSet.disabled');
+textInput.disabled = false;
+
+debug('Fieldset is enabled by default. A user can insertText into the text input field.');
+textInput.focus();
+document.execCommand('insertText', false, 'A');
+shouldBe('textInput.value', '"A"');
+
+debug('Disable fieldset.');
+fieldSet.disabled = true;
+shouldBeTrue('fieldSet.disabled');
+
+debug('Once the fieldset is disabled, text cannot be inserted.');
+textInput.focus();
+document.execCommand('insertText', false, 'B');
+shouldBe('textInput.value', '"A"');
+
+debug("Check if the style of the text element changed.");
+shouldBe("getComputedStyle(textInput).backgroundColor", "'rgb(255, 0, 0)'");
+
+debug('Enable fieldset.');
+fieldSet.disabled = false;
+shouldBeFalse('fieldSet.disabled');
+shouldBe("getComputedStyle(textInput).backgroundColor", "'rgb(255, 255, 100)'");
+
+textInput.focus();
+document.execCommand('insertText', false, 'B');
+shouldBe('textInput.value', '"AB"');
+
+debug('Move the textinput element out of the fieldset.');
+fieldSet.removeChild(textInput);
+document.body.appendChild(textInput);
+
+debug('Disable the fieldset.');
+fieldSet.disabled = true;
+shouldBeTrue('fieldSet.disabled');
+
+debug('Text can be inserted, because the textinput element is outside of the disabled fieldset.');
+textInput.focus();
+document.execCommand('insertText', false, 'C');
+shouldBe('textInput.value', '"ABC"');
+
+debug('Enable the fieldset.');
+fieldSet.disabled = false;
+shouldBeFalse('fieldSet.disabled');
+
+debug('Insert a table into the fieldset.');
+var table = document.createElement('table');
+fieldSet.appendChild(table);
+var tr = document.createElement('tr');
+table.appendChild(tr);
+var td = document.createElement('td');
+tr.appendChild(td);
+
+debug('Move the textinput field into the table.');
+document.body.removeChild(textInput);
+td.appendChild(textInput);
+
+textInput.focus();
+document.execCommand('insertText', false, 'D');
+shouldBe('textInput.value', '"ABCD"');
+
+debug('Disable the fieldset.');
+fieldSet.disabled = true;
+shouldBeTrue('fieldSet.disabled');
+
+debug('Inserting text should fail.')
+textInput.focus();
+document.execCommand('insertText', false, 'E');
+shouldBe('textInput.value', '"ABCD"');
+
+debug('Enable the fieldset.');
+fieldSet.disabled = false;
+shouldBeFalse('fieldSet.disabled');
+
+textInput.focus();
+document.execCommand('insertText', false, 'E');
+shouldBe('textInput.value', '"ABCDE"');
+
+
+debug('\nTesting nested fieldset elements.');
+var outerFieldSet = document.createElement('fieldset');
+document.body.appendChild(outerFieldSet);
+var innerFieldSet = document.createElement('fieldset');
+outerFieldSet.appendChild(innerFieldSet);
+var outerTextInput = document.createElement('input');
+outerTextInput.type = "text";
+outerFieldSet.appendChild(outerTextInput);
+var innerTextInput = document.createElement('input');
+innerTextInput.type = "text";
+innerFieldSet.appendChild(innerTextInput);
+
+debug('Verifying that subordinates of both fieldsets are enabled.');
+outerTextInput.focus();
+document.execCommand('insertText', false, 'F');
+innerTextInput.focus();
+document.execCommand('insertText', false, 'F');
+shouldBe('outerTextInput.value', '"F"');
+shouldBe('innerTextInput.value', '"F"');
+
+debug('Disabling the inner fieldset only.');
+innerFieldSet.disabled = true;
+shouldBeTrue('innerFieldSet.disabled');
+outerTextInput.focus();
+document.execCommand('insertText', false, 'G');
+innerTextInput.focus();
+document.execCommand('insertText', false, 'G');
+shouldBe('outerTextInput.value', '"FG"');
+shouldBe('innerTextInput.value', '"F"');
+
+debug('Enabling the inner and disabling the outer fieldset.');
+outerFieldSet.disabled = true;
+innerFieldSet.disabled = false;
+shouldBeTrue('outerFieldSet.disabled');
+shouldBeFalse('innerFieldSet.disabled');
+outerTextInput.focus();
+document.execCommand('insertText', false, 'H');
+innerTextInput.focus();
+document.execCommand('insertText', false, 'H');
+shouldBe('outerTextInput.value', '"FG"');
+shouldBe('innerTextInput.value', '"F"');
+
+debug('Disabling both fieldset elements.');
+outerFieldSet.disabled = true;
+innerFieldSet.disabled = true;
+shouldBeTrue('outerFieldSet.disabled');
+shouldBeTrue('innerFieldSet.disabled');
+outerTextInput.focus();
+document.execCommand('insertText', false, 'H');
+innerTextInput.focus();
+document.execCommand('insertText', false, 'H');
+shouldBe('outerTextInput.value', '"FG"');
+shouldBe('innerTextInput.value', '"F"');
+
+debug('Enabling both fieldset elements.');
+outerFieldSet.disabled = false;
+innerFieldSet.disabled = false;
+shouldBeFalse('outerFieldSet.disabled');
+shouldBeFalse('innerFieldSet.disabled');
+outerTextInput.focus();
+document.execCommand('insertText', false, 'H');
+innerTextInput.focus();
+document.execCommand('insertText', false, 'H');
+shouldBe('outerTextInput.value', '"FGH"');
+shouldBe('innerTextInput.value', '"FH"');
+
+
+debug('\nTest behavior of the first legend element in a fieldset elements.');
+var legendFieldSet = document.createElement('fieldset');
+document.body.appendChild(legendFieldSet);
+var firstLegend = document.createElement('legend');
+legendFieldSet.appendChild(firstLegend);
+var secondLegend = document.createElement('legend');
+legendFieldSet.appendChild(secondLegend);
+
+var firstLegendTextInput = document.createElement('input');
+firstLegendTextInput.type = "text";
+firstLegend.appendChild(firstLegendTextInput);
+
+var secondLegendTextInput = document.createElement('input');
+secondLegendTextInput.type = "text";
+secondLegend.appendChild(secondLegendTextInput);
+
+debug('Children of the first legend element in a fieldset should not get disabled with the fieldset.');
+legendFieldSet.disabled = true;
+shouldBeTrue('legendFieldSet.disabled');
+firstLegendTextInput.focus();
+document.execCommand('insertText', false, 'I');
+secondLegendTextInput.focus()
+document.execCommand('insertText', false, 'I');
+shouldBe('firstLegendTextInput.value', '"I"');
+shouldBe('secondLegendTextInput.value', '""');
+
+debug('Insert another legend element before the currently first one, and check again.');
+var insertedLegend = document.createElement('legend');
+legendFieldSet.insertBefore(insertedLegend, firstLegend);
+var insertedLegendTextInput = document.createElement('input');
+insertedLegend.appendChild(insertedLegendTextInput);
+
+insertedLegendTextInput.focus();
+document.execCommand('insertText', false, 'J');
+firstLegendTextInput.focus();
+document.execCommand('insertText', false, 'J');
+secondLegendTextInput.focus()
+document.execCommand('insertText', false, 'J');
+shouldBe('insertedLegendTextInput.value', '"J"');
+shouldBe('firstLegendTextInput.value', '"I"');
+shouldBe('secondLegendTextInput.value', '""');
+
+debug('Enable the fieldset again and check for sanity.');
+legendFieldSet.disabled = false;
+shouldBeFalse('legendFieldSet.disabled');
+insertedLegendTextInput.focus();
+document.execCommand('insertText', false, 'K');
+firstLegendTextInput.focus();
+document.execCommand('insertText', false, 'K');
+secondLegendTextInput.focus()
+document.execCommand('insertText', false, 'K');
+shouldBe('insertedLegendTextInput.value', '"JK"');
+shouldBe('firstLegendTextInput.value', '"IK"');
+shouldBe('secondLegendTextInput.value', '"K"');
+
+var successfullyParsed = true;
+</script>
+<script src=""
+
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (112514 => 112515)


--- trunk/Source/WebCore/ChangeLog	2012-03-29 10:12:12 UTC (rev 112514)
+++ trunk/Source/WebCore/ChangeLog	2012-03-29 10:14:32 UTC (rev 112515)
@@ -1,3 +1,37 @@
+2012-03-29  Zeno Albisser  <[email protected]>
+
+        Fieldset disabled attribute does not work.
+        https://bugs.webkit.org/show_bug.cgi?id=58837
+
+        Make HTMLFormControlElements inherit the disabled state
+        from HTMLFieldSetElement ancestors. Subordinates of the
+        first HTMLLegendElement in a fieldset will never be disabled.
+
+        Patch by Zeno Albisser <[email protected]>
+
+        Test: fast/forms/fieldset-disabled.html
+
+        Reviewed by Kent Tamura.
+
+        * html/HTMLFieldSetElement.cpp:
+        (WebCore::HTMLFieldSetElement::disabledAttributeChanged):
+        (WebCore):
+        (WebCore::HTMLFieldSetElement::legend):
+        * html/HTMLFieldSetElement.h:
+        (HTMLFieldSetElement):
+        * html/HTMLFieldSetElement.idl:
+        * html/HTMLFormControlElement.cpp:
+        (WebCore::HTMLFormControlElement::HTMLFormControlElement):
+        (WebCore::HTMLFormControlElement::updateFieldSetAndLegendAncestor):
+        (WebCore):
+        (WebCore::HTMLFormControlElement::parseAttribute):
+        (WebCore::HTMLFormControlElement::disabledAttributeChanged):
+        (WebCore::HTMLFormControlElement::removedFromTree):
+        (WebCore::HTMLFormControlElement::disabled):
+        * html/HTMLFormControlElement.h:
+        (WebCore):
+        (HTMLFormControlElement):
+
 2012-03-29  Tommy Widenflycht  <[email protected]>
 
         MediaStream API: Adding two missing release() calls to PeerConnection00.cpp

Modified: trunk/Source/WebCore/html/HTMLFieldSetElement.cpp (112514 => 112515)


--- trunk/Source/WebCore/html/HTMLFieldSetElement.cpp	2012-03-29 10:12:12 UTC (rev 112514)
+++ trunk/Source/WebCore/html/HTMLFieldSetElement.cpp	2012-03-29 10:14:32 UTC (rev 112515)
@@ -24,6 +24,7 @@
 
 #include "config.h"
 #include "HTMLFieldSetElement.h"
+#include "HTMLLegendElement.h"
 
 #include "HTMLNames.h"
 #include "RenderFieldset.h"
@@ -44,6 +45,18 @@
     return adoptRef(new HTMLFieldSetElement(tagName, document, form));
 }
 
+void HTMLFieldSetElement::disabledAttributeChanged()
+{
+    // This element must be updated before the style of nodes in its subtree gets recalculated.
+    HTMLFormControlElement::disabledAttributeChanged();
+
+    for (Node* currentNode = this; currentNode; currentNode = currentNode->traverseNextNode(this)) {
+        HTMLElement* element = toHTMLElement(currentNode);
+        if (element && element->isFormControlElement())
+            static_cast<HTMLFormControlElement*>(element)->setNeedsStyleRecalc();
+    }
+}
+
 bool HTMLFieldSetElement::supportsFocus() const
 {
     return HTMLElement::supportsFocus();
@@ -60,4 +73,13 @@
     return new (arena) RenderFieldset(this);
 }
 
+HTMLLegendElement* HTMLFieldSetElement::legend() const
+{
+    for (Element* node = firstElementChild(); node; node = node->nextElementSibling()) {
+        if (node->hasTagName(legendTag))
+            return static_cast<HTMLLegendElement*>(node);
+    }
+    return 0;
+}
+
 } // namespace

Modified: trunk/Source/WebCore/html/HTMLFieldSetElement.h (112514 => 112515)


--- trunk/Source/WebCore/html/HTMLFieldSetElement.h	2012-03-29 10:12:12 UTC (rev 112514)
+++ trunk/Source/WebCore/html/HTMLFieldSetElement.h	2012-03-29 10:14:32 UTC (rev 112515)
@@ -31,7 +31,11 @@
 class HTMLFieldSetElement : public HTMLFormControlElement {
 public:
     static PassRefPtr<HTMLFieldSetElement> create(const QualifiedName&, Document*, HTMLFormElement*);
+    HTMLLegendElement* legend() const;
 
+protected:
+    virtual void disabledAttributeChanged() OVERRIDE;
+
 private:
     HTMLFieldSetElement(const QualifiedName&, Document*, HTMLFormElement*);
 

Modified: trunk/Source/WebCore/html/HTMLFieldSetElement.idl (112514 => 112515)


--- trunk/Source/WebCore/html/HTMLFieldSetElement.idl	2012-03-29 10:12:12 UTC (rev 112514)
+++ trunk/Source/WebCore/html/HTMLFieldSetElement.idl	2012-03-29 10:14:32 UTC (rev 112515)
@@ -20,6 +20,7 @@
 module html {
 
     interface HTMLFieldSetElement : HTMLElement {
+        attribute [Reflect] boolean disabled;
         readonly attribute HTMLFormElement form;
         attribute [Reflect] DOMString name;
 

Modified: trunk/Source/WebCore/html/HTMLFormControlElement.cpp (112514 => 112515)


--- trunk/Source/WebCore/html/HTMLFormControlElement.cpp	2012-03-29 10:12:12 UTC (rev 112514)
+++ trunk/Source/WebCore/html/HTMLFormControlElement.cpp	2012-03-29 10:14:32 UTC (rev 112515)
@@ -30,8 +30,10 @@
 #include "EventHandler.h"
 #include "EventNames.h"
 #include "Frame.h"
+#include "HTMLFieldSetElement.h"
 #include "HTMLFormElement.h"
 #include "HTMLInputElement.h"
+#include "HTMLLegendElement.h"
 #include "RenderBox.h"
 #include "RenderTheme.h"
 #include "ScriptEventListener.h"
@@ -46,6 +48,9 @@
 
 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)
@@ -95,6 +100,21 @@
     return fastHasAttribute(formnovalidateAttr);
 }
 
+void HTMLFormControlElement::updateFieldSetAndLegendAncestor() const
+{
+    m_fieldSetAncestor = 0;
+    m_legendAncestor = 0;
+    for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
+        if (!m_legendAncestor && ancestor->hasTagName(legendTag))
+            m_legendAncestor = static_cast<HTMLLegendElement*>(ancestor);
+        if (ancestor->hasTagName(fieldsetTag)) {
+            m_fieldSetAncestor = static_cast<HTMLFieldSetElement*>(ancestor);
+            break;
+        }
+    }
+    m_fieldSetAncestorValid = true;
+}
+
 void HTMLFormControlElement::parseAttribute(Attribute* attr)
 {
     if (attr->name() == formAttr)
@@ -102,11 +122,8 @@
     else if (attr->name() == disabledAttr) {
         bool oldDisabled = m_disabled;
         m_disabled = !attr->isNull();
-        if (oldDisabled != m_disabled) {
-            setNeedsStyleRecalc();
-            if (renderer() && renderer()->style()->hasAppearance())
-                renderer()->theme()->stateChanged(renderer(), EnabledState);
-        }
+        if (oldDisabled != m_disabled)
+            disabledAttributeChanged();
     } else if (attr->name() == readonlyAttr) {
         bool oldReadOnly = m_readOnly;
         m_readOnly = !attr->isNull();
@@ -125,6 +142,13 @@
     setNeedsWillValidateCheck();
 }
 
+void HTMLFormControlElement::disabledAttributeChanged()
+{
+    setNeedsStyleRecalc();
+    if (renderer() && renderer()->style()->hasAppearance())
+        renderer()->theme()->stateChanged(renderer(), EnabledState);
+}
+
 void HTMLFormControlElement::requiredAttributeChanged()
 {
     setNeedsValidityCheck();
@@ -205,6 +229,7 @@
 
 void HTMLFormControlElement::removedFromTree(bool deep)
 {
+    m_fieldSetAncestorValid = false;
     FormAssociatedElement::removedFromTree();
     HTMLElement::removedFromTree(deep);
 }
@@ -254,6 +279,20 @@
     HTMLElement::dispatchInputEvent();
 }
 
+bool HTMLFormControlElement::disabled() const
+{
+    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;
+}
+
 void HTMLFormControlElement::setDisabled(bool b)
 {
     setAttribute(disabledAttr, b ? "" : 0);

Modified: trunk/Source/WebCore/html/HTMLFormControlElement.h (112514 => 112515)


--- trunk/Source/WebCore/html/HTMLFormControlElement.h	2012-03-29 10:12:12 UTC (rev 112514)
+++ trunk/Source/WebCore/html/HTMLFormControlElement.h	2012-03-29 10:14:32 UTC (rev 112515)
@@ -30,7 +30,9 @@
 namespace WebCore {
 
 class FormDataList;
+class HTMLFieldSetElement;
 class HTMLFormElement;
+class HTMLLegendElement;
 class ValidationMessage;
 class ValidityState;
 
@@ -49,6 +51,8 @@
     void setFormMethod(const String&);
     bool formNoValidate() const;
 
+    void updateFieldSetAndLegendAncestor() const;
+
     virtual void reset() { }
 
     virtual bool formControlValueMatchesRenderer() const { return m_valueMatchesRenderer; }
@@ -60,7 +64,7 @@
     virtual void dispatchFormControlChangeEvent();
     virtual void dispatchFormControlInputEvent();
 
-    virtual bool disabled() const { return m_disabled; }
+    virtual bool disabled() const;
     void setDisabled(bool);
 
     virtual bool isFocusable() const;
@@ -114,6 +118,7 @@
 
     virtual void parseAttribute(Attribute*) OVERRIDE;
     virtual void requiredAttributeChanged();
+    virtual void disabledAttributeChanged();
     virtual void attach();
     virtual void insertedIntoTree(bool deep);
     virtual void removedFromTree(bool deep);
@@ -147,7 +152,10 @@
     virtual bool isValidFormControlElement();
     String visibleValidationMessage() 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;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to