| Index: Source/core/html/HTMLCollection.cpp
|
| diff --git a/Source/core/html/HTMLCollection.cpp b/Source/core/html/HTMLCollection.cpp
|
| index 103efabd3e558610b093314e26ed079158043ff3..aeb8f2c64b8e04730afdb42c200c6b3c29a74f4f 100644
|
| --- a/Source/core/html/HTMLCollection.cpp
|
| +++ b/Source/core/html/HTMLCollection.cpp
|
| @@ -24,7 +24,7 @@
|
| #include "core/html/HTMLCollection.h"
|
|
|
| #include "HTMLNames.h"
|
| -#include "core/dom/ClassNodeList.h"
|
| +#include "core/dom/ClassCollection.h"
|
| #include "core/dom/ElementTraversal.h"
|
| #include "core/dom/NodeList.h"
|
| #include "core/dom/NodeRareData.h"
|
| @@ -40,6 +40,9 @@ using namespace HTMLNames;
|
| static bool shouldOnlyIncludeDirectChildren(CollectionType type)
|
| {
|
| switch (type) {
|
| + case ClassCollectionType:
|
| + case TagCollectionType:
|
| + case HTMLTagCollectionType:
|
| case DocAll:
|
| case DocAnchors:
|
| case DocApplets:
|
| @@ -63,10 +66,7 @@ static bool shouldOnlyIncludeDirectChildren(CollectionType type)
|
| case TableTBodies:
|
| return true;
|
| case ChildNodeListType:
|
| - case ClassNodeListType:
|
| case NameNodeListType:
|
| - case TagNodeListType:
|
| - case HTMLTagNodeListType:
|
| case RadioNodeListType:
|
| case RadioImgNodeListType:
|
| case LabelsNodeListType:
|
| @@ -91,6 +91,9 @@ static NodeListRootType rootTypeFromCollectionType(CollectionType type)
|
| case DocumentNamedItems:
|
| case FormControls:
|
| return NodeListIsRootedAtDocument;
|
| + case ClassCollectionType:
|
| + case TagCollectionType:
|
| + case HTMLTagCollectionType:
|
| case NodeChildren:
|
| case TableTBodies:
|
| case TSectionRows:
|
| @@ -102,10 +105,7 @@ static NodeListRootType rootTypeFromCollectionType(CollectionType type)
|
| case MapAreas:
|
| return NodeListIsRootedAtNode;
|
| case ChildNodeListType:
|
| - case ClassNodeListType:
|
| case NameNodeListType:
|
| - case TagNodeListType:
|
| - case HTMLTagNodeListType:
|
| case RadioNodeListType:
|
| case RadioImgNodeListType:
|
| case LabelsNodeListType:
|
| @@ -118,6 +118,8 @@ static NodeListRootType rootTypeFromCollectionType(CollectionType type)
|
| static NodeListInvalidationType invalidationTypeExcludingIdAndNameAttributes(CollectionType type)
|
| {
|
| switch (type) {
|
| + case TagCollectionType:
|
| + case HTMLTagCollectionType:
|
| case DocImages:
|
| case DocEmbeds:
|
| case DocForms:
|
| @@ -146,11 +148,10 @@ static NodeListInvalidationType invalidationTypeExcludingIdAndNameAttributes(Col
|
| return InvalidateOnIdNameAttrChange;
|
| case FormControls:
|
| return InvalidateForFormControls;
|
| + case ClassCollectionType:
|
| + return InvalidateOnClassAttrChange;
|
| case ChildNodeListType:
|
| - case ClassNodeListType:
|
| case NameNodeListType:
|
| - case TagNodeListType:
|
| - case HTMLTagNodeListType:
|
| case RadioNodeListType:
|
| case RadioImgNodeListType:
|
| case LabelsNodeListType:
|
| @@ -175,9 +176,11 @@ PassRefPtr<HTMLCollection> HTMLCollection::create(ContainerNode* base, Collectio
|
|
|
| HTMLCollection::~HTMLCollection()
|
| {
|
| - // HTMLNameCollection removes cache by itself.
|
| - if (type() != WindowNamedItems && type() != DocumentNamedItems)
|
| + // HTMLNameCollection, ClassCollection and TagCollection remove cache by themselves.
|
| + if (type() != WindowNamedItems && type() != DocumentNamedItems && type() != ClassCollectionType
|
| + && type() != HTMLTagCollectionType && type() != TagCollectionType) {
|
| ownerNode()->nodeLists()->removeCacheWithAtomicName(this, type());
|
| + }
|
| }
|
|
|
| void HTMLCollection::invalidateCache() const
|
| @@ -192,7 +195,24 @@ inline bool isMatchingElement(const NodeListType&, const Element&);
|
| template <> inline bool isMatchingElement(const HTMLCollection& htmlCollection, const Element& element)
|
| {
|
| CollectionType type = htmlCollection.type();
|
| - if (!element.isHTMLElement() && !(type == DocAll || type == NodeChildren || type == WindowNamedItems))
|
| +
|
| + // These collections apply to any kind of Elements, not just HTMLElements.
|
| + switch (type) {
|
| + case DocAll:
|
| + case NodeChildren:
|
| + return true;
|
| + case ClassCollectionType:
|
| + return static_cast<const ClassCollection&>(htmlCollection).elementMatches(element);
|
| + case TagCollectionType:
|
| + return static_cast<const TagCollection&>(htmlCollection).elementMatches(element);
|
| + case HTMLTagCollectionType:
|
| + return static_cast<const HTMLTagCollection&>(htmlCollection).elementMatches(element);
|
| + default:
|
| + break;
|
| + }
|
| +
|
| + // The following only applies to HTMLElements.
|
| + if (!element.isHTMLElement())
|
| return false;
|
|
|
| switch (type) {
|
| @@ -229,18 +249,17 @@ template <> inline bool isMatchingElement(const HTMLCollection& htmlCollection,
|
| return (element.hasLocalName(aTag) || element.hasLocalName(areaTag)) && element.fastHasAttribute(hrefAttr);
|
| case DocAnchors:
|
| return element.hasLocalName(aTag) && element.fastHasAttribute(nameAttr);
|
| + case ClassCollectionType:
|
| + case TagCollectionType:
|
| + case HTMLTagCollectionType:
|
| case DocAll:
|
| case NodeChildren:
|
| - return true;
|
| case FormControls:
|
| case DocumentNamedItems:
|
| case TableRows:
|
| case WindowNamedItems:
|
| case ChildNodeListType:
|
| - case ClassNodeListType:
|
| case NameNodeListType:
|
| - case TagNodeListType:
|
| - case HTMLTagNodeListType:
|
| case RadioNodeListType:
|
| case RadioImgNodeListType:
|
| case LabelsNodeListType:
|
| @@ -254,16 +273,6 @@ template <> inline bool isMatchingElement(const LiveNodeList& nodeList, const El
|
| return nodeList.nodeMatches(element);
|
| }
|
|
|
| -template <> inline bool isMatchingElement(const HTMLTagNodeList& nodeList, const Element& element)
|
| -{
|
| - return nodeList.nodeMatchesInlined(element);
|
| -}
|
| -
|
| -template <> inline bool isMatchingElement(const ClassNodeList& nodeList, const Element& element)
|
| -{
|
| - return nodeList.nodeMatchesInlined(element);
|
| -}
|
| -
|
| static Node* previousNode(const Node& base, const Node& previous, bool onlyIncludeDirectChildren)
|
| {
|
| return onlyIncludeDirectChildren ? previous.previousSibling() : NodeTraversal::previous(previous, &base);
|
| @@ -362,10 +371,6 @@ inline Node* LiveNodeList::traverseToFirstElement(const ContainerNode& root) con
|
| switch (type()) {
|
| case ChildNodeListType:
|
| return root.firstChild();
|
| - case HTMLTagNodeListType:
|
| - return firstMatchingElement(static_cast<const HTMLTagNodeList&>(*this), root);
|
| - case ClassNodeListType:
|
| - return firstMatchingElement(static_cast<const ClassNodeList&>(*this), root);
|
| default:
|
| return firstMatchingElement(static_cast<const LiveNodeList&>(*this), root);
|
| }
|
| @@ -378,10 +383,6 @@ inline Node* LiveNodeList::traverseForwardToOffset(unsigned offset, Node& curren
|
| switch (type()) {
|
| case ChildNodeListType:
|
| return traverseSiblingsForwardToOffset(offset, currentNode, currentOffset);
|
| - case HTMLTagNodeListType:
|
| - return traverseMatchingElementsForwardToOffset(static_cast<const HTMLTagNodeList&>(*this), offset, toElement(currentNode), currentOffset, root);
|
| - case ClassNodeListType:
|
| - return traverseMatchingElementsForwardToOffset(static_cast<const ClassNodeList&>(*this), offset, toElement(currentNode), currentOffset, root);
|
| default:
|
| return traverseMatchingElementsForwardToOffset(*this, offset, toElement(currentNode), currentOffset, root);
|
| }
|
|
|