<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[188520] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/188520">188520</a></dd>
<dt>Author</dt> <dd>cdumez@apple.com</dd>
<dt>Date</dt> <dd>2015-08-16 11:58:48 -0700 (Sun, 16 Aug 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Refactor HTMLCollection to be as fast as CachedLiveNodeList
https://bugs.webkit.org/show_bug.cgi?id=147979

Reviewed by Ryosuke Niwa and Antti Koivisto.

Refactor HTMLCollection to be as fast as CachedLiveNodeList. This is in
preparation of having getElementsByTagName*() / getElementsByClassName()
return an HTMLCollection instead of a NodeList, as per the
specification. Chrome and Firefox already match the specification in
this case.

Traversing an HTMLCollection was slow because of all the extra
branching it had compared to CachedLiveNodeList. To address the issue,
this patch introduces a new templated CachedHTMLCollection subclass,
which behaves in a similar way as CachedLiveNodeList. The 2 template
parameters are:
1. The type of the subclass of CachedHTMLCollection, so we can call
   elementMatches() directly on the subclass, without needed any
   virtual function call or switch statement. This is the same approach
   as in CachedLiveNodeList.
2. The type of tree traversal used (Descendants, ChildrenOnly,
   CustomForwardOnly). Unlike LiveNodeList, HTMLCollection needs to
   support these 3 types of tree traversal. These were causing extra
   branching for every item() call. We are now able to choose the right
   type of traversal for the CachedHTMLCollection at compile time.

* WebCore.xcodeproj/project.pbxproj:
Add new files to the Project.

* dom/ContainerNode.cpp:
(WebCore::ContainerNode::children):
(WebCore::ContainerNode::cachedHTMLCollection): Deleted.
* dom/ContainerNode.h:
Drop ContainerNode::ensureCachedHTMLCollection() and use
NodeListsNodeData::addCachedCollection() directly at call sites
instead. We need access to the CollectionType at build-time so
we can resolve the CollectionTraversalType parameter for the
GenericCachedHTMLCollection using CollectionTypeTraits.

* dom/Document.cpp:
* dom/Document.h:
Update ensureCachedCollection() so the CollectionType is now a template
parameter instead of a method argument. We need to know the
CollectionType at build time to construct the GenericCachedHTMLCollection.

* dom/ElementChildIterator.h:
(WebCore::ElementChildIterator&lt;ElementType&gt;::operator):
(WebCore::ElementChildConstIterator&lt;ElementType&gt;::operator):
Add support for decrementing an ElementChildIterator, for consistency
with ElementDescendantIterator. We need this to support backward
traversal in CachedHTMLCollections that use the 'ChildrenOnly' type
of traversal.

* dom/LiveNodeList.h:
(WebCore::CachedLiveNodeList&lt;NodeListType&gt;::collectionBegin):
(WebCore::CachedLiveNodeList&lt;NodeListType&gt;::collectionLast):
(WebCore::CachedLiveNodeList&lt;NodeListType&gt;::collectionTraverseForward):
(WebCore::CachedLiveNodeList&lt;NodeListType&gt;::collectionTraverseBackward):
Move traversal implementation to CollectionTraversal.h, so it can be
shared with achedHTMLCollection.h.

* html/CachedHTMLCollection.h: Added.
(WebCore::traversalType&gt;::CachedHTMLCollection):
(WebCore::traversalType&gt;::~CachedHTMLCollection):
(WebCore::traversalType&gt;::CachedHTMLCollection::memoryCost):
(WebCore::traversalType&gt;::collectionCanTraverseBackward):
(WebCore::traversalType&gt;::collectionTraverseForward):
(WebCore::traversalType&gt;::collectionTraverseBackward):
(WebCore::traversalType&gt;::willValidateIndexCache):
(WebCore::traversalType&gt;::length):
(WebCore::traversalType&gt;::item):
(WebCore::traversalType&gt;::invalidateCache):
(WebCore::traversalType&gt;::elementMatches):
(WebCore::nameShouldBeVisibleInDocumentAll):
(WebCore::traversalType&gt;::namedItem):

* html/CollectionTraversal.h: Added.
Add new template class that provide the collection traversal code
needed by CollectionIndexCache. It has template specializations for
all 3 types of traversal: Descendants, ChildrenOnly, and
CustomForwardOnly.

* html/CollectionType.h:
Add CollectionTypeTraits traits so we can resolve the
CollectionTraversalType used by a specific CollectionType at
compile-time. This is needed for the second template parameter of
CachedHTMLCollection.

* html/GenericCachedHTMLCollection.cpp: Added.
(WebCore::GenericCachedHTMLCollection&lt;traversalType&gt;::elementMatches):
* html/GenericCachedHTMLCollection.h: Added.
Add CachedHTMLCollection subclass is the generic one used for all
CollectionTypes that do not have their own subclass (e.g. NodeChildren).
This has an elementMatches() method with a switch() statement handling
all these CollectionTypes. Those are not normally not performance
sensitive.

* html/HTMLAllCollection.cpp:
(WebCore::HTMLAllCollection::HTMLAllCollection):
* html/HTMLAllCollection.h:
Subclass CachedHTMLCollection instead of HTMLCollection. Also provide
an elementMatches() method that simply returns true as we want to
match all elements.

* html/HTMLCollection.cpp:
(WebCore::HTMLCollection::HTMLCollection):
Move CollectionIndexCache member to the subclass and drop the 2 other
members as they are replaced with the CollectionTraversalType template
parameter of CachedHTMLCollection.

(WebCore::HTMLCollection::~HTMLCollection):
Move Document::unregisterCollection() call to ~CachedHTMLCollection()
as we needed to check if the CollectionIndexCache was valid first.

(WebCore::HTMLCollection::updateNamedElementCache):
Move part of the implementation to the CachedHTMLCollection subclass
as it needs to know about the type of traversal and it needs to be
able to call elementMatches().

* html/HTMLCollection.h:
(WebCore::HTMLCollection::rootNode):
Inline for performance reasons and consistency with CachedLiveNodeList.

(WebCore::HTMLCollection::memoryCost):
Make virtual and move part of the implementation to the
CachedHTMLCollection subclass to compute the cost of the
CollectionIndexCache.

(WebCore::HTMLCollection::invalidateCache):
Move part of the implementation to the subclass to invalidate the
CollectionIndexCache.

* html/HTMLFieldSetElement.cpp:
(WebCore::HTMLFieldSetElement::elements):

* html/HTMLFormControlsCollection.cpp:
* html/HTMLFormControlsCollection.h:
Subclass CachedHTMLCollection instead of HTMLCollection.
customElementAfter() no longer needs to be virtual as it
is called directly by CachedHTMLCollection on the subclass.

* html/HTMLFormElement.cpp:
(WebCore::HTMLFormElement::elements):
* html/HTMLMapElement.cpp:
(WebCore::HTMLMapElement::areas):
Call NodeListsNodeData::addCachedCollection() directly.

* html/HTMLNameCollection.cpp:
* html/HTMLNameCollection.h:
Subclass CachedHTMLCollection instead of HTMLCollection.

* html/HTMLOptionsCollection.cpp:
* html/HTMLOptionsCollection.h:
Subclass CachedHTMLCollection instead of HTMLCollection.

* html/HTMLSelectElement.cpp:
(WebCore::HTMLSelectElement::selectedOptions):
(WebCore::HTMLSelectElement::options):
* html/HTMLTableElement.cpp:
(WebCore::HTMLTableElement::rows):
(WebCore::HTMLTableElement::tBodies):
* html/HTMLTableRowElement.cpp:
(WebCore::HTMLTableRowElement::cells):
Call NodeListsNodeData::addCachedCollection() directly.

* html/HTMLTableRowsCollection.cpp:
* html/HTMLTableRowsCollection.h:
Subclass CachedHTMLCollection instead of HTMLCollection.
customElementAfter() no longer needs to be virtual as it
is called directly by CachedHTMLCollection on the subclass.

* html/HTMLTableSectionElement.cpp:
(WebCore::HTMLTableSectionElement::rows):
Call NodeListsNodeData::addCachedCollection() directly.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorevcxprojWebCorevcxproj">trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoredomContainerNodecpp">trunk/Source/WebCore/dom/ContainerNode.cpp</a></li>
<li><a href="#trunkSourceWebCoredomContainerNodeh">trunk/Source/WebCore/dom/ContainerNode.h</a></li>
<li><a href="#trunkSourceWebCoredomDocumentcpp">trunk/Source/WebCore/dom/Document.cpp</a></li>
<li><a href="#trunkSourceWebCoredomDocumenth">trunk/Source/WebCore/dom/Document.h</a></li>
<li><a href="#trunkSourceWebCoredomElementChildIteratorh">trunk/Source/WebCore/dom/ElementChildIterator.h</a></li>
<li><a href="#trunkSourceWebCoredomElementDescendantIteratorh">trunk/Source/WebCore/dom/ElementDescendantIterator.h</a></li>
<li><a href="#trunkSourceWebCoredomElementIteratorh">trunk/Source/WebCore/dom/ElementIterator.h</a></li>
<li><a href="#trunkSourceWebCoredomElementIteratorAssertionsh">trunk/Source/WebCore/dom/ElementIteratorAssertions.h</a></li>
<li><a href="#trunkSourceWebCoredomLiveNodeListh">trunk/Source/WebCore/dom/LiveNodeList.h</a></li>
<li><a href="#trunkSourceWebCorehtmlCollectionTypeh">trunk/Source/WebCore/html/CollectionType.h</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLAllCollectioncpp">trunk/Source/WebCore/html/HTMLAllCollection.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLAllCollectionh">trunk/Source/WebCore/html/HTMLAllCollection.h</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLCollectioncpp">trunk/Source/WebCore/html/HTMLCollection.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLCollectionh">trunk/Source/WebCore/html/HTMLCollection.h</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLDataListElementcpp">trunk/Source/WebCore/html/HTMLDataListElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLFieldSetElementcpp">trunk/Source/WebCore/html/HTMLFieldSetElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLFormControlsCollectioncpp">trunk/Source/WebCore/html/HTMLFormControlsCollection.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLFormControlsCollectionh">trunk/Source/WebCore/html/HTMLFormControlsCollection.h</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLFormElementcpp">trunk/Source/WebCore/html/HTMLFormElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLMapElementcpp">trunk/Source/WebCore/html/HTMLMapElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLNameCollectioncpp">trunk/Source/WebCore/html/HTMLNameCollection.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLNameCollectionh">trunk/Source/WebCore/html/HTMLNameCollection.h</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLOptionsCollectioncpp">trunk/Source/WebCore/html/HTMLOptionsCollection.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLOptionsCollectionh">trunk/Source/WebCore/html/HTMLOptionsCollection.h</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLSelectElementcpp">trunk/Source/WebCore/html/HTMLSelectElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLTableElementcpp">trunk/Source/WebCore/html/HTMLTableElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLTableRowElementcpp">trunk/Source/WebCore/html/HTMLTableRowElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLTableRowsCollectioncpp">trunk/Source/WebCore/html/HTMLTableRowsCollection.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLTableRowsCollectionh">trunk/Source/WebCore/html/HTMLTableRowsCollection.h</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLTableSectionElementcpp">trunk/Source/WebCore/html/HTMLTableSectionElement.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCorehtmlCachedHTMLCollectionh">trunk/Source/WebCore/html/CachedHTMLCollection.h</a></li>
<li><a href="#trunkSourceWebCorehtmlCollectionTraversalh">trunk/Source/WebCore/html/CollectionTraversal.h</a></li>
<li><a href="#trunkSourceWebCorehtmlGenericCachedHTMLCollectioncpp">trunk/Source/WebCore/html/GenericCachedHTMLCollection.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlGenericCachedHTMLCollectionh">trunk/Source/WebCore/html/GenericCachedHTMLCollection.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/CMakeLists.txt        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -1608,6 +1608,7 @@
</span><span class="cx">     html/FormAssociatedElement.cpp
</span><span class="cx">     html/FormController.cpp
</span><span class="cx">     html/FormDataList.cpp
</span><ins>+    html/GenericCachedHTMLCollection.cpp
</ins><span class="cx">     html/HTMLAllCollection.cpp
</span><span class="cx">     html/HTMLAnchorElement.cpp
</span><span class="cx">     html/HTMLAppletElement.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/ChangeLog        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -1,3 +1,180 @@
</span><ins>+2015-08-15  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        Refactor HTMLCollection to be as fast as CachedLiveNodeList
+        https://bugs.webkit.org/show_bug.cgi?id=147979
+
+        Reviewed by Ryosuke Niwa and Antti Koivisto.
+
+        Refactor HTMLCollection to be as fast as CachedLiveNodeList. This is in
+        preparation of having getElementsByTagName*() / getElementsByClassName()
+        return an HTMLCollection instead of a NodeList, as per the
+        specification. Chrome and Firefox already match the specification in
+        this case.
+
+        Traversing an HTMLCollection was slow because of all the extra
+        branching it had compared to CachedLiveNodeList. To address the issue,
+        this patch introduces a new templated CachedHTMLCollection subclass,
+        which behaves in a similar way as CachedLiveNodeList. The 2 template
+        parameters are:
+        1. The type of the subclass of CachedHTMLCollection, so we can call
+           elementMatches() directly on the subclass, without needed any
+           virtual function call or switch statement. This is the same approach
+           as in CachedLiveNodeList.
+        2. The type of tree traversal used (Descendants, ChildrenOnly,
+           CustomForwardOnly). Unlike LiveNodeList, HTMLCollection needs to
+           support these 3 types of tree traversal. These were causing extra
+           branching for every item() call. We are now able to choose the right
+           type of traversal for the CachedHTMLCollection at compile time.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        Add new files to the Project.
+
+        * dom/ContainerNode.cpp:
+        (WebCore::ContainerNode::children):
+        (WebCore::ContainerNode::cachedHTMLCollection): Deleted.
+        * dom/ContainerNode.h:
+        Drop ContainerNode::ensureCachedHTMLCollection() and use
+        NodeListsNodeData::addCachedCollection() directly at call sites
+        instead. We need access to the CollectionType at build-time so
+        we can resolve the CollectionTraversalType parameter for the
+        GenericCachedHTMLCollection using CollectionTypeTraits.
+
+        * dom/Document.cpp:
+        * dom/Document.h:
+        Update ensureCachedCollection() so the CollectionType is now a template
+        parameter instead of a method argument. We need to know the
+        CollectionType at build time to construct the GenericCachedHTMLCollection.
+
+        * dom/ElementChildIterator.h:
+        (WebCore::ElementChildIterator&lt;ElementType&gt;::operator):
+        (WebCore::ElementChildConstIterator&lt;ElementType&gt;::operator):
+        Add support for decrementing an ElementChildIterator, for consistency
+        with ElementDescendantIterator. We need this to support backward
+        traversal in CachedHTMLCollections that use the 'ChildrenOnly' type
+        of traversal.
+
+        * dom/LiveNodeList.h:
+        (WebCore::CachedLiveNodeList&lt;NodeListType&gt;::collectionBegin):
+        (WebCore::CachedLiveNodeList&lt;NodeListType&gt;::collectionLast):
+        (WebCore::CachedLiveNodeList&lt;NodeListType&gt;::collectionTraverseForward):
+        (WebCore::CachedLiveNodeList&lt;NodeListType&gt;::collectionTraverseBackward):
+        Move traversal implementation to CollectionTraversal.h, so it can be
+        shared with achedHTMLCollection.h.
+
+        * html/CachedHTMLCollection.h: Added.
+        (WebCore::traversalType&gt;::CachedHTMLCollection):
+        (WebCore::traversalType&gt;::~CachedHTMLCollection):
+        (WebCore::traversalType&gt;::CachedHTMLCollection::memoryCost):
+        (WebCore::traversalType&gt;::collectionCanTraverseBackward):
+        (WebCore::traversalType&gt;::collectionTraverseForward):
+        (WebCore::traversalType&gt;::collectionTraverseBackward):
+        (WebCore::traversalType&gt;::willValidateIndexCache):
+        (WebCore::traversalType&gt;::length):
+        (WebCore::traversalType&gt;::item):
+        (WebCore::traversalType&gt;::invalidateCache):
+        (WebCore::traversalType&gt;::elementMatches):
+        (WebCore::nameShouldBeVisibleInDocumentAll):
+        (WebCore::traversalType&gt;::namedItem):
+
+        * html/CollectionTraversal.h: Added.
+        Add new template class that provide the collection traversal code
+        needed by CollectionIndexCache. It has template specializations for
+        all 3 types of traversal: Descendants, ChildrenOnly, and
+        CustomForwardOnly.
+
+        * html/CollectionType.h:
+        Add CollectionTypeTraits traits so we can resolve the
+        CollectionTraversalType used by a specific CollectionType at
+        compile-time. This is needed for the second template parameter of
+        CachedHTMLCollection.
+
+        * html/GenericCachedHTMLCollection.cpp: Added.
+        (WebCore::GenericCachedHTMLCollection&lt;traversalType&gt;::elementMatches):
+        * html/GenericCachedHTMLCollection.h: Added.
+        Add CachedHTMLCollection subclass is the generic one used for all
+        CollectionTypes that do not have their own subclass (e.g. NodeChildren).
+        This has an elementMatches() method with a switch() statement handling
+        all these CollectionTypes. Those are not normally not performance
+        sensitive.
+
+        * html/HTMLAllCollection.cpp:
+        (WebCore::HTMLAllCollection::HTMLAllCollection):
+        * html/HTMLAllCollection.h:
+        Subclass CachedHTMLCollection instead of HTMLCollection. Also provide
+        an elementMatches() method that simply returns true as we want to
+        match all elements.
+
+        * html/HTMLCollection.cpp:
+        (WebCore::HTMLCollection::HTMLCollection):
+        Move CollectionIndexCache member to the subclass and drop the 2 other
+        members as they are replaced with the CollectionTraversalType template
+        parameter of CachedHTMLCollection.
+
+        (WebCore::HTMLCollection::~HTMLCollection):
+        Move Document::unregisterCollection() call to ~CachedHTMLCollection()
+        as we needed to check if the CollectionIndexCache was valid first.
+
+        (WebCore::HTMLCollection::updateNamedElementCache):
+        Move part of the implementation to the CachedHTMLCollection subclass
+        as it needs to know about the type of traversal and it needs to be
+        able to call elementMatches().
+
+        * html/HTMLCollection.h:
+        (WebCore::HTMLCollection::rootNode):
+        Inline for performance reasons and consistency with CachedLiveNodeList.
+
+        (WebCore::HTMLCollection::memoryCost):
+        Make virtual and move part of the implementation to the
+        CachedHTMLCollection subclass to compute the cost of the
+        CollectionIndexCache.
+
+        (WebCore::HTMLCollection::invalidateCache):
+        Move part of the implementation to the subclass to invalidate the
+        CollectionIndexCache.
+
+        * html/HTMLFieldSetElement.cpp:
+        (WebCore::HTMLFieldSetElement::elements):
+
+        * html/HTMLFormControlsCollection.cpp:
+        * html/HTMLFormControlsCollection.h:
+        Subclass CachedHTMLCollection instead of HTMLCollection.
+        customElementAfter() no longer needs to be virtual as it
+        is called directly by CachedHTMLCollection on the subclass.
+
+        * html/HTMLFormElement.cpp:
+        (WebCore::HTMLFormElement::elements):
+        * html/HTMLMapElement.cpp:
+        (WebCore::HTMLMapElement::areas):
+        Call NodeListsNodeData::addCachedCollection() directly.
+
+        * html/HTMLNameCollection.cpp:
+        * html/HTMLNameCollection.h:
+        Subclass CachedHTMLCollection instead of HTMLCollection.
+
+        * html/HTMLOptionsCollection.cpp:
+        * html/HTMLOptionsCollection.h:
+        Subclass CachedHTMLCollection instead of HTMLCollection.
+
+        * html/HTMLSelectElement.cpp:
+        (WebCore::HTMLSelectElement::selectedOptions):
+        (WebCore::HTMLSelectElement::options):
+        * html/HTMLTableElement.cpp:
+        (WebCore::HTMLTableElement::rows):
+        (WebCore::HTMLTableElement::tBodies):
+        * html/HTMLTableRowElement.cpp:
+        (WebCore::HTMLTableRowElement::cells):
+        Call NodeListsNodeData::addCachedCollection() directly.
+
+        * html/HTMLTableRowsCollection.cpp:
+        * html/HTMLTableRowsCollection.h:
+        Subclass CachedHTMLCollection instead of HTMLCollection.
+        customElementAfter() no longer needs to be virtual as it
+        is called directly by CachedHTMLCollection on the subclass.
+
+        * html/HTMLTableSectionElement.cpp:
+        (WebCore::HTMLTableSectionElement::rows):
+        Call NodeListsNodeData::addCachedCollection() directly.
+
</ins><span class="cx"> 2015-08-15  Timothy Horton  &lt;timothy_horton@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         REGRESSION (r168327): ImageDocuments with margins zoom to the wrong position when clicked
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorevcxprojWebCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -16121,6 +16121,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\html\FormController.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\html\FormDataList.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\html\FTPDirectoryDocument.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\html\GenericCachedHTMLCollection.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\html\HiddenInputType.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\html\HTMLAllCollection.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\html\HTMLAnchorElement.cpp&quot;&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -1689,6 +1689,7 @@
</span><span class="cx">                 46C83EFE1A9BBE2900A79A41 /* GeoNotifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 46C83EFC1A9BBE2900A79A41 /* GeoNotifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 46DB7D571B20FE46005651B2 /* VNodeTrackerCocoa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46DB7D561B20FE3C005651B2 /* VNodeTrackerCocoa.cpp */; };
</span><span class="cx">                 46DBB6501AB8C96F00D9A813 /* PowerObserverMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 46DBB64E1AB8C96F00D9A813 /* PowerObserverMac.h */; };
</span><ins>+                46EBEA021B7D4D6500BE4941 /* CollectionTraversal.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EBEA011B7D4D5D00BE4941 /* CollectionTraversal.h */; };
</ins><span class="cx">                 46F3E3F91B2109000087ED13 /* VNodeTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46DB7D581B20FE58005651B2 /* VNodeTracker.cpp */; };
</span><span class="cx">                 46F3E3FA1B2109100087ED13 /* VNodeTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46DB7D591B20FE58005651B2 /* VNodeTracker.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 46FCB6181A70820E00C5A21E /* DiagnosticLoggingKeys.h in Headers */ = {isa = PBXBuildFile; fileRef = CD37B37515C1A7E1006DC898 /* DiagnosticLoggingKeys.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -2673,6 +2674,11 @@
</span><span class="cx">                 82AB1776125C826700C5069D /* InspectorResourceAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 82AB1772125C826700C5069D /* InspectorResourceAgent.h */; };
</span><span class="cx">                 82E3D8DE122EA0D1003AE5BC /* CSSPropertySourceData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 82E3D8DC122EA0D1003AE5BC /* CSSPropertySourceData.cpp */; };
</span><span class="cx">                 82E3D8DF122EA0D1003AE5BC /* CSSPropertySourceData.h in Headers */ = {isa = PBXBuildFile; fileRef = 82E3D8DD122EA0D1003AE5BC /* CSSPropertySourceData.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                830030F51B7D33B500ED3AAC /* GenericCachedHTMLCollection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 830030F31B7D33A600ED3AAC /* GenericCachedHTMLCollection.cpp */; };
+                830030F61B7D33B500ED3AAC /* GenericCachedHTMLCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 830030F41B7D33A600ED3AAC /* GenericCachedHTMLCollection.h */; };
+                830030F81B7D3B7800ED3AAC /* CachedHTMLCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 830030F71B7D398800ED3AAC /* CachedHTMLCollection.h */; };
+                831D48C01B7D9A52006DE39A /* ClassNodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 831D48BE1B7D9A46006DE39A /* ClassNodeList.cpp */; };
+                831D48C11B7D9A52006DE39A /* ClassNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = 831D48BF1B7D9A46006DE39A /* ClassNodeList.h */; };
</ins><span class="cx">                 832B843419D8E55100B26055 /* SVGAnimateElementBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 832B843319D8E55100B26055 /* SVGAnimateElementBase.h */; };
</span><span class="cx">                 832B843619D8E57400B26055 /* SVGAnimateElementBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 832B843519D8E57400B26055 /* SVGAnimateElementBase.cpp */; };
</span><span class="cx">                 83520C7E1A71BFCC006BD2AA /* CSSFontFamily.h in Headers */ = {isa = PBXBuildFile; fileRef = 83520C7D1A71BFCC006BD2AA /* CSSFontFamily.h */; };
</span><span class="lines">@@ -5414,8 +5420,6 @@
</span><span class="cx">                 BC8BF15A1058141800A40A07 /* UserStyleSheetTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = BC8BF1591058141800A40A07 /* UserStyleSheetTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 BC8C8FAD0DDCD31B00B592F4 /* RenderStyle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC8C8FAB0DDCD31B00B592F4 /* RenderStyle.cpp */; };
</span><span class="cx">                 BC8C8FAE0DDCD31B00B592F4 /* RenderStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = BC8C8FAC0DDCD31B00B592F4 /* RenderStyle.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><del>-                BC904B760D10998F00680D32 /* ClassNodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC904B720D10998F00680D32 /* ClassNodeList.cpp */; };
-                BC904B770D10998F00680D32 /* ClassNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = BC904B730D10998F00680D32 /* ClassNodeList.h */; };
</del><span class="cx">                 BC926F800C0552470082776B /* JSHTMLFrameSetElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC926F7E0C0552470082776B /* JSHTMLFrameSetElement.cpp */; };
</span><span class="cx">                 BC926F810C0552470082776B /* JSHTMLFrameSetElement.h in Headers */ = {isa = PBXBuildFile; fileRef = BC926F7F0C0552470082776B /* JSHTMLFrameSetElement.h */; };
</span><span class="cx">                 BC9439C3116CF4940048C750 /* JSNodeCustom.h in Headers */ = {isa = PBXBuildFile; fileRef = BC9439C2116CF4940048C750 /* JSNodeCustom.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -8932,6 +8936,7 @@
</span><span class="cx">                 46DB7D581B20FE58005651B2 /* VNodeTracker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VNodeTracker.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 46DB7D591B20FE58005651B2 /* VNodeTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VNodeTracker.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 46DBB64E1AB8C96F00D9A813 /* PowerObserverMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PowerObserverMac.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                46EBEA011B7D4D5D00BE4941 /* CollectionTraversal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CollectionTraversal.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 490707E41219C04300D90E51 /* ANGLEWebKitBridge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ANGLEWebKitBridge.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 490707E51219C04300D90E51 /* ANGLEWebKitBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANGLEWebKitBridge.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 49291E4A134172C800E753DE /* ImageRenderingMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageRenderingMode.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -10032,6 +10037,11 @@
</span><span class="cx">                 82AB1772125C826700C5069D /* InspectorResourceAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorResourceAgent.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 82E3D8DC122EA0D1003AE5BC /* CSSPropertySourceData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSPropertySourceData.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 82E3D8DD122EA0D1003AE5BC /* CSSPropertySourceData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSPropertySourceData.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                830030F31B7D33A600ED3AAC /* GenericCachedHTMLCollection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GenericCachedHTMLCollection.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                830030F41B7D33A600ED3AAC /* GenericCachedHTMLCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GenericCachedHTMLCollection.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                830030F71B7D398800ED3AAC /* CachedHTMLCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedHTMLCollection.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                831D48BE1B7D9A46006DE39A /* ClassNodeList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ClassNodeList.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                831D48BF1B7D9A46006DE39A /* ClassNodeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClassNodeList.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 832B843319D8E55100B26055 /* SVGAnimateElementBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimateElementBase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 832B843519D8E57400B26055 /* SVGAnimateElementBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAnimateElementBase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 83520C7D1A71BFCC006BD2AA /* CSSFontFamily.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSFontFamily.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -13000,8 +13010,6 @@
</span><span class="cx">                 BC8BF1591058141800A40A07 /* UserStyleSheetTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserStyleSheetTypes.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 BC8C8FAB0DDCD31B00B592F4 /* RenderStyle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderStyle.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 BC8C8FAC0DDCD31B00B592F4 /* RenderStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderStyle.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                BC904B720D10998F00680D32 /* ClassNodeList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ClassNodeList.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
-                BC904B730D10998F00680D32 /* ClassNodeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClassNodeList.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 BC926F7E0C0552470082776B /* JSHTMLFrameSetElement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLFrameSetElement.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 BC926F7F0C0552470082776B /* JSHTMLFrameSetElement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSHTMLFrameSetElement.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 BC9439C2116CF4940048C750 /* JSNodeCustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSNodeCustom.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -18172,10 +18180,12 @@
</span><span class="cx">                                 F55B3D7A1251F12D003EF269 /* BaseTextInputType.h */,
</span><span class="cx">                                 F55B3D7B1251F12D003EF269 /* ButtonInputType.cpp */,
</span><span class="cx">                                 F55B3D7C1251F12D003EF269 /* ButtonInputType.h */,
</span><ins>+                                830030F71B7D398800ED3AAC /* CachedHTMLCollection.h */,
</ins><span class="cx">                                 F55B3D7D1251F12D003EF269 /* CheckboxInputType.cpp */,
</span><span class="cx">                                 F55B3D7E1251F12D003EF269 /* CheckboxInputType.h */,
</span><span class="cx">                                 4ACBC0BC12713CBD0094F9B2 /* ClassList.cpp */,
</span><span class="cx">                                 4ACBC0BD12713CBD0094F9B2 /* ClassList.h */,
</span><ins>+                                46EBEA011B7D4D5D00BE4941 /* CollectionTraversal.h */,
</ins><span class="cx">                                 93C441FF0F813AE100C1A634 /* CollectionType.h */,
</span><span class="cx">                                 BC29935C17A1DD5800BCE880 /* ColorInputType.cpp */,
</span><span class="cx">                                 F55B3D801251F12D003EF269 /* ColorInputType.h */,
</span><span class="lines">@@ -18210,6 +18220,8 @@
</span><span class="cx">                                 9B50B1DC17CD4C0F0087F63C /* FormNamedItem.h */,
</span><span class="cx">                                 97205AAD123928CA00B17380 /* FTPDirectoryDocument.cpp */,
</span><span class="cx">                                 97205AAE123928CA00B17380 /* FTPDirectoryDocument.h */,
</span><ins>+                                830030F31B7D33A600ED3AAC /* GenericCachedHTMLCollection.cpp */,
+                                830030F41B7D33A600ED3AAC /* GenericCachedHTMLCollection.h */,
</ins><span class="cx">                                 F55B3D8B1251F12D003EF269 /* HiddenInputType.cpp */,
</span><span class="cx">                                 F55B3D8C1251F12D003EF269 /* HiddenInputType.h */,
</span><span class="cx">                                 BC97E239109144950010D361 /* HTMLAllCollection.cpp */,
</span><span class="lines">@@ -23165,8 +23177,8 @@
</span><span class="cx">                                 83D26D3C1AFDCC50001B3873 /* ChildNode.idl */,
</span><span class="cx">                                 A818721A0977D3C0005826D9 /* ChildNodeList.cpp */,
</span><span class="cx">                                 A81872150977D3C0005826D9 /* ChildNodeList.h */,
</span><del>-                                BC904B720D10998F00680D32 /* ClassNodeList.cpp */,
-                                BC904B730D10998F00680D32 /* ClassNodeList.h */,
</del><ins>+                                831D48BE1B7D9A46006DE39A /* ClassNodeList.cpp */,
+                                831D48BF1B7D9A46006DE39A /* ClassNodeList.h */,
</ins><span class="cx">                                 BCC065770F3CE1B700CD2D87 /* ClientRect.cpp */,
</span><span class="cx">                                 BCC065780F3CE1B700CD2D87 /* ClientRect.h */,
</span><span class="cx">                                 BCC065790F3CE1B700CD2D87 /* ClientRect.idl */,
</span><span class="lines">@@ -24182,7 +24194,6 @@
</span><span class="cx">                                 14D823520AF92A790004F057 /* Chrome.h in Headers */,
</span><span class="cx">                                 14D824080AF93AEB0004F057 /* ChromeClient.h in Headers */,
</span><span class="cx">                                 4ACBC0BF12713CBD0094F9B2 /* ClassList.h in Headers */,
</span><del>-                                BC904B770D10998F00680D32 /* ClassNodeList.h in Headers */,
</del><span class="cx">                                 BCC0657E0F3CE1B700CD2D87 /* ClientRect.h in Headers */,
</span><span class="cx">                                 BCC065810F3CE1B700CD2D87 /* ClientRectList.h in Headers */,
</span><span class="cx">                                 85031B400A44EFC700F992E0 /* ClipboardEvent.h in Headers */,
</span><span class="lines">@@ -24454,6 +24465,7 @@
</span><span class="cx">                                 8372DB311A6780A800C697C5 /* DiagnosticLoggingResultType.h in Headers */,
</span><span class="cx">                                 CECADFC7153778FF00E37068 /* DictationAlternative.h in Headers */,
</span><span class="cx">                                 CECADFC9153778FF00E37068 /* DictationCommand.h in Headers */,
</span><ins>+                                46EBEA021B7D4D6500BE4941 /* CollectionTraversal.h in Headers */,
</ins><span class="cx">                                 D0BD4F5D1408850F006839B6 /* DictationCommandIOS.h in Headers */,
</span><span class="cx">                                 15145B901B3A1CE000662BF7 /* MediaDeviceInfo.h in Headers */,
</span><span class="cx">                                 316023F01532C40C00D50FF4 /* Dictionary.h in Headers */,
</span><span class="lines">@@ -24559,6 +24571,7 @@
</span><span class="cx">                                 85E711960AC5D5350053270F /* DOMDocumentTypeInternal.h in Headers */,
</span><span class="cx">                                 8518DCE90A9CC80D0091B7A6 /* DOMDOMImplementation.h in Headers */,
</span><span class="cx">                                 85E711970AC5D5350053270F /* DOMDOMImplementationInternal.h in Headers */,
</span><ins>+                                831D48C11B7D9A52006DE39A /* ClassNodeList.h in Headers */,
</ins><span class="cx">                                 52CCA9E815E3F64C0053C77F /* DOMDOMNamedFlowCollection.h in Headers */,
</span><span class="cx">                                 52CCA9EA15E3F64C0053C77F /* DOMDOMNamedFlowCollectionInternal.h in Headers */,
</span><span class="cx">                                 2D9A247415B9C2E300D34527 /* DOMDOMSecurityPolicy.h in Headers */,
</span><span class="lines">@@ -25642,6 +25655,7 @@
</span><span class="cx">                                 FDA15EB212B03EE1003A583A /* JSPannerNode.h in Headers */,
</span><span class="cx">                                 8A9A587511E84C81008ACFD1 /* JSPerformance.h in Headers */,
</span><span class="cx">                                 8A9A587111E84C36008ACFD1 /* JSPerformanceNavigation.h in Headers */,
</span><ins>+                                830030F61B7D33B500ED3AAC /* GenericCachedHTMLCollection.h in Headers */,
</ins><span class="cx">                                 8A9A588811E84F37008ACFD1 /* JSPerformanceTiming.h in Headers */,
</span><span class="cx">                                 FDEA6247152102FC00479DF0 /* JSPeriodicWave.h in Headers */,
</span><span class="cx">                                 93B70D6C09EB0C7C009D8468 /* JSPluginElementFunctions.h in Headers */,
</span><span class="lines">@@ -26982,6 +26996,7 @@
</span><span class="cx">                                 B2227A510D00BF220071B782 /* SVGNumberList.h in Headers */,
</span><span class="cx">                                 B2227A540D00BF220071B782 /* SVGPaint.h in Headers */,
</span><span class="cx">                                 B2227A570D00BF220071B782 /* SVGParserUtilities.h in Headers */,
</span><ins>+                                830030F81B7D3B7800ED3AAC /* CachedHTMLCollection.h in Headers */,
</ins><span class="cx">                                 2D3A0E3613A7D76100E85AF0 /* SVGParsingError.h in Headers */,
</span><span class="cx">                                 84C6784D1214814700A92902 /* SVGPathBlender.h in Headers */,
</span><span class="cx">                                 8476C9EB11DF6A2900555B02 /* SVGPathBuilder.h in Headers */,
</span><span class="lines">@@ -27977,7 +27992,6 @@
</span><span class="cx">                                 14D8238B0AF92DF60004F057 /* Chrome.cpp in Sources */,
</span><span class="cx">                                 ABAF22080C03B1C700B0BCF0 /* ChromeMac.mm in Sources */,
</span><span class="cx">                                 4ACBC0BE12713CBD0094F9B2 /* ClassList.cpp in Sources */,
</span><del>-                                BC904B760D10998F00680D32 /* ClassNodeList.cpp in Sources */,
</del><span class="cx">                                 BCC0657D0F3CE1B700CD2D87 /* ClientRect.cpp in Sources */,
</span><span class="cx">                                 BCC065800F3CE1B700CD2D87 /* ClientRectList.cpp in Sources */,
</span><span class="cx">                                 85031B3F0A44EFC700F992E0 /* ClipboardEvent.cpp in Sources */,
</span><span class="lines">@@ -28984,6 +28998,7 @@
</span><span class="cx">                                 A9C6E64C0D7465E7006442E9 /* JSDOMPluginArrayCustom.cpp in Sources */,
</span><span class="cx">                                 A9C6E64D0D7465E7006442E9 /* JSDOMPluginCustom.cpp in Sources */,
</span><span class="cx">                                 E172AF8F1811BC3700FBADB9 /* JSDOMPromise.cpp in Sources */,
</span><ins>+                                831D48C01B7D9A52006DE39A /* ClassNodeList.cpp in Sources */,
</ins><span class="cx">                                 BC5A86B50C3367E800EEA649 /* JSDOMSelection.cpp in Sources */,
</span><span class="cx">                                 4ACBC0CA12713D0A0094F9B2 /* JSDOMSettableTokenList.cpp in Sources */,
</span><span class="cx">                                 C5137CF211A58378004ADB99 /* JSDOMStringList.cpp in Sources */,
</span><span class="lines">@@ -29276,6 +29291,7 @@
</span><span class="cx">                                 07969DBD17D14151007FF842 /* JSRTCSessionDescriptionCallback.cpp in Sources */,
</span><span class="cx">                                 07D07B141834158800ABDD3C /* JSRTCSessionDescriptionCustom.cpp in Sources */,
</span><span class="cx">                                 07969DBF17D14151007FF842 /* JSRTCStatsCallback.cpp in Sources */,
</span><ins>+                                830030F51B7D33B500ED3AAC /* GenericCachedHTMLCollection.cpp in Sources */,
</ins><span class="cx">                                 07969DC117D14151007FF842 /* JSRTCStatsReport.cpp in Sources */,
</span><span class="cx">                                 07969DC317D14151007FF842 /* JSRTCStatsResponse.cpp in Sources */,
</span><span class="cx">                                 07DC5FD417D3EEE90099F890 /* JSRTCStatsResponseCustom.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoredomContainerNodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/ContainerNode.cpp (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/ContainerNode.cpp        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/dom/ContainerNode.cpp        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &quot;Editor.h&quot;
</span><span class="cx"> #include &quot;FloatRect.h&quot;
</span><span class="cx"> #include &quot;FrameView.h&quot;
</span><ins>+#include &quot;GenericCachedHTMLCollection.h&quot;
</ins><span class="cx"> #include &quot;HTMLFormControlsCollection.h&quot;
</span><span class="cx"> #include &quot;HTMLOptionsCollection.h&quot;
</span><span class="cx"> #include &quot;HTMLTableRowsCollection.h&quot;
</span><span class="lines">@@ -902,7 +903,7 @@
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;HTMLCollection&gt; ContainerNode::children()
</span><span class="cx"> {
</span><del>-    return ensureCachedHTMLCollection(NodeChildren);
</del><ins>+    return ensureRareData().ensureNodeLists().addCachedCollection&lt;GenericCachedHTMLCollection&lt;CollectionTypeTraits&lt;NodeChildren&gt;::traversalType&gt;&gt;(*this, NodeChildren);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Element* ContainerNode::firstElementChild() const
</span><span class="lines">@@ -939,22 +940,6 @@
</span><span class="cx">     insertBefore(node.release(), firstChild(), ec);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Ref&lt;HTMLCollection&gt; ContainerNode::ensureCachedHTMLCollection(CollectionType type)
-{
-    if (HTMLCollection* collection = cachedHTMLCollection(type))
-        return *collection;
-
-    if (type == TableRows)
-        return ensureRareData().ensureNodeLists().addCachedCollection&lt;HTMLTableRowsCollection&gt;(downcast&lt;HTMLTableElement&gt;(*this), type);
-    else if (type == SelectOptions)
-        return ensureRareData().ensureNodeLists().addCachedCollection&lt;HTMLOptionsCollection&gt;(downcast&lt;HTMLSelectElement&gt;(*this), type);
-    else if (type == FormControls) {
-        ASSERT(hasTagName(HTMLNames::formTag) || hasTagName(HTMLNames::fieldsetTag));
-        return ensureRareData().ensureNodeLists().addCachedCollection&lt;HTMLFormControlsCollection&gt;(*this, type);
-    }
-    return ensureRareData().ensureNodeLists().addCachedCollection&lt;HTMLCollection&gt;(*this, type);
-}
-
</del><span class="cx"> HTMLCollection* ContainerNode::cachedHTMLCollection(CollectionType type)
</span><span class="cx"> {
</span><span class="cx">     return hasRareData() &amp;&amp; rareData()-&gt;nodeLists() ? rareData()-&gt;nodeLists()-&gt;cachedCollection&lt;HTMLCollection&gt;(type) : nullptr;
</span></span></pre></div>
<a id="trunkSourceWebCoredomContainerNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/ContainerNode.h (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/ContainerNode.h        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/dom/ContainerNode.h        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -169,7 +169,6 @@
</span><span class="cx">     void setFirstChild(Node* child) { m_firstChild = child; }
</span><span class="cx">     void setLastChild(Node* child) { m_lastChild = child; }
</span><span class="cx"> 
</span><del>-    Ref&lt;HTMLCollection&gt; ensureCachedHTMLCollection(CollectionType);
</del><span class="cx">     HTMLCollection* cachedHTMLCollection(CollectionType);
</span><span class="cx"> 
</span><span class="cx"> private:
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.cpp (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.cpp        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/dom/Document.cpp        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -63,12 +63,12 @@
</span><span class="cx"> #include &quot;FrameLoader.h&quot;
</span><span class="cx"> #include &quot;FrameLoaderClient.h&quot;
</span><span class="cx"> #include &quot;FrameView.h&quot;
</span><ins>+#include &quot;GenericCachedHTMLCollection.h&quot;
</ins><span class="cx"> #include &quot;HTMLAllCollection.h&quot;
</span><span class="cx"> #include &quot;HTMLAnchorElement.h&quot;
</span><span class="cx"> #include &quot;HTMLBaseElement.h&quot;
</span><span class="cx"> #include &quot;HTMLBodyElement.h&quot;
</span><span class="cx"> #include &quot;HTMLCanvasElement.h&quot;
</span><del>-#include &quot;HTMLCollection.h&quot;
</del><span class="cx"> #include &quot;HTMLDocument.h&quot;
</span><span class="cx"> #include &quot;HTMLElementFactory.h&quot;
</span><span class="cx"> #include &quot;HTMLFormControlElement.h&quot;
</span><span class="lines">@@ -4772,50 +4772,51 @@
</span><span class="cx">     return documentElement() &amp;&amp; documentElement()-&gt;hasTagName(SVGNames::svgTag);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Ref&lt;HTMLCollection&gt; Document::ensureCachedCollection(CollectionType type)
</del><ins>+template &lt;CollectionType collectionType&gt;
+Ref&lt;HTMLCollection&gt; Document::ensureCachedCollection()
</ins><span class="cx"> {
</span><del>-    return ensureRareData().ensureNodeLists().addCachedCollection&lt;HTMLCollection&gt;(*this, type);
</del><ins>+    return ensureRareData().ensureNodeLists().addCachedCollection&lt;GenericCachedHTMLCollection&lt;CollectionTypeTraits&lt;collectionType&gt;::traversalType&gt;&gt;(*this, collectionType);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;HTMLCollection&gt; Document::images()
</span><span class="cx"> {
</span><del>-    return ensureCachedCollection(DocImages);
</del><ins>+    return ensureCachedCollection&lt;DocImages&gt;();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;HTMLCollection&gt; Document::applets()
</span><span class="cx"> {
</span><del>-    return ensureCachedCollection(DocApplets);
</del><ins>+    return ensureCachedCollection&lt;DocApplets&gt;();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;HTMLCollection&gt; Document::embeds()
</span><span class="cx"> {
</span><del>-    return ensureCachedCollection(DocEmbeds);
</del><ins>+    return ensureCachedCollection&lt;DocEmbeds&gt;();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;HTMLCollection&gt; Document::plugins()
</span><span class="cx"> {
</span><span class="cx">     // This is an alias for embeds() required for the JS DOM bindings.
</span><del>-    return ensureCachedCollection(DocEmbeds);
</del><ins>+    return ensureCachedCollection&lt;DocEmbeds&gt;();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;HTMLCollection&gt; Document::scripts()
</span><span class="cx"> {
</span><del>-    return ensureCachedCollection(DocScripts);
</del><ins>+    return ensureCachedCollection&lt;DocScripts&gt;();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;HTMLCollection&gt; Document::links()
</span><span class="cx"> {
</span><del>-    return ensureCachedCollection(DocLinks);
</del><ins>+    return ensureCachedCollection&lt;DocLinks&gt;();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;HTMLCollection&gt; Document::forms()
</span><span class="cx"> {
</span><del>-    return ensureCachedCollection(DocForms);
</del><ins>+    return ensureCachedCollection&lt;DocForms&gt;();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;HTMLCollection&gt; Document::anchors()
</span><span class="cx"> {
</span><del>-    return ensureCachedCollection(DocAnchors);
</del><ins>+    return ensureCachedCollection&lt;DocAnchors&gt;();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;HTMLCollection&gt; Document::all()
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.h (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.h        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/dom/Document.h        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -113,7 +113,6 @@
</span><span class="cx"> class HTMLImageElement;
</span><span class="cx"> class HTMLMapElement;
</span><span class="cx"> class HTMLMediaElement;
</span><del>-class HTMLNameCollection;
</del><span class="cx"> class HTMLScriptElement;
</span><span class="cx"> class HitTestRequest;
</span><span class="cx"> class HitTestResult;
</span><span class="lines">@@ -1345,7 +1344,8 @@
</span><span class="cx"> 
</span><span class="cx">     Node* nodeFromPoint(const LayoutPoint&amp; clientPoint, LayoutPoint* localPoint = nullptr);
</span><span class="cx"> 
</span><del>-    Ref&lt;HTMLCollection&gt; ensureCachedCollection(CollectionType);
</del><ins>+    template &lt;CollectionType collectionType&gt;
+    Ref&lt;HTMLCollection&gt; ensureCachedCollection();
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(FULLSCREEN_API)
</span><span class="cx">     void dispatchFullScreenChangeOrErrorEvent(Deque&lt;RefPtr&lt;Node&gt;&gt;&amp;, const AtomicString&amp; eventName, bool shouldNotifyMediaElement);
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementChildIteratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/ElementChildIterator.h (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/ElementChildIterator.h        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/dom/ElementChildIterator.h        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx"> 
</span><span class="cx">     ElementChildIterator(const ContainerNode&amp; parent);
</span><span class="cx">     ElementChildIterator(const ContainerNode&amp; parent, ElementType* current);
</span><ins>+    ElementChildIterator&amp; operator--();
</ins><span class="cx">     ElementChildIterator&amp; operator++();
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -55,6 +56,7 @@
</span><span class="cx"> 
</span><span class="cx">     ElementChildConstIterator(const ContainerNode&amp; parent);
</span><span class="cx">     ElementChildConstIterator(const ContainerNode&amp; parent, const ElementType* current);
</span><ins>+    ElementChildConstIterator&amp; operator--();
</ins><span class="cx">     ElementChildConstIterator&amp; operator++();
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -108,6 +110,12 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename ElementType&gt;
</span><ins>+inline ElementChildIterator&lt;ElementType&gt;&amp; ElementChildIterator&lt;ElementType&gt;::operator--()
+{
+    return static_cast&lt;ElementChildIterator&lt;ElementType&gt;&amp;&gt;(ElementIterator&lt;ElementType&gt;::traversePreviousSibling());
+}
+
+template &lt;typename ElementType&gt;
</ins><span class="cx"> inline ElementChildIterator&lt;ElementType&gt;&amp; ElementChildIterator&lt;ElementType&gt;::operator++()
</span><span class="cx"> {
</span><span class="cx">     return static_cast&lt;ElementChildIterator&lt;ElementType&gt;&amp;&gt;(ElementIterator&lt;ElementType&gt;::traverseNextSibling());
</span><span class="lines">@@ -128,6 +136,13 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename ElementType&gt;
</span><ins>+inline ElementChildConstIterator&lt;ElementType&gt;&amp; ElementChildConstIterator&lt;ElementType&gt;::operator--()
+{
+    return static_cast&lt;ElementChildConstIterator&lt;ElementType&gt;&amp;&gt;(ElementConstIterator&lt;ElementType&gt;::traversePreviousSibling());
+}
+
+
+template &lt;typename ElementType&gt;
</ins><span class="cx"> inline ElementChildConstIterator&lt;ElementType&gt;&amp; ElementChildConstIterator&lt;ElementType&gt;::operator++()
</span><span class="cx"> {
</span><span class="cx">     return static_cast&lt;ElementChildConstIterator&lt;ElementType&gt;&amp;&gt;(ElementConstIterator&lt;ElementType&gt;::traverseNextSibling());
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementDescendantIteratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/ElementDescendantIterator.h (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/ElementDescendantIterator.h        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/dom/ElementDescendantIterator.h        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -47,6 +47,8 @@
</span><span class="cx">     bool operator==(const ElementDescendantIterator&amp; other) const;
</span><span class="cx">     bool operator!=(const ElementDescendantIterator&amp; other) const;
</span><span class="cx"> 
</span><ins>+    void dropAssertions();
+
</ins><span class="cx"> private:
</span><span class="cx">     Element* m_current;
</span><span class="cx">     Vector&lt;Element*, 16&gt; m_ancestorSiblingStack;
</span><span class="lines">@@ -69,6 +71,8 @@
</span><span class="cx">     bool operator==(const ElementDescendantConstIterator&amp; other) const;
</span><span class="cx">     bool operator!=(const ElementDescendantConstIterator&amp; other) const;
</span><span class="cx"> 
</span><ins>+    void dropAssertions();
+
</ins><span class="cx"> private:
</span><span class="cx">     const Element* m_current;
</span><span class="cx">     Vector&lt;Element*, 16, UnsafeVectorOverflow&gt; m_ancestorSiblingStack;
</span><span class="lines">@@ -112,10 +116,20 @@
</span><span class="cx"> 
</span><span class="cx"> inline ElementDescendantIterator::ElementDescendantIterator(Element* current)
</span><span class="cx">     : m_current(current)
</span><ins>+#if !ASSERT_DISABLED
+    , m_assertions(current)
+#endif
</ins><span class="cx"> {
</span><span class="cx">     m_ancestorSiblingStack.uncheckedAppend(nullptr);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline void ElementDescendantIterator::dropAssertions()
+{
+#if !ASSERT_DISABLED
+    m_assertions.clear();
+#endif
+}
+
</ins><span class="cx"> ALWAYS_INLINE ElementDescendantIterator&amp; ElementDescendantIterator::operator++()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_current);
</span><span class="lines">@@ -215,10 +229,20 @@
</span><span class="cx"> 
</span><span class="cx"> inline ElementDescendantConstIterator::ElementDescendantConstIterator(const Element* current)
</span><span class="cx">     : m_current(current)
</span><ins>+#if !ASSERT_DISABLED
+    , m_assertions(current)
+#endif
</ins><span class="cx"> {
</span><span class="cx">     m_ancestorSiblingStack.uncheckedAppend(nullptr);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline void ElementDescendantConstIterator::dropAssertions()
+{
+#if !ASSERT_DISABLED
+    m_assertions.clear();
+#endif
+}
+
</ins><span class="cx"> ALWAYS_INLINE ElementDescendantConstIterator&amp; ElementDescendantConstIterator::operator++()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_current);
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementIteratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/ElementIterator.h (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/ElementIterator.h        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/dom/ElementIterator.h        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -53,6 +53,8 @@
</span><span class="cx">     ElementIterator&amp; traverseNextSkippingChildren();
</span><span class="cx">     ElementIterator&amp; traverseAncestor();
</span><span class="cx"> 
</span><ins>+    void dropAssertions();
+
</ins><span class="cx"> private:
</span><span class="cx">     const ContainerNode* m_root;
</span><span class="cx">     ElementType* m_current;
</span><span class="lines">@@ -81,6 +83,8 @@
</span><span class="cx">     ElementConstIterator&amp; traverseNextSkippingChildren();
</span><span class="cx">     ElementConstIterator&amp; traverseAncestor();
</span><span class="cx"> 
</span><ins>+    void dropAssertions();
+
</ins><span class="cx"> private:
</span><span class="cx">     const ContainerNode* m_root;
</span><span class="cx">     const ElementType* m_current;
</span><span class="lines">@@ -180,6 +184,14 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename ElementType&gt;
</span><ins>+inline void ElementIterator&lt;ElementType&gt;::dropAssertions()
+{
+#if !ASSERT_DISABLED
+    m_assertions.clear();
+#endif
+}
+
+template &lt;typename ElementType&gt;
</ins><span class="cx"> inline ElementType* findElementAncestorOfType(const Element&amp; current)
</span><span class="cx"> {
</span><span class="cx">     for (Element* ancestor = current.parentElement(); ancestor; ancestor = ancestor-&gt;parentElement()) {
</span><span class="lines">@@ -345,6 +357,14 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename ElementType&gt;
</span><ins>+inline void ElementConstIterator&lt;ElementType&gt;::dropAssertions()
+{
+#if !ASSERT_DISABLED
+    m_assertions.clear();
+#endif
+}
+
+template &lt;typename ElementType&gt;
</ins><span class="cx"> inline const ElementType&amp; ElementConstIterator&lt;ElementType&gt;::operator*() const
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_current);
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementIteratorAssertionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/ElementIteratorAssertions.h (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/ElementIteratorAssertions.h        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/dom/ElementIteratorAssertions.h        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -35,6 +35,7 @@
</span><span class="cx">     ElementIteratorAssertions(const Element* first = nullptr);
</span><span class="cx">     bool domTreeHasMutated() const;
</span><span class="cx">     void dropEventDispatchAssertion();
</span><ins>+    void clear();
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     const Document* m_document;
</span><span class="lines">@@ -62,6 +63,14 @@
</span><span class="cx">     m_eventDispatchAssertion = Nullopt;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline void ElementIteratorAssertions::clear()
+{
+    m_document = nullptr;
+    m_initialDOMTreeVersion = 0;
+    m_eventDispatchAssertion = Nullopt;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+
+}
+
</ins><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCoredomLiveNodeListh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/LiveNodeList.h (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/LiveNodeList.h        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/dom/LiveNodeList.h        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -25,6 +25,7 @@
</span><span class="cx"> #define LiveNodeList_h
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CollectionIndexCache.h&quot;
</span><ins>+#include &quot;CollectionTraversal.h&quot;
</ins><span class="cx"> #include &quot;CollectionType.h&quot;
</span><span class="cx"> #include &quot;Document.h&quot;
</span><span class="cx"> #include &quot;ElementDescendantIterator.h&quot;
</span><span class="lines">@@ -80,25 +81,28 @@
</span><span class="cx"> public:
</span><span class="cx">     virtual ~CachedLiveNodeList();
</span><span class="cx"> 
</span><del>-    virtual unsigned length() const override final;
-    virtual Node* item(unsigned offset) const override final;
</del><ins>+    unsigned length() const override final { return m_indexCache.nodeCount(nodeList()); }
+    Node* item(unsigned offset) const override final { return m_indexCache.nodeAt(nodeList(), offset); }
</ins><span class="cx"> 
</span><span class="cx">     // For CollectionIndexCache
</span><del>-    ElementDescendantIterator collectionBegin() const;
-    ElementDescendantIterator collectionLast() const;
</del><ins>+    ElementDescendantIterator collectionBegin() const { return CollectionTraversal&lt;CollectionTraversalType::Descendants&gt;::begin(nodeList(), rootNode()); }
+    ElementDescendantIterator collectionLast() const { return CollectionTraversal&lt;CollectionTraversalType::Descendants&gt;::last(nodeList(), rootNode()); }
</ins><span class="cx">     ElementDescendantIterator collectionEnd() const { return ElementDescendantIterator(); }
</span><del>-    void collectionTraverseForward(ElementDescendantIterator&amp;, unsigned count, unsigned&amp; traversedCount) const;
-    void collectionTraverseBackward(ElementDescendantIterator&amp;, unsigned count) const;
</del><ins>+    void collectionTraverseForward(ElementDescendantIterator&amp; current, unsigned count, unsigned&amp; traversedCount) const { CollectionTraversal&lt;CollectionTraversalType::Descendants&gt;::traverseForward(nodeList(), current, count, traversedCount); }
+    void collectionTraverseBackward(ElementDescendantIterator&amp; current, unsigned count) const { CollectionTraversal&lt;CollectionTraversalType::Descendants&gt;::traverseBackward(nodeList(), current, count); }
</ins><span class="cx">     bool collectionCanTraverseBackward() const { return true; }
</span><del>-    void willValidateIndexCache() const;
</del><ins>+    void willValidateIndexCache() const { document().registerNodeListForInvalidation(const_cast&lt;CachedLiveNodeList&lt;NodeListType&gt;&amp;&gt;(*this)); }
</ins><span class="cx"> 
</span><span class="cx">     virtual void invalidateCache(Document&amp;) const override final;
</span><del>-    virtual size_t memoryCost() const override final;
</del><ins>+    virtual size_t memoryCost() const override final { return m_indexCache.memoryCost(); }
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     CachedLiveNodeList(ContainerNode&amp; rootNode, NodeListInvalidationType);
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    NodeListType&amp; nodeList() { return static_cast&lt;NodeListType&amp;&gt;(*this); }
+    const NodeListType&amp; nodeList() const { return static_cast&lt;const NodeListType&amp;&gt;(*this); }
+
</ins><span class="cx">     ContainerNode&amp; rootNode() const;
</span><span class="cx"> 
</span><span class="cx">     mutable CollectionIndexCache&lt;NodeListType, ElementDescendantIterator&gt; m_indexCache;
</span><span class="lines">@@ -131,117 +135,35 @@
</span><span class="cx"> template &lt;class NodeListType&gt;
</span><span class="cx"> CachedLiveNodeList&lt;NodeListType&gt;::CachedLiveNodeList(ContainerNode&amp; ownerNode, NodeListInvalidationType invalidationType)
</span><span class="cx">     : LiveNodeList(ownerNode, invalidationType)
</span><del>-    , m_indexCache(static_cast&lt;NodeListType&amp;&gt;(*this))
</del><ins>+    , m_indexCache(nodeList())
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template &lt;class NodeListType&gt;
</span><span class="cx"> CachedLiveNodeList&lt;NodeListType&gt;::~CachedLiveNodeList()
</span><span class="cx"> {
</span><del>-    auto&amp; nodeList = static_cast&lt;const NodeListType&amp;&gt;(*this);
-    if (m_indexCache.hasValidCache(nodeList))
</del><ins>+    if (m_indexCache.hasValidCache(nodeList()))
</ins><span class="cx">         document().unregisterNodeListForInvalidation(*this);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template &lt;class NodeListType&gt;
</span><span class="cx"> inline ContainerNode&amp; CachedLiveNodeList&lt;NodeListType&gt;::rootNode() const
</span><span class="cx"> {
</span><del>-    if (static_cast&lt;const NodeListType&amp;&gt;(*this).isRootedAtDocument() &amp;&amp; ownerNode().inDocument())
</del><ins>+    if (nodeList().isRootedAtDocument() &amp;&amp; ownerNode().inDocument())
</ins><span class="cx">         return ownerNode().document();
</span><span class="cx"> 
</span><span class="cx">     return ownerNode();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template &lt;class NodeListType&gt;
</span><del>-ElementDescendantIterator CachedLiveNodeList&lt;NodeListType&gt;::collectionBegin() const
-{
-    auto&amp; nodeList = static_cast&lt;const NodeListType&amp;&gt;(*this);
-    auto descendants = elementDescendants(rootNode());
-    auto end = descendants.end();
-    for (auto it = descendants.begin(); it != end; ++it) {
-        if (nodeList.elementMatches(*it))
-            return it;
-    }
-    return end;
-}
-
-template &lt;class NodeListType&gt;
-ElementDescendantIterator CachedLiveNodeList&lt;NodeListType&gt;::collectionLast() const
-{
-    auto&amp; nodeList = static_cast&lt;const NodeListType&amp;&gt;(*this);
-    auto descendants = elementDescendants(rootNode());
-    auto end = descendants.end();
-    for (auto it = descendants.last(); it != end; --it) {
-        if (nodeList.elementMatches(*it))
-            return it;
-    }
-    return end;
-}
-
-template &lt;class NodeListType&gt;
-void CachedLiveNodeList&lt;NodeListType&gt;::collectionTraverseForward(ElementDescendantIterator&amp; current, unsigned count, unsigned&amp; traversedCount) const
-{
-    auto&amp; nodeList = static_cast&lt;const NodeListType&amp;&gt;(*this);
-    ASSERT(nodeList.elementMatches(*current));
-    auto end = collectionEnd();
-    for (traversedCount = 0; traversedCount &lt; count; ++traversedCount) {
-        do {
-            ++current;
-            if (current == end)
-                return;
-        } while (!nodeList.elementMatches(*current));
-    }
-}
-
-template &lt;class NodeListType&gt;
-void CachedLiveNodeList&lt;NodeListType&gt;::collectionTraverseBackward(ElementDescendantIterator&amp; current, unsigned count) const
-{
-    auto&amp; nodeList = static_cast&lt;const NodeListType&amp;&gt;(*this);
-    ASSERT(nodeList.elementMatches(*current));
-    auto end = collectionEnd();
-    for (; count; --count) {
-        do {
-            --current;
-            if (current == end)
-                return;
-        } while (!nodeList.elementMatches(*current));
-    }
-}
-
-template &lt;class NodeListType&gt;
-void CachedLiveNodeList&lt;NodeListType&gt;::willValidateIndexCache() const
-{
-    document().registerNodeListForInvalidation(const_cast&lt;NodeListType&amp;&gt;(static_cast&lt;const NodeListType&amp;&gt;(*this)));
-}
-
-template &lt;class NodeListType&gt;
</del><span class="cx"> void CachedLiveNodeList&lt;NodeListType&gt;::invalidateCache(Document&amp; document) const
</span><span class="cx"> {
</span><del>-    auto&amp; nodeList = static_cast&lt;const NodeListType&amp;&gt;(*this);
-    if (!m_indexCache.hasValidCache(nodeList))
</del><ins>+    if (!m_indexCache.hasValidCache(nodeList()))
</ins><span class="cx">         return;
</span><del>-    document.unregisterNodeListForInvalidation(const_cast&lt;NodeListType&amp;&gt;(nodeList));
-    m_indexCache.invalidate(nodeList);
</del><ins>+    document.unregisterNodeListForInvalidation(const_cast&lt;NodeListType&amp;&gt;(nodeList()));
+    m_indexCache.invalidate(nodeList());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-template &lt;class NodeListType&gt;
-unsigned CachedLiveNodeList&lt;NodeListType&gt;::length() const
-{
-    return m_indexCache.nodeCount(static_cast&lt;const NodeListType&amp;&gt;(*this));
-}
-
-template &lt;class NodeListType&gt;
-Node* CachedLiveNodeList&lt;NodeListType&gt;::item(unsigned offset) const
-{
-    return m_indexCache.nodeAt(static_cast&lt;const NodeListType&amp;&gt;(*this), offset);
-}
-
-template &lt;class NodeListType&gt;
-size_t CachedLiveNodeList&lt;NodeListType&gt;::memoryCost() const
-{
-    return m_indexCache.memoryCost();
-}
-
</del><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // LiveNodeList_h
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlCachedHTMLCollectionh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/html/CachedHTMLCollection.h (0 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/CachedHTMLCollection.h                                (rev 0)
+++ trunk/Source/WebCore/html/CachedHTMLCollection.h        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -0,0 +1,158 @@
</span><ins>+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef CachedHTMLCollection_h
+#define CachedHTMLCollection_h
+
+#include &quot;CollectionTraversal.h&quot;
+#include &quot;HTMLCollection.h&quot;
+#include &quot;HTMLElement.h&quot;
+
+namespace WebCore {
+
+template &lt;typename HTMLCollectionClass, CollectionTraversalType traversalType&gt;
+class CachedHTMLCollection : public HTMLCollection {
+public:
+    CachedHTMLCollection(ContainerNode&amp; base, CollectionType);
+
+    virtual ~CachedHTMLCollection();
+
+    virtual unsigned length() const override final { return m_indexCache.nodeCount(collection()); }
+    virtual Element* item(unsigned offset) const override final { return m_indexCache.nodeAt(collection(), offset); }
+    virtual Element* namedItem(const AtomicString&amp; name) const override;
+    virtual size_t memoryCost() const override final { return m_indexCache.memoryCost() + HTMLCollection::memoryCost(); }
+
+    // For CollectionIndexCache; do not use elsewhere.
+    using CollectionTraversalIterator = typename CollectionTraversal&lt;traversalType&gt;::Iterator;
+    CollectionTraversalIterator collectionBegin() const { return CollectionTraversal&lt;traversalType&gt;::begin(collection(), rootNode()); }
+    CollectionTraversalIterator collectionLast() const { return CollectionTraversal&lt;traversalType&gt;::last(collection(), rootNode()); }
+    CollectionTraversalIterator collectionEnd() const { return CollectionTraversal&lt;traversalType&gt;::end(rootNode()); }
+    void collectionTraverseForward(CollectionTraversalIterator&amp; current, unsigned count, unsigned&amp; traversedCount) const { CollectionTraversal&lt;traversalType&gt;::traverseForward(collection(), current, count, traversedCount); }
+    void collectionTraverseBackward(CollectionTraversalIterator&amp; current, unsigned count) const { CollectionTraversal&lt;traversalType&gt;::traverseBackward(collection(), current, count); }
+    bool collectionCanTraverseBackward() const { return traversalType != CollectionTraversalType::CustomForwardOnly; }
+    void willValidateIndexCache() const { document().registerCollection(const_cast&lt;CachedHTMLCollection&lt;HTMLCollectionClass, traversalType&gt;&amp;&gt;(*this)); }
+
+    virtual void invalidateCache(Document&amp;) override;
+
+    bool elementMatches(Element&amp;) const;
+
+private:
+    HTMLCollectionClass&amp; collection() { return static_cast&lt;HTMLCollectionClass&amp;&gt;(*this); }
+    const HTMLCollectionClass&amp; collection() const { return static_cast&lt;const HTMLCollectionClass&amp;&gt;(*this); }
+
+    mutable CollectionIndexCache&lt;HTMLCollectionClass, CollectionTraversalIterator&gt; m_indexCache;
+};
+
+template &lt;typename HTMLCollectionClass, CollectionTraversalType traversalType&gt;
+CachedHTMLCollection&lt;HTMLCollectionClass, traversalType&gt;::CachedHTMLCollection(ContainerNode&amp; base, CollectionType collectionType)
+    : HTMLCollection(base, collectionType)
+    , m_indexCache(collection())
+{ }
+
+template &lt;typename HTMLCollectionClass, CollectionTraversalType traversalType&gt;
+CachedHTMLCollection&lt;HTMLCollectionClass, traversalType&gt;::~CachedHTMLCollection()
+{
+    if (m_indexCache.hasValidCache(collection()))
+        document().unregisterCollection(*this);
+}
+
+template &lt;typename HTMLCollectionClass, CollectionTraversalType traversalType&gt;
+void CachedHTMLCollection&lt;HTMLCollectionClass, traversalType&gt;::invalidateCache(Document&amp; document)
+{
+    HTMLCollection::invalidateCache(document);
+    if (m_indexCache.hasValidCache(collection())) {
+        document.unregisterCollection(*this);
+        m_indexCache.invalidate(collection());
+    }
+}
+
+template &lt;typename HTMLCollectionClass, CollectionTraversalType traversalType&gt;
+bool CachedHTMLCollection&lt;HTMLCollectionClass, traversalType&gt;::elementMatches(Element&amp;) const
+{
+    // We call the elementMatches() method directly on the subclass instead for performance.
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
+static inline bool nameShouldBeVisibleInDocumentAll(HTMLElement&amp; element)
+{
+    // The document.all collection returns only certain types of elements by name,
+    // although it returns any type of element by id.
+    return element.hasTagName(HTMLNames::appletTag)
+        || element.hasTagName(HTMLNames::embedTag)
+        || element.hasTagName(HTMLNames::formTag)
+        || element.hasTagName(HTMLNames::imgTag)
+        || element.hasTagName(HTMLNames::inputTag)
+        || element.hasTagName(HTMLNames::objectTag)
+        || element.hasTagName(HTMLNames::selectTag);
+}
+
+static inline bool nameShouldBeVisibleInDocumentAll(Element&amp; element)
+{
+    return is&lt;HTMLElement&gt;(element) &amp;&amp; nameShouldBeVisibleInDocumentAll(downcast&lt;HTMLElement&gt;(element));
+}
+
+template &lt;typename HTMLCollectionClass, CollectionTraversalType traversalType&gt;
+Element* CachedHTMLCollection&lt;HTMLCollectionClass, traversalType&gt;::namedItem(const AtomicString&amp; name) const
+{
+    // http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/nameditem.asp
+    // This method first searches for an object with a matching id
+    // attribute. If a match is not found, the method then searches for an
+    // object with a matching name attribute, but only on those elements
+    // that are allowed a name attribute.
+
+    if (name.isEmpty())
+        return nullptr;
+
+    ContainerNode&amp; root = rootNode();
+    if (traversalType != CollectionTraversalType::CustomForwardOnly &amp;&amp; root.isInTreeScope()) {
+        Element* candidate = nullptr;
+
+        TreeScope&amp; treeScope = root.treeScope();
+        if (treeScope.hasElementWithId(*name.impl())) {
+            if (!treeScope.containsMultipleElementsWithId(name))
+                candidate = treeScope.getElementById(name);
+        } else if (treeScope.hasElementWithName(*name.impl())) {
+            if (!treeScope.containsMultipleElementsWithName(name)) {
+                candidate = treeScope.getElementByName(name);
+                if (candidate &amp;&amp; type() == DocAll &amp;&amp; !nameShouldBeVisibleInDocumentAll(*candidate))
+                    candidate = nullptr;
+            }
+        } else
+            return nullptr;
+
+        if (candidate &amp;&amp; collection().elementMatches(*candidate)) {
+            if (traversalType == CollectionTraversalType::ChildrenOnly ? candidate-&gt;parentNode() == &amp;root : candidate-&gt;isDescendantOf(&amp;root))
+                return candidate;
+        }
+    }
+
+    return namedItemSlow(name);
+}
+
+} // namespace WebCore
+
+#endif // CachedHTMLCollection_h
+
</ins></span></pre></div>
<a id="trunkSourceWebCorehtmlCollectionTraversalh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/html/CollectionTraversal.h (0 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/CollectionTraversal.h                                (rev 0)
+++ trunk/Source/WebCore/html/CollectionTraversal.h        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -0,0 +1,248 @@
</span><ins>+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef CollectionTraversal_h
+#define CollectionTraversal_h
+
+#include &quot;CollectionType.h&quot;
+#include &quot;ElementChildIterator.h&quot;
+#include &quot;ElementDescendantIterator.h&quot;
+
+namespace WebCore {
+
+template &lt;CollectionTraversalType traversalType&gt;
+struct CollectionTraversal { };
+
+template &lt;&gt;
+struct CollectionTraversal&lt;CollectionTraversalType::Descendants&gt; {
+    using Iterator = ElementDescendantIterator;
+
+    static ElementDescendantIterator end(ContainerNode&amp;) { return ElementDescendantIterator(); }
+
+    template &lt;typename CollectionClass&gt;
+    static ElementDescendantIterator begin(const CollectionClass&amp;, ContainerNode&amp; rootNode);
+
+    template &lt;typename CollectionClass&gt;
+    static ElementDescendantIterator last(const CollectionClass&amp;, ContainerNode&amp; rootNode);
+
+    template &lt;typename CollectionClass&gt;
+    static void traverseForward(const CollectionClass&amp;, ElementDescendantIterator&amp; current, unsigned count, unsigned&amp; traversedCount);
+
+    template &lt;typename CollectionClass&gt;
+    static void traverseBackward(const CollectionClass&amp;, ElementDescendantIterator&amp; current, unsigned count);
+};
+
+template &lt;typename CollectionClass&gt;
+inline ElementDescendantIterator CollectionTraversal&lt;CollectionTraversalType::Descendants&gt;::begin(const CollectionClass&amp; collection, ContainerNode&amp; rootNode)
+{
+    auto descendants = elementDescendants(rootNode);
+    auto end = descendants.end();
+    for (auto it = descendants.begin(); it != end; ++it) {
+        if (collection.elementMatches(*it)) {
+            // Drop iterator assertions because HTMLCollections / NodeList use a fine-grained invalidation scheme.
+            it.dropAssertions();
+            return it;
+        }
+    }
+    return end;
+}
+
+template &lt;typename CollectionClass&gt;
+inline ElementDescendantIterator CollectionTraversal&lt;CollectionTraversalType::Descendants&gt;::last(const CollectionClass&amp; collection, ContainerNode&amp; rootNode)
+{
+    auto descendants = elementDescendants(rootNode);
+    ElementDescendantIterator invalid;
+    for (auto it = descendants.last(); it != invalid; --it) {
+        if (collection.elementMatches(*it)) {
+            // Drop iterator assertions because HTMLCollections / NodeList use a fine-grained invalidation scheme.
+            it.dropAssertions();
+            return it;
+        }
+    }
+    return invalid;
+}
+
+template &lt;typename CollectionClass&gt;
+inline void CollectionTraversal&lt;CollectionTraversalType::Descendants&gt;::traverseForward(const CollectionClass&amp; collection, ElementDescendantIterator&amp; current, unsigned count, unsigned&amp; traversedCount)
+{
+    ASSERT(collection.elementMatches(*current));
+    ElementDescendantIterator invalid;
+    for (traversedCount = 0; traversedCount &lt; count; ++traversedCount) {
+        do {
+            ++current;
+            if (current == invalid)
+                return;
+        } while (!collection.elementMatches(*current));
+    }
+}
+
+template &lt;typename CollectionClass&gt;
+inline void CollectionTraversal&lt;CollectionTraversalType::Descendants&gt;::traverseBackward(const CollectionClass&amp; collection, ElementDescendantIterator&amp; current, unsigned count)
+{
+    ASSERT(collection.elementMatches(*current));
+    ElementDescendantIterator invalid;
+    for (; count; --count) {
+        do {
+            --current;
+            if (current == invalid)
+                return;
+        } while (!collection.elementMatches(*current));
+    }
+}
+
+template &lt;&gt;
+struct CollectionTraversal&lt;CollectionTraversalType::ChildrenOnly&gt; {
+    using Iterator = ElementChildIterator&lt;Element&gt;;
+
+    static ElementChildIterator&lt;Element&gt; end(ContainerNode&amp; rootNode) { return ElementChildIterator&lt;Element&gt;(rootNode); }
+
+    template &lt;typename CollectionClass&gt;
+    static ElementChildIterator&lt;Element&gt; begin(const CollectionClass&amp;, ContainerNode&amp; rootNode);
+
+    template &lt;typename CollectionClass&gt;
+    static ElementChildIterator&lt;Element&gt; last(const CollectionClass&amp;, ContainerNode&amp; rootNode);
+
+    template &lt;typename CollectionClass&gt;
+    static void traverseForward(const CollectionClass&amp;, ElementChildIterator&lt;Element&gt;&amp; current, unsigned count, unsigned&amp; traversedCount);
+
+    template &lt;typename CollectionClass&gt;
+    static void traverseBackward(const CollectionClass&amp;, ElementChildIterator&lt;Element&gt;&amp; current, unsigned count);
+};
+
+template &lt;typename CollectionClass&gt;
+inline ElementChildIterator&lt;Element&gt; CollectionTraversal&lt;CollectionTraversalType::ChildrenOnly&gt;::begin(const CollectionClass&amp; collection, ContainerNode&amp; rootNode)
+{
+    auto children = childrenOfType&lt;Element&gt;(rootNode);
+    auto end = children.end();
+    for (auto it = children.begin(); it != end; ++it) {
+        if (collection.elementMatches(*it)) {
+            // Drop iterator assertions because HTMLCollections / NodeList use a fine-grained invalidation scheme.
+            it.dropAssertions();
+            return it;
+        }
+    }
+    return end;
+}
+
+template &lt;typename CollectionClass&gt;
+inline ElementChildIterator&lt;Element&gt; CollectionTraversal&lt;CollectionTraversalType::ChildrenOnly&gt;::last(const CollectionClass&amp; collection, ContainerNode&amp; rootNode)
+{
+    auto children = childrenOfType&lt;Element&gt;(rootNode);
+    ElementChildIterator&lt;Element&gt; invalid(collection.rootNode());
+    ElementChildIterator&lt;Element&gt; last(rootNode, children.last());
+    for (auto it = last; it != invalid; --it) {
+        if (collection.elementMatches(*it)) {
+            // Drop iterator assertions because HTMLCollections / NodeList use a fine-grained invalidation scheme.
+            it.dropAssertions();
+            return it;
+        }
+    }
+    return invalid;
+}
+
+template &lt;typename CollectionClass&gt;
+inline void CollectionTraversal&lt;CollectionTraversalType::ChildrenOnly&gt;::traverseForward(const CollectionClass&amp; collection, ElementChildIterator&lt;Element&gt;&amp; current, unsigned count, unsigned&amp; traversedCount)
+{
+    ASSERT(collection.elementMatches(*current));
+    ElementChildIterator&lt;Element&gt; invalid(collection.rootNode());
+    for (traversedCount = 0; traversedCount &lt; count; ++traversedCount) {
+        do {
+            ++current;
+            if (current == invalid)
+                return;
+        } while (!collection.elementMatches(*current));
+    }
+}
+
+template &lt;typename CollectionClass&gt;
+inline void CollectionTraversal&lt;CollectionTraversalType::ChildrenOnly&gt;::traverseBackward(const CollectionClass&amp; collection, ElementChildIterator&lt;Element&gt;&amp; current, unsigned count)
+{
+    ASSERT(collection.elementMatches(*current));
+    ElementChildIterator&lt;Element&gt; invalid(collection.rootNode());
+    for (; count; --count) {
+        do {
+            --current;
+            if (current == invalid)
+                return;
+        } while (!collection.elementMatches(*current));
+    }
+}
+
+template &lt;&gt;
+struct CollectionTraversal&lt;CollectionTraversalType::CustomForwardOnly&gt; {
+    using Iterator = Element*;
+
+    static Element* end(ContainerNode&amp;) { return nullptr; }
+
+    template &lt;typename CollectionClass&gt;
+    static Element* begin(const CollectionClass&amp;, ContainerNode&amp;);
+
+    template &lt;typename CollectionClass&gt;
+    static Element* last(const CollectionClass&amp;, ContainerNode&amp;);
+
+    template &lt;typename CollectionClass&gt;
+    static void traverseForward(const CollectionClass&amp;, Element*&amp; current, unsigned count, unsigned&amp; traversedCount);
+
+    template &lt;typename CollectionClass&gt;
+    static void traverseBackward(const CollectionClass&amp;, Element*&amp;, unsigned count);
+};
+
+template &lt;typename CollectionClass&gt;
+inline Element* CollectionTraversal&lt;CollectionTraversalType::CustomForwardOnly&gt;::begin(const CollectionClass&amp; collection, ContainerNode&amp;)
+{
+    return collection.customElementAfter(nullptr);
+}
+
+template &lt;typename CollectionClass&gt;
+inline Element* CollectionTraversal&lt;CollectionTraversalType::CustomForwardOnly&gt;::last(const CollectionClass&amp;, ContainerNode&amp;)
+{
+    ASSERT_NOT_REACHED();
+    return nullptr;
+}
+
+template &lt;typename CollectionClass&gt;
+inline void CollectionTraversal&lt;CollectionTraversalType::CustomForwardOnly&gt;::traverseForward(const CollectionClass&amp; collection, Element*&amp; current, unsigned count, unsigned&amp; traversedCount)
+{
+    Element* element = current;
+    for (traversedCount = 0; traversedCount &lt; count; ++traversedCount) {
+        element = collection.customElementAfter(element);
+        if (!element) {
+            current = nullptr;
+            return;
+        }
+    }
+    current = element;
+}
+
+template &lt;typename CollectionClass&gt;
+inline void CollectionTraversal&lt;CollectionTraversalType::CustomForwardOnly&gt;::traverseBackward(const CollectionClass&amp;, Element*&amp;, unsigned count)
+{
+    UNUSED_PARAM(count);
+    ASSERT_NOT_REACHED();
+}
+
+} // namespace WebCore
+
+#endif // CollectionTraversal_h
</ins></span></pre></div>
<a id="trunkSourceWebCorehtmlCollectionTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/CollectionType.h (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/CollectionType.h        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/html/CollectionType.h        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -53,6 +53,42 @@
</span><span class="cx">     FormControls
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-} // namespace
</del><ins>+enum class CollectionTraversalType { Descendants, ChildrenOnly, CustomForwardOnly };
+template&lt;CollectionType collectionType&gt;
+struct CollectionTypeTraits {
+    static const CollectionTraversalType traversalType = CollectionTraversalType::Descendants;
+};
</ins><span class="cx"> 
</span><ins>+template&lt;&gt;
+struct CollectionTypeTraits&lt;NodeChildren&gt; {
+    static const CollectionTraversalType traversalType = CollectionTraversalType::ChildrenOnly;
+};
+
+template&lt;&gt;
+struct CollectionTypeTraits&lt;TRCells&gt; {
+    static const CollectionTraversalType traversalType = CollectionTraversalType::ChildrenOnly;
+};
+
+template&lt;&gt;
+struct CollectionTypeTraits&lt;TSectionRows&gt; {
+    static const CollectionTraversalType traversalType = CollectionTraversalType::ChildrenOnly;
+};
+
+template&lt;&gt;
+struct CollectionTypeTraits&lt;TableTBodies&gt; {
+    static const CollectionTraversalType traversalType = CollectionTraversalType::ChildrenOnly;
+};
+
+template&lt;&gt;
+struct CollectionTypeTraits&lt;TableRows&gt; {
+    static const CollectionTraversalType traversalType = CollectionTraversalType::CustomForwardOnly;
+};
+
+template&lt;&gt;
+struct CollectionTypeTraits&lt;FormControls&gt; {
+    static const CollectionTraversalType traversalType = CollectionTraversalType::CustomForwardOnly;
+};
+
+} // namespace WebCore
+
</ins><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlGenericCachedHTMLCollectioncpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/html/GenericCachedHTMLCollection.cpp (0 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/GenericCachedHTMLCollection.cpp                                (rev 0)
+++ trunk/Source/WebCore/html/GenericCachedHTMLCollection.cpp        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -0,0 +1,89 @@
</span><ins>+/*
+ * Copyright (C) 2015 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.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;GenericCachedHTMLCollection.h&quot;
+
+#include &quot;HTMLNames.h&quot;
+#include &quot;HTMLObjectElement.h&quot;
+#include &quot;HTMLOptionElement.h&quot;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+template &lt;CollectionTraversalType traversalType&gt;
+bool GenericCachedHTMLCollection&lt;traversalType&gt;::elementMatches(Element&amp; element) const
+{
+    switch (this-&gt;type()) {
+    case NodeChildren:
+        return true;
+    case DocImages:
+        return element.hasTagName(imgTag);
+    case DocScripts:
+        return element.hasTagName(scriptTag);
+    case DocForms:
+        return element.hasTagName(formTag);
+    case TableTBodies:
+        return element.hasTagName(tbodyTag);
+    case TRCells:
+        return element.hasTagName(tdTag) || element.hasTagName(thTag);
+    case TSectionRows:
+        return element.hasTagName(trTag);
+    case SelectedOptions:
+        return is&lt;HTMLOptionElement&gt;(element) &amp;&amp; downcast&lt;HTMLOptionElement&gt;(element).selected();
+    case DataListOptions:
+        if (is&lt;HTMLOptionElement&gt;(element)) {
+            HTMLOptionElement&amp; option = downcast&lt;HTMLOptionElement&gt;(element);
+            if (!option.isDisabledFormControl() &amp;&amp; !option.value().isEmpty())
+                return true;
+        }
+        return false;
+    case MapAreas:
+        return element.hasTagName(areaTag);
+    case DocApplets:
+        return is&lt;HTMLAppletElement&gt;(element) || (is&lt;HTMLObjectElement&gt;(element) &amp;&amp; downcast&lt;HTMLObjectElement&gt;(element).containsJavaApplet());
+    case DocEmbeds:
+        return element.hasTagName(embedTag);
+    case DocLinks:
+        return (element.hasTagName(aTag) || element.hasTagName(areaTag)) &amp;&amp; element.fastHasAttribute(hrefAttr);
+    case DocAnchors:
+        return element.hasTagName(aTag) &amp;&amp; element.fastHasAttribute(nameAttr);
+    case DocAll:
+    case DocumentNamedItems:
+    case FormControls:
+    case SelectOptions:
+    case TableRows:
+    case WindowNamedItems:
+        break;
+    }
+    // Remaining collection types have their own CachedHTMLCollection subclasses and are not using GenericCachedHTMLCollection.
+    ASSERT_NOT_REACHED();
+    return false;
+}
+template bool GenericCachedHTMLCollection&lt;CollectionTraversalType::Descendants&gt;::elementMatches(Element&amp;) const;
+template bool GenericCachedHTMLCollection&lt;CollectionTraversalType::ChildrenOnly&gt;::elementMatches(Element&amp;) const;
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCorehtmlGenericCachedHTMLCollectionh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/html/GenericCachedHTMLCollection.h (0 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/GenericCachedHTMLCollection.h                                (rev 0)
+++ trunk/Source/WebCore/html/GenericCachedHTMLCollection.h        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -0,0 +1,52 @@
</span><ins>+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef GenericCachedHTMLCollection_h
+#define GenericCachedHTMLCollection_h
+
+#include &quot;CachedHTMLCollection.h&quot;
+
+namespace WebCore {
+
+template &lt;CollectionTraversalType traversalType&gt;
+class GenericCachedHTMLCollection final : public CachedHTMLCollection&lt;GenericCachedHTMLCollection&lt;traversalType&gt;, traversalType&gt; {
+public:
+    static Ref&lt;GenericCachedHTMLCollection&gt; create(ContainerNode&amp; base, CollectionType collectionType)
+    {
+        return adoptRef(*new GenericCachedHTMLCollection(base, collectionType));
+    }
+
+    bool elementMatches(Element&amp;) const;
+
+private:
+    GenericCachedHTMLCollection(ContainerNode&amp; base, CollectionType collectionType)
+        : CachedHTMLCollection&lt;GenericCachedHTMLCollection&lt;traversalType&gt;, traversalType&gt;(base, collectionType)
+    { }
+};
+
+} // namespace WebCore
+
+#endif // GenericCachedHTMLCollection_h
+
</ins></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLAllCollectioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLAllCollection.cpp (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLAllCollection.cpp        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/html/HTMLAllCollection.cpp        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -36,7 +36,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline HTMLAllCollection::HTMLAllCollection(Document&amp; document, CollectionType type)
</span><del>-    : HTMLCollection(document, type)
</del><ins>+    : CachedHTMLCollection&lt;HTMLAllCollection, CollectionTypeTraits&lt;DocAll&gt;::traversalType&gt;(document, type)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLAllCollectionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLAllCollection.h (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLAllCollection.h        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/html/HTMLAllCollection.h        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -26,16 +26,19 @@
</span><span class="cx"> #ifndef HTMLAllCollection_h
</span><span class="cx"> #define HTMLAllCollection_h
</span><span class="cx"> 
</span><del>-#include &quot;HTMLCollection.h&quot;
</del><ins>+#include &quot;CachedHTMLCollection.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-class HTMLAllCollection final : public HTMLCollection {
</del><ins>+class HTMLAllCollection final : public CachedHTMLCollection&lt;HTMLAllCollection, CollectionTypeTraits&lt;DocAll&gt;::traversalType&gt; {
</ins><span class="cx"> public:
</span><span class="cx">     static Ref&lt;HTMLAllCollection&gt; create(Document&amp;, CollectionType);
</span><span class="cx"> 
</span><span class="cx">     Element* namedItemWithIndex(const AtomicString&amp; name, unsigned index) const;
</span><span class="cx"> 
</span><ins>+    // For CachedHTMLCollection.
+    bool elementMatches(Element&amp;) const { return true; }
+
</ins><span class="cx"> private:
</span><span class="cx">     HTMLAllCollection(Document&amp;, CollectionType);
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLCollectioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLCollection.cpp (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLCollection.cpp        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/html/HTMLCollection.cpp        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -23,48 +23,14 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;HTMLCollection.h&quot;
</span><span class="cx"> 
</span><del>-#include &quot;ElementTraversal.h&quot;
-#include &quot;HTMLDocument.h&quot;
-#include &quot;HTMLNameCollection.h&quot;
</del><ins>+#include &quot;CachedHTMLCollection.h&quot;
</ins><span class="cx"> #include &quot;HTMLNames.h&quot;
</span><del>-#include &quot;HTMLObjectElement.h&quot;
-#include &quot;HTMLOptionElement.h&quot;
</del><span class="cx"> #include &quot;NodeRareData.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> using namespace HTMLNames;
</span><span class="cx"> 
</span><del>-static bool shouldOnlyIncludeDirectChildren(CollectionType type)
-{
-    switch (type) {
-    case DocAll:
-    case DocAnchors:
-    case DocApplets:
-    case DocEmbeds:
-    case DocForms:
-    case DocImages:
-    case DocLinks:
-    case DocScripts:
-    case DocumentNamedItems:
-    case MapAreas:
-    case TableRows:
-    case SelectOptions:
-    case SelectedOptions:
-    case DataListOptions:
-    case WindowNamedItems:
-    case FormControls:
-        return false;
-    case NodeChildren:
-    case TRCells:
-    case TSectionRows:
-    case TableTBodies:
-        return true;
-    }
-    ASSERT_NOT_REACHED();
-    return false;
-}
-
</del><span class="cx"> inline auto HTMLCollection::rootTypeFromCollectionType(CollectionType type) -&gt; RootType
</span><span class="cx"> {
</span><span class="cx">     switch (type) {
</span><span class="lines">@@ -131,262 +97,29 @@
</span><span class="cx">     return DoNotInvalidateOnAttributeChanges;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-HTMLCollection::HTMLCollection(ContainerNode&amp; ownerNode, CollectionType type, ElementTraversalType traversalType)
</del><ins>+HTMLCollection::HTMLCollection(ContainerNode&amp; ownerNode, CollectionType type)
</ins><span class="cx">     : m_ownerNode(ownerNode)
</span><del>-    , m_indexCache(*this)
</del><span class="cx">     , m_collectionType(type)
</span><span class="cx">     , m_invalidationType(invalidationTypeExcludingIdAndNameAttributes(type))
</span><span class="cx">     , m_rootType(rootTypeFromCollectionType(type))
</span><del>-    , m_shouldOnlyIncludeDirectChildren(shouldOnlyIncludeDirectChildren(type))
-    , m_usesCustomForwardOnlyTraversal(traversalType == CustomForwardOnlyTraversal)
</del><span class="cx"> {
</span><span class="cx">     ASSERT(m_rootType == static_cast&lt;unsigned&gt;(rootTypeFromCollectionType(type)));
</span><span class="cx">     ASSERT(m_invalidationType == static_cast&lt;unsigned&gt;(invalidationTypeExcludingIdAndNameAttributes(type)));
</span><span class="cx">     ASSERT(m_collectionType == static_cast&lt;unsigned&gt;(type));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Ref&lt;HTMLCollection&gt; HTMLCollection::create(ContainerNode&amp; base, CollectionType type)
-{
-    return adoptRef(*new HTMLCollection(base, type));
-}
-
</del><span class="cx"> HTMLCollection::~HTMLCollection()
</span><span class="cx"> {
</span><del>-    if (m_indexCache.hasValidCache(*this))
-        document().unregisterCollection(*this);
</del><span class="cx">     if (hasNamedElementCache())
</span><span class="cx">         document().collectionWillClearIdNameMap(*this);
</span><ins>+
</ins><span class="cx">     // HTMLNameCollection removes cache by itself.
</span><span class="cx">     if (type() != WindowNamedItems &amp;&amp; type() != DocumentNamedItems)
</span><span class="cx">         ownerNode().nodeLists()-&gt;removeCachedCollection(this);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-ContainerNode&amp; HTMLCollection::rootNode() const
</del><ins>+void HTMLCollection::invalidateCache(Document&amp; document)
</ins><span class="cx"> {
</span><del>-    if (isRootedAtDocument() &amp;&amp; ownerNode().inDocument())
-        return ownerNode().document();
-
-    return ownerNode();
-}
-
-static inline bool isMatchingHTMLElement(const HTMLCollection&amp; collection, HTMLElement&amp; element)
-{
-    switch (collection.type()) {
-    case DocImages:
-        return element.hasTagName(imgTag);
-    case DocScripts:
-        return element.hasTagName(scriptTag);
-    case DocForms:
-        return element.hasTagName(formTag);
-    case TableTBodies:
-        return element.hasTagName(tbodyTag);
-    case TRCells:
-        return element.hasTagName(tdTag) || element.hasTagName(thTag);
-    case TSectionRows:
-        return element.hasTagName(trTag);
-    case SelectOptions:
-        return element.hasTagName(optionTag);
-    case SelectedOptions:
-        return is&lt;HTMLOptionElement&gt;(element) &amp;&amp; downcast&lt;HTMLOptionElement&gt;(element).selected();
-    case DataListOptions:
-        if (is&lt;HTMLOptionElement&gt;(element)) {
-            HTMLOptionElement&amp; option = downcast&lt;HTMLOptionElement&gt;(element);
-            if (!option.isDisabledFormControl() &amp;&amp; !option.value().isEmpty())
-                return true;
-        }
-        return false;
-    case MapAreas:
-        return element.hasTagName(areaTag);
-    case DocApplets:
-        return is&lt;HTMLAppletElement&gt;(element) || (is&lt;HTMLObjectElement&gt;(element) &amp;&amp; downcast&lt;HTMLObjectElement&gt;(element).containsJavaApplet());
-    case DocEmbeds:
-        return element.hasTagName(embedTag);
-    case DocLinks:
-        return (element.hasTagName(aTag) || element.hasTagName(areaTag)) &amp;&amp; element.fastHasAttribute(hrefAttr);
-    case DocAnchors:
-        return element.hasTagName(aTag) &amp;&amp; element.fastHasAttribute(nameAttr);
-    case DocumentNamedItems:
-        return downcast&lt;DocumentNameCollection&gt;(collection).elementMatches(element);
-    case DocAll:
-    case NodeChildren:
-    case WindowNamedItems:
-    case FormControls:
-    case TableRows:
-        break;
-    }
-    ASSERT_NOT_REACHED();
-    return false;
-}
-
-static inline bool isMatchingElement(const HTMLCollection&amp; collection, Element&amp; element)
-{
-    // Collection types that deal with any type of Elements, not just HTMLElements.
-    switch (collection.type()) {
-    case DocAll:
-    case NodeChildren:
-        return true;
-    case WindowNamedItems:
-        return downcast&lt;WindowNameCollection&gt;(collection).elementMatches(element);
-    default:
-        // Collection types that only deal with HTMLElements.
-        return is&lt;HTMLElement&gt;(element) &amp;&amp; isMatchingHTMLElement(collection, downcast&lt;HTMLElement&gt;(element));
-    }
-}
-
-static inline Element* previousElement(ContainerNode&amp; base, Element&amp; element, bool onlyIncludeDirectChildren)
-{
-    return onlyIncludeDirectChildren ? ElementTraversal::previousSibling(element) : ElementTraversal::previous(element, &amp;base);
-}
-
-ALWAYS_INLINE Element* HTMLCollection::iterateForPreviousElement(Element* element) const
-{
-    bool onlyIncludeDirectChildren = m_shouldOnlyIncludeDirectChildren;
-    ContainerNode&amp; rootNode = this-&gt;rootNode();
-    for (; element; element = previousElement(rootNode, *element, onlyIncludeDirectChildren)) {
-        if (isMatchingElement(*this, *element))
-            return element;
-    }
-    return nullptr;
-}
-
-static inline Element* firstMatchingElement(const HTMLCollection&amp; collection, ContainerNode&amp; root)
-{
-    Element* element = ElementTraversal::firstWithin(root);
-    while (element &amp;&amp; !isMatchingElement(collection, *element))
-        element = ElementTraversal::next(*element, &amp;root);
-    return element;
-}
-
-static inline Element* nextMatchingElement(const HTMLCollection&amp; collection, Element&amp; element, ContainerNode&amp; root)
-{
-    Element* next = &amp;element;
-    do {
-        next = ElementTraversal::next(*next, &amp;root);
-    } while (next &amp;&amp; !isMatchingElement(collection, *next));
-    return next;
-}
-
-unsigned HTMLCollection::length() const
-{
-    return m_indexCache.nodeCount(*this);
-}
-
-Element* HTMLCollection::item(unsigned offset) const
-{
-    return m_indexCache.nodeAt(*this, offset);
-}
-
-static inline bool nameShouldBeVisibleInDocumentAll(HTMLElement&amp; element)
-{
-    // The document.all collection returns only certain types of elements by name,
-    // although it returns any type of element by id.
-    return element.hasTagName(appletTag)
-        || element.hasTagName(embedTag)
-        || element.hasTagName(formTag)
-        || element.hasTagName(imgTag)
-        || element.hasTagName(inputTag)
-        || element.hasTagName(objectTag)
-        || element.hasTagName(selectTag);
-}
-
-static inline bool nameShouldBeVisibleInDocumentAll(Element&amp; element)
-{
-    return is&lt;HTMLElement&gt;(element) &amp;&amp; nameShouldBeVisibleInDocumentAll(downcast&lt;HTMLElement&gt;(element));
-}
-
-static inline Element* firstMatchingChildElement(const HTMLCollection&amp; nodeList, ContainerNode&amp; root)
-{
-    Element* element = ElementTraversal::firstWithin(root);
-    while (element &amp;&amp; !isMatchingElement(nodeList, *element))
-        element = ElementTraversal::nextSibling(*element);
-    return element;
-}
-
-static inline Element* nextMatchingSiblingElement(const HTMLCollection&amp; nodeList, Element&amp; element)
-{
-    Element* next = &amp;element;
-    do {
-        next = ElementTraversal::nextSibling(*next);
-    } while (next &amp;&amp; !isMatchingElement(nodeList, *next));
-    return next;
-}
-
-inline bool HTMLCollection::usesCustomForwardOnlyTraversal() const
-{
-    return m_usesCustomForwardOnlyTraversal;
-}
-
-inline Element* HTMLCollection::firstElement(ContainerNode&amp; root) const
-{
-    if (usesCustomForwardOnlyTraversal())
-        return customElementAfter(nullptr);
-    if (m_shouldOnlyIncludeDirectChildren)
-        return firstMatchingChildElement(*this, root);
-    return firstMatchingElement(*this, root);
-}
-
-inline Element* HTMLCollection::traverseForward(Element&amp; current, unsigned count, unsigned&amp; traversedCount, ContainerNode&amp; root) const
-{
-    Element* element = &amp;current;
-    if (usesCustomForwardOnlyTraversal()) {
-        for (traversedCount = 0; traversedCount &lt; count; ++traversedCount) {
-            element = customElementAfter(element);
-            if (!element)
-                return nullptr;
-        }
-    } else if (m_shouldOnlyIncludeDirectChildren) {
-        for (traversedCount = 0; traversedCount &lt; count; ++traversedCount) {
-            element = nextMatchingSiblingElement(*this, *element);
-            if (!element)
-                return nullptr;
-        }
-    } else {
-        for (traversedCount = 0; traversedCount &lt; count; ++traversedCount) {
-            element = nextMatchingElement(*this, *element, root);
-            if (!element)
-                return nullptr;
-        }
-    }
-    return element;
-}
-
-Element* HTMLCollection::collectionBegin() const
-{
-    return firstElement(rootNode());
-}
-
-Element* HTMLCollection::collectionLast() const
-{
-    // FIXME: This should be optimized similarly to the forward case.
-    auto&amp; root = rootNode();
-    Element* last = m_shouldOnlyIncludeDirectChildren ? ElementTraversal::lastChild(root) : ElementTraversal::lastWithin(root);
-    return iterateForPreviousElement(last);
-}
-
-void HTMLCollection::collectionTraverseForward(Element*&amp; current, unsigned count, unsigned&amp; traversedCount) const
-{
-    current = traverseForward(*current, count, traversedCount, rootNode());
-}
-
-void HTMLCollection::collectionTraverseBackward(Element*&amp; current, unsigned count) const
-{
-    // FIXME: This should be optimized similarly to the forward case.
-    if (m_shouldOnlyIncludeDirectChildren) {
-        for (; count &amp;&amp; current; --count)
-            current = iterateForPreviousElement(ElementTraversal::previousSibling(*current));
-        return;
-    }
-    auto&amp; root = rootNode();
-    for (; count &amp;&amp; current; --count)
-        current = iterateForPreviousElement(ElementTraversal::previous(*current, &amp;root));
-}
-
-void HTMLCollection::invalidateCache(Document&amp; document) const
-{
-    if (m_indexCache.hasValidCache(*this)) {
-        document.unregisterCollection(const_cast&lt;HTMLCollection&amp;&gt;(*this));
-        m_indexCache.invalidate(*this);
-    }
</del><span class="cx">     if (hasNamedElementCache())
</span><span class="cx">         invalidateNamedElementCache(document);
</span><span class="cx"> }
</span><span class="lines">@@ -398,40 +131,8 @@
</span><span class="cx">     m_namedElementCache = nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Element* HTMLCollection::namedItem(const AtomicString&amp; name) const
</del><ins>+Element* HTMLCollection::namedItemSlow(const AtomicString&amp; name) const
</ins><span class="cx"> {
</span><del>-    // http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/nameditem.asp
-    // This method first searches for an object with a matching id
-    // attribute. If a match is not found, the method then searches for an
-    // object with a matching name attribute, but only on those elements
-    // that are allowed a name attribute.
-
-    if (name.isEmpty())
-        return nullptr;
-
-    ContainerNode&amp; root = rootNode();
-    if (!usesCustomForwardOnlyTraversal() &amp;&amp; root.isInTreeScope()) {
-        Element* candidate = nullptr;
-
-        TreeScope&amp; treeScope = root.treeScope();
-        if (treeScope.hasElementWithId(*name.impl())) {
-            if (!treeScope.containsMultipleElementsWithId(name))
-                candidate = treeScope.getElementById(name);
-        } else if (treeScope.hasElementWithName(*name.impl())) {
-            if (!treeScope.containsMultipleElementsWithName(name)) {
-                candidate = treeScope.getElementByName(name);
-                if (candidate &amp;&amp; type() == DocAll &amp;&amp; !nameShouldBeVisibleInDocumentAll(*candidate))
-                    candidate = nullptr;
-            }
-        } else
-            return nullptr;
-
-        if (candidate &amp;&amp; isMatchingElement(*this, *candidate)) {
-            if (m_shouldOnlyIncludeDirectChildren ? candidate-&gt;parentNode() == &amp;root : candidate-&gt;isDescendantOf(&amp;root))
-                return candidate;
-        }
-    }
-
</del><span class="cx">     // The pathological case. We need to walk the entire subtree.
</span><span class="cx">     updateNamedElementCache();
</span><span class="cx">     ASSERT(m_namedElementCache);
</span><span class="lines">@@ -456,9 +157,9 @@
</span><span class="cx"> 
</span><span class="cx">     auto cache = std::make_unique&lt;CollectionNamedElementCache&gt;();
</span><span class="cx"> 
</span><del>-    unsigned size = m_indexCache.nodeCount(*this);
</del><ins>+    unsigned size = length();
</ins><span class="cx">     for (unsigned i = 0; i &lt; size; ++i) {
</span><del>-        Element&amp; element = *m_indexCache.nodeAt(*this, i);
</del><ins>+        Element&amp; element = *item(i);
</ins><span class="cx">         const AtomicString&amp; id = element.getIdAttribute();
</span><span class="cx">         if (!id.isEmpty())
</span><span class="cx">             cache-&gt;appendToIdCache(id, element);
</span><span class="lines">@@ -513,10 +214,4 @@
</span><span class="cx">     return ownerNode().getElementsByTagName(name);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Element* HTMLCollection::customElementAfter(Element*) const
-{
-    ASSERT_NOT_REACHED();
-    return nullptr;
-}
-
</del><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLCollectionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLCollection.h (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLCollection.h        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/html/HTMLCollection.h        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -60,58 +60,40 @@
</span><span class="cx"> 
</span><span class="cx"> class HTMLCollection : public ScriptWrappable, public RefCounted&lt;HTMLCollection&gt; {
</span><span class="cx"> public:
</span><del>-    static Ref&lt;HTMLCollection&gt; create(ContainerNode&amp; base, CollectionType);
</del><span class="cx">     virtual ~HTMLCollection();
</span><span class="cx"> 
</span><span class="cx">     // DOM API
</span><del>-    unsigned length() const;
-    Element* item(unsigned offset) const;
-    virtual Element* namedItem(const AtomicString&amp; name) const;
</del><ins>+    virtual unsigned length() const = 0;
+    virtual Element* item(unsigned offset) const = 0;
+    virtual Element* namedItem(const AtomicString&amp; name) const = 0;
</ins><span class="cx">     PassRefPtr&lt;NodeList&gt; tags(const String&amp;);
</span><span class="cx"> 
</span><span class="cx">     // Non-DOM API
</span><span class="cx">     bool hasNamedItem(const AtomicString&amp; name) const;
</span><span class="cx">     Vector&lt;Ref&lt;Element&gt;&gt; namedItems(const AtomicString&amp; name) const;
</span><del>-    size_t memoryCost() const;
</del><ins>+    virtual size_t memoryCost() const;
</ins><span class="cx"> 
</span><span class="cx">     bool isRootedAtDocument() const;
</span><span class="cx">     NodeListInvalidationType invalidationType() const;
</span><span class="cx">     CollectionType type() const;
</span><span class="cx">     ContainerNode&amp; ownerNode() const;
</span><del>-    void invalidateCache(const QualifiedName* attributeName) const;
-    virtual void invalidateCache(Document&amp;) const;
</del><ins>+    ContainerNode&amp; rootNode() const;
+    void invalidateCache(const QualifiedName* attributeName);
+    virtual void invalidateCache(Document&amp;);
</ins><span class="cx"> 
</span><del>-    // For CollectionIndexCache; do not use elsewhere.
-    Element* collectionBegin() const;
-    Element* collectionLast() const;
-    Element* collectionEnd() const;
-    void collectionTraverseForward(Element*&amp;, unsigned count, unsigned&amp; traversedCount) const;
-    void collectionTraverseBackward(Element*&amp;, unsigned count) const;
-    bool collectionCanTraverseBackward() const;
-    void willValidateIndexCache() const;
-
</del><span class="cx">     bool hasNamedElementCache() const;
</span><span class="cx"> 
</span><span class="cx"> protected:
</span><del>-    enum ElementTraversalType { NormalTraversal, CustomForwardOnlyTraversal };
-    HTMLCollection(ContainerNode&amp; base, CollectionType, ElementTraversalType = NormalTraversal);
</del><ins>+    HTMLCollection(ContainerNode&amp; base, CollectionType);
</ins><span class="cx"> 
</span><span class="cx">     virtual void updateNamedElementCache() const;
</span><ins>+    Element* namedItemSlow(const AtomicString&amp; name) const;
</ins><span class="cx"> 
</span><span class="cx">     void setNamedItemCache(std::unique_ptr&lt;CollectionNamedElementCache&gt;) const;
</span><span class="cx">     const CollectionNamedElementCache&amp; namedItemCaches() const;
</span><span class="cx"> 
</span><del>-private:
</del><span class="cx">     Document&amp; document() const;
</span><del>-    ContainerNode&amp; rootNode() const;
-    bool usesCustomForwardOnlyTraversal() const;
</del><span class="cx"> 
</span><del>-    Element* iterateForPreviousElement(Element*) const;
-    Element* firstElement(ContainerNode&amp; root) const;
-    Element* traverseForward(Element&amp;, unsigned count, unsigned&amp; traversedCount, ContainerNode&amp; root) const;
-
-    virtual Element* customElementAfter(Element*) const;
-
</del><span class="cx">     void invalidateNamedElementCache(Document&amp;) const;
</span><span class="cx"> 
</span><span class="cx">     enum RootType { IsRootedAtNode, IsRootedAtDocument };
</span><span class="lines">@@ -119,16 +101,21 @@
</span><span class="cx"> 
</span><span class="cx">     Ref&lt;ContainerNode&gt; m_ownerNode;
</span><span class="cx"> 
</span><del>-    mutable CollectionIndexCache&lt;HTMLCollection, Element*&gt; m_indexCache;
</del><span class="cx">     mutable std::unique_ptr&lt;CollectionNamedElementCache&gt; m_namedElementCache;
</span><span class="cx"> 
</span><span class="cx">     const unsigned m_collectionType : 5;
</span><span class="cx">     const unsigned m_invalidationType : 4;
</span><span class="cx">     const unsigned m_rootType : 1;
</span><del>-    const unsigned m_shouldOnlyIncludeDirectChildren : 1;
-    const unsigned m_usesCustomForwardOnlyTraversal : 1;
</del><span class="cx"> };
</span><span class="cx"> 
</span><ins>+inline ContainerNode&amp; HTMLCollection::rootNode() const
+{
+    if (isRootedAtDocument() &amp;&amp; ownerNode().inDocument())
+        return ownerNode().document();
+
+    return ownerNode();
+}
+
</ins><span class="cx"> inline const Vector&lt;Element*&gt;* CollectionNamedElementCache::findElementsWithId(const AtomicString&amp; id) const
</span><span class="cx"> {
</span><span class="cx">     return find(m_idMap, id);
</span><span class="lines">@@ -177,7 +164,7 @@
</span><span class="cx"> 
</span><span class="cx"> inline size_t HTMLCollection::memoryCost() const
</span><span class="cx"> {
</span><del>-    return m_indexCache.memoryCost() + (m_namedElementCache ? m_namedElementCache-&gt;memoryCost() : 0);
</del><ins>+    return m_namedElementCache ? m_namedElementCache-&gt;memoryCost() : 0;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline bool HTMLCollection::isRootedAtDocument() const
</span><span class="lines">@@ -205,7 +192,7 @@
</span><span class="cx">     return m_ownerNode-&gt;document();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline void HTMLCollection::invalidateCache(const QualifiedName* attributeName) const
</del><ins>+inline void HTMLCollection::invalidateCache(const QualifiedName* attributeName)
</ins><span class="cx"> {
</span><span class="cx">     if (!attributeName || shouldInvalidateTypeOnAttributeChange(invalidationType(), *attributeName))
</span><span class="cx">         invalidateCache(document());
</span><span class="lines">@@ -213,21 +200,6 @@
</span><span class="cx">         invalidateNamedElementCache(document());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline Element* HTMLCollection::collectionEnd() const
-{
-    return nullptr;
-}
-
-inline bool HTMLCollection::collectionCanTraverseBackward() const
-{
-    return !m_usesCustomForwardOnlyTraversal;
-}
-
-inline void HTMLCollection::willValidateIndexCache() const
-{
-    document().registerCollection(const_cast&lt;HTMLCollection&amp;&gt;(*this));
-}
-
</del><span class="cx"> inline bool HTMLCollection::hasNamedElementCache() const
</span><span class="cx"> {
</span><span class="cx">     return !!m_namedElementCache;
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLDataListElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLDataListElement.cpp (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLDataListElement.cpp        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/html/HTMLDataListElement.cpp        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -33,8 +33,10 @@
</span><span class="cx"> #if ENABLE(DATALIST_ELEMENT)
</span><span class="cx"> #include &quot;HTMLDataListElement.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;GenericCachedHTMLCollection.h&quot;
</ins><span class="cx"> #include &quot;HTMLNames.h&quot;
</span><span class="cx"> #include &quot;IdTargetObserverRegistry.h&quot;
</span><ins>+#include &quot;NodeRareData.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -50,7 +52,7 @@
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;HTMLCollection&gt; HTMLDataListElement::options()
</span><span class="cx"> {
</span><del>-    return ensureCachedHTMLCollection(DataListOptions);
</del><ins>+    return ensureRareData().ensureNodeLists().addCachedCollection&lt;GenericCachedHTMLCollection&lt;CollectionTypeTraits&lt;DataListOptions&gt;::traversalType&gt;&gt;(*this, DataListOptions);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HTMLDataListElement::optionElementChildrenChanged()
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLFieldSetElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLFieldSetElement.cpp (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLFieldSetElement.cpp        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/html/HTMLFieldSetElement.cpp        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -26,10 +26,11 @@
</span><span class="cx"> #include &quot;HTMLFieldSetElement.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ElementIterator.h&quot;
</span><del>-#include &quot;HTMLCollection.h&quot;
</del><ins>+#include &quot;HTMLFormControlsCollection.h&quot;
</ins><span class="cx"> #include &quot;HTMLLegendElement.h&quot;
</span><span class="cx"> #include &quot;HTMLNames.h&quot;
</span><span class="cx"> #include &quot;HTMLObjectElement.h&quot;
</span><ins>+#include &quot;NodeRareData.h&quot;
</ins><span class="cx"> #include &quot;RenderFieldset.h&quot;
</span><span class="cx"> #include &lt;wtf/StdLibExtras.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -161,7 +162,7 @@
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;HTMLCollection&gt; HTMLFieldSetElement::elements()
</span><span class="cx"> {
</span><del>-    return ensureCachedHTMLCollection(FormControls);
</del><ins>+    return ensureRareData().ensureNodeLists().addCachedCollection&lt;HTMLFormControlsCollection&gt;(*this, FormControls);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HTMLFieldSetElement::refreshElementsIfNeeded() const
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLFormControlsCollectioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLFormControlsCollection.cpp (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLFormControlsCollection.cpp        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/html/HTMLFormControlsCollection.cpp        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -36,7 +36,7 @@
</span><span class="cx"> // calculation every time if anything has changed.
</span><span class="cx"> 
</span><span class="cx"> HTMLFormControlsCollection::HTMLFormControlsCollection(ContainerNode&amp; ownerNode)
</span><del>-    : HTMLCollection(ownerNode, FormControls, CustomForwardOnlyTraversal)
</del><ins>+    : CachedHTMLCollection&lt;HTMLFormControlsCollection, CollectionTypeTraits&lt;FormControls&gt;::traversalType&gt;(ownerNode, FormControls)
</ins><span class="cx">     , m_cachedElement(nullptr)
</span><span class="cx">     , m_cachedElementOffsetInArray(0)
</span><span class="cx"> {
</span><span class="lines">@@ -177,9 +177,9 @@
</span><span class="cx">     setNamedItemCache(WTF::move(cache));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void HTMLFormControlsCollection::invalidateCache(Document&amp; document) const
</del><ins>+void HTMLFormControlsCollection::invalidateCache(Document&amp; document)
</ins><span class="cx"> {
</span><del>-    HTMLCollection::invalidateCache(document);
</del><ins>+    CachedHTMLCollection&lt;HTMLFormControlsCollection, CollectionTypeTraits&lt;FormControls&gt;::traversalType&gt;::invalidateCache(document);
</ins><span class="cx">     m_cachedElement = nullptr;
</span><span class="cx">     m_cachedElementOffsetInArray = 0;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLFormControlsCollectionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLFormControlsCollection.h (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLFormControlsCollection.h        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/html/HTMLFormControlsCollection.h        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -23,7 +23,7 @@
</span><span class="cx"> #ifndef HTMLFormControlsCollection_h
</span><span class="cx"> #define HTMLFormControlsCollection_h
</span><span class="cx"> 
</span><del>-#include &quot;HTMLCollection.h&quot;
</del><ins>+#include &quot;CachedHTMLCollection.h&quot;
</ins><span class="cx"> #include &quot;HTMLElement.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -34,21 +34,23 @@
</span><span class="cx"> // This class is just a big hack to find form elements even in malformed HTML elements.
</span><span class="cx"> // The famous &lt;table&gt;&lt;tr&gt;&lt;form&gt;&lt;td&gt; problem.
</span><span class="cx"> 
</span><del>-class HTMLFormControlsCollection final : public HTMLCollection {
</del><ins>+class HTMLFormControlsCollection final : public CachedHTMLCollection&lt;HTMLFormControlsCollection, CollectionTypeTraits&lt;FormControls&gt;::traversalType&gt; {
</ins><span class="cx"> public:
</span><span class="cx">     static Ref&lt;HTMLFormControlsCollection&gt; create(ContainerNode&amp;, CollectionType);
</span><span class="cx">     virtual ~HTMLFormControlsCollection();
</span><span class="cx"> 
</span><ins>+    // For CachedHTMLCollection.
+    Element* customElementAfter(Element*) const;
+
</ins><span class="cx"> private:
</span><span class="cx">     explicit HTMLFormControlsCollection(ContainerNode&amp;);
</span><span class="cx"> 
</span><span class="cx">     virtual HTMLElement* namedItem(const AtomicString&amp; name) const override;
</span><del>-    virtual void invalidateCache(Document&amp;) const override;
</del><ins>+    virtual void invalidateCache(Document&amp;) override;
</ins><span class="cx">     virtual void updateNamedElementCache() const override;
</span><span class="cx"> 
</span><span class="cx">     const Vector&lt;FormAssociatedElement*&gt;&amp; formControlElements() const;
</span><span class="cx">     const Vector&lt;HTMLImageElement*&gt;&amp; formImageElements() const;
</span><del>-    virtual Element* customElementAfter(Element*) const override;
</del><span class="cx"> 
</span><span class="cx">     mutable Element* m_cachedElement;
</span><span class="cx">     mutable unsigned m_cachedElementOffsetInArray;
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLFormElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLFormElement.cpp (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLFormElement.cpp        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/html/HTMLFormElement.cpp        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -37,11 +37,12 @@
</span><span class="cx"> #include &quot;Frame.h&quot;
</span><span class="cx"> #include &quot;FrameLoader.h&quot;
</span><span class="cx"> #include &quot;FrameLoaderClient.h&quot;
</span><del>-#include &quot;HTMLCollection.h&quot;
</del><ins>+#include &quot;HTMLFormControlsCollection.h&quot;
</ins><span class="cx"> #include &quot;HTMLImageElement.h&quot;
</span><span class="cx"> #include &quot;HTMLInputElement.h&quot;
</span><span class="cx"> #include &quot;HTMLNames.h&quot;
</span><span class="cx"> #include &quot;HTMLTableElement.h&quot;
</span><ins>+#include &quot;NodeRareData.h&quot;
</ins><span class="cx"> #include &quot;Page.h&quot;
</span><span class="cx"> #include &quot;RenderTextControl.h&quot;
</span><span class="cx"> #include &quot;ScriptController.h&quot;
</span><span class="lines">@@ -638,7 +639,7 @@
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;HTMLCollection&gt; HTMLFormElement::elements()
</span><span class="cx"> {
</span><del>-    return ensureCachedHTMLCollection(FormControls);
</del><ins>+    return ensureRareData().ensureNodeLists().addCachedCollection&lt;HTMLFormControlsCollection&gt;(*this, FormControls);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> String HTMLFormElement::name() const
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMapElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMapElement.cpp (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMapElement.cpp        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/html/HTMLMapElement.cpp        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -25,11 +25,12 @@
</span><span class="cx"> #include &quot;Attribute.h&quot;
</span><span class="cx"> #include &quot;Document.h&quot;
</span><span class="cx"> #include &quot;ElementIterator.h&quot;
</span><ins>+#include &quot;GenericCachedHTMLCollection.h&quot;
</ins><span class="cx"> #include &quot;HTMLAreaElement.h&quot;
</span><del>-#include &quot;HTMLCollection.h&quot;
</del><span class="cx"> #include &quot;HTMLImageElement.h&quot;
</span><span class="cx"> #include &quot;HitTestResult.h&quot;
</span><span class="cx"> #include &quot;IntSize.h&quot;
</span><ins>+#include &quot;NodeRareData.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -112,7 +113,7 @@
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;HTMLCollection&gt; HTMLMapElement::areas()
</span><span class="cx"> {
</span><del>-    return ensureCachedHTMLCollection(MapAreas);
</del><ins>+    return ensureRareData().ensureNodeLists().addCachedCollection&lt;GenericCachedHTMLCollection&lt;CollectionTypeTraits&lt;MapAreas&gt;::traversalType&gt;&gt;(*this, MapAreas);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Node::InsertionNotificationRequest HTMLMapElement::insertedInto(ContainerNode&amp; insertionPoint)
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLNameCollectioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLNameCollection.cpp (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLNameCollection.cpp        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/html/HTMLNameCollection.cpp        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -36,19 +36,6 @@
</span><span class="cx"> 
</span><span class="cx"> using namespace HTMLNames;
</span><span class="cx"> 
</span><del>-HTMLNameCollection::HTMLNameCollection(Document&amp; document, CollectionType type, const AtomicString&amp; name)
-    : HTMLCollection(document, type)
-    , m_name(name)
-{
-}
-
-HTMLNameCollection::~HTMLNameCollection()
-{
-    ASSERT(type() == WindowNamedItems || type() == DocumentNamedItems);
-
-    document().nodeLists()-&gt;removeCachedCollection(this, m_name);
-}
-
</del><span class="cx"> bool WindowNameCollection::elementMatchesIfNameAttributeMatch(const Element&amp; element)
</span><span class="cx"> {
</span><span class="cx">     return is&lt;HTMLImageElement&gt;(element) || is&lt;HTMLFormElement&gt;(element) || is&lt;HTMLAppletElement&gt;(element)
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLNameCollectionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLNameCollection.h (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLNameCollection.h        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/html/HTMLNameCollection.h        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -23,18 +23,20 @@
</span><span class="cx"> #ifndef HTMLNameCollection_h
</span><span class="cx"> #define HTMLNameCollection_h
</span><span class="cx"> 
</span><del>-#include &quot;HTMLCollection.h&quot;
</del><ins>+#include &quot;CachedHTMLCollection.h&quot;
+#include &quot;NodeRareData.h&quot;
</ins><span class="cx"> #include &lt;wtf/text/AtomicString.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class Document;
</span><span class="cx"> 
</span><del>-class HTMLNameCollection : public HTMLCollection {
</del><ins>+template &lt;typename HTMLCollectionClass, CollectionTraversalType traversalType&gt;
+class HTMLNameCollection : public CachedHTMLCollection&lt;HTMLCollectionClass, traversalType&gt; {
</ins><span class="cx"> public:
</span><span class="cx">     virtual ~HTMLNameCollection();
</span><span class="cx"> 
</span><del>-    Document&amp; document() { return downcast&lt;Document&gt;(ownerNode()); }
</del><ins>+    Document&amp; document() { return downcast&lt;Document&gt;(this-&gt;ownerNode()); }
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     HTMLNameCollection(Document&amp;, CollectionType, const AtomicString&amp; name);
</span><span class="lines">@@ -42,13 +44,29 @@
</span><span class="cx">     AtomicString m_name;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-class WindowNameCollection final : public HTMLNameCollection {
</del><ins>+template &lt;typename HTMLCollectionClass, CollectionTraversalType traversalType&gt;
+HTMLNameCollection&lt;HTMLCollectionClass, traversalType&gt;::HTMLNameCollection(Document&amp; document, CollectionType type, const AtomicString&amp; name)
+    : CachedHTMLCollection&lt;HTMLCollectionClass, traversalType&gt;(document, type)
+    , m_name(name)
+{
+}
+
+template &lt;typename HTMLCollectionClass, CollectionTraversalType traversalType&gt;
+HTMLNameCollection&lt;HTMLCollectionClass, traversalType&gt;::~HTMLNameCollection()
+{
+    ASSERT(this-&gt;type() == WindowNamedItems || this-&gt;type() == DocumentNamedItems);
+
+    document().nodeLists()-&gt;removeCachedCollection(this, m_name);
+}
+
+class WindowNameCollection final : public HTMLNameCollection&lt;WindowNameCollection, CollectionTraversalType::Descendants&gt; {
</ins><span class="cx"> public:
</span><span class="cx">     static Ref&lt;WindowNameCollection&gt; create(Document&amp; document, CollectionType type, const AtomicString&amp; name)
</span><span class="cx">     {
</span><span class="cx">         return adoptRef(*new WindowNameCollection(document, type, name));
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    // For CachedHTMLCollection.
</ins><span class="cx">     bool elementMatches(const Element&amp; element) const { return elementMatches(element, m_name.impl()); }
</span><span class="cx"> 
</span><span class="cx">     static bool elementMatchesIfIdAttributeMatch(const Element&amp;) { return true; }
</span><span class="lines">@@ -57,13 +75,13 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     WindowNameCollection(Document&amp; document, CollectionType type, const AtomicString&amp; name)
</span><del>-        : HTMLNameCollection(document, type, name)
</del><ins>+        : HTMLNameCollection&lt;WindowNameCollection, CollectionTraversalType::Descendants&gt;(document, type, name)
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(type == WindowNamedItems);
</span><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-class DocumentNameCollection final : public HTMLNameCollection {
</del><ins>+class DocumentNameCollection final : public HTMLNameCollection&lt;DocumentNameCollection, CollectionTraversalType::Descendants&gt; {
</ins><span class="cx"> public:
</span><span class="cx">     static Ref&lt;DocumentNameCollection&gt; create(Document&amp; document, CollectionType type, const AtomicString&amp; name)
</span><span class="cx">     {
</span><span class="lines">@@ -72,13 +90,15 @@
</span><span class="cx"> 
</span><span class="cx">     static bool elementMatchesIfIdAttributeMatch(const Element&amp;);
</span><span class="cx">     static bool elementMatchesIfNameAttributeMatch(const Element&amp;);
</span><ins>+
+    // For CachedHTMLCollection.
</ins><span class="cx">     bool elementMatches(const Element&amp; element) const { return elementMatches(element, m_name.impl()); }
</span><span class="cx"> 
</span><span class="cx">     static bool elementMatches(const Element&amp;, const AtomicStringImpl*);
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     DocumentNameCollection(Document&amp; document, CollectionType type, const AtomicString&amp; name)
</span><del>-        : HTMLNameCollection(document, type, name)
</del><ins>+        : HTMLNameCollection&lt;DocumentNameCollection, CollectionTraversalType::Descendants&gt;(document, type, name)
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(type == DocumentNamedItems);
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLOptionsCollectioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLOptionsCollection.cpp (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLOptionsCollection.cpp        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/html/HTMLOptionsCollection.cpp        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -27,7 +27,7 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> HTMLOptionsCollection::HTMLOptionsCollection(HTMLSelectElement&amp; select)
</span><del>-    : HTMLCollection(select, SelectOptions)
</del><ins>+    : CachedHTMLCollection&lt;HTMLOptionsCollection, CollectionTypeTraits&lt;SelectOptions&gt;::traversalType&gt;(select, SelectOptions)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLOptionsCollectionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLOptionsCollection.h (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLOptionsCollection.h        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/html/HTMLOptionsCollection.h        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -24,7 +24,7 @@
</span><span class="cx"> #ifndef HTMLOptionsCollection_h
</span><span class="cx"> #define HTMLOptionsCollection_h
</span><span class="cx"> 
</span><del>-#include &quot;HTMLCollection.h&quot;
</del><ins>+#include &quot;CachedHTMLCollection.h&quot;
</ins><span class="cx"> #include &quot;HTMLSelectElement.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -33,7 +33,7 @@
</span><span class="cx"> 
</span><span class="cx"> typedef int ExceptionCode;
</span><span class="cx"> 
</span><del>-class HTMLOptionsCollection final : public HTMLCollection {
</del><ins>+class HTMLOptionsCollection final : public CachedHTMLCollection&lt;HTMLOptionsCollection, CollectionTypeTraits&lt;SelectOptions&gt;::traversalType&gt; {
</ins><span class="cx"> public:
</span><span class="cx">     static Ref&lt;HTMLOptionsCollection&gt; create(HTMLSelectElement&amp;, CollectionType);
</span><span class="cx"> 
</span><span class="lines">@@ -50,10 +50,18 @@
</span><span class="cx"> 
</span><span class="cx">     void setLength(unsigned, ExceptionCode&amp;);
</span><span class="cx"> 
</span><ins>+    // For CachedHTMLCollection.
+    bool elementMatches(Element&amp;) const;
+
</ins><span class="cx"> private:
</span><span class="cx">     explicit HTMLOptionsCollection(HTMLSelectElement&amp;);
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+inline bool HTMLOptionsCollection::elementMatches(Element&amp; element) const
+{
+    return element.hasTagName(HTMLNames::optionTag);
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> SPECIALIZE_TYPE_TRAITS_HTMLCOLLECTION(HTMLOptionsCollection, SelectOptions)
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLSelectElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLSelectElement.cpp (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLSelectElement.cpp        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/html/HTMLSelectElement.cpp        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -38,6 +38,7 @@
</span><span class="cx"> #include &quot;FormController.h&quot;
</span><span class="cx"> #include &quot;FormDataList.h&quot;
</span><span class="cx"> #include &quot;Frame.h&quot;
</span><ins>+#include &quot;GenericCachedHTMLCollection.h&quot;
</ins><span class="cx"> #include &quot;HTMLFormElement.h&quot;
</span><span class="cx"> #include &quot;HTMLNames.h&quot;
</span><span class="cx"> #include &quot;HTMLOptGroupElement.h&quot;
</span><span class="lines">@@ -46,6 +47,7 @@
</span><span class="cx"> #include &quot;KeyboardEvent.h&quot;
</span><span class="cx"> #include &quot;LocalizedStrings.h&quot;
</span><span class="cx"> #include &quot;MouseEvent.h&quot;
</span><ins>+#include &quot;NodeRareData.h&quot;
</ins><span class="cx"> #include &quot;Page.h&quot;
</span><span class="cx"> #include &quot;PlatformMouseEvent.h&quot;
</span><span class="cx"> #include &quot;RenderListBox.h&quot;
</span><span class="lines">@@ -374,12 +376,12 @@
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;HTMLCollection&gt; HTMLSelectElement::selectedOptions()
</span><span class="cx"> {
</span><del>-    return ensureCachedHTMLCollection(SelectedOptions);
</del><ins>+    return ensureRareData().ensureNodeLists().addCachedCollection&lt;GenericCachedHTMLCollection&lt;CollectionTypeTraits&lt;SelectedOptions&gt;::traversalType&gt;&gt;(*this, SelectedOptions);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;HTMLOptionsCollection&gt; HTMLSelectElement::options()
</span><span class="cx"> {
</span><del>-    return downcast&lt;HTMLOptionsCollection&gt;(ensureCachedHTMLCollection(SelectOptions).get());
</del><ins>+    return ensureRareData().ensureNodeLists().addCachedCollection&lt;HTMLOptionsCollection&gt;(*this, SelectOptions);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HTMLSelectElement::updateListItemSelectedStates()
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLTableElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLTableElement.cpp (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLTableElement.cpp        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/html/HTMLTableElement.cpp        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -31,12 +31,14 @@
</span><span class="cx"> #include &quot;CSSValuePool.h&quot;
</span><span class="cx"> #include &quot;ExceptionCode.h&quot;
</span><span class="cx"> #include &quot;ExceptionCodePlaceholder.h&quot;
</span><ins>+#include &quot;GenericCachedHTMLCollection.h&quot;
</ins><span class="cx"> #include &quot;HTMLNames.h&quot;
</span><span class="cx"> #include &quot;HTMLParserIdioms.h&quot;
</span><span class="cx"> #include &quot;HTMLTableCaptionElement.h&quot;
</span><span class="cx"> #include &quot;HTMLTableRowElement.h&quot;
</span><span class="cx"> #include &quot;HTMLTableRowsCollection.h&quot;
</span><span class="cx"> #include &quot;HTMLTableSectionElement.h&quot;
</span><ins>+#include &quot;NodeRareData.h&quot;
</ins><span class="cx"> #include &quot;RenderTable.h&quot;
</span><span class="cx"> #include &quot;StyleProperties.h&quot;
</span><span class="cx"> #include &lt;wtf/Ref.h&gt;
</span><span class="lines">@@ -551,12 +553,12 @@
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;HTMLCollection&gt; HTMLTableElement::rows()
</span><span class="cx"> {
</span><del>-    return ensureCachedHTMLCollection(TableRows);
</del><ins>+    return ensureRareData().ensureNodeLists().addCachedCollection&lt;HTMLTableRowsCollection&gt;(*this, TableRows);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;HTMLCollection&gt; HTMLTableElement::tBodies()
</span><span class="cx"> {
</span><del>-    return ensureCachedHTMLCollection(TableTBodies);
</del><ins>+    return ensureRareData().ensureNodeLists().addCachedCollection&lt;GenericCachedHTMLCollection&lt;CollectionTypeTraits&lt;TableTBodies&gt;::traversalType&gt;&gt;(*this, TableTBodies);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> const AtomicString&amp; HTMLTableElement::rules() const
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLTableRowElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLTableRowElement.cpp (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLTableRowElement.cpp        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/html/HTMLTableRowElement.cpp        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -26,12 +26,13 @@
</span><span class="cx"> #include &quot;HTMLTableRowElement.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ExceptionCode.h&quot;
</span><del>-#include &quot;HTMLCollection.h&quot;
</del><ins>+#include &quot;GenericCachedHTMLCollection.h&quot;
</ins><span class="cx"> #include &quot;HTMLNames.h&quot;
</span><span class="cx"> #include &quot;HTMLTableCellElement.h&quot;
</span><span class="cx"> #include &quot;HTMLTableElement.h&quot;
</span><span class="cx"> #include &quot;HTMLTableSectionElement.h&quot;
</span><span class="cx"> #include &quot;NodeList.h&quot;
</span><ins>+#include &quot;NodeRareData.h&quot;
</ins><span class="cx"> #include &quot;Text.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -156,7 +157,7 @@
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;HTMLCollection&gt; HTMLTableRowElement::cells()
</span><span class="cx"> {
</span><del>-    return ensureCachedHTMLCollection(TRCells);
</del><ins>+    return ensureRareData().ensureNodeLists().addCachedCollection&lt;GenericCachedHTMLCollection&lt;CollectionTypeTraits&lt;TRCells&gt;::traversalType&gt;&gt;(*this, TRCells);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HTMLTableRowElement::setCells(HTMLCollection*, ExceptionCode&amp; ec)
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLTableRowsCollectioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLTableRowsCollection.cpp (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLTableRowsCollection.cpp        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/html/HTMLTableRowsCollection.cpp        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -149,7 +149,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> HTMLTableRowsCollection::HTMLTableRowsCollection(HTMLTableElement&amp; table)
</span><del>-    : HTMLCollection(table, TableRows, CustomForwardOnlyTraversal)
</del><ins>+    : CachedHTMLCollection&lt;HTMLTableRowsCollection, CollectionTypeTraits&lt;TableRows&gt;::traversalType&gt;(table, TableRows)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLTableRowsCollectionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLTableRowsCollection.h (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLTableRowsCollection.h        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/html/HTMLTableRowsCollection.h        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -29,14 +29,14 @@
</span><span class="cx"> #ifndef HTMLTableRowsCollection_h
</span><span class="cx"> #define HTMLTableRowsCollection_h
</span><span class="cx"> 
</span><del>-#include &quot;HTMLCollection.h&quot;
</del><ins>+#include &quot;CachedHTMLCollection.h&quot;
</ins><span class="cx"> #include &quot;HTMLTableElement.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class HTMLTableRowElement;
</span><span class="cx"> 
</span><del>-class HTMLTableRowsCollection final : public HTMLCollection {
</del><ins>+class HTMLTableRowsCollection final : public CachedHTMLCollection&lt;HTMLTableRowsCollection, CollectionTypeTraits&lt;TableRows&gt;::traversalType&gt; {
</ins><span class="cx"> public:
</span><span class="cx">     static Ref&lt;HTMLTableRowsCollection&gt; create(HTMLTableElement&amp;, CollectionType);
</span><span class="cx"> 
</span><span class="lines">@@ -46,10 +46,11 @@
</span><span class="cx">     static HTMLTableRowElement* rowAfter(HTMLTableElement&amp;, HTMLTableRowElement*);
</span><span class="cx">     static HTMLTableRowElement* lastRow(HTMLTableElement&amp;);
</span><span class="cx"> 
</span><ins>+    // For CachedHTMLCollection.
+    Element* customElementAfter(Element*) const;
+
</ins><span class="cx"> private:
</span><span class="cx">     explicit HTMLTableRowsCollection(HTMLTableElement&amp;);
</span><del>-
-    virtual Element* customElementAfter(Element*) const override;
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLTableSectionElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLTableSectionElement.cpp (188519 => 188520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLTableSectionElement.cpp        2015-08-16 08:13:50 UTC (rev 188519)
+++ trunk/Source/WebCore/html/HTMLTableSectionElement.cpp        2015-08-16 18:58:48 UTC (rev 188520)
</span><span class="lines">@@ -26,11 +26,13 @@
</span><span class="cx"> #include &quot;HTMLTableSectionElement.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ExceptionCode.h&quot;
</span><ins>+#include &quot;GenericCachedHTMLCollection.h&quot;
</ins><span class="cx"> #include &quot;HTMLCollection.h&quot;
</span><span class="cx"> #include &quot;HTMLNames.h&quot;
</span><span class="cx"> #include &quot;HTMLTableRowElement.h&quot;
</span><span class="cx"> #include &quot;HTMLTableElement.h&quot;
</span><span class="cx"> #include &quot;NodeList.h&quot;
</span><ins>+#include &quot;NodeRareData.h&quot;
</ins><span class="cx"> #include &quot;Text.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -147,7 +149,7 @@
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;HTMLCollection&gt; HTMLTableSectionElement::rows()
</span><span class="cx"> {
</span><del>-    return ensureCachedHTMLCollection(TSectionRows);
</del><ins>+    return ensureRareData().ensureNodeLists().addCachedCollection&lt;GenericCachedHTMLCollection&lt;CollectionTypeTraits&lt;TSectionRows&gt;::traversalType&gt;&gt;(*this, TSectionRows);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>