Chromium Code Reviews| Index: Source/core/html/HTMLCollection.cpp |
| diff --git a/Source/core/html/HTMLCollection.cpp b/Source/core/html/HTMLCollection.cpp |
| index 14023c7a3d6aeb227faccedbeddf67341e1de004..f600f26df3cd81e9cef7a790188af1e5dee25bcd 100644 |
| --- a/Source/core/html/HTMLCollection.cpp |
| +++ b/Source/core/html/HTMLCollection.cpp |
| @@ -269,6 +269,16 @@ template <> inline bool isMatchingElement(const HTMLCollection& htmlCollection, |
| return false; |
| } |
| +template <> inline bool isMatchingElement(const ClassCollection& collection, const Element& element) |
| +{ |
| + return collection.elementMatches(element); |
| +} |
| + |
| +template <> inline bool isMatchingElement(const HTMLTagCollection& collection, const Element& element) |
| +{ |
| + return collection.elementMatches(element); |
| +} |
| + |
| template <> inline bool isMatchingElement(const LiveNodeList& nodeList, const Element& element) |
| { |
| return nodeList.nodeMatches(element); |
| @@ -442,11 +452,18 @@ inline Element* nextMatchingChildElement(const HTMLCollection& nodeList, Element |
| Element* HTMLCollection::traverseToFirstElement(const ContainerNode& root) const |
| { |
| - if (overridesItemAfter()) |
| - return virtualItemAfter(0); |
| - if (shouldOnlyIncludeDirectChildren()) |
| - return firstMatchingChildElement(*this, root); |
| - return firstMatchingElement(*this, root); |
| + switch (type()) { |
|
arv (Not doing code reviews)
2014/02/04 15:12:36
Would it make sense to use virtual dispatch instea
Inactive
2014/02/04 15:30:15
As this is hot code, I think we should avoid virtu
|
| + case HTMLTagCollectionType: |
| + return firstMatchingElement(static_cast<const HTMLTagCollection&>(*this), root); |
| + case ClassCollectionType: |
| + return firstMatchingElement(static_cast<const ClassCollection&>(*this), root); |
| + default: |
| + if (overridesItemAfter()) |
| + return virtualItemAfter(0); |
| + if (shouldOnlyIncludeDirectChildren()) |
| + return firstMatchingChildElement(*this, root); |
| + return firstMatchingElement(*this, root); |
| + } |
| } |
| inline Element* HTMLCollection::traverseNextElement(Element& previous, const ContainerNode& root) const |
| @@ -461,23 +478,30 @@ inline Element* HTMLCollection::traverseNextElement(Element& previous, const Con |
| Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Node& currentElement, unsigned& currentOffset, const ContainerNode& root) const |
| { |
| ASSERT(currentOffset < offset); |
| - if (overridesItemAfter()) { |
| - Element* next = &toElement(currentElement); |
| - while ((next = virtualItemAfter(next))) { |
| - if (++currentOffset == offset) |
| - return next; |
| + switch (type()) { |
| + case HTMLTagCollectionType: |
| + return traverseMatchingElementsForwardToOffset(static_cast<const HTMLTagCollection&>(*this), offset, toElement(currentElement), currentOffset, root); |
| + case ClassCollectionType: |
| + return traverseMatchingElementsForwardToOffset(static_cast<const ClassCollection&>(*this), offset, toElement(currentElement), currentOffset, root); |
| + default: |
| + if (overridesItemAfter()) { |
| + Element* next = &toElement(currentElement); |
| + while ((next = virtualItemAfter(next))) { |
| + if (++currentOffset == offset) |
| + return next; |
| + } |
| + return 0; |
| } |
| - return 0; |
| - } |
| - if (shouldOnlyIncludeDirectChildren()) { |
| - Element* next = &toElement(currentElement); |
| - while ((next = nextMatchingChildElement(*this, *next, root))) { |
| - if (++currentOffset == offset) |
| - return next; |
| + if (shouldOnlyIncludeDirectChildren()) { |
| + Element* next = &toElement(currentElement); |
| + while ((next = nextMatchingChildElement(*this, *next, root))) { |
| + if (++currentOffset == offset) |
| + return next; |
| + } |
| + return 0; |
| } |
| - return 0; |
| + return traverseMatchingElementsForwardToOffset(*this, offset, toElement(currentElement), currentOffset, root); |
| } |
| - return traverseMatchingElementsForwardToOffset(*this, offset, toElement(currentElement), currentOffset, root); |
| } |
| Element* HTMLCollection::namedItem(const AtomicString& name) const |