Node* FlatTreeTraversal::traversePreviousAncestorSibling(const Node& node) { DCHECK(!traversePreviousSibling(node)); for (Node* parent = traverseParent(node); parent; parent = traverseParent(*parent)) { if (Node* previousSibling = traversePreviousSibling(*parent)) return previousSibling; } return nullptr; }
Node* ComposedTreeTraversal::traversePreviousAncestorSibling(const Node& node) { ASSERT(!traversePreviousSibling(node)); for (Node* parent = traverseParent(node); parent; parent = traverseParent(*parent)) { if (Node* previousSibling = traversePreviousSibling(*parent)) return previousSibling; } return nullptr; }
unsigned FlatTreeTraversal::index(const Node& node) { assertPrecondition(node); unsigned count = 0; for (Node* runner = traversePreviousSibling(node); runner; runner = previousSibling(*runner)) ++count; return count; }
Node* previousInScope(const Node* node) { ASSERT(!isActiveInsertionPoint(node)); if (Node* current = traversePreviousSibling(node)) { while (Node* child = traverseLastChild(current, DontCrossShadowRoot)) current = child; return current; } return traverseParent(node, DontCrossShadowRoot); }
void ComposedShadowTreeWalker::previous() { assertPrecondition(); if (Node* n = traversePreviousSibling(m_node)) { while (Node* child = traverseLastChild(n)) n = child; m_node = n; } else parent(); assertPostcondition(); }
static Node* traversePreviousSibling(const Node* node) { ASSERT(node); InsertionPoint* insertionPoint; if (nodeCanBeDistributed(node) && (insertionPoint = findInsertionPointOf(node))) { Node* found = findLastFromDistributedNode(insertionPoint->previousDistributedTo(node), insertionPoint); if (found) return found; return traversePreviousSibling(insertionPoint); } for (const Node* sibling = node->previousSibling(); sibling; sibling = sibling->previousSibling()) { if (Node* found = findLastEnteringInsertionPoints(sibling)) return found; } if (node->parentNode() && isActiveInsertionPoint(node->parentNode())) return traversePreviousSibling(node->parentNode()); return nullptr; }
// 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* previousSiblingSlow(const Node* node) { ASSERT(!node->isShadowRoot()); Node* previousSibling = 0; if (node->isAfterPseudoElement()) { ContainerNode* parent = traverseParent(node, CrossShadowRoot); previousSibling = traverseLastChild(parent, CrossShadowRoot); } else previousSibling = traversePreviousSibling(node); if (previousSibling || node->isBeforePseudoElement()) return previousSibling; ContainerNode* parent = traverseParent(node, CrossShadowRoot); if (parent && parent->isElementNode()) return toElement(parent)->beforePseudoElement(); return 0; }
Node* FlatTreeTraversal::previousSkippingChildren(const Node& node) { if (Node* previousSibling = traversePreviousSibling(node)) return previousSibling; return traversePreviousAncestorSibling(node); }