Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * Copyright (C) 2000 Frederik Holljen (frederik.holljen@hig.no) | 3 * Copyright (C) 2000 Frederik Holljen (frederik.holljen@hig.no) |
| 4 * Copyright (C) 2001 Peter Kelly (pmk@post.com) | 4 * Copyright (C) 2001 Peter Kelly (pmk@post.com) |
| 5 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) | 5 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) |
| 6 * Copyright (C) 2004, 2008 Apple Inc. All rights reserved. | 6 * Copyright (C) 2004, 2008 Apple Inc. All rights reserved. |
| 7 * | 7 * |
| 8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
| 9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
| 10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 22 * | 22 * |
| 23 */ | 23 */ |
| 24 | 24 |
| 25 #include "config.h" | 25 #include "config.h" |
| 26 #include "core/dom/NodeIterator.h" | 26 #include "core/dom/NodeIterator.h" |
| 27 | 27 |
| 28 #include "bindings/v8/ExceptionState.h" | 28 #include "bindings/v8/ExceptionState.h" |
| 29 #include "core/dom/Document.h" | 29 #include "core/dom/Document.h" |
| 30 #include "core/dom/ExceptionCode.h" | 30 #include "core/dom/ExceptionCode.h" |
| 31 #include "core/dom/NodeTraversal.h" | 31 #include "core/dom/NodeTraversal.h" |
| 32 #include "core/frame/UseCounter.h" | |
| 32 | 33 |
| 33 namespace WebCore { | 34 namespace WebCore { |
| 34 | 35 |
| 35 NodeIterator::NodePointer::NodePointer() | 36 NodeIterator::NodePointer::NodePointer() |
| 36 { | 37 { |
| 37 } | 38 } |
| 38 | 39 |
| 39 NodeIterator::NodePointer::NodePointer(PassRefPtr<Node> n, bool b) | 40 NodeIterator::NodePointer::NodePointer(PassRefPtr<Node> n, bool b) |
| 40 : node(n) | 41 : node(n) |
| 41 , isPointerBeforeNode(b) | 42 , isPointerBeforeNode(b) |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 67 isPointerBeforeNode = true; | 68 isPointerBeforeNode = true; |
| 68 return true; | 69 return true; |
| 69 } | 70 } |
| 70 node = NodeTraversal::previous(*node, root); | 71 node = NodeTraversal::previous(*node, root); |
| 71 return node; | 72 return node; |
| 72 } | 73 } |
| 73 | 74 |
| 74 NodeIterator::NodeIterator(PassRefPtr<Node> rootNode, unsigned whatToShow, PassR efPtr<NodeFilter> filter) | 75 NodeIterator::NodeIterator(PassRefPtr<Node> rootNode, unsigned whatToShow, PassR efPtr<NodeFilter> filter) |
| 75 : NodeIteratorBase(rootNode, whatToShow, filter) | 76 : NodeIteratorBase(rootNode, whatToShow, filter) |
| 76 , m_referenceNode(root(), true) | 77 , m_referenceNode(root(), true) |
| 77 , m_detached(false) | |
| 78 { | 78 { |
| 79 ScriptWrappable::init(this); | 79 ScriptWrappable::init(this); |
| 80 root()->document().attachNodeIterator(this); | 80 root()->document().attachNodeIterator(this); |
| 81 } | 81 } |
| 82 | 82 |
| 83 NodeIterator::~NodeIterator() | 83 NodeIterator::~NodeIterator() |
| 84 { | 84 { |
| 85 root()->document().detachNodeIterator(this); | 85 root()->document().detachNodeIterator(this); |
| 86 } | 86 } |
| 87 | 87 |
| 88 PassRefPtr<Node> NodeIterator::nextNode(ExceptionState& exceptionState) | 88 PassRefPtr<Node> NodeIterator::nextNode(ExceptionState& exceptionState) |
| 89 { | 89 { |
| 90 if (m_detached) { | |
| 91 exceptionState.throwDOMException(InvalidStateError, "The iterator is det ached."); | |
| 92 return nullptr; | |
| 93 } | |
| 94 | |
| 95 RefPtr<Node> result; | 90 RefPtr<Node> result; |
| 96 | 91 |
| 97 m_candidateNode = m_referenceNode; | 92 m_candidateNode = m_referenceNode; |
| 98 while (m_candidateNode.moveToNext(root())) { | 93 while (m_candidateNode.moveToNext(root())) { |
| 99 // NodeIterators treat the DOM tree as a flat list of nodes. | 94 // NodeIterators treat the DOM tree as a flat list of nodes. |
| 100 // In other words, FILTER_REJECT does not pass over descendants | 95 // In other words, FILTER_REJECT does not pass over descendants |
| 101 // of the rejected node. Hence, FILTER_REJECT is the same as FILTER_SKIP . | 96 // of the rejected node. Hence, FILTER_REJECT is the same as FILTER_SKIP . |
| 102 RefPtr<Node> provisionalResult = m_candidateNode.node; | 97 RefPtr<Node> provisionalResult = m_candidateNode.node; |
| 103 bool nodeWasAccepted = acceptNode(provisionalResult.get(), exceptionStat e) == NodeFilter::FILTER_ACCEPT; | 98 bool nodeWasAccepted = acceptNode(provisionalResult.get(), exceptionStat e) == NodeFilter::FILTER_ACCEPT; |
| 104 if (exceptionState.hadException()) | 99 if (exceptionState.hadException()) |
| 105 break; | 100 break; |
| 106 if (nodeWasAccepted) { | 101 if (nodeWasAccepted) { |
| 107 m_referenceNode = m_candidateNode; | 102 m_referenceNode = m_candidateNode; |
| 108 result = provisionalResult.release(); | 103 result = provisionalResult.release(); |
| 109 break; | 104 break; |
| 110 } | 105 } |
| 111 } | 106 } |
| 112 | 107 |
| 113 m_candidateNode.clear(); | 108 m_candidateNode.clear(); |
| 114 return result.release(); | 109 return result.release(); |
| 115 } | 110 } |
| 116 | 111 |
| 117 PassRefPtr<Node> NodeIterator::previousNode(ExceptionState& exceptionState) | 112 PassRefPtr<Node> NodeIterator::previousNode(ExceptionState& exceptionState) |
| 118 { | 113 { |
| 119 if (m_detached) { | |
| 120 exceptionState.throwDOMException(InvalidStateError, "The iterator is det ached."); | |
| 121 return nullptr; | |
| 122 } | |
| 123 | |
| 124 RefPtr<Node> result; | 114 RefPtr<Node> result; |
| 125 | 115 |
| 126 m_candidateNode = m_referenceNode; | 116 m_candidateNode = m_referenceNode; |
| 127 while (m_candidateNode.moveToPrevious(root())) { | 117 while (m_candidateNode.moveToPrevious(root())) { |
| 128 // NodeIterators treat the DOM tree as a flat list of nodes. | 118 // NodeIterators treat the DOM tree as a flat list of nodes. |
| 129 // In other words, FILTER_REJECT does not pass over descendants | 119 // In other words, FILTER_REJECT does not pass over descendants |
| 130 // of the rejected node. Hence, FILTER_REJECT is the same as FILTER_SKIP . | 120 // of the rejected node. Hence, FILTER_REJECT is the same as FILTER_SKIP . |
| 131 RefPtr<Node> provisionalResult = m_candidateNode.node; | 121 RefPtr<Node> provisionalResult = m_candidateNode.node; |
| 132 bool nodeWasAccepted = acceptNode(provisionalResult.get(), exceptionStat e) == NodeFilter::FILTER_ACCEPT; | 122 bool nodeWasAccepted = acceptNode(provisionalResult.get(), exceptionStat e) == NodeFilter::FILTER_ACCEPT; |
| 133 if (exceptionState.hadException()) | 123 if (exceptionState.hadException()) |
| 134 break; | 124 break; |
| 135 if (nodeWasAccepted) { | 125 if (nodeWasAccepted) { |
| 136 m_referenceNode = m_candidateNode; | 126 m_referenceNode = m_candidateNode; |
| 137 result = provisionalResult.release(); | 127 result = provisionalResult.release(); |
| 138 break; | 128 break; |
| 139 } | 129 } |
| 140 } | 130 } |
| 141 | 131 |
| 142 m_candidateNode.clear(); | 132 m_candidateNode.clear(); |
| 143 return result.release(); | 133 return result.release(); |
| 144 } | 134 } |
| 145 | 135 |
| 146 void NodeIterator::detach() | 136 void NodeIterator::detach() |
| 147 { | 137 { |
| 148 root()->document().detachNodeIterator(this); | 138 // This is now a no-op as per the DOM specification. |
|
arv (Not doing code reviews)
2014/04/28 14:22:24
Why not use the IDL extended attribute?
Inactive
2014/04/28 14:26:20
Done.
| |
| 149 m_detached = true; | 139 UseCounter::countDeprecation(root()->document(), UseCounter::NodeIteratorDet ach); |
| 150 m_referenceNode.node.clear(); | |
| 151 } | 140 } |
| 152 | 141 |
| 153 void NodeIterator::nodeWillBeRemoved(Node& removedNode) | 142 void NodeIterator::nodeWillBeRemoved(Node& removedNode) |
| 154 { | 143 { |
| 155 updateForNodeRemoval(removedNode, m_candidateNode); | 144 updateForNodeRemoval(removedNode, m_candidateNode); |
| 156 updateForNodeRemoval(removedNode, m_referenceNode); | 145 updateForNodeRemoval(removedNode, m_referenceNode); |
| 157 } | 146 } |
| 158 | 147 |
| 159 void NodeIterator::updateForNodeRemoval(Node& removedNode, NodePointer& referenc eNode) const | 148 void NodeIterator::updateForNodeRemoval(Node& removedNode, NodePointer& referenc eNode) const |
| 160 { | 149 { |
| 161 ASSERT(!m_detached); | |
| 162 ASSERT(root()->document() == removedNode.document()); | 150 ASSERT(root()->document() == removedNode.document()); |
| 163 | 151 |
| 164 // Iterator is not affected if the removed node is the reference node and is the root. | 152 // Iterator is not affected if the removed node is the reference node and is the root. |
| 165 // or if removed node is not the reference node, or the ancestor of the refe rence node. | 153 // or if removed node is not the reference node, or the ancestor of the refe rence node. |
| 166 if (!removedNode.isDescendantOf(root())) | 154 if (!removedNode.isDescendantOf(root())) |
| 167 return; | 155 return; |
| 168 bool willRemoveReferenceNode = removedNode == referenceNode.node; | 156 bool willRemoveReferenceNode = removedNode == referenceNode.node; |
| 169 bool willRemoveReferenceNodeAncestor = referenceNode.node && referenceNode.n ode->isDescendantOf(&removedNode); | 157 bool willRemoveReferenceNodeAncestor = referenceNode.node && referenceNode.n ode->isDescendantOf(&removedNode); |
| 170 if (!willRemoveReferenceNode && !willRemoveReferenceNodeAncestor) | 158 if (!willRemoveReferenceNode && !willRemoveReferenceNodeAncestor) |
| 171 return; | 159 return; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 218 node = NodeTraversal::previous(*node, root()); | 206 node = NodeTraversal::previous(*node, root()); |
| 219 } | 207 } |
| 220 if (node) | 208 if (node) |
| 221 referenceNode.node = node; | 209 referenceNode.node = node; |
| 222 } | 210 } |
| 223 } | 211 } |
| 224 } | 212 } |
| 225 | 213 |
| 226 | 214 |
| 227 } // namespace WebCore | 215 } // namespace WebCore |
| OLD | NEW |