unsigned FlatTreeTraversal::countChildren(const Node& node) { assertPrecondition(node); unsigned count = 0; for (Node* runner = traverseFirstChild(node); runner; runner = traverseNextSibling(*runner)) ++count; return count; }
Node* FlatTreeTraversal::childAt(const Node& node, unsigned index) { assertPrecondition(node); Node* child = traverseFirstChild(node); while (child && index--) child = nextSibling(*child); assertPostcondition(child); return child; }
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(); }
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; }