summaryrefslogtreecommitdiff
path: root/Source/WebCore/dom/ElementTraversal.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/dom/ElementTraversal.h')
-rw-r--r--Source/WebCore/dom/ElementTraversal.h321
1 files changed, 121 insertions, 200 deletions
diff --git a/Source/WebCore/dom/ElementTraversal.h b/Source/WebCore/dom/ElementTraversal.h
index 03a7c98f1..57f42e234 100644
--- a/Source/WebCore/dom/ElementTraversal.h
+++ b/Source/WebCore/dom/ElementTraversal.h
@@ -22,8 +22,7 @@
*
*/
-#ifndef ElementTraversal_h
-#define ElementTraversal_h
+#pragma once
#include "Element.h"
#include "NodeTraversal.h"
@@ -34,335 +33,257 @@ template <typename ElementType>
class Traversal {
public:
// First or last ElementType child of the node.
- static ElementType* firstChild(const Node*);
- static ElementType* firstChild(const ContainerNode*);
- static ElementType* lastChild(const Node*);
- static ElementType* lastChild(const ContainerNode*);
+ static ElementType* firstChild(const Node&);
+ static ElementType* firstChild(const ContainerNode&);
+ static ElementType* lastChild(const Node&);
+ static ElementType* lastChild(const ContainerNode&);
// First or last ElementType descendant of the node. For Elements firstWithin is always the same as first child.
- static ElementType* firstWithin(const Node*);
- static ElementType* firstWithin(const ContainerNode*);
- static ElementType* lastWithin(const Node*);
- static ElementType* lastWithin(const ContainerNode*);
+ static ElementType* firstWithin(const Node&);
+ static ElementType* firstWithin(const ContainerNode&);
+ static ElementType* lastWithin(const Node&);
+ static ElementType* lastWithin(const ContainerNode&);
// Pre-order traversal skipping non-ElementType nodes.
- static ElementType* next(const Node*);
- static ElementType* next(const Node*, const Node* stayWithin);
- static ElementType* next(const ContainerNode*);
- static ElementType* next(const ContainerNode*, const Node* stayWithin);
- static ElementType* previous(const Node*);
- static ElementType* previous(const Node*, const Node* stayWithin);
- static ElementType* previous(const ContainerNode*);
- static ElementType* previous(const ContainerNode*, const Node* stayWithin);
+ static ElementType* next(const Node&);
+ static ElementType* next(const Node&, const Node* stayWithin);
+ static ElementType* next(const ContainerNode&);
+ static ElementType* next(const ContainerNode&, const Node* stayWithin);
+ static ElementType* previous(const Node&);
+ static ElementType* previous(const Node&, const Node* stayWithin);
// Next or previous ElementType sibling if there is one.
- static ElementType* nextSibling(const Node*);
- static ElementType* nextSibling(const ContainerNode*);
- static ElementType* previousSibling(const Node*);
- static ElementType* previousSibling(const ContainerNode*);
+ static ElementType* nextSibling(const Node&);
+ static ElementType* previousSibling(const Node&);
// Like next, but skips children.
- static ElementType* nextSkippingChildren(const Node*);
- static ElementType* nextSkippingChildren(const Node*, const Node* stayWithin);
- static ElementType* nextSkippingChildren(const ContainerNode*);
- static ElementType* nextSkippingChildren(const ContainerNode*, const Node* stayWithin);
+ static ElementType* nextSkippingChildren(const Node&);
+ static ElementType* nextSkippingChildren(const Node&, const Node* stayWithin);
private:
- template <typename CurrentType> static ElementType* firstChildTemplate(CurrentType*);
- template <typename CurrentType> static ElementType* lastChildTemplate(CurrentType*);
- template <typename CurrentType> static ElementType* firstWithinTemplate(CurrentType*);
- template <typename CurrentType> static ElementType* lastWithinTemplate(CurrentType*);
- template <typename CurrentType> static ElementType* nextTemplate(CurrentType*);
- template <typename CurrentType> static ElementType* nextTemplate(CurrentType*, const Node* stayWithin);
- template <typename CurrentType> static ElementType* previousTemplate(CurrentType*);
- template <typename CurrentType> static ElementType* previousTemplate(CurrentType*, const Node* stayWithin);
- template <typename CurrentType> static ElementType* nextSiblingTemplate(CurrentType*);
- template <typename CurrentType> static ElementType* previousSiblingTemplate(CurrentType*);
- template <typename CurrentType> static ElementType* nextSkippingChildrenTemplate(CurrentType*);
- template <typename CurrentType> static ElementType* nextSkippingChildrenTemplate(CurrentType*, const Node* stayWithin);
+ template <typename CurrentType> static ElementType* firstChildTemplate(CurrentType&);
+ template <typename CurrentType> static ElementType* lastChildTemplate(CurrentType&);
+ template <typename CurrentType> static ElementType* firstWithinTemplate(CurrentType&);
+ template <typename CurrentType> static ElementType* lastWithinTemplate(CurrentType&);
+ template <typename CurrentType> static ElementType* nextTemplate(CurrentType&);
+ template <typename CurrentType> static ElementType* nextTemplate(CurrentType&, const Node* stayWithin);
};
class ElementTraversal : public Traversal<Element> {
public:
// FIXME: These should go somewhere else.
// Pre-order traversal including the pseudo-elements.
- static Element* previousIncludingPseudo(const Node*, const Node* = 0);
- static Element* nextIncludingPseudo(const Node*, const Node* = 0);
- static Element* nextIncludingPseudoSkippingChildren(const Node*, const Node* = 0);
+ static Element* previousIncludingPseudo(const Node&, const Node* = nullptr);
+ static Element* nextIncludingPseudo(const Node&, const Node* = nullptr);
+ static Element* nextIncludingPseudoSkippingChildren(const Node&, const Node* = nullptr);
// Utility function to traverse only the element and pseudo-element siblings of a node.
- static Element* pseudoAwarePreviousSibling(const Node*);
+ static Element* pseudoAwarePreviousSibling(const Node&);
};
// Specialized for pure Element to exploit the fact that Elements parent is always either another Element or the root.
template <>
template <typename CurrentType>
-inline Element* Traversal<Element>::firstWithinTemplate(CurrentType* current)
+inline Element* Traversal<Element>::firstWithinTemplate(CurrentType& current)
{
return firstChildTemplate(current);
}
template <>
template <typename CurrentType>
-inline Element* Traversal<Element>::lastWithinTemplate(CurrentType* current)
-{
- Node* node = NodeTraversal::last(current);
- while (node && !node->isElementNode())
- node = NodeTraversal::previous(node, current);
- return toElement(node);
-}
-
-template <>
-template <typename CurrentType>
-inline Element* Traversal<Element>::nextTemplate(CurrentType* current)
+inline Element* Traversal<Element>::nextTemplate(CurrentType& current)
{
Node* node = NodeTraversal::next(current);
- while (node && !node->isElementNode())
- node = NodeTraversal::nextSkippingChildren(node);
- return toElement(node);
+ while (node && !is<Element>(*node))
+ node = NodeTraversal::nextSkippingChildren(*node);
+ return downcast<Element>(node);
}
template <>
template <typename CurrentType>
-inline Element* Traversal<Element>::nextTemplate(CurrentType* current, const Node* stayWithin)
+inline Element* Traversal<Element>::nextTemplate(CurrentType& current, const Node* stayWithin)
{
Node* node = NodeTraversal::next(current, stayWithin);
- while (node && !node->isElementNode())
- node = NodeTraversal::nextSkippingChildren(node, stayWithin);
- return toElement(node);
-}
-
-template <>
-template <typename CurrentType>
-inline Element* Traversal<Element>::previousTemplate(CurrentType* current)
-{
- Node* node = NodeTraversal::previous(current);
- while (node && !node->isElementNode())
- node = NodeTraversal::previous(node);
- return toElement(node);
-}
-
-template <>
-template <typename CurrentType>
-inline Element* Traversal<Element>::previousTemplate(CurrentType* current, const Node* stayWithin)
-{
- Node* node = NodeTraversal::previous(current, stayWithin);
- while (node && !node->isElementNode())
- node = NodeTraversal::previous(node, stayWithin);
- return toElement(node);
+ while (node && !is<Element>(*node))
+ node = NodeTraversal::nextSkippingChildren(*node, stayWithin);
+ return downcast<Element>(node);
}
// Generic versions.
template <typename ElementType>
template <typename CurrentType>
-inline ElementType* Traversal<ElementType>::firstChildTemplate(CurrentType* current)
+inline ElementType* Traversal<ElementType>::firstChildTemplate(CurrentType& current)
{
- Node* node = current->firstChild();
- while (node && !isElementOfType<const ElementType>(*node))
+ Node* node = current.firstChild();
+ while (node && !is<ElementType>(*node))
node = node->nextSibling();
- return static_cast<ElementType*>(node);
+ return downcast<ElementType>(node);
}
template <typename ElementType>
template <typename CurrentType>
-inline ElementType* Traversal<ElementType>::lastChildTemplate(CurrentType* current)
+inline ElementType* Traversal<ElementType>::lastChildTemplate(CurrentType& current)
{
- Node* node = current->lastChild();
- while (node && !isElementOfType<const ElementType>(*node))
+ Node* node = current.lastChild();
+ while (node && !is<ElementType>(*node))
node = node->previousSibling();
- return static_cast<ElementType*>(node);
+ return downcast<ElementType>(node);
}
template <typename ElementType>
template <typename CurrentType>
-inline ElementType* Traversal<ElementType>::firstWithinTemplate(CurrentType* current)
+inline ElementType* Traversal<ElementType>::firstWithinTemplate(CurrentType& current)
{
- Element* element = Traversal<Element>::firstWithin(current);
- while (element && !isElementOfType<const ElementType>(*element))
- element = Traversal<Element>::next(element, current);
- return static_cast<ElementType*>(element);
+ Node* node = current.firstChild();
+ while (node && !is<ElementType>(*node))
+ node = NodeTraversal::next(*node, &current);
+ return downcast<ElementType>(node);
}
template <typename ElementType>
template <typename CurrentType>
-inline ElementType* Traversal<ElementType>::lastWithinTemplate(CurrentType* current)
+inline ElementType* Traversal<ElementType>::lastWithinTemplate(CurrentType& current)
{
- Element* element = Traversal<Element>::lastWithin(current);
- while (element && !isElementOfType<const ElementType>(*element))
- element = Traversal<Element>::previous(element, current);
- return static_cast<ElementType*>(element);
+ Node* node = NodeTraversal::last(current);
+ while (node && !is<ElementType>(*node))
+ node = NodeTraversal::previous(*node, &current);
+ return downcast<ElementType>(node);
}
template <typename ElementType>
template <typename CurrentType>
-inline ElementType* Traversal<ElementType>::nextTemplate(CurrentType* current)
+inline ElementType* Traversal<ElementType>::nextTemplate(CurrentType& current)
{
- Element* element = Traversal<Element>::next(current);
- while (element && !isElementOfType<const ElementType>(*element))
- element = Traversal<Element>::next(element);
- return static_cast<ElementType*>(element);
+ Node* node = NodeTraversal::next(current);
+ while (node && !is<ElementType>(*node))
+ node = NodeTraversal::next(*node);
+ return downcast<ElementType>(node);
}
template <typename ElementType>
template <typename CurrentType>
-inline ElementType* Traversal<ElementType>::nextTemplate(CurrentType* current, const Node* stayWithin)
+inline ElementType* Traversal<ElementType>::nextTemplate(CurrentType& current, const Node* stayWithin)
{
- Element* element = Traversal<Element>::next(current, stayWithin);
- while (element && !isElementOfType<const ElementType>(*element))
- element = Traversal<Element>::next(element, stayWithin);
- return static_cast<ElementType*>(element);
+ Node* node = NodeTraversal::next(current, stayWithin);
+ while (node && !is<ElementType>(*node))
+ node = NodeTraversal::next(*node, stayWithin);
+ return downcast<ElementType>(node);
}
template <typename ElementType>
-template <typename CurrentType>
-inline ElementType* Traversal<ElementType>::previousTemplate(CurrentType* current)
+inline ElementType* Traversal<ElementType>::previous(const Node& current)
{
- Element* element = Traversal<Element>::previous(current);
- while (element && !isElementOfType<const ElementType>(*element))
- element = Traversal<Element>::previous(element);
- return static_cast<ElementType*>(element);
+ Node* node = NodeTraversal::previous(current);
+ while (node && !is<ElementType>(*node))
+ node = NodeTraversal::previous(*node);
+ return downcast<ElementType>(node);
}
template <typename ElementType>
-template <typename CurrentType>
-inline ElementType* Traversal<ElementType>::previousTemplate(CurrentType* current, const Node* stayWithin)
+inline ElementType* Traversal<ElementType>::previous(const Node& current, const Node* stayWithin)
{
- Element* element = Traversal<Element>::previous(current, stayWithin);
- while (element && !isElementOfType<const ElementType>(*element))
- element = Traversal<Element>::previous(element, stayWithin);
- return static_cast<ElementType*>(element);
+ Node* node = NodeTraversal::previous(current, stayWithin);
+ while (node && !is<ElementType>(*node))
+ node = NodeTraversal::previous(*node, stayWithin);
+ return downcast<ElementType>(node);
}
template <typename ElementType>
-template <typename CurrentType>
-inline ElementType* Traversal<ElementType>::nextSiblingTemplate(CurrentType* current)
+inline ElementType* Traversal<ElementType>::nextSibling(const Node& current)
{
- Node* node = current->nextSibling();
- while (node && !isElementOfType<const ElementType>(*node))
+ Node* node = current.nextSibling();
+ while (node && !is<ElementType>(*node))
node = node->nextSibling();
- return static_cast<ElementType*>(node);
+ return downcast<ElementType>(node);
}
template <typename ElementType>
-template <typename CurrentType>
-inline ElementType* Traversal<ElementType>::previousSiblingTemplate(CurrentType* current)
+inline ElementType* Traversal<ElementType>::previousSibling(const Node& current)
{
- Node* node = current->previousSibling();
- while (node && !isElementOfType<const ElementType>(*node))
+ Node* node = current.previousSibling();
+ while (node && !is<ElementType>(*node))
node = node->previousSibling();
- return static_cast<ElementType*>(node);
+ return downcast<ElementType>(node);
}
template <typename ElementType>
-template <typename CurrentType>
-inline ElementType* Traversal<ElementType>::nextSkippingChildrenTemplate(CurrentType* current)
+inline ElementType* Traversal<ElementType>::nextSkippingChildren(const Node& current)
{
Node* node = NodeTraversal::nextSkippingChildren(current);
- while (node && !isElementOfType<const ElementType>(*node))
- node = NodeTraversal::nextSkippingChildren(node);
- return static_cast<ElementType*>(node);
+ while (node && !is<ElementType>(*node))
+ node = NodeTraversal::nextSkippingChildren(*node);
+ return downcast<ElementType>(node);
}
template <typename ElementType>
-template <typename CurrentType>
-inline ElementType* Traversal<ElementType>::nextSkippingChildrenTemplate(CurrentType* current, const Node* stayWithin)
+inline ElementType* Traversal<ElementType>::nextSkippingChildren(const Node& current, const Node* stayWithin)
{
Node* node = NodeTraversal::nextSkippingChildren(current, stayWithin);
- while (node && !isElementOfType<const ElementType>(*node))
- node = NodeTraversal::nextSkippingChildren(node, stayWithin);
- return static_cast<ElementType*>(node);
+ while (node && !is<ElementType>(*node))
+ node = NodeTraversal::nextSkippingChildren(*node, stayWithin);
+ return downcast<ElementType>(node);
}
template <typename ElementType>
-inline ElementType* Traversal<ElementType>::firstChild(const ContainerNode* current) { return firstChildTemplate(current); }
+inline ElementType* Traversal<ElementType>::firstChild(const ContainerNode& current) { return firstChildTemplate(current); }
template <typename ElementType>
-inline ElementType* Traversal<ElementType>::firstChild(const Node* current) { return firstChildTemplate(current); }
+inline ElementType* Traversal<ElementType>::firstChild(const Node& current) { return firstChildTemplate(current); }
template <typename ElementType>
-inline ElementType* Traversal<ElementType>::lastChild(const ContainerNode* current) { return lastChildTemplate(current); }
+inline ElementType* Traversal<ElementType>::lastChild(const ContainerNode& current) { return lastChildTemplate(current); }
template <typename ElementType>
-inline ElementType* Traversal<ElementType>::lastChild(const Node* current) { return lastChildTemplate(current); }
+inline ElementType* Traversal<ElementType>::lastChild(const Node& current) { return lastChildTemplate(current); }
template <typename ElementType>
-inline ElementType* Traversal<ElementType>::firstWithin(const ContainerNode* current) { return firstWithinTemplate(current); }
-template <typename ElementType>
-inline ElementType* Traversal<ElementType>::firstWithin(const Node* current) { return firstWithinTemplate(current); }
+inline ElementType* Traversal<ElementType>::firstWithin(const ContainerNode& current) { return firstWithinTemplate(current); }
template <typename ElementType>
-
-inline ElementType* Traversal<ElementType>::lastWithin(const ContainerNode* current) { return lastWithinTemplate(current); }
+inline ElementType* Traversal<ElementType>::firstWithin(const Node& current) { return firstWithinTemplate(current); }
template <typename ElementType>
-inline ElementType* Traversal<ElementType>::lastWithin(const Node* current) { return lastWithinTemplate(current); }
+inline ElementType* Traversal<ElementType>::lastWithin(const ContainerNode& current) { return lastWithinTemplate(current); }
template <typename ElementType>
-inline ElementType* Traversal<ElementType>::next(const ContainerNode* current) { return nextTemplate(current); }
-template <typename ElementType>
-inline ElementType* Traversal<ElementType>::next(const Node* current) { return nextTemplate(current); }
-template <typename ElementType>
-inline ElementType* Traversal<ElementType>::next(const ContainerNode* current, const Node* stayWithin) { return nextTemplate(current, stayWithin); }
-template <typename ElementType>
-inline ElementType* Traversal<ElementType>::next(const Node* current, const Node* stayWithin) { return nextTemplate(current, stayWithin); }
+inline ElementType* Traversal<ElementType>::lastWithin(const Node& current) { return lastWithinTemplate(current); }
template <typename ElementType>
-inline ElementType* Traversal<ElementType>::previous(const ContainerNode* current) { return previousTemplate(current); }
+inline ElementType* Traversal<ElementType>::next(const ContainerNode& current) { return nextTemplate(current); }
template <typename ElementType>
-inline ElementType* Traversal<ElementType>::previous(const Node* current) { return previousTemplate(current); }
+inline ElementType* Traversal<ElementType>::next(const Node& current) { return nextTemplate(current); }
template <typename ElementType>
-inline ElementType* Traversal<ElementType>::previous(const ContainerNode* current, const Node* stayWithin) { return previousTemplate(current, stayWithin); }
+inline ElementType* Traversal<ElementType>::next(const ContainerNode& current, const Node* stayWithin) { return nextTemplate(current, stayWithin); }
template <typename ElementType>
-inline ElementType* Traversal<ElementType>::previous(const Node* current, const Node* stayWithin) { return previousTemplate(current, stayWithin); }
-
-template <typename ElementType>
-inline ElementType* Traversal<ElementType>::nextSibling(const ContainerNode* current) { return nextSiblingTemplate(current); }
-template <typename ElementType>
-inline ElementType* Traversal<ElementType>::nextSibling(const Node* current) { return nextSiblingTemplate(current); }
-
-template <typename ElementType>
-inline ElementType* Traversal<ElementType>::previousSibling(const ContainerNode* current) { return previousSiblingTemplate(current); }
-template <typename ElementType>
-inline ElementType* Traversal<ElementType>::previousSibling(const Node* current) { return previousSiblingTemplate(current); }
-
-template <typename ElementType>
-inline ElementType* Traversal<ElementType>::nextSkippingChildren(const ContainerNode* current) { return nextSkippingChildrenTemplate(current); }
-template <typename ElementType>
-inline ElementType* Traversal<ElementType>::nextSkippingChildren(const Node* current) { return nextSkippingChildrenTemplate(current); }
-template <typename ElementType>
-inline ElementType* Traversal<ElementType>::nextSkippingChildren(const ContainerNode* current, const Node* stayWithin) { return nextSkippingChildrenTemplate(current, stayWithin); }
-template <typename ElementType>
-inline ElementType* Traversal<ElementType>::nextSkippingChildren(const Node* current, const Node* stayWithin) { return nextSkippingChildrenTemplate(current, stayWithin); }
+inline ElementType* Traversal<ElementType>::next(const Node& current, const Node* stayWithin) { return nextTemplate(current, stayWithin); }
// FIXME: These should go somewhere else.
-inline Element* ElementTraversal::previousIncludingPseudo(const Node* current, const Node* stayWithin)
+inline Element* ElementTraversal::previousIncludingPseudo(const Node& current, const Node* stayWithin)
{
Node* node = NodeTraversal::previousIncludingPseudo(current, stayWithin);
- while (node && !node->isElementNode())
- node = NodeTraversal::previousIncludingPseudo(node, stayWithin);
- return toElement(node);
+ while (node && !is<Element>(*node))
+ node = NodeTraversal::previousIncludingPseudo(*node, stayWithin);
+ return downcast<Element>(node);
}
-inline Element* ElementTraversal::nextIncludingPseudo(const Node* current, const Node* stayWithin)
+inline Element* ElementTraversal::nextIncludingPseudo(const Node& current, const Node* stayWithin)
{
Node* node = NodeTraversal::nextIncludingPseudo(current, stayWithin);
- while (node && !node->isElementNode())
- node = NodeTraversal::nextIncludingPseudo(node, stayWithin);
- return toElement(node);
+ while (node && !is<Element>(*node))
+ node = NodeTraversal::nextIncludingPseudo(*node, stayWithin);
+ return downcast<Element>(node);
}
-inline Element* ElementTraversal::nextIncludingPseudoSkippingChildren(const Node* current, const Node* stayWithin)
+inline Element* ElementTraversal::nextIncludingPseudoSkippingChildren(const Node& current, const Node* stayWithin)
{
Node* node = NodeTraversal::nextIncludingPseudoSkippingChildren(current, stayWithin);
- while (node && !node->isElementNode())
- node = NodeTraversal::nextIncludingPseudoSkippingChildren(node, stayWithin);
- return toElement(node);
+ while (node && !is<Element>(*node))
+ node = NodeTraversal::nextIncludingPseudoSkippingChildren(*node, stayWithin);
+ return downcast<Element>(node);
}
-inline Element* ElementTraversal::pseudoAwarePreviousSibling(const Node* current)
+inline Element* ElementTraversal::pseudoAwarePreviousSibling(const Node& current)
{
- Node* node = current->pseudoAwarePreviousSibling();
- while (node && !node->isElementNode())
+ Node* node = current.pseudoAwarePreviousSibling();
+ while (node && !is<Element>(*node))
node = node->pseudoAwarePreviousSibling();
- return toElement(node);
-}
-
+ return downcast<Element>(node);
}
-#endif
+} // namespace WebCore