ContainerNode* FlatTreeTraversal::traverseParent(const Node& node, ParentTraversalDetails* details) { // TODO(hayato): Stop this hack for a pseudo element because a pseudo element is not a child of its parentOrShadowHostNode() in a flat tree. if (node.isPseudoElement()) return node.parentOrShadowHostNode(); if (node.isChildOfV1ShadowHost()) { HTMLSlotElement* slot = finalDestinationSlotFor(node); if (!slot) return nullptr; return traverseParent(*slot); } Element* parent = node.parentElement(); if (parent && isHTMLSlotElement(parent)) { HTMLSlotElement& slot = toHTMLSlotElement(*parent); if (!slot.assignedNodes().isEmpty()) return nullptr; return traverseParent(slot, details); } if (canBeDistributedToInsertionPoint(node)) return traverseParentForV0(node, details); DCHECK(!shadowWhereNodeCanBeDistributed(node)); return traverseParentOrHost(node); }
// FIXME: Use an iterative algorithm so that it can be inlined. // https://bugs.webkit.org/show_bug.cgi?id=90415 Node* ComposedTreeWalker::traverseParent(const Node* node, ParentTraversalDetails* details) const { if (node->isPseudoElement()) return node->parentOrShadowHostNode(); if (shadowWhereNodeCanBeDistributed(*node)) { if (const InsertionPoint* insertionPoint = resolveReprojection(node)) { if (details) details->didTraverseInsertionPoint(insertionPoint); // The node is distributed. But the distribution was stopped at this insertion point. if (shadowWhereNodeCanBeDistributed(*insertionPoint)) return 0; return traverseParentOrHost(insertionPoint, details); } return 0; } return traverseParentOrHost(node, details); }
ContainerNode* FlatTreeTraversal::traverseParentForV0(const Node& node, ParentTraversalDetails* details) { if (shadowWhereNodeCanBeDistributed(node)) { if (const InsertionPoint* insertionPoint = resolveReprojection(&node)) { if (details) details->didTraverseInsertionPoint(insertionPoint); // The node is distributed. But the distribution was stopped at this insertion point. if (shadowWhereNodeCanBeDistributed(*insertionPoint)) return nullptr; return traverseParent(*insertionPoint); } return nullptr; } ContainerNode* parent = traverseParentOrHost(node); if (isActiveInsertionPoint(*parent)) return nullptr; return parent; }