31
29
#include "ExceptionCode.h"
32
30
#include "NodeFilter.h"
34
34
namespace WebCore {
36
NodeIterator::NodeIterator(Node* rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter, bool expandEntityReferences)
36
NodeIterator::NodePointer::NodePointer()
40
NodeIterator::NodePointer::NodePointer(PassRefPtr<Node> n, bool b)
42
, isPointerBeforeNode(b)
46
void NodeIterator::NodePointer::clear()
51
bool NodeIterator::NodePointer::moveToNext(Node* root)
55
if (isPointerBeforeNode) {
56
isPointerBeforeNode = false;
59
node = node->traverseNextNode(root);
63
bool NodeIterator::NodePointer::moveToPrevious(Node* root)
67
if (!isPointerBeforeNode) {
68
isPointerBeforeNode = true;
71
node = node->traversePreviousNode(root);
75
NodeIterator::NodeIterator(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter, bool expandEntityReferences)
37
76
: Traversal(rootNode, whatToShow, filter, expandEntityReferences)
38
, m_beforeReferenceNode(true)
77
, m_referenceNode(root(), true)
39
78
, m_detached(false)
40
, m_doc(rootNode ? rootNode->document() : 0)
43
document()->attachNodeIterator(this);
80
root()->document()->attachNodeIterator(this);
46
83
NodeIterator::~NodeIterator()
49
document()->detachNodeIterator(this);
52
Node* NodeIterator::findNextNode(Node* node) const
54
while ((node = node->traverseNextNode(root()))) {
55
// NodeIterators treat the DOM tree as a flat list of nodes.
56
// In other words, FILTER_REJECT does not pass over descendants
57
// of the rejected node. Hence, FILTER_REJECT is the same as FILTER_SKIP.
58
if (acceptNode(node) == NodeFilter::FILTER_ACCEPT)
64
Node* NodeIterator::nextNode(ExceptionCode& ec)
67
ec = INVALID_STATE_ERR;
71
Node* node = referenceNode() ? referenceNode() : root();
72
if (!pointerBeforeReferenceNode() || acceptNode(node) != NodeFilter::FILTER_ACCEPT)
73
node = findNextNode(node);
75
setReferenceNode(node);
76
setPointerBeforeReferenceNode(false);
80
Node* NodeIterator::findPreviousNode(Node* node) const
82
while ((node = node->traversePreviousNode(root()))) {
83
// NodeIterators treat the DOM tree as a flat list of nodes.
84
// In other words, FILTER_REJECT does not pass over descendants
85
// of the rejected node. Hence, FILTER_REJECT is the same as FILTER_SKIP.
86
if (acceptNode(node) == NodeFilter::FILTER_ACCEPT)
92
Node* NodeIterator::previousNode(ExceptionCode&)
94
Node* node = referenceNode() ? referenceNode() : root();
95
if (pointerBeforeReferenceNode() || acceptNode(node) != NodeFilter::FILTER_ACCEPT)
96
node = findPreviousNode(node);
98
setReferenceNode(node);
99
setPointerBeforeReferenceNode();
85
root()->document()->detachNodeIterator(this);
88
PassRefPtr<Node> NodeIterator::nextNode(ExceptionCode& ec, JSValue*& exception)
91
ec = INVALID_STATE_ERR;
97
m_candidateNode = m_referenceNode;
98
while (m_candidateNode.moveToNext(root())) {
99
// NodeIterators treat the DOM tree as a flat list of nodes.
100
// In other words, FILTER_REJECT does not pass over descendants
101
// of the rejected node. Hence, FILTER_REJECT is the same as FILTER_SKIP.
103
RefPtr<Node> provisionalResult = m_candidateNode.node;
104
bool nodeWasAccepted = acceptNode(provisionalResult.get(), exception) == NodeFilter::FILTER_ACCEPT;
107
if (nodeWasAccepted) {
108
m_referenceNode = m_candidateNode;
109
result = provisionalResult.release();
114
m_candidateNode.clear();
115
return result.release();
118
PassRefPtr<Node> NodeIterator::previousNode(ExceptionCode& ec, JSValue*& exception)
121
ec = INVALID_STATE_ERR;
127
m_candidateNode = m_referenceNode;
128
while (m_candidateNode.moveToPrevious(root())) {
129
// NodeIterators treat the DOM tree as a flat list of nodes.
130
// In other words, FILTER_REJECT does not pass over descendants
131
// of the rejected node. Hence, FILTER_REJECT is the same as FILTER_SKIP.
133
RefPtr<Node> provisionalResult = m_candidateNode.node;
134
bool nodeWasAccepted = acceptNode(provisionalResult.get(), exception) == NodeFilter::FILTER_ACCEPT;
137
if (nodeWasAccepted) {
138
m_referenceNode = m_candidateNode;
139
result = provisionalResult.release();
144
m_candidateNode.clear();
145
return result.release();
103
148
void NodeIterator::detach()
105
if (!detached() && document())
106
document()->detachNodeIterator(this);
110
void NodeIterator::setReferenceNode(Node* node)
112
m_referenceNode = node;
115
void NodeIterator::notifyBeforeNodeRemoval(Node* removedNode)
150
root()->document()->detachNodeIterator(this);
152
m_referenceNode.node.clear();
155
void NodeIterator::nodeWillBeRemoved(Node* removedNode)
157
updateForNodeRemoval(removedNode, m_candidateNode);
158
updateForNodeRemoval(removedNode, m_referenceNode);
161
void NodeIterator::updateForNodeRemoval(Node* removedNode, NodePointer& referenceNode) const
165
ASSERT(root()->document() == removedNode->document());
117
167
// Iterator is not affected if the removed node is the reference node and is the root.
118
168
// or if removed node is not the reference node, or the ancestor of the reference node.
119
if (!removedNode || removedNode == root() || !removedNode->isDescendantOf(root()))
169
if (!removedNode->isDescendantOf(root()))
121
bool willRemoveReferenceNode = removedNode == referenceNode();
122
bool willRemoveReferenceNodeAncestor = referenceNode() && referenceNode()->isDescendantOf(removedNode);
171
bool willRemoveReferenceNode = removedNode == referenceNode.node;
172
bool willRemoveReferenceNodeAncestor = referenceNode.node && referenceNode.node->isDescendantOf(removedNode);
123
173
if (!willRemoveReferenceNode && !willRemoveReferenceNodeAncestor)
126
if (pointerBeforeReferenceNode()) {
127
Node* node = findNextNode(removedNode);
176
if (referenceNode.isPointerBeforeNode) {
177
Node* node = removedNode->traverseNextNode(root());
129
179
// Move out from under the node being removed if the reference node is
130
180
// a descendant of the node being removed.
131
181
if (willRemoveReferenceNodeAncestor) {
132
182
while (node && node->isDescendantOf(removedNode))
133
node = findNextNode(node);
183
node = node->traverseNextNode(root());
136
setReferenceNode(node);
186
referenceNode.node = node;
138
node = findPreviousNode(removedNode);
188
node = removedNode->traversePreviousNode(root());
140
190
// Move out from under the node being removed if the reference node is
141
191
// a descendant of the node being removed.
142
192
if (willRemoveReferenceNodeAncestor) {
143
193
while (node && node->isDescendantOf(removedNode))
144
node = findPreviousNode(node);
194
node = node->traversePreviousNode(root());
147
197
// Removing last node.
148
198
// Need to move the pointer after the node preceding the
149
199
// new reference node.
150
setReferenceNode(node);
151
setPointerBeforeReferenceNode(false);
200
referenceNode.node = node;
201
referenceNode.isPointerBeforeNode = false;
156
Node* node = findPreviousNode(removedNode);
206
Node* node = removedNode->traversePreviousNode(root());
158
208
// Move out from under the node being removed if the reference node is
159
209
// a descendant of the node being removed.
160
210
if (willRemoveReferenceNodeAncestor) {
161
211
while (node && node->isDescendantOf(removedNode))
162
node = findPreviousNode(node);
212
node = node->traversePreviousNode(root());
165
setReferenceNode(node);
215
referenceNode.node = node;
167
node = findNextNode(removedNode);
217
node = removedNode->traverseNextNode(root());
168
218
// Move out from under the node being removed if the reference node is
169
219
// a descendant of the node being removed.
170
220
if (willRemoveReferenceNodeAncestor) {
171
221
while (node && node->isDescendantOf(removedNode))
172
node = findPreviousNode(node);
222
node = node->traversePreviousNode(root());
175
setReferenceNode(node);
225
referenceNode.node = node;