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: http://svn.webkit.org/repository/webkit/trunk@188809 268f45cc-cd09-0410-ab3c-d52691b4dbfc
47 files changed