// TODO(yosin) We should consider introducing template class to share code // between DOM tree traversal and flat tree tarversal. Node* FlatTreeTraversal::previousPostOrder(const Node& current, const Node* stayWithin) { assertPrecondition(current); if (stayWithin) assertPrecondition(*stayWithin); if (Node* lastChild = traverseLastChild(current)) { assertPostcondition(lastChild); return lastChild; } if (current == stayWithin) return nullptr; if (Node* previousSibling = traversePreviousSibling(current)) { assertPostcondition(previousSibling); return previousSibling; } return previousAncestorSiblingPostOrder(current, stayWithin); }
Node& FlatTreeTraversal::lastWithinOrSelf(const Node& node) { assertPrecondition(node); Node* lastDescendant = lastWithin(node); Node& result = lastDescendant ? *lastDescendant : const_cast<Node&>(node); assertPostcondition(&result); return result; }
Node* FlatTreeTraversal::lastWithin(const Node& node) { assertPrecondition(node); Node* descendant = traverseLastChild(node); for (Node* child = descendant; child; child = lastChild(*child)) descendant = child; assertPostcondition(descendant); return descendant; }
Node* FlatTreeTraversal::childAt(const Node& node, unsigned index) { assertPrecondition(node); Node* child = traverseFirstChild(node); while (child && index--) child = nextSibling(*child); assertPostcondition(child); return child; }
void ComposedShadowTreeWalker::previous() { assertPrecondition(); if (Node* n = traversePreviousSibling(m_node)) { while (Node* child = traverseLastChild(n)) n = child; m_node = n; } else parent(); assertPostcondition(); }
Node* FlatTreeTraversal::commonAncestor(const Node& nodeA, const Node& nodeB) { assertPrecondition(nodeA); assertPrecondition(nodeB); Node* result = nodeA.commonAncestor(nodeB, [](const Node& node) { return FlatTreeTraversal::parent(node); }); assertPostcondition(result); return result; }
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(); }
void ComposedShadowTreeWalker::lastChild() { assertPrecondition(); m_node = traverseLastChild(m_node); assertPostcondition(); }
void ComposedShadowTreeWalker::firstChild() { assertPrecondition(); m_node = traverseChild(m_node, TraversalDirectionForward); assertPostcondition(); }
void ComposedShadowTreeWalker::parent() { assertPrecondition(); m_node = traverseParent(m_node); assertPostcondition(); }
void ComposedShadowTreeWalker::previousSibling() { assertPrecondition(); m_node = traverseSiblingOrBackToInsertionPoint(m_node, TraversalDirectionBackward); assertPostcondition(); }