Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(771)

Unified Diff: Source/core/html/HTMLCollection.cpp

Issue 468183002: Move matching Element traversal functions from LiveNodeListBase to ElementTraversal (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Use anonymous namespace Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/html/HTMLCollection.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/html/HTMLCollection.cpp
diff --git a/Source/core/html/HTMLCollection.cpp b/Source/core/html/HTMLCollection.cpp
index 6402d501849435ac64123ad87c3b3f89c9e09bd0..e9852fd019d507cc420b8ce4e06ba05a9d88bc8d 100644
--- a/Source/core/html/HTMLCollection.cpp
+++ b/Source/core/html/HTMLCollection.cpp
@@ -255,43 +255,53 @@ 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);
-}
+namespace {
-template <> inline bool isMatchingElement(const HTMLTagCollection& collection, const Element& element)
-{
- return collection.elementMatches(element);
-}
+template <class HTMLCollectionType>
+class IsMatch {
+public:
+ IsMatch(const HTMLCollectionType& list)
+ : m_list(list)
+ { }
+
+ bool operator() (const Element& element) const
+ {
+ return m_list.elementMatches(element);
+ }
+
+private:
+ const HTMLCollectionType& m_list;
+};
+
+} // namespace
+
+template <class HTMLCollectionType>
+static inline IsMatch<HTMLCollectionType> makeIsMatch(const HTMLCollectionType& list) { return IsMatch<HTMLCollectionType>(list); }
Element* HTMLCollection::virtualItemAfter(Element*) const
{
@@ -318,53 +328,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 = &current;
- do {
- next = ElementTraversal::nextSibling(*next);
- } while (next && !isMatchingElement(nodeList, *next));
- return next;
-}
-
-inline Element* previousMatchingChildElement(const HTMLCollection& nodeList, Element& current)
-{
- Element* previous = &current;
- 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 +348,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 +357,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(&currentElement); next; next = virtualItemAfter(next)) {
@@ -393,13 +369,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 +385,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
« no previous file with comments | « Source/core/html/HTMLCollection.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698