getElementsByTagName() should take a qualifiedName in parameter
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 13 Aug 2016 04:20:30 +0000 (04:20 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 13 Aug 2016 04:20:30 +0000 (04:20 +0000)
https://bugs.webkit.org/show_bug.cgi?id=160682

Reviewed by Ryosuke Niwa.

LayoutTests/imported/w3c:

* web-platform-tests/dom/nodes/Document-getElementsByTagName-expected.txt:
* web-platform-tests/dom/nodes/Document-getElementsByTagName-xhtml-expected.txt:
* web-platform-tests/dom/nodes/Element-getElementsByTagName-expected.txt:
* web-platform-tests/dom/nodes/case-expected.txt:
Rebaseline several W3C tests now that more checks are passing.

* web-platform-tests/dom/nodes/Document-getElementsByTagName-xhtml.xhtml:
Re-sync this test from upstream as it was outdated after:
- https://github.com/w3c/web-platform-tests/pull/3457

Source/WebCore:

getElementsByTagName() should take a qualifiedName in parameter, not a
localName, according to the latest DOM specification:
- https://dom.spec.whatwg.org/#dom-document-getelementsbytagname
- https://dom.spec.whatwg.org/#concept-getelementsbytagname

The new behavior matches Firefox and Edge. There is a slight
compatiblity risk but we should give it a try.

No new tests, rebaselined existing tests.

* WebCore.xcodeproj/project.pbxproj:
* dom/AllDescendantsCollection.h: Added.
* dom/ContainerNode.cpp:
(WebCore::ContainerNode::getElementsByTagName):
(WebCore::ContainerNode::getElementsByTagNameNS):
* dom/Node.cpp:
(WebCore::NodeListsNodeData::invalidateCaches):
* dom/NodeRareData.h:
(WebCore::NodeListsNodeData::addCachedTagCollectionNS):
(WebCore::NodeListsNodeData::removeCachedTagCollectionNS):
(WebCore::NodeListsNodeData::adoptDocument):
(WebCore::NodeListsNodeData::deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList):
* dom/TagCollection.cpp:
(WebCore::makeQualifiedName):
(WebCore::splitQualifiedName):
(WebCore::TagCollectionNS::TagCollectionNS):
(WebCore::TagCollectionNS::~TagCollectionNS):
(WebCore::TagCollection::TagCollection):
(WebCore::TagCollection::~TagCollection):
(WebCore::HTMLTagCollection::HTMLTagCollection):
(WebCore::HTMLTagCollection::~HTMLTagCollection):
* dom/TagCollection.h:
(WebCore::TagCollection::elementMatches):
(WebCore::TagCollectionNS::elementMatches):
(WebCore::HTMLTagCollection::elementMatches):
* html/CollectionType.h:
* html/GenericCachedHTMLCollection.cpp:
(WebCore::GenericCachedHTMLCollection<traversalType>::elementMatches):
* html/HTMLCollection.cpp:
(WebCore::invalidationTypeExcludingIdAndNameAttributes):

LayoutTests:

Update existing tests to reflect behavior change.

* fast/dom/getElementsByClassName/010.xml:
* fast/dom/getElementsByClassName/011.xml:

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

22 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/dom/getElementsByClassName/010.xml
LayoutTests/fast/dom/getElementsByClassName/011.xml
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/dom/nodes/Document-getElementsByTagName-expected.txt
LayoutTests/imported/w3c/web-platform-tests/dom/nodes/Document-getElementsByTagName-xhtml-expected.txt
LayoutTests/imported/w3c/web-platform-tests/dom/nodes/Document-getElementsByTagName-xhtml.xhtml
LayoutTests/imported/w3c/web-platform-tests/dom/nodes/Element-getElementsByTagName-expected.txt
LayoutTests/imported/w3c/web-platform-tests/dom/nodes/case-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/dom/AllDescendantsCollection.h [new file with mode: 0644]
Source/WebCore/dom/ContainerNode.cpp
Source/WebCore/dom/Node.cpp
Source/WebCore/dom/NodeRareData.h
Source/WebCore/dom/TagCollection.cpp
Source/WebCore/dom/TagCollection.h
Source/WebCore/html/CollectionType.h
Source/WebCore/html/GenericCachedHTMLCollection.cpp
Source/WebCore/html/HTMLAllCollection.cpp
Source/WebCore/html/HTMLAllCollection.h
Source/WebCore/html/HTMLCollection.cpp

index b7e97a5..9f76053 100644 (file)
@@ -1,3 +1,15 @@
+2016-08-12  Chris Dumez  <cdumez@apple.com>
+
+        getElementsByTagName() should take a qualifiedName in parameter
+        https://bugs.webkit.org/show_bug.cgi?id=160682
+
+        Reviewed by Ryosuke Niwa.
+
+        Update existing tests to reflect behavior change.
+
+        * fast/dom/getElementsByClassName/010.xml:
+        * fast/dom/getElementsByClassName/011.xml:
+
 2016-08-12  Saam Barati  <sbarati@apple.com>
 
         Inline store loop for CopyRest in DFG and FTL for certain array modes
index 44f8474..5ca7888 100644 (file)
@@ -7,6 +7,6 @@
   <p id="r">FAIL (script did not run)</p>  
   <x class="a"/>
   <g:x class="a"/>
-  <script> t(document.getElementsByClassName("a"), document.getElementsByTagName("x")) </script>
+  <script> t(document.getElementsByClassName("a"), document.getElementsByTagNameNS("*", "x")) </script>
  </body>
 </html>
index 6790b5a..827a2f3 100644 (file)
@@ -12,7 +12,7 @@
   <t:x class="a" t:class="a" h:class="a" g:class="a"/>
   <script>
    var collection = document.getElementsByClassName("a"),
-       test = document.getElementsByTagName("x")
+       test = document.getElementsByTagNameNS("*", "x")
    t(collection, [test[0], test[1]])
   </script>
  </body>
index 1117938..aa1f031 100644 (file)
@@ -1,3 +1,20 @@
+2016-08-12  Chris Dumez  <cdumez@apple.com>
+
+        getElementsByTagName() should take a qualifiedName in parameter
+        https://bugs.webkit.org/show_bug.cgi?id=160682
+
+        Reviewed by Ryosuke Niwa.
+
+        * web-platform-tests/dom/nodes/Document-getElementsByTagName-expected.txt:
+        * web-platform-tests/dom/nodes/Document-getElementsByTagName-xhtml-expected.txt:
+        * web-platform-tests/dom/nodes/Element-getElementsByTagName-expected.txt:
+        * web-platform-tests/dom/nodes/case-expected.txt:
+        Rebaseline several W3C tests now that more checks are passing.
+
+        * web-platform-tests/dom/nodes/Document-getElementsByTagName-xhtml.xhtml:
+        Re-sync this test from upstream as it was outdated after:
+        - https://github.com/w3c/web-platform-tests/pull/3457
+
 2016-08-11  Chris Dumez  <cdumez@apple.com>
 
         Align Range.surroundContents() with the latest DOM specification
index 768f782..790b75c 100644 (file)
@@ -12,11 +12,11 @@ PASS hasOwnProperty, getOwnPropertyDescriptor, getOwnPropertyNames
 PASS HTML element with uppercase tagName never matches in HTML Documents 
 PASS Element in non-HTML namespace, no prefix, lowercase name 
 PASS Element in non-HTML namespace, no prefix, uppercase name 
-FAIL Element in non-HTML namespace, prefix, lowercase name assert_array_equals: lengths differ, expected 0 got 1
-FAIL Element in non-HTML namespace, prefix, uppercase name assert_array_equals: lengths differ, expected 0 got 1
+PASS Element in non-HTML namespace, prefix, lowercase name 
+PASS Element in non-HTML namespace, prefix, uppercase name 
 PASS Element in HTML namespace, no prefix, non-ascii characters in name 
 PASS Element in non-HTML namespace, non-ascii characters in name 
-FAIL Element in HTML namespace, prefix, non-ascii characters in name assert_array_equals: All uppercase input lengths differ, expected 1 got 0
-FAIL Element in non-HTML namespace, prefix, non-ascii characters in name assert_array_equals: All uppercase input lengths differ, expected 1 got 0
+PASS Element in HTML namespace, prefix, non-ascii characters in name 
+PASS Element in non-HTML namespace, prefix, non-ascii characters in name 
 PASS getElementsByTagName('*') 
 
index 36ac277..2c01fdc 100644 (file)
@@ -2,8 +2,8 @@
 PASS HTML element with uppercase tag name matches in XHTML documents 
 PASS Element in non-HTML namespace, no prefix, lowercase name 
 PASS Element in non-HTML namespace, no prefix, uppercase name 
-FAIL Element in non-HTML namespace, prefix, lowercase name assert_array_equals: lengths differ, expected 0 got 1
-FAIL Element in non-HTML namespace, prefix, uppercase name assert_array_equals: lengths differ, expected 0 got 1
+PASS Element in non-HTML namespace, prefix, lowercase name 
+PASS Element in non-HTML namespace, prefix, uppercase name 
 PASS Element in HTML namespace, no prefix, non-ascii characters in name 
 PASS Element in non-HTML namespace, non-ascii characters in name 
 PASS Element in HTML namespace, prefix, non-ascii characters in name 
index 2ae9074..309a29a 100644 (file)
@@ -71,17 +71,17 @@ test(function() {
 test(function() {
   var t = document.body.appendChild(document.createElementNS("http://www.w3.org/1999/xhtml", "test:aÇ"))
   this.add_cleanup(function() {document.body.removeChild(t)})
-  assert_array_equals(document.getElementsByTagName("AÇ"), [], "All uppercase input")
-  assert_array_equals(document.getElementsByTagName("aÇ"), [t], "Ascii lowercase input")
-  assert_array_equals(document.getElementsByTagName("aç"), [], "All lowercase input")
+  assert_array_equals(document.getElementsByTagName("TEST:AÇ"), [], "All uppercase input")
+  assert_array_equals(document.getElementsByTagName("test:aÇ"), [t], "Ascii lowercase input")
+  assert_array_equals(document.getElementsByTagName("test:aç"), [], "All lowercase input")
 }, "Element in HTML namespace, prefix, non-ascii characters in name")
 
 test(function() {
-  var t = document.body.appendChild(document.createElementNS("test", "test:AÇ"))
+  var t = document.body.appendChild(document.createElementNS("test", "TEST:AÇ"))
   this.add_cleanup(function() {document.body.removeChild(t)})
-  assert_array_equals(document.getElementsByTagName("AÇ"), [t], "All uppercase input")
-  assert_array_equals(document.getElementsByTagName("aÇ"), [], "Ascii lowercase input")
-  assert_array_equals(document.getElementsByTagName("aç"), [], "All lowercase input")
+  assert_array_equals(document.getElementsByTagName("TEST:AÇ"), [t], "All uppercase input")
+  assert_array_equals(document.getElementsByTagName("test:aÇ"), [], "Ascii lowercase input")
+  assert_array_equals(document.getElementsByTagName("test:aç"), [], "All lowercase input")
 }, "Element in non-HTML namespace, prefix, non-ascii characters in name")
 
 test(function() {
index eed8753..cc7ae5d 100644 (file)
@@ -12,12 +12,12 @@ PASS hasOwnProperty, getOwnPropertyDescriptor, getOwnPropertyNames
 PASS HTML element with uppercase tagName never matches in HTML Documents 
 PASS Element in non-HTML namespace, no prefix, lowercase name 
 PASS Element in non-HTML namespace, no prefix, uppercase name 
-FAIL Element in non-HTML namespace, prefix, lowercase name assert_array_equals: lengths differ, expected 0 got 1
-FAIL Element in non-HTML namespace, prefix, uppercase name assert_array_equals: lengths differ, expected 0 got 1
+PASS Element in non-HTML namespace, prefix, lowercase name 
+PASS Element in non-HTML namespace, prefix, uppercase name 
 PASS Element in HTML namespace, no prefix, non-ascii characters in name 
 PASS Element in non-HTML namespace, non-ascii characters in name 
-FAIL Element in HTML namespace, prefix, non-ascii characters in name assert_array_equals: All uppercase input lengths differ, expected 1 got 0
-FAIL Element in non-HTML namespace, prefix, non-ascii characters in name assert_array_equals: All uppercase input lengths differ, expected 1 got 0
+PASS Element in HTML namespace, prefix, non-ascii characters in name 
+PASS Element in non-HTML namespace, prefix, non-ascii characters in name 
 PASS getElementsByTagName('*') 
 PASS Matching the context object 
 
index e2b2882..f42ee70 100644 (file)
@@ -2,27 +2,27 @@
 PASS createElement abc 
 PASS setAttribute abc 
 PASS getAttribute abc 
-FAIL getElementsByTagName a:abc assert_array_equals: lengths differ, expected 0 got 3
+PASS getElementsByTagName a:abc 
 PASS getElementsByTagName abc 
 PASS createElement Abc 
 PASS setAttribute Abc 
 PASS getAttribute Abc 
-FAIL getElementsByTagName a:Abc assert_array_equals: lengths differ, expected 0 got 3
+PASS getElementsByTagName a:Abc 
 PASS getElementsByTagName Abc 
 PASS createElement ABC 
 PASS setAttribute ABC 
 PASS getAttribute ABC 
-FAIL getElementsByTagName a:ABC assert_array_equals: lengths differ, expected 0 got 3
+PASS getElementsByTagName a:ABC 
 PASS getElementsByTagName ABC 
 PASS createElement ä 
 PASS setAttribute ä 
 PASS getAttribute ä 
-FAIL getElementsByTagName a:ä assert_array_equals: lengths differ, expected 0 got 3
+PASS getElementsByTagName a:ä 
 PASS getElementsByTagName ä 
 PASS createElement Ä 
 PASS setAttribute Ä 
 PASS getAttribute Ä 
-FAIL getElementsByTagName a:Ä assert_array_equals: lengths differ, expected 0 got 3
+PASS getElementsByTagName a:Ä 
 PASS getElementsByTagName Ä 
 PASS createElementNS http://www.w3.org/1999/xhtml,abc,abc 
 PASS setAttributeNS http://www.w3.org/1999/xhtml,abc,abc 
index 79694b8..7ec2971 100644 (file)
@@ -1,3 +1,51 @@
+2016-08-12  Chris Dumez  <cdumez@apple.com>
+
+        getElementsByTagName() should take a qualifiedName in parameter
+        https://bugs.webkit.org/show_bug.cgi?id=160682
+
+        Reviewed by Ryosuke Niwa.
+
+        getElementsByTagName() should take a qualifiedName in parameter, not a
+        localName, according to the latest DOM specification:
+        - https://dom.spec.whatwg.org/#dom-document-getelementsbytagname
+        - https://dom.spec.whatwg.org/#concept-getelementsbytagname
+
+        The new behavior matches Firefox and Edge. There is a slight
+        compatiblity risk but we should give it a try.
+
+        No new tests, rebaselined existing tests.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * dom/AllDescendantsCollection.h: Added.
+        * dom/ContainerNode.cpp:
+        (WebCore::ContainerNode::getElementsByTagName):
+        (WebCore::ContainerNode::getElementsByTagNameNS):
+        * dom/Node.cpp:
+        (WebCore::NodeListsNodeData::invalidateCaches):
+        * dom/NodeRareData.h:
+        (WebCore::NodeListsNodeData::addCachedTagCollectionNS):
+        (WebCore::NodeListsNodeData::removeCachedTagCollectionNS):
+        (WebCore::NodeListsNodeData::adoptDocument):
+        (WebCore::NodeListsNodeData::deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList):
+        * dom/TagCollection.cpp:
+        (WebCore::makeQualifiedName):
+        (WebCore::splitQualifiedName):
+        (WebCore::TagCollectionNS::TagCollectionNS):
+        (WebCore::TagCollectionNS::~TagCollectionNS):
+        (WebCore::TagCollection::TagCollection):
+        (WebCore::TagCollection::~TagCollection):
+        (WebCore::HTMLTagCollection::HTMLTagCollection):
+        (WebCore::HTMLTagCollection::~HTMLTagCollection):
+        * dom/TagCollection.h:
+        (WebCore::TagCollection::elementMatches):
+        (WebCore::TagCollectionNS::elementMatches):
+        (WebCore::HTMLTagCollection::elementMatches):
+        * html/CollectionType.h:
+        * html/GenericCachedHTMLCollection.cpp:
+        (WebCore::GenericCachedHTMLCollection<traversalType>::elementMatches):
+        * html/HTMLCollection.cpp:
+        (WebCore::invalidationTypeExcludingIdAndNameAttributes):
+
 2016-08-12  Alex Christensen  <achristensen@webkit.org>
 
         Make URLParser work with URLs missing URL parts
index 5751d1b..fe45daf 100644 (file)
                83A4A9F91CE7FD8100709B00 /* JSXMLDocumentCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83A4A9F81CE7FD7E00709B00 /* JSXMLDocumentCustom.cpp */; };
                83B2D1751B8BCD6A00A02E47 /* NativeNodeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 83E959E11B8BC22B004D9385 /* NativeNodeFilter.h */; };
                83B9687B19F8AB83004EF7AF /* StyleBuilderConverter.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B9687919F8AB83004EF7AF /* StyleBuilderConverter.h */; };
+               83BB5C881D5D6F45005A71F4 /* AllDescendantsCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 83BB5C871D5D6F3A005A71F4 /* AllDescendantsCollection.h */; };
                83C05A5A1A686212007E5DEA /* StylePropertyShorthandFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83C05A581A686212007E5DEA /* StylePropertyShorthandFunctions.cpp */; };
                83C05A5B1A686212007E5DEA /* StylePropertyShorthandFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C05A591A686212007E5DEA /* StylePropertyShorthandFunctions.h */; };
                83C1D425178D5AB400141E68 /* SVGPathSegArcAbs.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C1D413178D5AB400141E68 /* SVGPathSegArcAbs.h */; };
                839AAFEB1A0C0C8D00605F99 /* HTMLWBRElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLWBRElement.h; sourceTree = "<group>"; };
                83A4A9F81CE7FD7E00709B00 /* JSXMLDocumentCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSXMLDocumentCustom.cpp; sourceTree = "<group>"; };
                83B9687919F8AB83004EF7AF /* StyleBuilderConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleBuilderConverter.h; sourceTree = "<group>"; };
+               83BB5C871D5D6F3A005A71F4 /* AllDescendantsCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AllDescendantsCollection.h; sourceTree = "<group>"; };
                83C05A581A686212007E5DEA /* StylePropertyShorthandFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StylePropertyShorthandFunctions.cpp; sourceTree = "<group>"; };
                83C05A591A686212007E5DEA /* StylePropertyShorthandFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StylePropertyShorthandFunctions.h; sourceTree = "<group>"; };
                83C1D413178D5AB400141E68 /* SVGPathSegArcAbs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGPathSegArcAbs.h; sourceTree = "<group>"; };
                9BD4E9181C462CFC005065BC /* CustomElementsRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CustomElementsRegistry.cpp; sourceTree = "<group>"; };
                9BD4E9191C462CFC005065BC /* CustomElementsRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomElementsRegistry.h; sourceTree = "<group>"; };
                9BD8A95918BEFC7600987E9A /* CollectionIndexCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CollectionIndexCache.cpp; sourceTree = "<group>"; };
-               9BE671091D5AEB0400345514 /* JSCustomElementsRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JSCustomElementsRegistry.cpp; path = "JSCustomElementsRegistry.cpp"; sourceTree = "<group>"; };
-               9BE6710A1D5AEB0400345514 /* JSCustomElementsRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSCustomElementsRegistry.h; path = "JSCustomElementsRegistry.h"; sourceTree = "<group>"; };
+               9BE671091D5AEB0400345514 /* JSCustomElementsRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCustomElementsRegistry.cpp; sourceTree = "<group>"; };
+               9BE6710A1D5AEB0400345514 /* JSCustomElementsRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCustomElementsRegistry.h; sourceTree = "<group>"; };
                9BF9A87E1648DD2F001C6B23 /* JSHTMLFormControlsCollection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLFormControlsCollection.cpp; sourceTree = "<group>"; };
                9BF9A87F1648DD2F001C6B23 /* JSHTMLFormControlsCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSHTMLFormControlsCollection.h; sourceTree = "<group>"; };
                9D63800F1AF16E160031A15C /* StyleSelfAlignmentData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleSelfAlignmentData.h; sourceTree = "<group>"; };
                                7CD0BA031B8F79C9005CEBBE /* ActiveDOMCallbackMicrotask.h */,
                                E1C4DE6D0EA75C650023CCD6 /* ActiveDOMObject.cpp */,
                                E1C4DE680EA75C1E0023CCD6 /* ActiveDOMObject.h */,
+                               83BB5C871D5D6F3A005A71F4 /* AllDescendantsCollection.h */,
                                319847FE1A1D816700A13318 /* AnimationEvent.cpp */,
                                319847FF1A1D816700A13318 /* AnimationEvent.h */,
                                319848001A1D816700A13318 /* AnimationEvent.idl */,
                                B658FFA21522EF3A00DD5595 /* JSRadioNodeList.h in Headers */,
                                65DF320209D1CC60000BE325 /* JSRange.h in Headers */,
                                7C4C96DD1AD4483500365A50 /* JSReadableStream.h in Headers */,
+                               83BB5C881D5D6F45005A71F4 /* AllDescendantsCollection.h in Headers */,
                                6C4C96DF1AD4483500365A50 /* JSReadableStreamDefaultController.h in Headers */,
                                7C4C96DF1AD4483500365A50 /* JSReadableStreamDefaultReader.h in Headers */,
                                4129DF861BB5B80C00322A16 /* JSReadableStreamPrivateConstructors.h in Headers */,
diff --git a/Source/WebCore/dom/AllDescendantsCollection.h b/Source/WebCore/dom/AllDescendantsCollection.h
new file mode 100644 (file)
index 0000000..22ed9d8
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 Apple 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 APPLE 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 APPLE 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.
+ */
+
+#pragma once
+
+#include "CachedHTMLCollection.h"
+
+namespace WebCore {
+
+class AllDescendantsCollection : public CachedHTMLCollection<AllDescendantsCollection, CollectionTypeTraits<AllDescendants>::traversalType> {
+public:
+    static Ref<AllDescendantsCollection> create(ContainerNode& rootNode, CollectionType type)
+    {
+        ASSERT_UNUSED(type, type == AllDescendants);
+        return adoptRef(*new AllDescendantsCollection(rootNode, type));
+    }
+
+    bool elementMatches(Element&) const { return true; }
+
+protected:
+    AllDescendantsCollection(ContainerNode& rootNode, CollectionType type)
+        : CachedHTMLCollection<AllDescendantsCollection, CollectionTypeTraits<AllDescendants>::traversalType>(rootNode, type)
+    { }
+};
+
+}
index 5e97ee7..be0c5d5 100644 (file)
@@ -24,6 +24,7 @@
 #include "ContainerNode.h"
 
 #include "AXObjectCache.h"
+#include "AllDescendantsCollection.h"
 #include "ChildListMutationScope.h"
 #include "Chrome.h"
 #include "ChromeClient.h"
@@ -820,23 +821,22 @@ RefPtr<NodeList> ContainerNode::querySelectorAll(const String& selectors, Except
     return nullptr;
 }
 
-Ref<HTMLCollection> ContainerNode::getElementsByTagName(const AtomicString& localName)
+Ref<HTMLCollection> ContainerNode::getElementsByTagName(const AtomicString& qualifiedName)
 {
-    ASSERT(!localName.isNull());
+    ASSERT(!qualifiedName.isNull());
+
+    if (qualifiedName == starAtom)
+        return ensureRareData().ensureNodeLists().addCachedCollection<AllDescendantsCollection>(*this, AllDescendants);
 
     if (document().isHTMLDocument())
-        return ensureRareData().ensureNodeLists().addCachedCollection<HTMLTagCollection>(*this, ByHTMLTag, localName);
-    return ensureRareData().ensureNodeLists().addCachedCollection<TagCollection>(*this, ByTag, localName);
+        return ensureRareData().ensureNodeLists().addCachedCollection<HTMLTagCollection>(*this, ByHTMLTag, qualifiedName);
+    return ensureRareData().ensureNodeLists().addCachedCollection<TagCollection>(*this, ByTag, qualifiedName);
 }
 
 Ref<HTMLCollection> ContainerNode::getElementsByTagNameNS(const AtomicString& namespaceURI, const AtomicString& localName)
 {
     ASSERT(!localName.isNull());
-
-    if (namespaceURI == starAtom)
-        return getElementsByTagName(localName);
-
-    return ensureRareData().ensureNodeLists().addCachedCollectionWithQualifiedName(*this, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localName);
+    return ensureRareData().ensureNodeLists().addCachedTagCollectionNS(*this, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localName);
 }
 
 Ref<NodeList> ContainerNode::getElementsByName(const String& elementName)
index 56d7f58..1d42108 100644 (file)
@@ -1876,7 +1876,7 @@ void NodeListsNodeData::invalidateCaches(const QualifiedName* attrName)
     if (attrName)
         return;
 
-    for (auto& tagCollection : m_tagCollectionCacheNS)
+    for (auto& tagCollection : m_tagCollectionNSCache)
         tagCollection.value->invalidateCacheForAttribute(nullptr);
 }
 
index 092e56d..c10c776 100644 (file)
@@ -114,7 +114,7 @@ public:
 
     typedef HashMap<std::pair<unsigned char, AtomicString>, LiveNodeList*, NodeListCacheMapEntryHash> NodeListAtomicNameCacheMap;
     typedef HashMap<std::pair<unsigned char, AtomicString>, HTMLCollection*, NodeListCacheMapEntryHash> CollectionCacheMap;
-    typedef HashMap<QualifiedName, TagCollection*> TagCollectionCacheNS;
+    typedef HashMap<QualifiedName, TagCollectionNS*> TagCollectionNSCache;
 
     template<typename T, typename ContainerType>
     ALWAYS_INLINE Ref<T> addCacheWithAtomicName(ContainerType& container, const AtomicString& name)
@@ -128,14 +128,14 @@ public:
         return list;
     }
 
-    ALWAYS_INLINE Ref<TagCollection> addCachedCollectionWithQualifiedName(ContainerNode& node, const AtomicString& namespaceURI, const AtomicString& localName)
+    ALWAYS_INLINE Ref<TagCollectionNS> addCachedTagCollectionNS(ContainerNode& node, const AtomicString& namespaceURI, const AtomicString& localName)
     {
         QualifiedName name(nullAtom, localName, namespaceURI);
-        TagCollectionCacheNS::AddResult result = m_tagCollectionCacheNS.fastAdd(name, nullptr);
+        TagCollectionNSCache::AddResult result = m_tagCollectionNSCache.fastAdd(name, nullptr);
         if (!result.isNewEntry)
             return *result.iterator->value;
 
-        auto list = TagCollection::create(node, namespaceURI, localName);
+        auto list = TagCollectionNS::create(node, namespaceURI, localName);
         result.iterator->value = list.ptr();
         return list;
     }
@@ -179,13 +179,13 @@ public:
         m_atomicNameCaches.remove(namedNodeListKey<NodeListType>(name));
     }
 
-    void removeCachedCollectionWithQualifiedName(HTMLCollection& collection, const AtomicString& namespaceURI, const AtomicString& localName)
+    void removeCachedTagCollectionNS(HTMLCollection& collection, const AtomicString& namespaceURI, const AtomicString& localName)
     {
         QualifiedName name(nullAtom, localName, namespaceURI);
-        ASSERT(&collection == m_tagCollectionCacheNS.get(name));
+        ASSERT(&collection == m_tagCollectionNSCache.get(name));
         if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(collection.ownerNode()))
             return;
-        m_tagCollectionCacheNS.remove(name);
+        m_tagCollectionNSCache.remove(name);
     }
 
     void removeCachedCollection(HTMLCollection* collection, const AtomicString& name = starAtom)
@@ -214,7 +214,7 @@ public:
         for (auto& cache : m_atomicNameCaches.values())
             cache->invalidateCache(*oldDocument);
 
-        for (auto& list : m_tagCollectionCacheNS.values()) {
+        for (auto& list : m_tagCollectionNSCache.values()) {
             ASSERT(!list->isRootedAtDocument());
             list->invalidateCache(*oldDocument);
         }
@@ -242,7 +242,7 @@ private:
     EmptyNodeList* m_emptyChildNodeList;
 
     NodeListAtomicNameCacheMap m_atomicNameCaches;
-    TagCollectionCacheNS m_tagCollectionCacheNS;
+    TagCollectionNSCache m_tagCollectionNSCache;
     CollectionCacheMap m_cachedCollections;
 };
 
@@ -303,7 +303,7 @@ inline bool NodeListsNodeData::deleteThisAndUpdateNodeRareDataIfAboutToRemoveLas
 {
     ASSERT(ownerNode.nodeLists() == this);
     if ((m_childNodeList ? 1 : 0) + (m_emptyChildNodeList ? 1 : 0) + m_atomicNameCaches.size()
-        + m_tagCollectionCacheNS.size() + m_cachedCollections.size() != 1)
+        + m_tagCollectionNSCache.size() + m_cachedCollections.size() != 1)
         return false;
     ownerNode.clearNodeLists();
     return true;
index 81403b6..f07d613 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
  *           (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004-2007, 2014, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2007, 2014-2016 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
  *
  * This library is free software; you can redistribute it and/or
 
 namespace WebCore {
 
-TagCollection::TagCollection(ContainerNode& rootNode, const AtomicString& namespaceURI, const AtomicString& localName)
-    : CachedHTMLCollection<TagCollection, CollectionTypeTraits<ByTag>::traversalType>(rootNode, ByTag)
+static inline AtomicString makeQualifiedName(const String& prefix, const String& localName)
+{
+    if (LIKELY(prefix.isNull()))
+        return localName;
+    return prefix + ':' + localName;
+}
+
+static inline void splitQualifiedName(const String& qualifiedName, AtomicString& prefix, AtomicString& localName)
+{
+    size_t index = qualifiedName.find(':');
+    if (UNLIKELY(index == notFound))
+        localName = qualifiedName;
+    else {
+        prefix = qualifiedName.substring(0, index);
+        localName = qualifiedName.substring(index + 1);
+    }
+    ASSERT(makeQualifiedName(prefix, localName) == qualifiedName);
+}
+
+TagCollectionNS::TagCollectionNS(ContainerNode& rootNode, const AtomicString& namespaceURI, const AtomicString& localName)
+    : CachedHTMLCollection<TagCollectionNS, CollectionTypeTraits<ByTag>::traversalType>(rootNode, ByTag)
     , m_namespaceURI(namespaceURI)
     , m_localName(localName)
 {
     ASSERT(m_namespaceURI.isNull() || !m_namespaceURI.isEmpty());
 }
 
+TagCollectionNS::~TagCollectionNS()
+{
+    ownerNode().nodeLists()->removeCachedTagCollectionNS(*this, m_namespaceURI, m_localName);
+}
+
+TagCollection::TagCollection(ContainerNode& rootNode, const AtomicString& qualifiedName)
+    : CachedHTMLCollection<TagCollection, CollectionTypeTraits<ByTag>::traversalType>(rootNode, ByTag)
+{
+    ASSERT(qualifiedName != starAtom);
+    splitQualifiedName(qualifiedName, m_prefix, m_localName);
+}
+
 TagCollection::~TagCollection()
 {
-    if (m_namespaceURI == starAtom)
-        ownerNode().nodeLists()->removeCachedCollection(this, m_localName);
-    else
-        ownerNode().nodeLists()->removeCachedCollectionWithQualifiedName(*this, m_namespaceURI, m_localName);
+    ownerNode().nodeLists()->removeCachedCollection(this, makeQualifiedName(m_prefix, m_localName));
 }
 
-HTMLTagCollection::HTMLTagCollection(ContainerNode& rootNode, const AtomicString& localName)
+HTMLTagCollection::HTMLTagCollection(ContainerNode& rootNode, const AtomicString& qualifiedName)
     : CachedHTMLCollection<HTMLTagCollection, CollectionTypeTraits<ByHTMLTag>::traversalType>(rootNode, ByHTMLTag)
-    , m_localName(localName)
-    , m_loweredLocalName(localName.convertToASCIILowercase())
 {
+    ASSERT(qualifiedName != starAtom);
+    splitQualifiedName(qualifiedName, m_prefix, m_localName);
+    m_loweredPrefix = m_prefix.convertToASCIILowercase();
+    m_loweredLocalName = m_localName.convertToASCIILowercase();
 }
 
 HTMLTagCollection::~HTMLTagCollection()
 {
-    ownerNode().nodeLists()->removeCachedCollection(this, m_localName);
+    ownerNode().nodeLists()->removeCachedCollection(this, makeQualifiedName(m_prefix, m_localName));
 }
 
 } // namespace WebCore
index 4cfd381..5788998 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
  *           (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004-2008, 2014, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2008, 2014-2016 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
  *
  * This library is free software; you can redistribute it and/or
@@ -32,64 +32,76 @@ namespace WebCore {
 // HTMLCollection that limits to a particular tag.
 class TagCollection final : public CachedHTMLCollection<TagCollection, CollectionTypeTraits<ByTag>::traversalType> {
 public:
-    static Ref<TagCollection> create(ContainerNode& rootNode, const AtomicString& namespaceURI, const AtomicString& localName)
-    {
-        ASSERT(namespaceURI != starAtom);
-        return adoptRef(*new TagCollection(rootNode, namespaceURI, localName));
-    }
-
-    static Ref<TagCollection> create(ContainerNode& rootNode, CollectionType type, const AtomicString& localName)
+    static Ref<TagCollection> create(ContainerNode& rootNode, CollectionType type, const AtomicString& qualifiedName)
     {
         ASSERT_UNUSED(type, type == ByTag);
-        return adoptRef(*new TagCollection(rootNode, starAtom, localName));
+        return adoptRef(*new TagCollection(rootNode, qualifiedName));
     }
 
     virtual ~TagCollection();
-
     bool elementMatches(Element&) const;
 
-protected:
-    TagCollection(ContainerNode& rootNode, const AtomicString& namespaceURI, const AtomicString& localName);
+private:
+    TagCollection(ContainerNode& rootNode, const AtomicString& qualifiedName);
 
-    AtomicString m_namespaceURI;
+    AtomicString m_prefix;
     AtomicString m_localName;
 };
 
-inline bool TagCollection::elementMatches(Element& element) const
-{
-    // Implements http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-getelementsbytagnamens
-    if (m_localName != starAtom && m_localName != element.localName())
-        return false;
+class TagCollectionNS final : public CachedHTMLCollection<TagCollectionNS, CollectionTypeTraits<ByTag>::traversalType> {
+public:
+    static Ref<TagCollectionNS> create(ContainerNode& rootNode, const AtomicString& namespaceURI, const AtomicString& localName)
+    {
+        return adoptRef(*new TagCollectionNS(rootNode, namespaceURI, localName));
+    }
 
-    return m_namespaceURI == starAtom || m_namespaceURI == element.namespaceURI();
-}
+    virtual ~TagCollectionNS();
+    bool elementMatches(Element&) const;
+
+private:
+    TagCollectionNS(ContainerNode& rootNode, const AtomicString& namespaceURI, const AtomicString& localName);
+
+    AtomicString m_namespaceURI;
+    AtomicString m_localName;
+};
 
 class HTMLTagCollection final : public CachedHTMLCollection<HTMLTagCollection, CollectionTypeTraits<ByHTMLTag>::traversalType> {
 public:
-    static Ref<HTMLTagCollection> create(ContainerNode& rootNode, CollectionType type, const AtomicString& localName)
+    static Ref<HTMLTagCollection> create(ContainerNode& rootNode, CollectionType type, const AtomicString& qualifiedName)
     {
         ASSERT_UNUSED(type, type == ByHTMLTag);
-        return adoptRef(*new HTMLTagCollection(rootNode, localName));
+        return adoptRef(*new HTMLTagCollection(rootNode, qualifiedName));
     }
 
     virtual ~HTMLTagCollection();
-
     bool elementMatches(Element&) const;
 
 private:
-    HTMLTagCollection(ContainerNode& rootNode, const AtomicString& localName);
+    HTMLTagCollection(ContainerNode& rootNode, const AtomicString& qualifiedName);
 
+    AtomicString m_prefix;
+    AtomicString m_loweredPrefix;
     AtomicString m_localName;
     AtomicString m_loweredLocalName;
 };
 
+inline bool TagCollection::elementMatches(Element& element) const
+{
+    return m_localName == element.localName() && m_prefix == element.prefix();
+}
+
+inline bool TagCollectionNS::elementMatches(Element& element) const
+{
+    if (m_localName != starAtom && m_localName != element.localName())
+        return false;
+    return m_namespaceURI == starAtom || m_namespaceURI == element.namespaceURI();
+}
+
 inline bool HTMLTagCollection::elementMatches(Element& element) const
 {
-    // Implements http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-getelementsbytagname
-    if (m_localName == starAtom)
-        return true;
-    const AtomicString& localName = element.isHTMLElement() ? m_loweredLocalName : m_localName;
-    return localName == element.localName();
+    if (element.isHTMLElement())
+        return m_loweredLocalName == element.localName() && m_loweredPrefix == element.prefix();
+    return m_localName == element.localName() && m_prefix == element.prefix();
 }
 
 } // namespace WebCore
index 831d676..d76a902 100644 (file)
@@ -54,6 +54,7 @@ enum CollectionType {
     ByClass,
     ByTag,
     ByHTMLTag,
+    AllDescendants
 };
 
 enum class CollectionTraversalType { Descendants, ChildrenOnly, CustomForwardOnly };
index 2752e4a..83052ec 100644 (file)
@@ -75,6 +75,7 @@ bool GenericCachedHTMLCollection<traversalType>::elementMatches(Element& element
     case ByClass:
     case ByTag:
     case ByHTMLTag:
+    case AllDescendants:
     case DocAll:
     case DocumentNamedItems:
     case FormControls:
index fcf3aa0..13d8de7 100644 (file)
@@ -36,7 +36,7 @@ Ref<HTMLAllCollection> HTMLAllCollection::create(Document& document, CollectionT
 }
 
 inline HTMLAllCollection::HTMLAllCollection(Document& document, CollectionType type)
-    : CachedHTMLCollection<HTMLAllCollection, CollectionTypeTraits<DocAll>::traversalType>(document, type)
+    : AllDescendantsCollection(document, type)
 {
 }
 
index 089b72a..3063998 100644 (file)
 #ifndef HTMLAllCollection_h
 #define HTMLAllCollection_h
 
-#include "CachedHTMLCollection.h"
+#include "AllDescendantsCollection.h"
 
 namespace WebCore {
 
-class HTMLAllCollection final : public CachedHTMLCollection<HTMLAllCollection, CollectionTypeTraits<DocAll>::traversalType> {
+class HTMLAllCollection final : public AllDescendantsCollection {
 public:
     static Ref<HTMLAllCollection> create(Document&, CollectionType);
 
     Element* namedItemWithIndex(const AtomicString& name, unsigned index) const;
     RefPtr<NodeList> tags(const String&);
 
-    // For CachedHTMLCollection.
-    bool elementMatches(Element&) const { return true; }
-
 private:
     HTMLAllCollection(Document&, CollectionType);
 };
index 929f4e6..8c1738a 100644 (file)
@@ -46,6 +46,7 @@ inline auto HTMLCollection::rootTypeFromCollectionType(CollectionType type) -> R
     case DocumentNamedItems:
     case FormControls:
         return HTMLCollection::IsRootedAtDocument;
+    case AllDescendants:
     case ByClass:
     case ByTag:
     case ByHTMLTag:
@@ -69,6 +70,7 @@ static NodeListInvalidationType invalidationTypeExcludingIdAndNameAttributes(Col
     switch (type) {
     case ByTag:
     case ByHTMLTag:
+    case AllDescendants:
     case DocImages:
     case DocEmbeds:
     case DocForms: