15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2001 Peter Kelly (pmk@post.com)
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/NodeIterator.h"
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
28df95704c49daea886ddad70775bda23618d6274dBen Murdoch#include "bindings/v8/ExceptionState.h"
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h"
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/ExceptionCode.h"
3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/NodeTraversal.h"
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore {
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)NodeIterator::NodePointer::NodePointer()
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
39d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)NodeIterator::NodePointer::NodePointer(PassRefPtrWillBeRawPtr<Node> n, bool b)
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : node(n)
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , isPointerBeforeNode(b)
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void NodeIterator::NodePointer::clear()
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    node.clear();
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool NodeIterator::NodePointer::moveToNext(Node* root)
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!node)
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isPointerBeforeNode) {
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        isPointerBeforeNode = false;
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    node = NodeTraversal::next(*node, root);
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return node;
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool NodeIterator::NodePointer::moveToPrevious(Node* root)
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!node)
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!isPointerBeforeNode) {
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        isPointerBeforeNode = true;
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    node = NodeTraversal::previous(*node, root);
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return node;
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
74d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)NodeIterator::NodeIterator(PassRefPtrWillBeRawPtr<Node> rootNode, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter> filter)
75d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    : NodeIteratorBase(rootNode, whatToShow, filter)
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_referenceNode(root(), true)
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ScriptWrappable::init(this);
798abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    root()->document().attachNodeIterator(this);
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)NodeIterator::~NodeIterator()
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
84d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#if !ENABLE(OILPAN)
858abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    root()->document().detachNodeIterator(this);
86d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#endif
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
89d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)PassRefPtrWillBeRawPtr<Node> NodeIterator::nextNode(ExceptionState& exceptionState)
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
91d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RefPtrWillBeRawPtr<Node> result = nullptr;
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_candidateNode = m_referenceNode;
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (m_candidateNode.moveToNext(root())) {
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // NodeIterators treat the DOM tree as a flat list of nodes.
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // In other words, FILTER_REJECT does not pass over descendants
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // of the rejected node. Hence, FILTER_REJECT is the same as FILTER_SKIP.
98d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        RefPtrWillBeRawPtr<Node> provisionalResult = m_candidateNode.node;
99a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        bool nodeWasAccepted = acceptNode(provisionalResult.get(), exceptionState) == NodeFilter::FILTER_ACCEPT;
100a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        if (exceptionState.hadException())
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (nodeWasAccepted) {
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_referenceNode = m_candidateNode;
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result = provisionalResult.release();
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_candidateNode.clear();
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result.release();
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
113d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)PassRefPtrWillBeRawPtr<Node> NodeIterator::previousNode(ExceptionState& exceptionState)
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
115d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RefPtrWillBeRawPtr<Node> result = nullptr;
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_candidateNode = m_referenceNode;
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (m_candidateNode.moveToPrevious(root())) {
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // NodeIterators treat the DOM tree as a flat list of nodes.
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // In other words, FILTER_REJECT does not pass over descendants
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // of the rejected node. Hence, FILTER_REJECT is the same as FILTER_SKIP.
122d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        RefPtrWillBeRawPtr<Node> provisionalResult = m_candidateNode.node;
123a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        bool nodeWasAccepted = acceptNode(provisionalResult.get(), exceptionState) == NodeFilter::FILTER_ACCEPT;
124a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        if (exceptionState.hadException())
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (nodeWasAccepted) {
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_referenceNode = m_candidateNode;
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result = provisionalResult.release();
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_candidateNode.clear();
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result.release();
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void NodeIterator::detach()
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
139f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    // This is now a no-op as per the DOM specification.
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)void NodeIterator::nodeWillBeRemoved(Node& removedNode)
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    updateForNodeRemoval(removedNode, m_candidateNode);
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    updateForNodeRemoval(removedNode, m_referenceNode);
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)void NodeIterator::updateForNodeRemoval(Node& removedNode, NodePointer& referenceNode) const
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    ASSERT(root()->document() == removedNode.document());
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Iterator is not affected if the removed node is the reference node and is the root.
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // or if removed node is not the reference node, or the ancestor of the reference node.
15419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    if (!removedNode.isDescendantOf(root()))
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
156d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    bool willRemoveReferenceNode = removedNode == referenceNode.node.get();
15719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    bool willRemoveReferenceNodeAncestor = referenceNode.node && referenceNode.node->isDescendantOf(&removedNode);
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!willRemoveReferenceNode && !willRemoveReferenceNodeAncestor)
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (referenceNode.isPointerBeforeNode) {
16251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        Node* node = NodeTraversal::next(removedNode, root());
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (node) {
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Move out from under the node being removed if the new reference
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // node is a descendant of the node being removed.
16619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            while (node && node->isDescendantOf(&removedNode))
16751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                node = NodeTraversal::next(*node, root());
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (node)
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                referenceNode.node = node;
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
17151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            node = NodeTraversal::previous(removedNode, root());
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (node) {
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // Move out from under the node being removed if the reference node is
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // a descendant of the node being removed.
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (willRemoveReferenceNodeAncestor) {
17619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)                    while (node && node->isDescendantOf(&removedNode))
17751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                        node = NodeTraversal::previous(*node, root());
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (node) {
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    // Removing last node.
18102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch                    // Need to move the pointer after the node preceding the
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    // new reference node.
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    referenceNode.node = node;
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    referenceNode.isPointerBeforeNode = false;
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
18951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        Node* node = NodeTraversal::previous(removedNode, root());
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (node) {
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Move out from under the node being removed if the reference node is
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // a descendant of the node being removed.
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (willRemoveReferenceNodeAncestor) {
19419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)                while (node && node->isDescendantOf(&removedNode))
19551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    node = NodeTraversal::previous(*node, root());
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (node)
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                referenceNode.node = node;
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // FIXME: This branch doesn't appear to have any LayoutTests.
20151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            node = NodeTraversal::next(removedNode, root());
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Move out from under the node being removed if the reference node is
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // a descendant of the node being removed.
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (willRemoveReferenceNodeAncestor) {
20519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)                while (node && node->isDescendantOf(&removedNode))
20651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    node = NodeTraversal::previous(*node, root());
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (node)
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                referenceNode.node = node;
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
214d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void NodeIterator::trace(Visitor* visitor)
215d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){
216d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    visitor->trace(m_referenceNode);
217d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    visitor->trace(m_candidateNode);
218d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    NodeIteratorBase::trace(visitor);
219d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)}
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore
222