Node* FlatTreeTraversal::commonAncestor(const Node& nodeA, const Node& nodeB)
{
    assertPrecondition(nodeA);
    assertPrecondition(nodeB);
    Node* result = nodeA.commonAncestor(nodeB,
                                        [](const Node& node)
    {
        return FlatTreeTraversal::parent(node);
    });
    assertPostcondition(result);
    return result;
}
bool FlatTreeTraversal::containsIncludingPseudoElement(const ContainerNode& container, const Node& node)
{
    assertPrecondition(container);
    assertPrecondition(node);
    // This can be slower than FlatTreeTraversal::contains() because we
    // can't early exit even when container doesn't have children.
    for (const Node* current = &node; current; current = traverseParent(*current)) {
        if (current == &container)
            return true;
    }
    return false;
}
bool FlatTreeTraversal::isDescendantOf(const Node& node, const Node& other)
{
    assertPrecondition(node);
    assertPrecondition(other);
    if (!hasChildren(other) || node.inShadowIncludingDocument() != other.inShadowIncludingDocument())
        return false;
    for (const ContainerNode* n = traverseParent(node); n; n = traverseParent(*n)) {
        if (n == other)
            return true;
    }
    return false;
}
Node& FlatTreeTraversal::lastWithinOrSelf(const Node& node)
{
    assertPrecondition(node);
    Node* lastDescendant = lastWithin(node);
    Node& result = lastDescendant ? *lastDescendant : const_cast<Node&>(node);
    assertPostcondition(&result);
    return result;
}
unsigned FlatTreeTraversal::countChildren(const Node& node)
{
    assertPrecondition(node);
    unsigned count = 0;
    for (Node* runner = traverseFirstChild(node); runner; runner = traverseNextSibling(*runner))
        ++count;
    return count;
}
unsigned FlatTreeTraversal::index(const Node& node)
{
    assertPrecondition(node);
    unsigned count = 0;
    for (Node* runner = traversePreviousSibling(node); runner; runner = previousSibling(*runner))
        ++count;
    return count;
}
// 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* FlatTreeTraversal::lastWithin(const Node& node)
{
    assertPrecondition(node);
    Node* descendant = traverseLastChild(node);
    for (Node* child = descendant; child; child = lastChild(*child))
        descendant = child;
    assertPostcondition(descendant);
    return descendant;
}
Node* FlatTreeTraversal::childAt(const Node& node, unsigned index)
{
    assertPrecondition(node);
    Node* child = traverseFirstChild(node);
    while (child && index--)
        child = nextSibling(*child);
    assertPostcondition(child);
    return child;
}
Пример #10
0
ComposedShadowTreeWalker::ComposedShadowTreeWalker(const Node* node, Policy policy)
    : m_node(node)
    , m_policy(policy)
{
#ifndef NDEBUG
    if (m_node)
        assertPrecondition();
#endif
}
void ComposedShadowTreeWalker::previous()
{
    assertPrecondition();
    if (Node* n = traversePreviousSibling(m_node)) {
        while (Node* child = traverseLastChild(n))
            n = child;
        m_node = n;
    } else
        parent();
    assertPostcondition();
}
void ComposedShadowTreeWalker::next()
{
    assertPrecondition();
    if (Node* next = traverseFirstChild(m_node))
        m_node = next;
    else if (Node* next = traverseNextSibling(m_node))
        m_node = next;
    else {
        const Node* n = m_node;
        while (n && !traverseNextSibling(n))
            n = traverseParent(n);
        m_node = n ? traverseNextSibling(n) : 0;
    }
    assertPostcondition();
}
void ComposedShadowTreeWalker::lastChild()
{
    assertPrecondition();
    m_node = traverseLastChild(m_node);
    assertPostcondition();
}
void ComposedShadowTreeWalker::firstChild()
{
    assertPrecondition();
    m_node = traverseChild(m_node, TraversalDirectionForward);
    assertPostcondition();
}
void ComposedShadowTreeWalker::parent()
{
    assertPrecondition();
    m_node = traverseParent(m_node);
    assertPostcondition();
}
void ComposedShadowTreeWalker::previousSibling()
{
    assertPrecondition();
    m_node = traverseSiblingOrBackToInsertionPoint(m_node, TraversalDirectionBackward);
    assertPostcondition();
}