Node* ComposedTreeTraversal::traverseNextAncestorSibling(const Node& node) { ASSERT(!traverseNextSibling(node)); for (Node* parent = traverseParent(node); parent; parent = traverseParent(*parent)) { if (Node* nextSibling = traverseNextSibling(*parent)) return nextSibling; } return nullptr; }
Node* FlatTreeTraversal::traverseNextAncestorSibling(const Node& node) { DCHECK(!traverseNextSibling(node)); for (Node* parent = traverseParent(node); parent; parent = traverseParent(*parent)) { if (Node* nextSibling = traverseNextSibling(*parent)) return nextSibling; } return nullptr; }
Node* nextInScope(const Node* node) { ASSERT(!isActiveInsertionPoint(node)); if (Node* next = traverseFirstChild(node, DontCrossShadowRoot)) return next; if (Node* next = traverseNextSibling(node)) return next; const Node* current = node; while (current && !traverseNextSibling(current)) current = traverseParent(current, DontCrossShadowRoot); return current ? traverseNextSibling(current) : 0; }
void ComposedShadowTreeWalker::next() { assertPrecondition(); if (Node* next = traverseFirstChild(m_node)) m_node = next; else if (Node* next = traverseNextSibling(m_node)) m_node = next; else { const Node* n = m_node; while (n && !traverseNextSibling(n)) n = traverseParent(n); m_node = n ? traverseNextSibling(n) : 0; } assertPostcondition(); }
unsigned FlatTreeTraversal::countChildren(const Node& node) { assertPrecondition(node); unsigned count = 0; for (Node* runner = traverseFirstChild(node); runner; runner = traverseNextSibling(*runner)) ++count; return count; }
static Node* traverseNextSibling(const Node* node) { ASSERT(node); InsertionPoint* insertionPoint; if (nodeCanBeDistributed(node) && (insertionPoint = findInsertionPointOf(node))) { Node* found = findFirstFromDistributedNode(insertionPoint->nextDistributedTo(node), insertionPoint); if (found) return found; return traverseNextSibling(insertionPoint); } for (const Node* sibling = node->nextSibling(); sibling; sibling = sibling->nextSibling()) { if (Node* found = findFirstEnteringInsertionPoints(sibling)) return found; } if (node->parentNode() && isActiveInsertionPoint(node->parentNode())) return traverseNextSibling(node->parentNode()); return nullptr; }
Node* nextSiblingSlow(const Node* node) { ASSERT(!node->isShadowRoot()); // FIXME: Why do these functions deal with before/after when other code here doesn't? Node* nextSibling = 0; if (node->isBeforePseudoElement()) { nextSibling = traverseParent(node, CrossShadowRoot); nextSibling = traverseFirstChild(nextSibling, CrossShadowRoot); } else nextSibling = traverseNextSibling(node); if (nextSibling || node->isAfterPseudoElement()) return nextSibling; Node* parent = traverseParent(node, CrossShadowRoot); if (parent && parent->isElementNode()) return toElement(parent)->afterPseudoElement(); return 0; }
Node* FlatTreeTraversal::nextSkippingChildren(const Node& node) { if (Node* nextSibling = traverseNextSibling(node)) return nextSibling; return traverseNextAncestorSibling(node); }