Chromium Code Reviews| Index: Source/core/html/HTMLCollection.cpp |
| diff --git a/Source/core/html/HTMLCollection.cpp b/Source/core/html/HTMLCollection.cpp |
| index 6402d501849435ac64123ad87c3b3f89c9e09bd0..73a7f1ee14bbaef3b52fa7a45ff49b9a7868bedc 100644 |
| --- a/Source/core/html/HTMLCollection.cpp |
| +++ b/Source/core/html/HTMLCollection.cpp |
| @@ -255,43 +255,49 @@ static inline bool isMatchingHTMLElement(const HTMLCollection& htmlCollection, c |
| return false; |
| } |
| -template <class NodeListType> |
| -inline bool isMatchingElement(const NodeListType&, const Element&); |
| - |
| -template <> inline bool isMatchingElement(const HTMLCollection& htmlCollection, const Element& element) |
| +inline bool HTMLCollection::elementMatches(const Element& element) const |
| { |
| // These collections apply to any kind of Elements, not just HTMLElements. |
| - switch (htmlCollection.type()) { |
| + switch (type()) { |
| case DocAll: |
| case NodeChildren: |
| return true; |
| case ClassCollectionType: |
| - return toClassCollection(htmlCollection).elementMatches(element); |
| + return toClassCollection(*this).elementMatches(element); |
| case TagCollectionType: |
| - return toTagCollection(htmlCollection).elementMatches(element); |
| + return toTagCollection(*this).elementMatches(element); |
| case HTMLTagCollectionType: |
| - return toHTMLTagCollection(htmlCollection).elementMatches(element); |
| + return toHTMLTagCollection(*this).elementMatches(element); |
| case DocumentNamedItems: |
| - return toDocumentNameCollection(htmlCollection).elementMatches(element); |
| + return toDocumentNameCollection(*this).elementMatches(element); |
| case WindowNamedItems: |
| - return toWindowNameCollection(htmlCollection).elementMatches(element); |
| + return toWindowNameCollection(*this).elementMatches(element); |
| default: |
| break; |
| } |
| // The following only applies to HTMLElements. |
| - return element.isHTMLElement() && isMatchingHTMLElement(htmlCollection, toHTMLElement(element)); |
| + return element.isHTMLElement() && isMatchingHTMLElement(*this, toHTMLElement(element)); |
| } |
| -template <> inline bool isMatchingElement(const ClassCollection& collection, const Element& element) |
| -{ |
| - return collection.elementMatches(element); |
| -} |
| +template <class HTMLCollectionType> |
| +class IsMatch { |
|
adamk
2014/08/13 20:53:55
Same with this, anonymous namespace please.
Inactive
2014/08/13 21:17:19
Done.
|
| +public: |
| + IsMatch(const HTMLCollectionType& list) |
| + : m_list(list) |
| + { } |
| -template <> inline bool isMatchingElement(const HTMLTagCollection& collection, const Element& element) |
| -{ |
| - return collection.elementMatches(element); |
| -} |
| + bool operator() (const Element& element) const |
| + { |
| + return m_list.elementMatches(element); |
| + } |
| + |
| +private: |
| + const HTMLCollectionType& m_list; |
| +}; |
| + |
| +template <class HTMLCollectionType> |
| +static inline IsMatch<HTMLCollectionType> makeIsMatch(const HTMLCollectionType& list) { return IsMatch<HTMLCollectionType>(list); } |
| Element* HTMLCollection::virtualItemAfter(Element*) const |
| { |
| @@ -318,53 +324,19 @@ static inline bool nameShouldBeVisibleInDocumentAll(const HTMLElement& element) |
| || element.hasTagName(selectTag); |
| } |
| -inline Element* firstMatchingChildElement(const HTMLCollection& nodeList) |
| -{ |
| - Element* element = ElementTraversal::firstChild(nodeList.rootNode()); |
| - while (element && !isMatchingElement(nodeList, *element)) |
| - element = ElementTraversal::nextSibling(*element); |
| - return element; |
| -} |
| - |
| -inline Element* lastMatchingChildElement(const HTMLCollection& nodeList) |
| -{ |
| - Element* element = ElementTraversal::lastChild(nodeList.rootNode()); |
| - while (element && !isMatchingElement(nodeList, *element)) |
| - element = ElementTraversal::previousSibling(*element); |
| - return element; |
| -} |
| - |
| -inline Element* nextMatchingChildElement(const HTMLCollection& nodeList, Element& current) |
| -{ |
| - Element* next = ¤t; |
| - do { |
| - next = ElementTraversal::nextSibling(*next); |
| - } while (next && !isMatchingElement(nodeList, *next)); |
| - return next; |
| -} |
| - |
| -inline Element* previousMatchingChildElement(const HTMLCollection& nodeList, Element& current) |
| -{ |
| - Element* previous = ¤t; |
| - do { |
| - previous = ElementTraversal::previousSibling(*previous); |
| - } while (previous && !isMatchingElement(nodeList, *previous)); |
| - return previous; |
| -} |
| - |
| Element* HTMLCollection::traverseToFirstElement() const |
| { |
| switch (type()) { |
| case HTMLTagCollectionType: |
| - return firstMatchingElement(toHTMLTagCollection(*this)); |
| + return ElementTraversal::firstWithin(rootNode(), makeIsMatch(toHTMLTagCollection(*this))); |
| case ClassCollectionType: |
| - return firstMatchingElement(toClassCollection(*this)); |
| + return ElementTraversal::firstWithin(rootNode(), makeIsMatch(toClassCollection(*this))); |
| default: |
| if (overridesItemAfter()) |
| return virtualItemAfter(0); |
| if (shouldOnlyIncludeDirectChildren()) |
| - return firstMatchingChildElement(*this); |
| - return firstMatchingElement(*this); |
| + return ElementTraversal::firstChild(rootNode(), makeIsMatch(*this)); |
| + return ElementTraversal::firstWithin(rootNode(), makeIsMatch(*this)); |
| } |
| } |
| @@ -372,8 +344,8 @@ Element* HTMLCollection::traverseToLastElement() const |
| { |
| ASSERT(canTraverseBackward()); |
| if (shouldOnlyIncludeDirectChildren()) |
| - return lastMatchingChildElement(*this); |
| - return lastMatchingElement(*this); |
| + return ElementTraversal::lastChild(rootNode(), makeIsMatch(*this)); |
| + return ElementTraversal::lastWithin(rootNode(), makeIsMatch(*this)); |
| } |
| Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Element& currentElement, unsigned& currentOffset) const |
| @@ -381,9 +353,9 @@ Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Element& curre |
| ASSERT(currentOffset < offset); |
| switch (type()) { |
| case HTMLTagCollectionType: |
| - return traverseMatchingElementsForwardToOffset(toHTMLTagCollection(*this), offset, currentElement, currentOffset); |
| + return traverseMatchingElementsForwardToOffset(currentElement, &rootNode(), offset, currentOffset, makeIsMatch(toHTMLTagCollection(*this))); |
| case ClassCollectionType: |
| - return traverseMatchingElementsForwardToOffset(toClassCollection(*this), offset, currentElement, currentOffset); |
| + return traverseMatchingElementsForwardToOffset(currentElement, &rootNode(), offset, currentOffset, makeIsMatch(toClassCollection(*this))); |
| default: |
| if (overridesItemAfter()) { |
| for (Element* next = virtualItemAfter(¤tElement); next; next = virtualItemAfter(next)) { |
| @@ -393,13 +365,14 @@ Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Element& curre |
| return 0; |
| } |
| if (shouldOnlyIncludeDirectChildren()) { |
| - for (Element* next = nextMatchingChildElement(*this, currentElement); next; next = nextMatchingChildElement(*this, *next)) { |
| + IsMatch<HTMLCollection> isMatch(*this); |
| + for (Element* next = ElementTraversal::nextSibling(currentElement, isMatch); next; next = ElementTraversal::nextSibling(*next, isMatch)) { |
| if (++currentOffset == offset) |
| return next; |
| } |
| return 0; |
| } |
| - return traverseMatchingElementsForwardToOffset(*this, offset, currentElement, currentOffset); |
| + return traverseMatchingElementsForwardToOffset(currentElement, &rootNode(), offset, currentOffset, makeIsMatch(*this)); |
| } |
| } |
| @@ -408,13 +381,14 @@ Element* HTMLCollection::traverseBackwardToOffset(unsigned offset, Element& curr |
| ASSERT(currentOffset > offset); |
| ASSERT(canTraverseBackward()); |
| if (shouldOnlyIncludeDirectChildren()) { |
| - for (Element* previous = previousMatchingChildElement(*this, currentElement); previous; previous = previousMatchingChildElement(*this, *previous)) { |
| + IsMatch<HTMLCollection> isMatch(*this); |
| + for (Element* previous = ElementTraversal::previousSibling(currentElement, isMatch); previous; previous = ElementTraversal::previousSibling(*previous, isMatch)) { |
| if (--currentOffset == offset) |
| return previous; |
| } |
| return 0; |
| } |
| - return traverseMatchingElementsBackwardToOffset(*this, offset, currentElement, currentOffset); |
| + return traverseMatchingElementsBackwardToOffset(currentElement, &rootNode(), offset, currentOffset, makeIsMatch(*this)); |
| } |
| Element* HTMLCollection::namedItem(const AtomicString& name) const |