示例#1
0
void EventPathWalker::moveToParent()
{
    ASSERT(m_node);
    ASSERT(m_distributedNode);
    if (ElementShadow* shadow = shadowOfParent(m_node)) {
        ContentDistributor::ensureDistribution(shadow->youngestShadowRoot());
        if (InsertionPoint* insertionPoint = shadow->distributor().findInsertionPointFor(m_distributedNode)) {
            m_node = insertionPoint;
            m_isVisitingInsertionPointInReprojection = true;
            return;
        }
    }
    if (!m_node->isShadowRoot()) {
        m_node = m_node->parentNode();
        if (!(m_node && m_node->isShadowRoot() && ScopeContentDistribution::assignedTo(toShadowRoot(m_node))))
            m_distributedNode = m_node;
        m_isVisitingInsertionPointInReprojection = false;
        return;
    }

    const ShadowRoot* shadowRoot = toShadowRoot(m_node);
    if (InsertionPoint* insertionPoint = ScopeContentDistribution::assignedTo(shadowRoot)) {
        m_node = insertionPoint;
        m_isVisitingInsertionPointInReprojection = true;
        return;
    }
    m_node = shadowRoot->host();
    m_distributedNode = m_node;
    m_isVisitingInsertionPointInReprojection = false;
}
void AncestorChainWalker::parent()
{
    ASSERT(m_node);
    ASSERT(m_distributedNode);
    if (ElementShadow* shadow = shadowOfParent(m_node)) {
        if (InsertionPoint* insertionPoint = shadow->insertionPointFor(m_distributedNode)) {
            m_node = insertionPoint;
            m_isCrossingInsertionPoint = true;
            return;
        }
    }
    if (!m_node->isShadowRoot()) {
        m_node = m_node->parentNode();
        m_distributedNode = m_node;
        m_isCrossingInsertionPoint = false;
        return;
    }

    const ShadowRoot* shadowRoot = toShadowRoot(m_node);
    if (InsertionPoint* insertionPoint = shadowRoot->assignedTo()) {
        m_node = insertionPoint;
        m_isCrossingInsertionPoint = true;
        return;
    }
    m_node = shadowRoot->host();
    m_distributedNode = m_node;
    m_isCrossingInsertionPoint = false;
}
示例#3
0
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);
}
示例#4
0
Node* ComposedShadowTreeWalker::traverseSiblingOrBackToInsertionPoint(const Node* node, TraversalDirection direction)
{
    ASSERT(node);
    ElementShadow* shadow = shadowOfParent(node);
    if (!shadow)
        return traverseSiblingInCurrentTree(node, direction);
    InsertionPoint* insertionPoint = shadow->insertionPointFor(node);
    if (!insertionPoint)
        return traverseSiblingInCurrentTree(node, direction);
    if (Node* next = (direction == TraversalDirectionForward ? insertionPoint->nextTo(node) : insertionPoint->previousTo(node)))
        return traverseNode(next, direction);
    return traverseSiblingOrBackToInsertionPoint(insertionPoint, direction);
}
static inline InsertionPoint* resolveReprojection(const Node* node)
{
    InsertionPoint* insertionPoint = 0;
    const Node* current = node;
    while (ElementShadow* shadow = shadowOfParent(current)) {
        shadow->ensureDistribution();
        if (InsertionPoint* insertedTo = shadow->insertionPointFor(node)) {
            current = insertedTo;
            insertionPoint = insertedTo;
        } else
            break;
    }
    return insertionPoint;
}
Node* ComposedShadowTreeWalker::traverseSiblingOrBackToInsertionPoint(const Node* node, TraversalDirection direction)
{
    ASSERT(node);
    ElementShadow* shadow = shadowOfParent(node);
    if (!shadow)
        return traverseSiblingInCurrentTree(node, direction);
    InsertionPoint* insertionPoint = resolveReprojection(node);
    if (!insertionPoint)
        return traverseSiblingInCurrentTree(node, direction);

    if (Node* found = traverseDistributedNodes(direction == TraversalDirectionForward ? insertionPoint->nextTo(node) : insertionPoint->previousTo(node), insertionPoint, direction))
        return found;
    return traverseSiblingOrBackToInsertionPoint(insertionPoint, direction);
}
示例#7
0
Node* ComposedShadowTreeParentWalker::traverseParentIncludingInsertionPointAndShadowRoot(const Node* node) const
{
    if (ElementShadow* shadow = shadowOfParent(node)) {
        if (InsertionPoint* insertionPoint = shadow->insertionPointFor(node))
            return insertionPoint;
    }
    if (!node->isShadowRoot())
        return node->parentNode();
    const ShadowRoot* shadowRoot = toShadowRoot(node);
    if (shadowRoot->isYoungest())
        return shadowRoot->host();
    InsertionPoint* assignedInsertionPoint = shadowRoot->assignedTo();
    ASSERT(assignedInsertionPoint);
    return assignedInsertionPoint;
}
// 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);
}