#ifndef NodeTraversal_h
#define NodeTraversal_h
#include "ContainerNode.h"
#include "Text.h"
namespace WebCore {
namespace NodeTraversal {
Node* next(const Node*);
Node* next(const Node*, const Node* stayWithin);
Node* next(const ContainerNode*);
Node* next(const ContainerNode*, const Node* stayWithin);
Node* next(const Text*);
Node* next(const Text*, const Node* stayWithin);
Node* nextSkippingChildren(const Node*);
Node* nextSkippingChildren(const Node*, const Node* stayWithin);
Node* nextSkippingChildren(const ContainerNode*);
Node* nextSkippingChildren(const ContainerNode*, const Node* stayWithin);
Node* last(const ContainerNode*);
Node* previous(const Node*, const Node* stayWithin = 0);
Node* previousSkippingChildren(const Node*, const Node* stayWithin = 0);
Node* nextPostOrder(const Node*, const Node* stayWithin = 0);
Node* previousPostOrder(const Node*, const Node* stayWithin = 0);
Node* previousSkippingChildrenPostOrder(const Node*, const Node* stayWithin = 0);
Node* previousIncludingPseudo(const Node*, const Node* = 0);
Node* nextIncludingPseudo(const Node*, const Node* = 0);
Node* nextIncludingPseudoSkippingChildren(const Node*, const Node* = 0);
}
namespace NodeTraversal {
Node* nextAncestorSibling(const Node*);
Node* nextAncestorSibling(const Node*, const Node* stayWithin);
Node* deepLastChild(Node*);
template <class NodeType>
inline Node* traverseNextTemplate(NodeType* current)
{
if (current->firstChild())
return current->firstChild();
if (current->nextSibling())
return current->nextSibling();
return nextAncestorSibling(current);
}
inline Node* next(const Node* current) { return traverseNextTemplate(current); }
inline Node* next(const ContainerNode* current) { return traverseNextTemplate(current); }
template <class NodeType>
inline Node* traverseNextTemplate(NodeType* current, const Node* stayWithin)
{
if (current->firstChild())
return current->firstChild();
if (current == stayWithin)
return 0;
if (current->nextSibling())
return current->nextSibling();
return nextAncestorSibling(current, stayWithin);
}
inline Node* next(const Node* current, const Node* stayWithin) { return traverseNextTemplate(current, stayWithin); }
inline Node* next(const ContainerNode* current, const Node* stayWithin) { return traverseNextTemplate(current, stayWithin); }
template <class NodeType>
inline Node* traverseNextSkippingChildrenTemplate(NodeType* current)
{
if (current->nextSibling())
return current->nextSibling();
return nextAncestorSibling(current);
}
inline Node* nextSkippingChildren(const Node* current) { return traverseNextSkippingChildrenTemplate(current); }
inline Node* nextSkippingChildren(const ContainerNode* current) { return traverseNextSkippingChildrenTemplate(current); }
template <class NodeType>
inline Node* traverseNextSkippingChildrenTemplate(NodeType* current, const Node* stayWithin)
{
if (current == stayWithin)
return 0;
if (current->nextSibling())
return current->nextSibling();
return nextAncestorSibling(current, stayWithin);
}
inline Node* nextSkippingChildren(const Node* current, const Node* stayWithin) { return traverseNextSkippingChildrenTemplate(current, stayWithin); }
inline Node* nextSkippingChildren(const ContainerNode* current, const Node* stayWithin) { return traverseNextSkippingChildrenTemplate(current, stayWithin); }
inline Node* next(const Text* current) { return traverseNextSkippingChildrenTemplate(current); }
inline Node* next(const Text* current, const Node* stayWithin) { return traverseNextSkippingChildrenTemplate(current, stayWithin); }
inline Node* previous(const Node* current, const Node* stayWithin)
{
if (Node* previous = current->previousSibling())
return deepLastChild(previous);
if (current->parentNode() == stayWithin)
return nullptr;
return current->parentNode();
}
}
}
#endif