// TODO(hayato): This may return a wrong result for a node which is not in a
// document flat tree.  See FlatTreeTraversalTest's redistribution test for details.
Node* FlatTreeTraversal::traverseSiblings(const Node& node, TraversalDirection direction)
{
    if (node.isChildOfV1ShadowHost())
        return traverseSiblingsForV1HostChild(node, direction);

    if (shadowWhereNodeCanBeDistributed(node))
        return traverseSiblingsForV0Distribution(node, direction);

    if (Node* found = resolveDistributionStartingAt(direction == TraversalDirectionForward ? node.nextSibling() : node.previousSibling(), direction))
        return found;

    if (!node.isInV0ShadowTree())
        return nullptr;

    // For v0 older shadow tree
    if (node.parentNode() && node.parentNode()->isShadowRoot()) {
        ShadowRoot* parentShadowRoot = toShadowRoot(node.parentNode());
        if (!parentShadowRoot->isYoungest()) {
            HTMLShadowElement* assignedInsertionPoint = parentShadowRoot->shadowInsertionPointOfYoungerShadowRoot();
            DCHECK(assignedInsertionPoint);
            return traverseSiblings(*assignedInsertionPoint, direction);
        }
    }
    return nullptr;
}
Beispiel #2
0
Node* ComposedShadowTreeWalker::traverseSiblingInCurrentTree(const Node* node, TraversalDirection direction)
{
    ASSERT(node);
    if (Node* found = traverseSiblings(direction == TraversalDirectionForward ? node->nextSibling() : node->previousSibling(), direction))
        return found;
    return escapeFallbackContentElement(node, direction);
}
Node* FlatTreeTraversal::traverseSiblingsForV1HostChild(const Node& node, TraversalDirection direction)
{
    HTMLSlotElement* slot = finalDestinationSlotFor(node);
    if (!slot)
        return nullptr;
    if (Node* siblingInDistributedNodes = (direction == TraversalDirectionForward ? slot->distributedNodeNextTo(node) : slot->distributedNodePreviousTo(node)))
        return siblingInDistributedNodes;
    return traverseSiblings(*slot, direction);
}
Node* ComposedTreeWalker::traverseSiblingInCurrentTree(const Node* node, TraversalDirection direction)
{
    ASSERT(node);
    if (Node* found = traverseSiblings(direction == TraversalDirectionForward ? node->nextSibling() : node->previousSibling(), direction))
        return found;
    if (Node* next = traverseBackToYoungerShadowRoot(node, direction))
        return next;
    return 0;
}
Node* FlatTreeTraversal::traverseSiblingsForV0Distribution(const Node& node, TraversalDirection direction)
{
    const InsertionPoint* finalDestination = resolveReprojection(&node);
    if (!finalDestination)
        return nullptr;
    if (Node* found = (direction == TraversalDirectionForward ? finalDestination->distributedNodeNextTo(&node) : finalDestination->distributedNodePreviousTo(&node)))
        return found;
    return traverseSiblings(*finalDestination, direction);

}
Node* ComposedShadowTreeWalker::traverseLightChildren(const Node* node, TraversalDirection direction)
{
    ASSERT(node);
    return traverseSiblings(direction == TraversalDirectionForward ? node->firstChild() : node->lastChild(), direction);
}