#include "config.h"
#include "NodeTraversal.h"
#include "PseudoElement.h"
namespace WebCore {
namespace NodeTraversal {
Node* previousIncludingPseudo(const Node* current, const Node* stayWithin)
{
Node* previous;
if (current == stayWithin)
return 0;
if ((previous = current->pseudoAwarePreviousSibling())) {
while (previous->pseudoAwareLastChild())
previous = previous->pseudoAwareLastChild();
return previous;
}
return current->isPseudoElement() ? toPseudoElement(current)->hostElement() : current->parentNode();
}
Node* nextIncludingPseudo(const Node* current, const Node* stayWithin)
{
Node* next;
if ((next = current->pseudoAwareFirstChild()))
return next;
if (current == stayWithin)
return 0;
if ((next = current->pseudoAwareNextSibling()))
return next;
current = current->isPseudoElement() ? toPseudoElement(current)->hostElement() : current->parentNode();
for (; current; current = current->parentNode()) {
if (current == stayWithin)
return 0;
if ((next = current->pseudoAwareNextSibling()))
return next;
}
return 0;
}
Node* nextIncludingPseudoSkippingChildren(const Node* current, const Node* stayWithin)
{
Node* next;
if (current == stayWithin)
return 0;
if ((next = current->pseudoAwareNextSibling()))
return next;
current = current->isPseudoElement() ? toPseudoElement(current)->hostElement() : current->parentNode();
for (; current; current = current->parentNode()) {
if (current == stayWithin)
return 0;
if ((next = current->pseudoAwareNextSibling()))
return next;
}
return 0;
}
Node* nextAncestorSibling(const Node* current)
{
ASSERT(!current->nextSibling());
for (current = current->parentNode(); current; current = current->parentNode()) {
if (current->nextSibling())
return current->nextSibling();
}
return 0;
}
Node* nextAncestorSibling(const Node* current, const Node* stayWithin)
{
ASSERT(!current->nextSibling());
ASSERT(current != stayWithin);
for (current = current->parentNode(); current; current = current->parentNode()) {
if (current == stayWithin)
return 0;
if (current->nextSibling())
return current->nextSibling();
}
return 0;
}
Node* last(const ContainerNode* current)
{
Node* node = current->lastChild();
if (!node)
return nullptr;
while (node->lastChild())
node = node->lastChild();
return node;
}
Node* deepLastChild(Node* node)
{
while (node->lastChild())
node = node->lastChild();
return node;
}
Node* previousSkippingChildren(const Node* current, const Node* stayWithin)
{
if (current == stayWithin)
return 0;
if (current->previousSibling())
return current->previousSibling();
for (current = current->parentNode(); current; current = current->parentNode()) {
if (current == stayWithin)
return 0;
if (current->previousSibling())
return current->previousSibling();
}
return 0;
}
Node* nextPostOrder(const Node* current, const Node* stayWithin)
{
if (current == stayWithin)
return 0;
if (!current->nextSibling())
return current->parentNode();
Node* next = current->nextSibling();
while (next->firstChild())
next = next->firstChild();
return next;
}
static Node* previousAncestorSiblingPostOrder(const Node* current, const Node* stayWithin)
{
ASSERT(!current->previousSibling());
for (current = current->parentNode(); current; current = current->parentNode()) {
if (current == stayWithin)
return 0;
if (current->previousSibling())
return current->previousSibling();
}
return 0;
}
Node* previousPostOrder(const Node* current, const Node* stayWithin)
{
if (current->lastChild())
return current->lastChild();
if (current == stayWithin)
return 0;
if (current->previousSibling())
return current->previousSibling();
return previousAncestorSiblingPostOrder(current, stayWithin);
}
Node* previousSkippingChildrenPostOrder(const Node* current, const Node* stayWithin)
{
if (current == stayWithin)
return 0;
if (current->previousSibling())
return current->previousSibling();
return previousAncestorSiblingPostOrder(current, stayWithin);
}
}
}