Node* ComposedShadowTreeWalker::traverseChild(const Node* node, TraversalDirection direction) const { ASSERT(node); if (canCrossUpperBoundary()) { return node->shadowRoot() ? traverseLightChildren(node->shadowRoot(), direction) : traverseLightChildren(node, direction); } if (isShadowHost(node)) return 0; return traverseLightChildren(node, direction); }
Node* ComposedShadowTreeWalker::traverseChild(const Node* node, TraversalDirection direction) const { ASSERT(node); if (canCrossUpperBoundary()) { ElementShadow* shadow = shadowFor(node); return shadow ? traverseLightChildren(shadow->youngestShadowRoot(), direction) : traverseLightChildren(node, direction); } if (isShadowHost(node)) return 0; return traverseLightChildren(node, direction); }
Node* ComposedShadowTreeWalker::traverseParentBackToShadowRootOrHost(const ShadowRoot* shadowRoot, ParentTraversalDetails* details) const { ASSERT(shadowRoot); if (canCrossUpperBoundary()) { if (details) details->didTraverseShadowRoot(shadowRoot); return shadowRoot->hostElement(); } return const_cast<ShadowRoot*>(shadowRoot); }
Node* ComposedShadowTreeWalker::traverseParentBackToYoungerShadowRootOrHost(const ShadowRoot* shadowRoot) const { ASSERT(shadowRoot); if (shadowRoot->isYoungest()) { if (canCrossUpperBoundary()) return shadowRoot->host(); return const_cast<ShadowRoot*>(shadowRoot); } InsertionPoint* assignedInsertionPoint = shadowRoot->assignedTo(); ASSERT(assignedInsertionPoint); return traverseParent(assignedInsertionPoint); }
Node* ComposedShadowTreeWalker::traverseParent(const Node* node) const { if (!canCrossUpperBoundary() && node->isShadowRoot()) { ASSERT(toShadowRoot(node)->isYoungest()); return 0; } if (ElementShadow* shadow = shadowOfParent(node)) { if (InsertionPoint* insertionPoint = shadow->insertionPointFor(node)) return traverseParent(insertionPoint); } return traverseParentInCurrentTree(node); }
Node* ComposedShadowTreeWalker::traverseParentBackToYoungerShadowRootOrHost(const ShadowRoot* shadowRoot, ParentTraversalDetails* details) const { ASSERT(shadowRoot); ASSERT(!ScopeContentDistribution::assignedTo(shadowRoot)); if (shadowRoot->isYoungest()) { if (canCrossUpperBoundary()) { if (details) details->didTraverseShadowRoot(shadowRoot); return shadowRoot->host(); } return const_cast<ShadowRoot*>(shadowRoot); } return 0; }
// FIXME: Use an iterative algorithm so that it can be inlined. // https://bugs.webkit.org/show_bug.cgi?id=90415 Node* ComposedShadowTreeWalker::traverseParent(const Node* node, ParentTraversalDetails* details) const { if (!canCrossUpperBoundary() && node->isShadowRoot()) { ASSERT(toShadowRoot(node)->isYoungest()); return 0; } if (ElementShadow* shadow = shadowOfParent(node)) { shadow->ensureDistribution(); if (InsertionPoint* insertionPoint = resolveReprojection(node)) { if (details) details->didTraverseInsertionPoint(insertionPoint); return traverseParent(insertionPoint, details); } // The node is a non-distributed light child or older shadow's child. if (details) details->childWasOutOfComposition(); } return traverseParentInCurrentTree(node, details); }
Node* ComposedShadowTreeWalker::traverseParentBackToYoungerShadowRootOrHost(const ShadowRoot* shadowRoot, ParentTraversalDetails* details) const { ASSERT(shadowRoot); if (shadowRoot->isYoungest()) { if (canCrossUpperBoundary()) { if (details) details->didTraverseShadowRoot(shadowRoot); return shadowRoot->host(); } return const_cast<ShadowRoot*>(shadowRoot); } if (InsertionPoint* assignedInsertionPoint = shadowRoot->assignedTo()) { if (details) details->didTraverseShadowRoot(shadowRoot); return traverseParent(assignedInsertionPoint, details); } return 0; }
// FIXME: Use an iterative algorithm so that it can be inlined. // https://bugs.webkit.org/show_bug.cgi?id=90415 Node* ComposedShadowTreeWalker::traverseParent(const Node* node, ParentTraversalDetails* details) const { if (node->isPseudoElement()) return toPseudoElement(node)->hostElement(); if (!canCrossUpperBoundary() && node->isShadowRoot()) return 0; if (nodeCanBeDistributed(node)) { if (InsertionPoint* insertionPoint = resolveReprojection(node)) { if (details) details->didTraverseInsertionPoint(insertionPoint); return traverseParent(insertionPoint, details); } // The node is a non-distributed light child or older shadow's child. if (details) details->childWasOutOfComposition(); } return traverseParentInCurrentTree(node, details); }