Diff
Modified: trunk/LayoutTests/ChangeLog (236777 => 236778)
--- trunk/LayoutTests/ChangeLog 2018-10-03 00:25:10 UTC (rev 236777)
+++ trunk/LayoutTests/ChangeLog 2018-10-03 00:26:41 UTC (rev 236778)
@@ -1,3 +1,20 @@
+2018-10-02 Chris Dumez <[email protected]>
+
+ fieldset.elements should return an HTMLCollection instead of an HTMLFormControlsCollection
+ https://bugs.webkit.org/show_bug.cgi?id=190218
+
+ Reviewed by Alex Christensen.
+
+ Update existing tests to reflect behavior change, after checking that our behavior is consistent
+ with Gecko and Blink on these tests.
+
+ * fast/forms/fieldset/fieldset-elements-expected.txt:
+ * fast/forms/fieldset/fieldset-elements-htmlcollection-expected.txt: Added.
+ * fast/forms/fieldset/fieldset-elements-htmlcollection.html: Added.
+ * fast/forms/fieldset/fieldset-elements.html:
+ * fast/forms/fieldset/fieldset-form-collection-radionode-list-expected.txt: Removed.
+ * fast/forms/fieldset/fieldset-form-collection-radionode-list.html: Removed.
+
2018-10-02 Devin Rousso <[email protected]>
Web Inspector: prevent layer events from firing until the layer information is re-requested
Modified: trunk/LayoutTests/fast/forms/fieldset/fieldset-elements-expected.txt (236777 => 236778)
--- trunk/LayoutTests/fast/forms/fieldset/fieldset-elements-expected.txt 2018-10-03 00:25:10 UTC (rev 236777)
+++ trunk/LayoutTests/fast/forms/fieldset/fieldset-elements-expected.txt 2018-10-03 00:26:41 UTC (rev 236778)
@@ -3,7 +3,7 @@
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-PASS owner.elements.length is 23
+PASS owner.elements.length is 24
PASS owner.elements[0].id is 'button1'
PASS owner.elements[1].id is 'fieldset1'
PASS owner.elements[2].id is 'inputhidden'
@@ -20,29 +20,30 @@
PASS owner.elements[13].id is 'inputradio'
PASS owner.elements[14].id is 'inputfile'
PASS owner.elements[15].id is 'inputsubmit'
-PASS owner.elements[16].id is 'inputreset'
-PASS owner.elements[17].id is 'inputbutton'
-PASS owner.elements[18].id is 'keygen1'
-PASS owner.elements[19].id is 'object1'
-PASS owner.elements[20].id is 'output1'
-PASS owner.elements[21].id is 'select1'
-PASS owner.elements[22].id is 'textarea1'
+PASS owner.elements[16].id is 'inputimage'
+PASS owner.elements[17].id is 'inputreset'
+PASS owner.elements[18].id is 'inputbutton'
+PASS owner.elements[19].id is 'keygen1'
+PASS owner.elements[20].id is 'object1'
+PASS owner.elements[21].id is 'output1'
+PASS owner.elements[22].id is 'select1'
+PASS owner.elements[23].id is 'textarea1'
Check elements array is updated after adding a new element
-PASS owner.appendChild(newElement); owner.elements.length is 24
+PASS owner.appendChild(newElement); owner.elements.length is 25
Check elements array is updated after remove an element
-PASS owner.removeChild(newElement); owner.elements.length is 23
+PASS owner.removeChild(newElement); owner.elements.length is 24
Check owner.elements is updated properly
-PASS document.getElementById("inputfile").type="image"; owner.elements.length is 22
+PASS document.getElementById("inputfile").type="image"; owner.elements.length is 24
Check owner.elements is updated properly after removing from parent
PASS form.appendChild(newElement); form.elements.length is 1
PASS form.removeChild(newElement); form.elements.length is 0
-PASS owner.elements.length is 22
-PASS owner.appendChild(newElement); owner.elements.length is 23
-PASS owner.removeChild(newElement); owner.elements.length is 22
+PASS owner.elements.length is 24
+PASS owner.appendChild(newElement); owner.elements.length is 25
+PASS owner.removeChild(newElement); owner.elements.length is 24
PASS successfullyParsed is true
TEST COMPLETE
Added: trunk/LayoutTests/fast/forms/fieldset/fieldset-elements-htmlcollection-expected.txt (0 => 236778)
--- trunk/LayoutTests/fast/forms/fieldset/fieldset-elements-htmlcollection-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/forms/fieldset/fieldset-elements-htmlcollection-expected.txt 2018-10-03 00:26:41 UTC (rev 236778)
@@ -0,0 +1,17 @@
+This test that fieldset.elements attribute returns an HTMLCollection and not an HTMLFormControlsCollection.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+
+
+PASS elementsList instanceof HTMLCollection is true
+PASS elementsList instanceof HTMLFormControlsCollection is false
+PASS elementsList.length is 24
+PASS inputcommonElement instanceof RadioNodeList is false
+PASS inputcommonElement instanceof HTMLInputElement is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/forms/fieldset/fieldset-elements-htmlcollection.html (0 => 236778)
--- trunk/LayoutTests/fast/forms/fieldset/fieldset-elements-htmlcollection.html (rev 0)
+++ trunk/LayoutTests/fast/forms/fieldset/fieldset-elements-htmlcollection.html 2018-10-03 00:26:41 UTC (rev 236778)
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<p id="description"></p>
+<div id="divId">
+<form>
+<fieldset id="fs">
+ <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>
+</fieldset>
+</form>
+</div>
+<div id="console"></div>
+<script>
+description("This test that fieldset.elements attribute returns an HTMLCollection and not an HTMLFormControlsCollection.");
+debug("");
+var owner = document.getElementById('fs');
+
+var elementsList = owner.elements;
+shouldBeTrue('elementsList instanceof HTMLCollection');
+shouldBeFalse('elementsList instanceof HTMLFormControlsCollection');
+
+shouldBe('elementsList.length', '24');
+
+var inputcommonElement = elementsList.namedItem("inputcommon");
+shouldBeFalse('inputcommonElement instanceof RadioNodeList');
+shouldBeTrue('inputcommonElement instanceof HTMLInputElement');
+</script>
+<script src=""
+</body>
+</html>
Modified: trunk/LayoutTests/fast/forms/fieldset/fieldset-elements.html (236777 => 236778)
--- trunk/LayoutTests/fast/forms/fieldset/fieldset-elements.html 2018-10-03 00:25:10 UTC (rev 236777)
+++ trunk/LayoutTests/fast/forms/fieldset/fieldset-elements.html 2018-10-03 00:26:41 UTC (rev 236778)
@@ -46,7 +46,7 @@
var owner = document.getElementById('fs');
-shouldBe('owner.elements.length', '23');
+shouldBe('owner.elements.length', '24');
shouldBe('owner.elements[0].id', "'button1'");
shouldBe('owner.elements[1].id', "'fieldset1'");
shouldBe('owner.elements[2].id', "'inputhidden'");
@@ -63,13 +63,14 @@
shouldBe('owner.elements[13].id', "'inputradio'");
shouldBe('owner.elements[14].id', "'inputfile'");
shouldBe('owner.elements[15].id', "'inputsubmit'");
-shouldBe('owner.elements[16].id', "'inputreset'");
-shouldBe('owner.elements[17].id', "'inputbutton'");
-shouldBe('owner.elements[18].id', "'keygen1'");
-shouldBe('owner.elements[19].id', "'object1'");
-shouldBe('owner.elements[20].id', "'output1'");
-shouldBe('owner.elements[21].id', "'select1'");
-shouldBe('owner.elements[22].id', "'textarea1'");
+shouldBe('owner.elements[16].id', "'inputimage'");
+shouldBe('owner.elements[17].id', "'inputreset'");
+shouldBe('owner.elements[18].id', "'inputbutton'");
+shouldBe('owner.elements[19].id', "'keygen1'");
+shouldBe('owner.elements[20].id', "'object1'");
+shouldBe('owner.elements[21].id', "'output1'");
+shouldBe('owner.elements[22].id', "'select1'");
+shouldBe('owner.elements[23].id', "'textarea1'");
var newElement = document.createElement("input");
newElement.setAttribute("type", "text");
@@ -78,15 +79,15 @@
debug("");
debug("Check elements array is updated after adding a new element");
-shouldBe('owner.appendChild(newElement); owner.elements.length', '24');
+shouldBe('owner.appendChild(newElement); owner.elements.length', '25');
debug("");
debug("Check elements array is updated after remove an element");
-shouldBe('owner.removeChild(newElement); owner.elements.length', '23');
+shouldBe('owner.removeChild(newElement); owner.elements.length', '24');
debug("");
debug("Check owner.elements is updated properly");
-shouldBe('document.getElementById("inputfile").type="image"; owner.elements.length', '22');
+shouldBe('document.getElementById("inputfile").type="image"; owner.elements.length', '24');
debug("");
debug("Check owner.elements is updated properly after removing from parent");
@@ -94,9 +95,9 @@
var form = document.getElementById("formElement");
shouldBe('form.appendChild(newElement); form.elements.length', '1');
shouldBe('form.removeChild(newElement); form.elements.length', '0');
-shouldBe('owner.elements.length', '22');
-shouldBe('owner.appendChild(newElement); owner.elements.length', '23');
-shouldBe('owner.removeChild(newElement); owner.elements.length', '22');
+shouldBe('owner.elements.length', '24');
+shouldBe('owner.appendChild(newElement); owner.elements.length', '25');
+shouldBe('owner.removeChild(newElement); owner.elements.length', '24');
container.parentNode.removeChild(container);
</script>
Deleted: trunk/LayoutTests/fast/forms/fieldset/fieldset-form-collection-radionode-list-expected.txt (236777 => 236778)
--- trunk/LayoutTests/fast/forms/fieldset/fieldset-form-collection-radionode-list-expected.txt 2018-10-03 00:25:10 UTC (rev 236777)
+++ trunk/LayoutTests/fast/forms/fieldset/fieldset-form-collection-radionode-list-expected.txt 2018-10-03 00:26:41 UTC (rev 236778)
@@ -1,53 +0,0 @@
-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 owner.elements.length is 24
-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 change in id, type and checked state of an element
-PASS radioNodeList.length is 4
-After changing the id
-PASS radioNodeList.length is 3
-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
-
Deleted: trunk/LayoutTests/fast/forms/fieldset/fieldset-form-collection-radionode-list.html (236777 => 236778)
--- trunk/LayoutTests/fast/forms/fieldset/fieldset-form-collection-radionode-list.html 2018-10-03 00:25:10 UTC (rev 236777)
+++ trunk/LayoutTests/fast/forms/fieldset/fieldset-form-collection-radionode-list.html 2018-10-03 00:26:41 UTC (rev 236778)
@@ -1,120 +0,0 @@
-<!DOCTYPE html>
-<html>
-<body>
-<script src=""
-<p id="description"></p>
-<div id="divId">
-<form>
-<fieldset id="fs">
- <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>
-</fieldset>
-</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('fs');
-
-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('owner.elements.length', '24');
-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'");
-
-debug("");
-debug("Check RadioNodeList is updated after change in id, type and checked state of an element");
-shouldBe('radioNodeList.length', '4');
-debug("After changing the id");
-radioNodeList[3].id = "changedName";
-shouldBe('radioNodeList.length', '3');
-
-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("");
-
-var container = document.getElementById("divId");
-container.parentNode.removeChild(container);
-</script>
-<script src=""
-</body>
-</html>
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (236777 => 236778)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2018-10-03 00:25:10 UTC (rev 236777)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2018-10-03 00:26:41 UTC (rev 236778)
@@ -1,5 +1,16 @@
2018-10-02 Chris Dumez <[email protected]>
+ fieldset.elements should return an HTMLCollection instead of an HTMLFormControlsCollection
+ https://bugs.webkit.org/show_bug.cgi?id=190218
+
+ Reviewed by Alex Christensen.
+
+ Rebaseline existing WPT test now that it is passing.
+
+ * web-platform-tests/html/semantics/forms/the-fieldset-element/HTMLFieldSetElement-expected.txt:
+
+2018-10-02 Chris Dumez <[email protected]>
+
Refresh imported/w3c/web-platform-tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh
https://bugs.webkit.org/show_bug.cgi?id=190212
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-fieldset-element/HTMLFieldSetElement-expected.txt (236777 => 236778)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-fieldset-element/HTMLFieldSetElement-expected.txt 2018-10-03 00:25:10 UTC (rev 236777)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-fieldset-element/HTMLFieldSetElement-expected.txt 2018-10-03 00:26:41 UTC (rev 236778)
@@ -1,10 +1,6 @@
PASS The type attribute must return 'fieldset'
PASS The form attribute must return the fieldset's form owner
-FAIL The elements must return an HTMLCollection object assert_equals: The elements attribute should be an HTMLCollection object expected function "function HTMLCollection() {
- [native code]
-}" but got function "function HTMLFormControlsCollection() {
- [native code]
-}"
+PASS The elements must return an HTMLCollection object
PASS The controls must root at the fieldset element
Modified: trunk/Source/WebCore/ChangeLog (236777 => 236778)
--- trunk/Source/WebCore/ChangeLog 2018-10-03 00:25:10 UTC (rev 236777)
+++ trunk/Source/WebCore/ChangeLog 2018-10-03 00:26:41 UTC (rev 236778)
@@ -1,3 +1,38 @@
+2018-10-02 Chris Dumez <[email protected]>
+
+ fieldset.elements should return an HTMLCollection instead of an HTMLFormControlsCollection
+ https://bugs.webkit.org/show_bug.cgi?id=190218
+
+ Reviewed by Alex Christensen.
+
+ fieldset.elements should return an HTMLCollection instead of an HTMLFormControlsCollection:
+ - https://github.com/whatwg/html/commit/8beedf0c2ffd38853caddec67490288f47afc8eb
+
+ Gecko has always behaved this way. Blink aligned with Gecko and the HTML specification in December 2016:
+ - https://bugs.chromium.org/p/chromium/issues/detail?id=665291
+
+ This simplifies our HTMLFieldSetElement code a lot.
+
+ Test: fast/forms/fieldset/fieldset-elements-htmlcollection.html
+
+ * html/CollectionType.h:
+ * html/GenericCachedHTMLCollection.cpp:
+ (WebCore::GenericCachedHTMLCollection<traversalType>::elementMatches const):
+ * html/HTMLCollection.cpp:
+ (WebCore::HTMLCollection::rootTypeFromCollectionType):
+ (WebCore::invalidationTypeExcludingIdAndNameAttributes):
+ * html/HTMLFieldSetElement.cpp:
+ (WebCore::HTMLFieldSetElement::elements):
+ * html/HTMLFieldSetElement.h:
+ * html/HTMLFieldSetElement.idl:
+ * html/HTMLFormControlsCollection.cpp:
+ (WebCore::HTMLFormControlsCollection::HTMLFormControlsCollection):
+ (WebCore:: const):
+ (WebCore::HTMLFormControlsCollection::copyFormControlElementsVector const):
+ (WebCore::HTMLFormControlsCollection::ownerNode const):
+ (WebCore::HTMLFormControlsCollection::updateNamedElementCache const):
+ * html/HTMLFormControlsCollection.h:
+
2018-10-02 Devin Rousso <[email protected]>
Web Inspector: prevent layer events from firing until the layer information is re-requested
Modified: trunk/Source/WebCore/html/CollectionType.h (236777 => 236778)
--- trunk/Source/WebCore/html/CollectionType.h 2018-10-03 00:25:10 UTC (rev 236777)
+++ trunk/Source/WebCore/html/CollectionType.h 2018-10-03 00:26:41 UTC (rev 236778)
@@ -52,6 +52,7 @@
DataListOptions,
MapAreas,
FormControls,
+ FieldSetElements,
ByClass,
ByTag,
ByHTMLTag,
Modified: trunk/Source/WebCore/html/GenericCachedHTMLCollection.cpp (236777 => 236778)
--- trunk/Source/WebCore/html/GenericCachedHTMLCollection.cpp 2018-10-03 00:25:10 UTC (rev 236777)
+++ trunk/Source/WebCore/html/GenericCachedHTMLCollection.cpp 2018-10-03 00:26:41 UTC (rev 236778)
@@ -27,6 +27,7 @@
#include "GenericCachedHTMLCollection.h"
#include "HTMLAppletElement.h"
+#include "HTMLFieldSetElement.h"
#include "HTMLNames.h"
#include "HTMLObjectElement.h"
#include "HTMLOptionElement.h"
@@ -72,6 +73,8 @@
return (element.hasTagName(aTag) || element.hasTagName(areaTag)) && element.hasAttributeWithoutSynchronization(hrefAttr);
case DocAnchors:
return element.hasTagName(aTag) && element.hasAttributeWithoutSynchronization(nameAttr);
+ case FieldSetElements:
+ return is<HTMLObjectElement>(element) || is<HTMLFormControlElement>(element);
case ByClass:
case ByTag:
case ByHTMLTag:
Modified: trunk/Source/WebCore/html/HTMLCollection.cpp (236777 => 236778)
--- trunk/Source/WebCore/html/HTMLCollection.cpp 2018-10-03 00:25:10 UTC (rev 236777)
+++ trunk/Source/WebCore/html/HTMLCollection.cpp 2018-10-03 00:26:41 UTC (rev 236778)
@@ -51,6 +51,7 @@
case ByClass:
case ByTag:
case ByHTMLTag:
+ case FieldSetElements:
case NodeChildren:
case TableTBodies:
case TSectionRows:
@@ -100,6 +101,7 @@
case DocumentNamedItems:
case DocumentAllNamedItems:
return InvalidateOnIdNameAttrChange;
+ case FieldSetElements:
case FormControls:
return InvalidateForFormControls;
}
Modified: trunk/Source/WebCore/html/HTMLFieldSetElement.cpp (236777 => 236778)
--- trunk/Source/WebCore/html/HTMLFieldSetElement.cpp 2018-10-03 00:25:10 UTC (rev 236777)
+++ trunk/Source/WebCore/html/HTMLFieldSetElement.cpp 2018-10-03 00:26:41 UTC (rev 236778)
@@ -26,6 +26,7 @@
#include "HTMLFieldSetElement.h"
#include "ElementIterator.h"
+#include "GenericCachedHTMLCollection.h"
#include "HTMLFormControlsCollection.h"
#include "HTMLLegendElement.h"
#include "HTMLNames.h"
@@ -167,60 +168,11 @@
return const_cast<HTMLLegendElement*>(childrenOfType<HTMLLegendElement>(*this).first());
}
-Ref<HTMLFormControlsCollection> HTMLFieldSetElement::elements()
+Ref<HTMLCollection> HTMLFieldSetElement::elements()
{
- return ensureRareData().ensureNodeLists().addCachedCollection<HTMLFormControlsCollection>(*this, FormControls);
+ return ensureRareData().ensureNodeLists().addCachedCollection<GenericCachedHTMLCollection<CollectionTypeTraits<FieldSetElements>::traversalType>>(*this, FieldSetElements);
}
-Ref<HTMLCollection> HTMLFieldSetElement::elementsForNativeBindings()
-{
- return elements();
-}
-
-void HTMLFieldSetElement::updateAssociatedElements() const
-{
- uint64_t documentVersion = document().domTreeVersion();
- if (m_documentVersion == documentVersion)
- return;
-
- m_documentVersion = documentVersion;
-
- m_associatedElements.clear();
-
- for (auto& element : descendantsOfType<HTMLElement>(const_cast<HTMLFieldSetElement&>(*this))) {
- if (is<HTMLObjectElement>(element))
- m_associatedElements.append(&downcast<HTMLObjectElement>(element));
- else if (is<HTMLFormControlElement>(element))
- m_associatedElements.append(&downcast<HTMLFormControlElement>(element));
- }
-}
-
-Vector<Ref<FormAssociatedElement>> HTMLFieldSetElement::copyAssociatedElementsVector() const
-{
- updateAssociatedElements();
- return WTF::map(m_associatedElements, [] (auto* rawElement) {
- return Ref<FormAssociatedElement>(*rawElement);
- });
-}
-
-const Vector<FormAssociatedElement*>& HTMLFieldSetElement::unsafeAssociatedElements() const
-{
- ASSERT(!ScriptDisallowedScope::InMainThread::isScriptAllowed());
- updateAssociatedElements();
- return m_associatedElements;
-}
-
-unsigned HTMLFieldSetElement::length() const
-{
- ScriptDisallowedScope::InMainThread scriptDisallowedScope;
- unsigned length = 0;
- for (auto* element : unsafeAssociatedElements()) {
- if (element->isEnumeratable())
- ++length;
- }
- return length;
-}
-
void HTMLFieldSetElement::addInvalidDescendant(const HTMLFormControlElement& invalidFormControlElement)
{
ASSERT_WITH_MESSAGE(!is<HTMLFieldSetElement>(invalidFormControlElement), "FieldSet are never candidates for constraint validation.");
Modified: trunk/Source/WebCore/html/HTMLFieldSetElement.h (236777 => 236778)
--- trunk/Source/WebCore/html/HTMLFieldSetElement.h 2018-10-03 00:25:10 UTC (rev 236777)
+++ trunk/Source/WebCore/html/HTMLFieldSetElement.h 2018-10-03 00:26:41 UTC (rev 236778)
@@ -38,13 +38,8 @@
HTMLLegendElement* legend() const;
- Ref<HTMLFormControlsCollection> elements();
- Ref<HTMLCollection> elementsForNativeBindings();
+ Ref<HTMLCollection> elements();
- const Vector<FormAssociatedElement*>& unsafeAssociatedElements() const;
- Vector<Ref<FormAssociatedElement>> copyAssociatedElementsVector() const;
- unsigned length() const;
-
void addInvalidDescendant(const HTMLFormControlElement&);
void removeInvalidDescendant(const HTMLFormControlElement&);
@@ -65,11 +60,6 @@
bool matchesValidPseudoClass() const final;
bool matchesInvalidPseudoClass() const final;
- void updateAssociatedElements() const;
-
- mutable Vector<FormAssociatedElement*> m_associatedElements;
- // When the DOM tree is modified, we have to refresh the m_associatedElements array.
- mutable uint64_t m_documentVersion { 0 };
HashSet<const HTMLFormControlElement*> m_invalidDescendants;
bool m_hasDisabledAttribute { false };
};
Modified: trunk/Source/WebCore/html/HTMLFieldSetElement.idl (236777 => 236778)
--- trunk/Source/WebCore/html/HTMLFieldSetElement.idl 2018-10-03 00:25:10 UTC (rev 236777)
+++ trunk/Source/WebCore/html/HTMLFieldSetElement.idl 2018-10-03 00:26:41 UTC (rev 236778)
@@ -24,7 +24,7 @@
readonly attribute DOMString type;
- readonly attribute HTMLFormControlsCollection elements;
+ readonly attribute HTMLCollection elements;
readonly attribute boolean willValidate;
readonly attribute ValidityState validity;
Modified: trunk/Source/WebCore/html/HTMLFormControlsCollection.cpp (236777 => 236778)
--- trunk/Source/WebCore/html/HTMLFormControlsCollection.cpp 2018-10-03 00:25:10 UTC (rev 236777)
+++ trunk/Source/WebCore/html/HTMLFormControlsCollection.cpp 2018-10-03 00:26:41 UTC (rev 236778)
@@ -23,7 +23,6 @@
#include "config.h"
#include "HTMLFormControlsCollection.h"
-#include "HTMLFieldSetElement.h"
#include "HTMLFormElement.h"
#include "HTMLImageElement.h"
#include "HTMLNames.h"
@@ -41,7 +40,7 @@
, m_cachedElement(nullptr)
, m_cachedElementOffsetInArray(0)
{
- ASSERT(is<HTMLFormElement>(ownerNode) || is<HTMLFieldSetElement>(ownerNode));
+ ASSERT(is<HTMLFormElement>(ownerNode));
}
Ref<HTMLFormControlsCollection> HTMLFormControlsCollection::create(ContainerNode& ownerNode, CollectionType)
@@ -65,24 +64,17 @@
const Vector<FormAssociatedElement*>& HTMLFormControlsCollection::unsafeFormControlElements() const
{
- ASSERT(is<HTMLFormElement>(ownerNode()) || is<HTMLFieldSetElement>(ownerNode()));
- if (is<HTMLFormElement>(ownerNode()))
- return downcast<HTMLFormElement>(ownerNode()).unsafeAssociatedElements();
- return downcast<HTMLFieldSetElement>(ownerNode()).unsafeAssociatedElements();
+ return ownerNode().unsafeAssociatedElements();
}
Vector<Ref<FormAssociatedElement>> HTMLFormControlsCollection::copyFormControlElementsVector() const
{
- ASSERT(is<HTMLFormElement>(ownerNode()) || is<HTMLFieldSetElement>(ownerNode()));
- if (is<HTMLFormElement>(ownerNode()))
- return downcast<HTMLFormElement>(ownerNode()).copyAssociatedElementsVector();
- return downcast<HTMLFieldSetElement>(ownerNode()).copyAssociatedElementsVector();
+ return ownerNode().copyAssociatedElementsVector();
}
const Vector<HTMLImageElement*>& HTMLFormControlsCollection::formImageElements() const
{
- ASSERT(is<HTMLFormElement>(ownerNode()));
- return downcast<HTMLFormElement>(ownerNode()).imageElements();
+ return ownerNode().imageElements();
}
static unsigned findFormAssociatedElement(const Vector<FormAssociatedElement*>& elements, const Element& element)
@@ -118,6 +110,11 @@
return nullptr;
}
+HTMLFormElement& HTMLFormControlsCollection::ownerNode() const
+{
+ return downcast<HTMLFormElement>(CachedHTMLCollection<HTMLFormControlsCollection, CollectionTypeTraits<FormControls>::traversalType>::ownerNode());
+}
+
void HTMLFormControlsCollection::updateNamedElementCache() const
{
if (hasNamedElementCache())
@@ -125,7 +122,6 @@
auto cache = std::make_unique<CollectionNamedElementCache>();
- bool ownerIsFormElement = is<HTMLFormElement>(ownerNode());
HashSet<AtomicStringImpl*> foundInputElements;
ScriptDisallowedScope::InMainThread scriptDisallowedScope;
@@ -136,27 +132,24 @@
const AtomicString& id = element.getIdAttribute();
if (!id.isEmpty()) {
cache->appendToIdCache(id, element);
- if (ownerIsFormElement)
- foundInputElements.add(id.impl());
+ foundInputElements.add(id.impl());
}
const AtomicString& name = element.getNameAttribute();
if (!name.isEmpty() && id != name) {
cache->appendToNameCache(name, element);
- if (ownerIsFormElement)
- foundInputElements.add(name.impl());
+ foundInputElements.add(name.impl());
}
}
}
- if (ownerIsFormElement) {
- for (auto* elementPtr : formImageElements()) {
- HTMLImageElement& element = *elementPtr;
- const AtomicString& id = element.getIdAttribute();
- if (!id.isEmpty() && !foundInputElements.contains(id.impl()))
- cache->appendToIdCache(id, element);
- const AtomicString& name = element.getNameAttribute();
- if (!name.isEmpty() && id != name && !foundInputElements.contains(name.impl()))
- cache->appendToNameCache(name, element);
- }
+
+ for (auto* elementPtr : formImageElements()) {
+ HTMLImageElement& element = *elementPtr;
+ const AtomicString& id = element.getIdAttribute();
+ if (!id.isEmpty() && !foundInputElements.contains(id.impl()))
+ cache->appendToIdCache(id, element);
+ const AtomicString& name = element.getNameAttribute();
+ if (!name.isEmpty() && id != name && !foundInputElements.contains(name.impl()))
+ cache->appendToNameCache(name, element);
}
setNamedItemCache(WTFMove(cache));
Modified: trunk/Source/WebCore/html/HTMLFormControlsCollection.h (236777 => 236778)
--- trunk/Source/WebCore/html/HTMLFormControlsCollection.h 2018-10-03 00:25:10 UTC (rev 236777)
+++ trunk/Source/WebCore/html/HTMLFormControlsCollection.h 2018-10-03 00:26:41 UTC (rev 236778)
@@ -23,7 +23,7 @@
#pragma once
#include "CachedHTMLCollection.h"
-#include "HTMLElement.h"
+#include "HTMLFormElement.h"
#include "RadioNodeList.h"
namespace WebCore {
@@ -42,6 +42,8 @@
HTMLElement* item(unsigned offset) const override;
std::optional<Variant<RefPtr<RadioNodeList>, RefPtr<Element>>> namedItemOrItems(const String&) const;
+ HTMLFormElement& ownerNode() const;
+
// For CachedHTMLCollection.
HTMLElement* customElementAfter(Element*) const;