document.getElementsByTagName should return an HTMLCollection
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 22 Aug 2015 00:50:13 +0000 (00:50 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 22 Aug 2015 00:50:13 +0000 (00:50 +0000)
commitb6232a74642bf3b0aad72d5893359a69031710ca
tree4566059c577a6a1bcd8d61b63d49a368adeecc13
parent63b9504a251776a2ae747271823190c705be169d
document.getElementsByTagName should return an HTMLCollection
https://bugs.webkit.org/show_bug.cgi?id=110611

Reviewed by Darin Adler.

Source/WebCore:

Update getElementsByTagName*() to return an HTMLCollection as per
the specification:
- https://dom.spec.whatwg.org/#interface-document
- https://dom.spec.whatwg.org/#interface-element

Firefox, Chrome and IE all match the specification but WebKit was
returning a NodeList.

Performance:
DOM/get-elements-by-tag-name-traversal-uncached.html is ~4.5% faster.

Test: fast/dom/getElementsByTagName-return-type.html

* CMakeLists.txt:
* WebCore.vcxproj/WebCore.vcxproj:
* WebCore.vcxproj/WebCore.vcxproj.filters:
* WebCore.xcodeproj/project.pbxproj:
Rename TagNodeList.* to TagCollection.*

* accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::addRadioButtonGroupMembers):
Update the function to use descendantsOfType<>() instead of
getElementsByTagName(). The code is both shorter and more efficient.

* dom/ContainerNode.cpp:
(WebCore::ContainerNode::getElementsByTagName):
(WebCore::ContainerNode::getElementsByTagNameForObjC):
(WebCore::ContainerNode::getElementsByTagNameNS):
(WebCore::ContainerNode::getElementsByTagNameNSForObjC):
* dom/ContainerNode.h:
- Have getElementsByTagName*() return an HTMLCollection.
- Introduce versions used by the ObjC bindings that return a NodeList
  for API compatibility reasons.
- Move the localName null check to the *ForObjC versions and use a
  simple assertion for the non ObjC versions. This gets rid of a
  branch for our JS bindings as this function is hot. It is currently
  impossible to get a null AtomicString from our JS bindings code because
  getElementsByTagName() and getElementsByTagName(undefined) in JS end up
  calling ContainerNode::getElementsByTagName("undefined").
  Also getElementsByTagName(null) in JS ends up calling
  ContainerNode::getElementsByTagName("null"). I have also gotten rid of
  most of the getElementsByTagName() calls from our native code. The
  remaining ones either call with a non-null AtomicString and they now
  have a null-check.

* dom/Document.idl:
* dom/Element.idl:
Have getElementsByTagName*() return an HTMLCollection except for ObjC
bindings in order to maintain legacy API compatibility.

* dom/Node.cpp:
(WebCore::Document::invalidateNodeListAndCollectionCaches):
(WebCore::NodeListsNodeData::invalidateCaches):
HTMLCollection::invalidateCache(attr) is now renamed to
invalidateCacheForAttribute(attr) to avoid ambiguity with
HTMLCollection::invalidateCache(doc) and for consistency
with LiveNodeList.

* dom/NodeRareData.h:
Make necessary updates now that TagNodeList is renamed to TagCollection
and is an HTMLCollection.

* dom/TagCollection.cpp: Renamed from Source/WebCore/dom/TagNodeList.cpp.
* dom/TagCollection.h: Renamed from Source/WebCore/dom/TagNodeList.h.
Rename TagNodeList / HTMLTagNodeList to TagCollection / HTMLTagCollection
and inherit CachedHTMLCollection instead of CachedLiveNodeList.

* editing/Editor.cpp:
(WebCore::Editor::applyEditingStyleToBodyElement):
Update code using getElementsByTagName() to reflect the fact that it
now returns an HTMLCollection and item() returns an Element*. This
function is matching any Element with "body" tag, not just HTMLBodyElement
so I did not refactor it to use an descendantsOfType<HTMLBodyElement>().
It is not clear to me what the intention of this code is.

* editing/markup.cpp:
(WebCore::createFragmentFromMarkup):
* editing/markup.h:
- Return a Ref<> instead of a PassRefPtr<> as it can never return null.
- Use descendantsOfType<HTMLAttachmentElement>(fragment) instead of
  getElementsByTagName() as it results in both shorter and more efficient
  code.

* html/CollectionType.h:
Add new ByTag / ByHTMLTag collection types for TagCollection /
HTMLTabCollection.

* html/GenericCachedHTMLCollection.cpp:
(WebCore::GenericCachedHTMLCollection<traversalType>::elementMatches):
Handle new ByTag / ByHTMLTag collection types in the switch statement.

* html/HTMLCollection.cpp:
(WebCore::invalidationTypeExcludingIdAndNameAttributes):
(WebCore::HTMLCollection::~HTMLCollection):
Handle new ByTag / ByHTMLTag collection types in switch statements.

(WebCore::HTMLCollection::tags):
Add a null-check on localName() before calling getElementsByTagName().
This function is currently for ObjC bindings only.

* html/HTMLPlugInImageElement.cpp:
(WebCore::HTMLPlugInImageElement::restartSimilarPlugIns):
Simplify / optimize the code by using descendantsOfType<HTMLPlugInImageElement>()
instead of getElementsByTagName().

* html/MediaDocument.cpp:
(WebCore::descendantVideoElement):
Use descendantsOfType<HTMLVideoElement> instead of getElementsByTagNameNS().

Source/WebKit/mac:

* WebView/WebFrame.mm:
(-[WebFrame _documentFragmentWithMarkupString:baseURLString:]):
Use .ptr() as createFragmentFromMarkup() now returns a
Ref<> instead of a RefPtr<>.

Source/WebKit/win:

* DOMCoreClasses.cpp:
(DOMDocument::getElementsByTagName):
(DOMDocument::getElementsByTagNameNS):
Add null checks for localName() before calling
ContainerNode::getElementsByTagName*().

LayoutTests:

* fast/dom/getElementsByTagName-return-type-expected.txt: Added.
* fast/dom/getElementsByTagName-return-type.html: Added.
New test checking that getElementsByTagName*() returns an HTMLcollection.

* fast/dom/NodeList/script-tests/nodelist-item-call-as-function.js:
* fast/dom/domListEnumeration-expected.txt:
* fast/dom/named-items-with-symbol-name-expected.txt:
* fast/dom/script-tests/domListEnumeration.js:
* fast/dom/wrapper-classes-expected.txt:
* fast/dom/wrapper-classes.html:
* js/dom/constructor-expected.txt:
* js/dom/script-tests/constructor.js:
* platform/mac/fast/dom/wrapper-classes-objc-expected.txt:
* platform/mac/fast/dom/wrapper-classes-objc.html:
Rebaseline / update.

* fast/dom/non-numeric-values-numeric-parameters-expected.txt:
One of the checks is now failing because HTMLCollection.item()'s
parameter is optional. The specification says the parameter should
be mandatory so I did not update the test. It was previously passing
because NodeList.item()'s parameter is mandatory.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@188809 268f45cc-cd09-0410-ab3c-d52691b4dbfc
45 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/dom/NodeList/script-tests/nodelist-item-call-as-function.js
LayoutTests/fast/dom/domListEnumeration-expected.txt
LayoutTests/fast/dom/getElementsByTagName-return-type-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/getElementsByTagName-return-type.html [new file with mode: 0644]
LayoutTests/fast/dom/named-items-with-symbol-name-expected.txt
LayoutTests/fast/dom/non-numeric-values-numeric-parameters-expected.txt
LayoutTests/fast/dom/script-tests/domListEnumeration.js
LayoutTests/fast/dom/wrapper-classes-expected.txt
LayoutTests/fast/dom/wrapper-classes.html
LayoutTests/js/dom/constructor-expected.txt
LayoutTests/js/dom/script-tests/constructor.js
LayoutTests/platform/mac/fast/dom/wrapper-classes-objc-expected.txt
LayoutTests/platform/mac/fast/dom/wrapper-classes-objc.html
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/accessibility/AccessibilityRenderObject.cpp
Source/WebCore/bindings/objc/DOMHTML.mm
Source/WebCore/dom/ContainerNode.cpp
Source/WebCore/dom/ContainerNode.h
Source/WebCore/dom/DOMAllInOne.cpp
Source/WebCore/dom/Document.idl
Source/WebCore/dom/Element.idl
Source/WebCore/dom/LiveNodeList.cpp
Source/WebCore/dom/Node.cpp
Source/WebCore/dom/Node.h
Source/WebCore/dom/NodeRareData.h
Source/WebCore/dom/TagCollection.cpp [moved from Source/WebCore/dom/TagNodeList.cpp with 59% similarity]
Source/WebCore/dom/TagCollection.h [moved from Source/WebCore/dom/TagNodeList.h with 54% similarity]
Source/WebCore/editing/Editor.cpp
Source/WebCore/editing/markup.cpp
Source/WebCore/editing/markup.h
Source/WebCore/html/CollectionType.h
Source/WebCore/html/GenericCachedHTMLCollection.cpp
Source/WebCore/html/HTMLCollection.cpp
Source/WebCore/html/HTMLCollection.h
Source/WebCore/html/HTMLPlugInImageElement.cpp
Source/WebCore/html/MediaDocument.cpp
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebView/WebFrame.mm
Source/WebKit/win/ChangeLog
Source/WebKit/win/DOMCoreClasses.cpp