RadioNodeList support in HTMLFormElement::elements
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 9 May 2012 03:23:16 +0000 (03:23 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 9 May 2012 03:23:16 +0000 (03:23 +0000)
https://bugs.webkit.org/show_bug.cgi?id=81854

Patch by Rakesh KN <rakesh.kn@motorola.com> on 2012-05-08
Reviewed by Ryosuke Niwa.

Source/WebCore:

Implement RadioNodeList support spec'ed at
http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#radionodelist

Test: fast/forms/form-collection-radio-node-list.html

* CMakeLists.txt:
Added entries for new files.
* DerivedSources.cpp: Ditto.
* DerivedSources.make: Ditto.
* DerivedSources.pri: Ditto.
* GNUmakefile.list.am: Ditto.
* Target.pri: Ditto.
* WebCore.gypi: Ditto.
* WebCore.vcproj/WebCore.vcproj: Ditto.
* WebCore.xcodeproj/project.pbxproj: Ditto.
* bindings/js/JSHTMLCollectionCustom.cpp:
(WebCore::getNamedItems):
Modified to create RadioNodeList object when FormControlCollection has more than
one element of same name/id.
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateImplementation):
Added code to include Node.h and JSNode.h in JSRadioNodeElement.cpp.
* bindings/v8/custom/V8HTMLCollectionCustom.cpp:
(WebCore::getNamedItems):
Modified to create RadioNodeList object when FormControlCollection has more than
one element of same name/id.
* dom/Node.cpp:
(WebCore::Node::invalidateNodeListsCacheAfterAttributeChanged):
Invalidate lists even for change in id, type, checked attributes.
(WebCore::NodeListsNodeData::invalidateCachesThatDependOnAttributes):
Invalidate radioNodeList cache.
(WebCore::NodeListsNodeData::isEmpty):
Changes for radioNodeList.
(WebCore::Node::radioNodeList):
Creates if needed a RadioNodeList and adds it to the cache.
(WebCore::Node::removeCachedRadioNodeList):
Removes a cached radioNodeList.
* dom/Node.h: Ditto
* dom/NodeRareData.h:
(WebCore):
(NodeListsNodeData):
Added radioNodeList list.
* html/CollectionType.h:
Added new FormControls type.
* html/HTMLCollection.cpp:
(WebCore::HTMLCollection::shouldIncludeChildren):
(WebCore::HTMLCollection::isAcceptableElement):
Handle FormControls collection type.
* html/HTMLFormCollection.cpp:
(WebCore::HTMLFormCollection::HTMLFormCollection):
Contruct collection of FormControls type.
* html/RadioNodeList.cpp: Added.
(WebCore):
(WebCore::RadioNodeList::RadioNodeList):
(WebCore::RadioNodeList::~RadioNodeList):
(WebCore::toRadioButtonInputElement):
(WebCore::RadioNodeList::value):
(WebCore::RadioNodeList::setValue):
(WebCore::RadioNodeList::nodeMatches):
* html/RadioNodeList.h: Added.
(WebCore):
(RadioNodeList):
(WebCore::RadioNodeList::create):
RadioNodeList implementation.
* html/RadioNodeList.idl: Added.
Idl for generating RadioNodeList JS/V8 bindings.

LayoutTests:

* fast/forms/form-collection-radio-node-list-expected.txt: Added.
* fast/forms/form-collection-radio-node-list.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@116487 268f45cc-cd09-0410-ab3c-d52691b4dbfc

25 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/forms/form-collection-radio-node-list-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/form-collection-radio-node-list.html [new file with mode: 0644]
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/DerivedSources.cpp
Source/WebCore/DerivedSources.make
Source/WebCore/DerivedSources.pri
Source/WebCore/GNUmakefile.list.am
Source/WebCore/Target.pri
Source/WebCore/WebCore.gypi
Source/WebCore/WebCore.vcproj/WebCore.vcproj
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/bindings/js/JSHTMLCollectionCustom.cpp
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/bindings/v8/custom/V8HTMLCollectionCustom.cpp
Source/WebCore/dom/Node.cpp
Source/WebCore/dom/Node.h
Source/WebCore/dom/NodeRareData.h
Source/WebCore/html/CollectionType.h
Source/WebCore/html/HTMLCollection.cpp
Source/WebCore/html/HTMLFormCollection.cpp
Source/WebCore/html/RadioNodeList.cpp [new file with mode: 0644]
Source/WebCore/html/RadioNodeList.h [new file with mode: 0644]
Source/WebCore/html/RadioNodeList.idl [new file with mode: 0644]

index f0e7399..7a9d9ce 100644 (file)
@@ -1,3 +1,13 @@
+2012-05-08  Rakesh KN  <rakesh.kn@motorola.com>
+
+        RadioNodeList support in HTMLFormElement::elements
+        https://bugs.webkit.org/show_bug.cgi?id=81854
+
+        Reviewed by Ryosuke Niwa.
+
+        * fast/forms/form-collection-radio-node-list-expected.txt: Added.
+        * fast/forms/form-collection-radio-node-list.html: Added.
+
 2012-05-08  Benjamin Poulain  <bpoulain@apple.com>
 
         [JSC] Regression: addEventListener() and removeEventListener() raise an exception on missing args
diff --git a/LayoutTests/fast/forms/form-collection-radio-node-list-expected.txt b/LayoutTests/fast/forms/form-collection-radio-node-list-expected.txt
new file mode 100644 (file)
index 0000000..75bce98
--- /dev/null
@@ -0,0 +1,60 @@
+This test is for RadioNodeList specified at http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#radionodelist
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+                                       
+
+
+PASS owner.elements.length is 23
+PASS radioNodeList.length is 4
+PASS radioNodeList[0].value is 'searching'
+PASS radioNodeList[1].value is '123'
+PASS radioNodeList[2].value is 'inputRadioValue'
+PASS radioNodeList[3].value is 'buttonValue'
+
+Changing the input value to check RadioNodeList is live view of FormCollection
+PASS radioNodeList[1].value is '456'
+
+Checking value IDL attribute on the RadioNodeList
+PASS radioNodeList.value is ""
+PASS radioNodeList.value = "inputRadioValue"; radioNodeList[2].checked is true
+PASS Object.prototype.toString.call(radioNodeList[2]) is '[object HTMLInputElement]'
+PASS radioNodeList[2].type is 'radio'
+PASS radioNodeList.value is ""
+PASS radioNodeList[2].checked = true; radioNodeList.value is 'inputRadioValue'
+
+Check RadioNodeList is updated after adding a new element
+PASS owner.appendChild(newElement); radioNodeList.length is 5
+PASS radioNodeList[4].value is 'new element'
+
+Check RadioNodeList is updated after remove an element
+PASS owner.removeChild(newElement); radioNodeList.length is 4
+PASS radioNodeList[3].value is 'buttonValue'
+
+Check RadioNodeList is updated after adding a new element
+PASS container.appendChild(nonSubtreeElement); radioNodeList.length is 5
+PASS owner.elements.length is 24
+PASS radioNodeList[4].value is 'non subtree element'
+
+Check RadioNodeList is updated after change in id, type and checked state of an element
+PASS radioNodeList.length is 5
+After changing the id
+PASS radioNodeList.length is 4
+PASS elementsList[13].checked = false; radioNodeList.value is ""
+PASS elementsList[13].checked = true; radioNodeList.value is 'inputRadioValue'
+PASS elementsList[13].type = "date"; radioNodeList.value is ''
+
+Check second RadioNodeList is also created properly
+PASS radioNodeList2.length is 3
+PASS radioNodeList2[0].type is 'text'
+PASS radioNodeList2[1].type is 'email'
+PASS radioNodeList2[2].type is 'reset'
+After changing the id
+PASS radioNodeList2.length is 2
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/forms/form-collection-radio-node-list.html b/LayoutTests/fast/forms/form-collection-radio-node-list.html
new file mode 100644 (file)
index 0000000..5e557a3
--- /dev/null
@@ -0,0 +1,128 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="../js/resources/js-test-pre.js"></script>
+<p id="description"></p>
+<div id="divId">
+<form id="form1">
+    <button id=button1></button>
+    <fieldset id=fieldset1><legend id=legend1></legend></fieldset>
+    <input id=inputhidden type=hidden>
+    <input id=commoninput type=text>
+    <input id=inputcommon type=search value=searching>
+    <input id=inputurl type=url>
+    <input id=commoninput type=email>
+    <input id=inputpassword type=password>
+    <input id=inputdate type=date>
+    <input id=numberId name=inputcommon type=number value=123>
+    <input id=inputrange type=range>
+    <input id=inputcolor type=color>
+    <input id=inputcheckbox type=checkbox>
+    <input id=inputcommon type=radio value="inputRadioValue">
+    <input id=inputfile type=file>
+    <input id=inputsubmit type=submit>
+    <input id=inputcommon type=image>
+    <input id=commoninput type=reset>
+    <input id=inputcommon type=button value=buttonValue>
+    <keygen id=keygen1></keygen>
+    <label id=label1></label>
+    <meter id=meter1></meter>
+    <object id=object1></object>
+    <output id=output1></output>
+    <progress id=progress1></progress>
+    <select id=select1>
+        <optgroup id=optgroup1>group1</optgroup>
+        <option id=option1>option1</option>
+    </select>
+    <textarea id=textarea1></textarea>
+</form>
+</div>
+<div id="console"></div>
+<script>
+description("This test is for RadioNodeList specified at http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#radionodelist ");
+debug("");
+var owner = document.getElementById('form1');
+
+shouldBe('owner.elements.length', '23');
+
+var elementsList = owner.elements;
+var radioNodeList = elementsList.namedItem("inputcommon");
+shouldBe('radioNodeList.length', '4');
+
+shouldBe('radioNodeList[0].value', "'searching'");
+shouldBe('radioNodeList[1].value', "'123'");
+shouldBe('radioNodeList[2].value', "'inputRadioValue'");
+shouldBe('radioNodeList[3].value', "'buttonValue'");
+
+debug("");
+debug("Changing the input value to check RadioNodeList is live view of FormCollection");
+document.getElementById("numberId").value = 456;
+shouldBe('radioNodeList[1].value', "'456'");
+
+debug("");
+debug("Checking value IDL attribute on the RadioNodeList");
+shouldBe('radioNodeList.value', '""');
+shouldBe('radioNodeList.value = "inputRadioValue"; radioNodeList[2].checked', 'true');
+shouldBe('Object.prototype.toString.call(radioNodeList[2])', "'[object HTMLInputElement]'");
+shouldBe('radioNodeList[2].type', "'radio'");
+
+radioNodeList[2].checked = false;
+shouldBe('radioNodeList.value', '""');
+shouldBe('radioNodeList[2].checked = true; radioNodeList.value', "'inputRadioValue'");
+
+var newElement = document.createElement("input");
+newElement.setAttribute("type", "text");
+newElement.setAttribute("value", "new element");
+newElement.setAttribute("id", "inputcommon");
+
+debug("");
+debug("Check RadioNodeList is updated after adding a new element");
+shouldBe('owner.appendChild(newElement); radioNodeList.length', '5');
+shouldBe('radioNodeList[4].value', "'new element'");
+
+debug("");
+debug("Check RadioNodeList is updated after remove an element");
+shouldBe('owner.removeChild(newElement); radioNodeList.length', '4');
+shouldBe('radioNodeList[3].value', "'buttonValue'");
+
+var nonSubtreeElement = document.createElement("input");
+nonSubtreeElement.setAttribute("type", "text");
+nonSubtreeElement.setAttribute("value", "non subtree element");
+nonSubtreeElement.setAttribute("id", "inputcommon");
+nonSubtreeElement.setAttribute("form", "form1");
+
+var container = document.getElementById("divId");
+
+debug("");
+debug("Check RadioNodeList is updated after adding a new element");
+shouldBe('container.appendChild(nonSubtreeElement); radioNodeList.length', '5');
+shouldBe('owner.elements.length', '24');
+shouldBe('radioNodeList[4].value', "'non subtree element'");
+
+debug("");
+debug("Check RadioNodeList is updated after change in id, type and checked state of an element");
+shouldBe('radioNodeList.length', '5');
+debug("After changing the id");
+radioNodeList[4].id = "changedName";
+shouldBe('radioNodeList.length', '4');
+
+shouldBe('elementsList[13].checked = false; radioNodeList.value', '""');
+shouldBe('elementsList[13].checked = true; radioNodeList.value', "'inputRadioValue'");
+shouldBe('elementsList[13].type = "date"; radioNodeList.value', "''");
+
+debug("");
+debug("Check second RadioNodeList is also created properly");
+var radioNodeList2 = elementsList.namedItem("commoninput");
+shouldBe('radioNodeList2.length', '3');
+
+shouldBe('radioNodeList2[0].type', "'text'");
+shouldBe('radioNodeList2[1].type', "'email'");
+shouldBe('radioNodeList2[2].type', "'reset'");
+radioNodeList2[2].id = "idChanged";
+debug("After changing the id");
+shouldBe('radioNodeList2.length', '2');
+debug("");
+</script>
+<script src="../js/resources/js-test-post.js"></script>
+</body>
+</html>
index b8fc7e4..cada7c5 100644 (file)
@@ -331,6 +331,7 @@ SET(WebCore_IDL_FILES
     html/ImageData.idl
     html/MediaController.idl
     html/MediaError.idl
+    html/RadioNodeList.idl
     html/TextMetrics.idl
     html/TimeRanges.idl
     html/ValidityState.idl
@@ -855,6 +856,7 @@ SET(WebCore_SOURCES
     html/PasswordInputType.cpp
     html/PluginDocument.cpp
     html/RadioInputType.cpp
+    html/RadioNodeList.cpp
     html/RangeInputType.cpp
     html/ResetInputType.cpp
     html/SearchInputType.cpp
index 8bc49d8..2449f05 100644 (file)
@@ -1,3 +1,77 @@
+2012-05-08  Rakesh KN  <rakesh.kn@motorola.com>
+
+        RadioNodeList support in HTMLFormElement::elements
+        https://bugs.webkit.org/show_bug.cgi?id=81854
+
+        Reviewed by Ryosuke Niwa.
+
+        Implement RadioNodeList support spec'ed at
+        http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#radionodelist
+
+        Test: fast/forms/form-collection-radio-node-list.html
+
+        * CMakeLists.txt:
+        Added entries for new files.
+        * DerivedSources.cpp: Ditto.
+        * DerivedSources.make: Ditto.
+        * DerivedSources.pri: Ditto.
+        * GNUmakefile.list.am: Ditto.
+        * Target.pri: Ditto.
+        * WebCore.gypi: Ditto.
+        * WebCore.vcproj/WebCore.vcproj: Ditto.
+        * WebCore.xcodeproj/project.pbxproj: Ditto.
+        * bindings/js/JSHTMLCollectionCustom.cpp:
+        (WebCore::getNamedItems):
+        Modified to create RadioNodeList object when FormControlCollection has more than
+        one element of same name/id.
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateImplementation):
+        Added code to include Node.h and JSNode.h in JSRadioNodeElement.cpp.
+        * bindings/v8/custom/V8HTMLCollectionCustom.cpp:
+        (WebCore::getNamedItems):
+        Modified to create RadioNodeList object when FormControlCollection has more than
+        one element of same name/id.
+        * dom/Node.cpp:
+        (WebCore::Node::invalidateNodeListsCacheAfterAttributeChanged):
+        Invalidate lists even for change in id, type, checked attributes.
+        (WebCore::NodeListsNodeData::invalidateCachesThatDependOnAttributes):
+        Invalidate radioNodeList cache.
+        (WebCore::NodeListsNodeData::isEmpty):
+        Changes for radioNodeList.
+        (WebCore::Node::radioNodeList):
+        Creates if needed a RadioNodeList and adds it to the cache.
+        (WebCore::Node::removeCachedRadioNodeList):
+        Removes a cached radioNodeList.
+        * dom/Node.h: Ditto
+        * dom/NodeRareData.h:
+        (WebCore):
+        (NodeListsNodeData):
+        Added radioNodeList list.
+        * html/CollectionType.h:
+        Added new FormControls type.
+        * html/HTMLCollection.cpp:
+        (WebCore::HTMLCollection::shouldIncludeChildren):
+        (WebCore::HTMLCollection::isAcceptableElement):
+        Handle FormControls collection type.
+        * html/HTMLFormCollection.cpp:
+        (WebCore::HTMLFormCollection::HTMLFormCollection):
+        Contruct collection of FormControls type.
+        * html/RadioNodeList.cpp: Added.
+        (WebCore):
+        (WebCore::RadioNodeList::RadioNodeList):
+        (WebCore::RadioNodeList::~RadioNodeList):
+        (WebCore::toRadioButtonInputElement):
+        (WebCore::RadioNodeList::value):
+        (WebCore::RadioNodeList::setValue):
+        (WebCore::RadioNodeList::nodeMatches):
+        * html/RadioNodeList.h: Added.
+        (WebCore):
+        (RadioNodeList):
+        (WebCore::RadioNodeList::create):
+        RadioNodeList implementation.
+        * html/RadioNodeList.idl: Added.
+        Idl for generating RadioNodeList JS/V8 bindings.
+
 2012-05-08  Benjamin Poulain  <bpoulain@apple.com>
 
         [JSC] Regression: addEventListener() and removeEventListener() raise an exception on missing args
index ef05a8d..988d582 100644 (file)
 #include "JSPositionErrorCallback.cpp"
 #include "JSProcessingInstruction.cpp"
 #include "JSProgressEvent.cpp"
+#include "JSRadioNodeList.cpp"
 #include "JSRange.cpp"
 #include "JSRangeException.cpp"
 #include "JSRect.cpp"
index 680ae70..3d07a30 100644 (file)
@@ -335,6 +335,7 @@ BINDING_IDLS = \
     $(WebCore)/html/ImageData.idl \
     $(WebCore)/html/MediaController.idl \
     $(WebCore)/html/MediaError.idl \
+    $(WebCore)/html/RadioNodeList.idl \
     $(WebCore)/html/TextMetrics.idl \
     $(WebCore)/html/TimeRanges.idl \
     $(WebCore)/html/ValidityState.idl \
index 70104a8..a29087d 100644 (file)
@@ -383,6 +383,7 @@ IDL_BINDINGS += \
     $$PWD/html/ImageData.idl \
     $$PWD/html/MediaController.idl \
     $$PWD/html/MediaError.idl \
+    $$PWD/html/RadioNodeList.idl \
     $$PWD/html/TextMetrics.idl \
     $$PWD/html/TimeRanges.idl \
     $$PWD/html/ValidityState.idl \
index 538b92a..25ae934 100644 (file)
@@ -466,6 +466,8 @@ webcore_built_sources += \
        DerivedSources/WebCore/JSProcessingInstruction.h \
        DerivedSources/WebCore/JSProgressEvent.cpp \
        DerivedSources/WebCore/JSProgressEvent.h \
+       DerivedSources/WebCore/JSRadioNodeList.cpp \
+       DerivedSources/WebCore/JSRadioNodeList.h \
        DerivedSources/WebCore/JSRange.cpp \
        DerivedSources/WebCore/JSRangeException.cpp \
        DerivedSources/WebCore/JSRangeException.h \
@@ -879,6 +881,7 @@ dom_binding_idls += \
        $(WebCore)/html/MediaError.idl \
        $(WebCore)/html/MediaKeyError.idl \
        $(WebCore)/html/MediaKeyEvent.idl \
+       $(WebCore)/html/RadioNodeList.idl \
        $(WebCore)/html/TextMetrics.idl \
        $(WebCore)/html/TimeRanges.idl \
        $(WebCore)/html/ValidityState.idl \
@@ -2532,6 +2535,8 @@ webcore_sources += \
        Source/WebCore/html/RadioInputType.h \
        Source/WebCore/html/RangeInputType.cpp \
        Source/WebCore/html/RangeInputType.h \
+       Source/WebCore/html/RadioNodeList.cpp \
+       Source/WebCore/html/RadioNodeList.h \
        Source/WebCore/html/ResetInputType.cpp \
        Source/WebCore/html/ResetInputType.h \
        Source/WebCore/html/SearchInputType.cpp \
index 378ece8..e47a335 100644 (file)
@@ -832,6 +832,7 @@ SOURCES += \
     html/PasswordInputType.cpp \
     html/PluginDocument.cpp \
     html/RadioInputType.cpp \
+    html/RadioNodeList.cpp \
     html/RangeInputType.cpp \
     html/ResetInputType.cpp \
     html/SearchInputType.cpp \
@@ -1974,6 +1975,7 @@ HEADERS += \
     html/MicroDataItemValue.h \
     html/PluginDocument.h \
     html/PublicURLManager.h \
+    html/RadioNodeList.h \
     html/StepRange.h \
     html/TextDocument.h \
     html/TimeRanges.h \
index 7630abf..18574ab 100644 (file)
             'html/MediaError.idl',
             'html/MediaKeyError.idl',
             'html/MediaKeyEvent.idl',
+            'html/RadioNodeList.idl',
             'html/TextMetrics.idl',
             'html/TimeRanges.idl',
             'html/ValidityState.idl',
             'html/PublicURLManager.h',
             'html/RadioInputType.cpp',
             'html/RadioInputType.h',
+            'html/RadioNodeList.cpp',
+            'html/RadioNodeList.h',
             'html/RangeInputType.cpp',
             'html/RangeInputType.h',
             'html/ResetInputType.cpp',
index 675f41d..0ace54d 100755 (executable)
                                >
                        </File>
                        <File
+                               RelativePath="$(ConfigurationBuildDir)\obj\$(ProjectName)\DerivedSources\JSRadioNodeList.cpp"
+                               >
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       ExcludedFromBuild="true"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       ExcludedFromBuild="true"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug_Cairo_CFLite|Win32"
+                                       ExcludedFromBuild="true"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release_Cairo_CFLite|Win32"
+                                       ExcludedFromBuild="true"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug_All|Win32"
+                                       ExcludedFromBuild="true"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Production|Win32"
+                                       ExcludedFromBuild="true"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                       />
+                               </FileConfiguration>
+                       </File>
+                       <File
+                               RelativePath="$(ConfigurationBuildDir)\obj\$(ProjectName)\DerivedSources\JSRadioNodeList.h"
+                               >
+                       </File>
+                       <File
                                RelativePath="$(ConfigurationBuildDir)\obj\$(ProjectName)\DerivedSources\JSRange.cpp"
                                >
                                <FileConfiguration
                                >
                        </File>
                        <File
+                               RelativePath="..\html\RadioNodeList.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\html\RadioNodeList.h"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\html\RangeInputType.cpp"
                                >
                        </File>
index d178682..9eeac8e 100644 (file)
                B5D31DFB11CF610B009F22B4 /* ActiveDOMCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = B5D31DF911CF610B009F22B4 /* ActiveDOMCallback.h */; };
                B6566270120B1227006EA85C /* JSIDBTransaction.h in Headers */ = {isa = PBXBuildFile; fileRef = B656626E120B1227006EA85C /* JSIDBTransaction.h */; };
                B6566271120B1227006EA85C /* JSIDBTransaction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B656626F120B1227006EA85C /* JSIDBTransaction.cpp */; };
+               B658FFA11522EF3A00DD5595 /* JSRadioNodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B658FF9F1522EF3A00DD5595 /* JSRadioNodeList.cpp */; };
+               B658FFA21522EF3A00DD5595 /* JSRadioNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = B658FFA01522EF3A00DD5595 /* JSRadioNodeList.h */; };
+               B658FFA51522EFAA00DD5595 /* RadioNodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B658FFA31522EFAA00DD5595 /* RadioNodeList.cpp */; };
+               B658FFA61522EFAA00DD5595 /* RadioNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = B658FFA41522EFAA00DD5595 /* RadioNodeList.h */; };
                B71FE6DF11091CB300DAEF77 /* PrintContext.h in Headers */ = {isa = PBXBuildFile; fileRef = B776D43A1104525D00BEB0EC /* PrintContext.h */; settings = {ATTRIBUTES = (Private, ); }; };
                B734B181119B9911006587BD /* FontTranscoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B734B180119B9911006587BD /* FontTranscoder.cpp */; };
                B734B183119B991D006587BD /* FontTranscoder.h in Headers */ = {isa = PBXBuildFile; fileRef = B734B182119B991D006587BD /* FontTranscoder.h */; };
                B5D31DF911CF610B009F22B4 /* ActiveDOMCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ActiveDOMCallback.h; path = generic/ActiveDOMCallback.h; sourceTree = "<group>"; };
                B656626E120B1227006EA85C /* JSIDBTransaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSIDBTransaction.h; sourceTree = "<group>"; };
                B656626F120B1227006EA85C /* JSIDBTransaction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBTransaction.cpp; sourceTree = "<group>"; };
+               B658FF9F1522EF3A00DD5595 /* JSRadioNodeList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSRadioNodeList.cpp; sourceTree = "<group>"; };
+               B658FFA01522EF3A00DD5595 /* JSRadioNodeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSRadioNodeList.h; sourceTree = "<group>"; };
+               B658FFA31522EFAA00DD5595 /* RadioNodeList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RadioNodeList.cpp; sourceTree = "<group>"; };
+               B658FFA41522EFAA00DD5595 /* RadioNodeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RadioNodeList.h; sourceTree = "<group>"; };
                B734B180119B9911006587BD /* FontTranscoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FontTranscoder.cpp; path = transcoder/FontTranscoder.cpp; sourceTree = "<group>"; };
                B734B182119B991D006587BD /* FontTranscoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FontTranscoder.h; path = transcoder/FontTranscoder.h; sourceTree = "<group>"; };
                B776D43A1104525D00BEB0EC /* PrintContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrintContext.h; sourceTree = "<group>"; };
                93EEC1EC09C2877700C515D1 /* html */ = {
                        isa = PBXGroup;
                        children = (
+                               B658FFA31522EFAA00DD5595 /* RadioNodeList.cpp */,
+                               B658FFA41522EFAA00DD5595 /* RadioNodeList.h */,
                                49484FAE102CF01E00187DD3 /* canvas */,
                                97C1F5511228558800EDE616 /* parser */,
                                4150F9ED12B6E0990008C860 /* shadow */,
                A83B79080CCAFF2B000B0825 /* HTML */ = {
                        isa = PBXGroup;
                        children = (
+                               B658FF9F1522EF3A00DD5595 /* JSRadioNodeList.cpp */,
+                               B658FFA01522EF3A00DD5595 /* JSRadioNodeList.h */,
                                49EECEF2105070C400099FAB /* JSArrayBuffer.cpp */,
                                49EECEF3105070C400099FAB /* JSArrayBuffer.h */,
                                49EECF19105072F300099FAB /* JSArrayBufferView.cpp */,
                                FD629EA3154B47160006D026 /* AudioBasicInspectorNode.h in Headers */,
                                31EC1E2914FF60EE00C94662 /* JSNotificationPermissionCallback.h in Headers */,
                                31FE6DFA15004C2A0004EBC4 /* NotificationPermissionCallback.h in Headers */,
+                               B658FFA21522EF3A00DD5595 /* JSRadioNodeList.h in Headers */,
+                               B658FFA61522EFAA00DD5595 /* RadioNodeList.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                FD629EA4154B47160006D026 /* AudioBasicInspectorNode.cpp in Sources */,
                                31EC1E2814FF60EE00C94662 /* JSNotificationPermissionCallback.cpp in Sources */,
                                31FE6E6D1501A3BF0004EBC4 /* JSNotificationCustom.cpp in Sources */,
+                               B658FFA11522EF3A00DD5595 /* JSRadioNodeList.cpp in Sources */,
+                               B658FFA51522EFAA00DD5595 /* RadioNodeList.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 4f5f56c..c62a7dd 100644 (file)
@@ -28,7 +28,9 @@
 #include "JSHTMLOptionsCollection.h"
 #include "JSNode.h"
 #include "JSNodeList.h"
+#include "JSRadioNodeList.h"
 #include "Node.h"
+#include "RadioNodeList.h"
 #include "StaticNodeList.h"
 #include <wtf/Vector.h>
 #include <wtf/text/AtomicString.h>
@@ -40,13 +42,17 @@ namespace WebCore {
 static JSValue getNamedItems(ExecState* exec, JSHTMLCollection* collection, const Identifier& propertyName)
 {
     Vector<RefPtr<Node> > namedItems;
-    collection->impl()->namedItems(identifierToAtomicString(propertyName), namedItems);
+    const AtomicString& name = identifierToAtomicString(propertyName);
+    collection->impl()->namedItems(name, namedItems);
 
     if (namedItems.isEmpty())
         return jsUndefined();
     if (namedItems.size() == 1)
         return toJS(exec, collection->globalObject(), namedItems[0].get());
 
+    if (collection->impl()->type() == FormControls)
+       return toJS(exec, collection->globalObject(), collection->impl()->base()->radioNodeList(name).get());
+
     // FIXME: HTML5 specifies that this should be a DynamicNodeList.
     // FIXME: HTML5 specifies that non-HTMLOptionsCollection collections should return
     // the first matching item instead of a NodeList.
index 2028653..9b1f7c4 100644 (file)
@@ -2223,7 +2223,7 @@ sub GenerateImplementation
             push(@implContent, "    return toJS(exec, thisObj->globalObject(), static_cast<$implClassName*>(thisObj->impl())->item(index));\n");
         }
         push(@implContent, "}\n\n");
-        if ($interfaceName eq "HTMLCollection" or $interfaceName eq "HTMLAllCollection") {
+        if ($interfaceName eq "HTMLCollection" or $interfaceName eq "HTMLAllCollection" or $interfaceName eq "RadioNodeList") {
             $implIncludes{"JSNode.h"} = 1;
             $implIncludes{"Node.h"} = 1;
         }
index 87bfcda..d2416e8 100644 (file)
 #include "V8HTMLCollection.h"
 
 #include "HTMLCollection.h"
+#include "RadioNodeList.h"
 #include "V8Binding.h"
 #include "V8HTMLAllCollection.h"
 #include "V8NamedNodesCollection.h"
 #include "V8Node.h"
 #include "V8NodeList.h"
 #include "V8Proxy.h"
+#include "V8RadioNodeList.h"
 
 namespace WebCore {
 
@@ -52,6 +54,9 @@ static v8::Handle<v8::Value> getNamedItems(HTMLCollection* collection, AtomicStr
     if (namedItems.size() == 1)
         return toV8(namedItems.at(0).release(), isolate);
 
+    if (collection->type() == FormControls)
+        return toV8(collection->base()->radioNodeList(name).get());
+
     return toV8(V8NamedNodesCollection::create(namedItems), isolate);
 }
 
index c644ba1..0b02ce8 100644 (file)
@@ -77,6 +77,7 @@
 #include "PlatformWheelEvent.h"
 #include "ProcessingInstruction.h"
 #include "ProgressEvent.h"
+#include "RadioNodeList.h"
 #include "RegisteredEventListener.h"
 #include "RenderBlock.h"
 #include "RenderBox.h"
@@ -991,6 +992,9 @@ void Node::invalidateNodeListsCacheAfterAttributeChanged(const QualifiedName& at
         && attrName != itempropAttr
         && attrName != itemtypeAttr
 #endif
+        && attrName != idAttr
+        && attrName != typeAttr
+        && attrName != checkedAttr
         && attrName != nameAttr
         && attrName != forAttr)
         return;
@@ -2329,6 +2333,10 @@ void NodeListsNodeData::invalidateCachesThatDependOnAttributes()
     for (MicroDataItemListCache::iterator it = m_microDataItemListCache.begin(); it != itemListCacheEnd; ++it)
         it->second->invalidateCache();
 #endif
+
+    RadioNodeListCache::iterator radioNodeListCacheEnd = m_radioNodeListCache.end();
+    for (RadioNodeListCache::iterator it = m_radioNodeListCache.begin(); it != radioNodeListCacheEnd; ++it)
+        it->second->invalidateCache();
 }
 
 bool NodeListsNodeData::isEmpty() const
@@ -2351,7 +2359,10 @@ bool NodeListsNodeData::isEmpty() const
 
     if (m_labelsNodeListCache)
         return false;
-    
+
+    if (!m_radioNodeListCache.isEmpty())
+        return false;
+
     return true;
 }
 
@@ -2958,6 +2969,31 @@ void NodeRareData::clearChildNodeListCache()
         m_childNodeList->invalidateCache();
 }
 
+PassRefPtr<RadioNodeList> Node::radioNodeList(const AtomicString& name)
+{
+    ASSERT(hasTagName(formTag));
+
+    NodeListsNodeData* nodeLists = ensureRareData()->ensureNodeLists(this);
+
+    NodeListsNodeData::RadioNodeListCache::AddResult result = nodeLists->m_radioNodeListCache.add(name, 0);
+    if (!result.isNewEntry)
+        return PassRefPtr<RadioNodeList>(result.iterator->second);
+
+    RefPtr<RadioNodeList> list = RadioNodeList::create(name, toElement(this));
+    result.iterator->second = list.get();
+    return list.release();
+}
+
+void Node::removeCachedRadioNodeList(RadioNodeList* list, const AtomicString& name)
+{
+    ASSERT(rareData());
+    ASSERT(rareData()->nodeLists());
+
+    NodeListsNodeData* data = rareData()->nodeLists();
+    ASSERT_UNUSED(list, list == data->m_radioNodeListCache.get(name));
+    data->m_radioNodeListCache.remove(name);
+}
+
 } // namespace WebCore
 
 #ifndef NDEBUG
index bd78271..e8ffdc1 100644 (file)
@@ -75,6 +75,7 @@ class PlatformKeyboardEvent;
 class PlatformMouseEvent;
 class PlatformWheelEvent;
 class QualifiedName;
+class RadioNodeList;
 class RegisteredEventListener;
 class RenderArena;
 class RenderBox;
@@ -562,6 +563,9 @@ public:
 
     void removeCachedChildNodeList();
 
+    PassRefPtr<RadioNodeList> radioNodeList(const AtomicString&);
+    void removeCachedRadioNodeList(RadioNodeList*, const AtomicString&);
+
     PassRefPtr<NodeList> getElementsByTagName(const AtomicString&);
     PassRefPtr<NodeList> getElementsByTagNameNS(const AtomicString& namespaceURI, const AtomicString& localName);
     PassRefPtr<NodeList> getElementsByName(const String& elementName);
index fc17f2d..eaef9a5 100644 (file)
@@ -45,6 +45,7 @@
 namespace WebCore {
 
 class LabelsNodeList;
+class RadioNodeList;
 class TreeScope;
 
 struct NodeListsNodeData {
@@ -72,6 +73,9 @@ public:
 
     LabelsNodeList* m_labelsNodeListCache;
 
+    typedef HashMap<String, RadioNodeList*> RadioNodeListCache;
+    RadioNodeListCache m_radioNodeListCache;
+
     static PassOwnPtr<NodeListsNodeData> create()
     {
         return adoptPtr(new NodeListsNodeData);
index 4ed9819..5bed4d8 100644 (file)
@@ -59,6 +59,7 @@ enum CollectionType {
     ItemProperties, // Microdata item properties in the document
 #endif
 
+    FormControls,
     OtherCollection
 };
 
index 1b9cc31..a908da0 100644 (file)
@@ -67,6 +67,7 @@ bool HTMLCollection::shouldIncludeChildren(CollectionType type)
 #if ENABLE(MICRODATA)
     case ItemProperties:
 #endif
+    case FormControls:
         return true;
     case NodeChildren:
     case TRCells:
@@ -151,6 +152,7 @@ inline bool HTMLCollection::isAcceptableElement(Element* element) const
     case ItemProperties:
         return element->fastHasAttribute(itempropAttr);
 #endif
+    case FormControls:
     case DocumentNamedItems:
     case OtherCollection:
     case WindowNamedItems:
index 684e3a5..c688d8d 100644 (file)
@@ -36,7 +36,7 @@ using namespace HTMLNames;
 // calculation every time if anything has changed.
 
 HTMLFormCollection::HTMLFormCollection(HTMLFormElement* form)
-    : HTMLCollection(form, OtherCollection)
+    : HTMLCollection(form, FormControls)
     , currentPos(0)
 {
 }
diff --git a/Source/WebCore/html/RadioNodeList.cpp b/Source/WebCore/html/RadioNodeList.cpp
new file mode 100644 (file)
index 0000000..b72a3d4
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2012 Motorola Mobility, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MOTOROLA MOBILITY, INC. AND ITS CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY, INC. OR ITS
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "RadioNodeList.h"
+
+#include "Element.h"
+#include "HTMLFormElement.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+RadioNodeList::RadioNodeList(const AtomicString& name, Element* formElement)
+    : DynamicSubtreeNodeList(formElement->document())
+    , m_name(name)
+    , m_formElement(formElement)
+{
+    m_formElement->document()->registerDynamicSubtreeNodeList(this);
+}
+
+RadioNodeList::~RadioNodeList()
+{
+    m_formElement->removeCachedRadioNodeList(this, m_name);
+    m_formElement->document()->unregisterDynamicSubtreeNodeList(this);
+}
+
+static inline HTMLInputElement* toRadioButtonInputElement(Node* node)
+{
+    ASSERT(node->isElementNode());
+    HTMLInputElement* inputElement = node->toInputElement();
+    if (!inputElement || !inputElement->isRadioButton() || inputElement->value().isEmpty())
+        return 0;
+    return inputElement;
+}
+
+String RadioNodeList::value() const
+{
+    for (unsigned i = 0; i < length(); ++i) {
+        Node* node = item(i);
+        const HTMLInputElement* inputElement = toRadioButtonInputElement(node);
+        if (!inputElement || !inputElement->checked())
+            continue;
+        return inputElement->value();
+    }
+    return String();
+}
+
+void RadioNodeList::setValue(const String& value)
+{
+    for (unsigned i = 0; i < length(); ++i) {
+        Node* node = item(i);
+        HTMLInputElement* inputElement = toRadioButtonInputElement(node);
+        if (!inputElement || inputElement->value() != value)
+            continue;
+        inputElement->setChecked(true);
+        return;
+    }
+}
+
+bool RadioNodeList::nodeMatches(Element* testElement) const
+{
+    if (!testElement->isFormControlElement())
+        return false;
+
+    HTMLFormElement* formElement = static_cast<HTMLFormControlElement*>(testElement)->form();
+    if (!formElement || formElement != m_formElement)
+        return false;
+
+    if (HTMLInputElement* inputElement = testElement->toInputElement()) {
+        if (inputElement->isImageButton())
+            return false;
+    }
+
+    return equalIgnoringCase(testElement->getIdAttribute(), m_name) || equalIgnoringCase(testElement->getNameAttribute(), m_name);
+}
+
+} // namspace
+
diff --git a/Source/WebCore/html/RadioNodeList.h b/Source/WebCore/html/RadioNodeList.h
new file mode 100644 (file)
index 0000000..ebde797
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2012 Motorola Mobility, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MOTOROLA MOBILITY, INC. AND ITS CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY, INC. OR ITS
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RadioNodeList_h
+#define RadioNodeList_h
+
+#include "DynamicNodeList.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+#include <wtf/text/AtomicString.h>
+
+namespace WebCore {
+
+class RadioNodeList : public DynamicSubtreeNodeList {
+public:
+    static PassRefPtr<RadioNodeList> create(const AtomicString& name, Element* formElement)
+    {
+        return adoptRef(new RadioNodeList(name, formElement));
+    }
+
+    ~RadioNodeList();
+
+    String value() const;
+    void setValue(const String&);
+
+protected:
+    virtual bool nodeMatches(Element*) const;
+
+private:
+    RadioNodeList(const AtomicString& name, Element*);
+
+    AtomicString m_name;
+    RefPtr<Element> m_formElement;
+};
+
+} // namepsace
+
+#endif
+
diff --git a/Source/WebCore/html/RadioNodeList.idl b/Source/WebCore/html/RadioNodeList.idl
new file mode 100644 (file)
index 0000000..8ed57ba
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012 Motorola Mobility, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MOTOROLA MOBILITY, INC. AND ITS CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY, INC. OR ITS
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+
+    interface [
+        JSGenerateToJSObject,
+        IndexedGetter,
+    ] RadioNodeList : NodeList {
+        attribute DOMString value;
+    };
+}
+