18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2001 Peter Kelly (pmk@post.com)
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "NodeIterator.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Document.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ExceptionCode.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "NodeFilter.h"
31635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "ScriptState.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNodeIterator::NodePointer::NodePointer()
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNodeIterator::NodePointer::NodePointer(PassRefPtr<Node> n, bool b)
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : node(n)
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , isPointerBeforeNode(b)
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid NodeIterator::NodePointer::clear()
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    node.clear();
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool NodeIterator::NodePointer::moveToNext(Node* root)
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!node)
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isPointerBeforeNode) {
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        isPointerBeforeNode = false;
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    node = node->traverseNextNode(root);
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return node;
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool NodeIterator::NodePointer::moveToPrevious(Node* root)
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!node)
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!isPointerBeforeNode) {
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        isPointerBeforeNode = true;
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    node = node->traversePreviousNode(root);
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return node;
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNodeIterator::NodeIterator(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter, bool expandEntityReferences)
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : Traversal(rootNode, whatToShow, filter, expandEntityReferences)
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_referenceNode(root(), true)
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_detached(false)
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
79bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // Document type nodes may have a null document. But since they can't have children, there is no need to listen for modifications to these.
80bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    ASSERT(root()->document() || root()->nodeType() == Node::DOCUMENT_TYPE_NODE);
81bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (Document* ownerDocument = root()->document())
82bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        ownerDocument->attachNodeIterator(this);
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNodeIterator::~NodeIterator()
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
87bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (Document* ownerDocument = root()->document())
88bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        ownerDocument->detachNodeIterator(this);
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
91635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassRefPtr<Node> NodeIterator::nextNode(ScriptState* state, ExceptionCode& ec)
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_detached) {
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Node> result;
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_candidateNode = m_referenceNode;
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (m_candidateNode.moveToNext(root())) {
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // NodeIterators treat the DOM tree as a flat list of nodes.
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // In other words, FILTER_REJECT does not pass over descendants
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // of the rejected node. Hence, FILTER_REJECT is the same as FILTER_SKIP.
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RefPtr<Node> provisionalResult = m_candidateNode.node;
106635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        bool nodeWasAccepted = acceptNode(state, provisionalResult.get()) == NodeFilter::FILTER_ACCEPT;
107635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (state && state->hadException())
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (nodeWasAccepted) {
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_referenceNode = m_candidateNode;
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            result = provisionalResult.release();
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_candidateNode.clear();
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result.release();
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
120635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassRefPtr<Node> NodeIterator::previousNode(ScriptState* state, ExceptionCode& ec)
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_detached) {
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Node> result;
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_candidateNode = m_referenceNode;
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (m_candidateNode.moveToPrevious(root())) {
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // NodeIterators treat the DOM tree as a flat list of nodes.
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // In other words, FILTER_REJECT does not pass over descendants
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // of the rejected node. Hence, FILTER_REJECT is the same as FILTER_SKIP.
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RefPtr<Node> provisionalResult = m_candidateNode.node;
135635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        bool nodeWasAccepted = acceptNode(state, provisionalResult.get()) == NodeFilter::FILTER_ACCEPT;
136635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (state && state->hadException())
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (nodeWasAccepted) {
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_referenceNode = m_candidateNode;
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            result = provisionalResult.release();
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_candidateNode.clear();
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result.release();
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid NodeIterator::detach()
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
151bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (Document* ownerDocument = root()->document())
152bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        ownerDocument->detachNodeIterator(this);
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_detached = true;
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_referenceNode.node.clear();
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid NodeIterator::nodeWillBeRemoved(Node* removedNode)
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    updateForNodeRemoval(removedNode, m_candidateNode);
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    updateForNodeRemoval(removedNode, m_referenceNode);
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid NodeIterator::updateForNodeRemoval(Node* removedNode, NodePointer& referenceNode) const
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!m_detached);
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(removedNode);
167bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    ASSERT(root()->document());
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(root()->document() == removedNode->document());
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Iterator is not affected if the removed node is the reference node and is the root.
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // or if removed node is not the reference node, or the ancestor of the reference node.
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!removedNode->isDescendantOf(root()))
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool willRemoveReferenceNode = removedNode == referenceNode.node;
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool willRemoveReferenceNodeAncestor = referenceNode.node && referenceNode.node->isDescendantOf(removedNode);
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!willRemoveReferenceNode && !willRemoveReferenceNodeAncestor)
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (referenceNode.isPointerBeforeNode) {
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Node* node = removedNode->traverseNextNode(root());
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (node) {
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Move out from under the node being removed if the reference node is
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // a descendant of the node being removed.
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (willRemoveReferenceNodeAncestor) {
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                while (node && node->isDescendantOf(removedNode))
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    node = node->traverseNextNode(root());
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (node)
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                referenceNode.node = node;
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            node = removedNode->traversePreviousNode(root());
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (node) {
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Move out from under the node being removed if the reference node is
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // a descendant of the node being removed.
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (willRemoveReferenceNodeAncestor) {
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    while (node && node->isDescendantOf(removedNode))
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        node = node->traversePreviousNode(root());
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (node) {
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // Removing last node.
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // Need to move the pointer after the node preceding the
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // new reference node.
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    referenceNode.node = node;
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    referenceNode.isPointerBeforeNode = false;
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Node* node = removedNode->traversePreviousNode(root());
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (node) {
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Move out from under the node being removed if the reference node is
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // a descendant of the node being removed.
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (willRemoveReferenceNodeAncestor) {
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                while (node && node->isDescendantOf(removedNode))
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    node = node->traversePreviousNode(root());
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (node)
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                referenceNode.node = node;
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            node = removedNode->traverseNextNode(root());
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Move out from under the node being removed if the reference node is
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // a descendant of the node being removed.
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (willRemoveReferenceNodeAncestor) {
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                while (node && node->isDescendantOf(removedNode))
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    node = node->traversePreviousNode(root());
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (node)
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                referenceNode.node = node;
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
235