Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1255)

Side by Side Diff: Source/core/dom/ContainerNode.cpp

Issue 54273007: Use more references in ContainerNode code (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Fix crashes Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv ed. 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv ed.
6 * 6 *
7 * This library is free software; you can redistribute it and/or 7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public 8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 ChildNodesLazySnapshot* ChildNodesLazySnapshot::latestSnapshot = 0; 56 ChildNodesLazySnapshot* ChildNodesLazySnapshot::latestSnapshot = 0;
57 57
58 #ifndef NDEBUG 58 #ifndef NDEBUG
59 unsigned NoEventDispatchAssertion::s_count = 0; 59 unsigned NoEventDispatchAssertion::s_count = 0;
60 #endif 60 #endif
61 61
62 static const char appendChildMethodName[] = "appendChild"; 62 static const char appendChildMethodName[] = "appendChild";
63 static const char insertBeforeMethodName[] = "insertBefore"; 63 static const char insertBeforeMethodName[] = "insertBefore";
64 static const char replaceChildMethodName[] = "replaceChild"; 64 static const char replaceChildMethodName[] = "replaceChild";
65 65
66 static void collectChildrenAndRemoveFromOldParent(Node* node, NodeVector& nodes, ExceptionState& es) 66 static void collectChildrenAndRemoveFromOldParent(Node& node, NodeVector& nodes, ExceptionState& es)
67 { 67 {
68 if (node->nodeType() != Node::DOCUMENT_FRAGMENT_NODE) { 68 if (node.nodeType() != Node::DOCUMENT_FRAGMENT_NODE) {
69 nodes.append(node); 69 nodes.append(&node);
70 if (ContainerNode* oldParent = node->parentNode()) 70 if (ContainerNode* oldParent = node.parentNode())
71 oldParent->removeChild(node, es); 71 oldParent->removeChild(&node, es);
72 return; 72 return;
73 } 73 }
74 getChildNodes(node, nodes); 74 getChildNodes(node, nodes);
75 toContainerNode(node)->removeChildren(); 75 toContainerNode(node).removeChildren();
76 } 76 }
77 77
78 void ContainerNode::removeDetachedChildren() 78 void ContainerNode::removeDetachedChildren()
79 { 79 {
80 if (connectedSubframeCount()) { 80 if (connectedSubframeCount()) {
81 for (Node* child = firstChild(); child; child = child->nextSibling()) 81 for (Node* child = firstChild(); child; child = child->nextSibling())
82 child->updateAncestorConnectedSubframeCountForRemoval(); 82 child->updateAncestorConnectedSubframeCountForRemoval();
83 } 83 }
84 // FIXME: We should be able to ASSERT(!confusingAndOftenMisusedAttached()) h ere: https://bugs.webkit.org/show_bug.cgi?id=107801 84 // FIXME: We should be able to ASSERT(!confusingAndOftenMisusedAttached()) h ere: https://bugs.webkit.org/show_bug.cgi?id=107801
85 removeDetachedChildrenInContainer<Node, ContainerNode>(*this); 85 removeDetachedChildrenInContainer<Node, ContainerNode>(*this);
86 } 86 }
87 87
88 void ContainerNode::parserTakeAllChildrenFrom(ContainerNode* oldParent) 88 void ContainerNode::parserTakeAllChildrenFrom(ContainerNode& oldParent)
89 { 89 {
90 while (RefPtr<Node> child = oldParent->firstChild()) { 90 while (RefPtr<Node> child = oldParent.firstChild()) {
91 oldParent->parserRemoveChild(*child); 91 oldParent.parserRemoveChild(*child);
92 treeScope().adoptIfNeeded(*child); 92 treeScope().adoptIfNeeded(*child);
93 parserAppendChild(child.get()); 93 parserAppendChild(child.get());
94 } 94 }
95 } 95 }
96 96
97 ContainerNode::~ContainerNode() 97 ContainerNode::~ContainerNode()
98 { 98 {
99 willBeDeletedFromDocument(); 99 willBeDeletedFromDocument();
100 removeDetachedChildren(); 100 removeDetachedChildren();
101 } 101 }
102 102
103 static inline bool isChildTypeAllowed(ContainerNode* newParent, Node* child) 103 static inline bool isChildTypeAllowed(ContainerNode& newParent, Node& child)
104 { 104 {
105 if (!child->isDocumentFragment()) 105 if (!child.isDocumentFragment())
106 return newParent->childTypeAllowed(child->nodeType()); 106 return newParent.childTypeAllowed(child.nodeType());
107 107
108 for (Node* node = child->firstChild(); node; node = node->nextSibling()) { 108 for (Node* node = child.firstChild(); node; node = node->nextSibling()) {
109 if (!newParent->childTypeAllowed(node->nodeType())) 109 if (!newParent.childTypeAllowed(node->nodeType()))
110 return false; 110 return false;
111 } 111 }
112 return true; 112 return true;
113 } 113 }
114 114
115 static inline bool isInTemplateContent(const Node* node) 115 static inline bool isInTemplateContent(const Node& node)
116 { 116 {
117 Document& document = node->document(); 117 const Document& document = node.document();
118 return document == document.templateDocument(); 118 return document == document.templateDocument();
119 } 119 }
120 120
121 static inline bool containsConsideringHostElements(const Node* newChild, const N ode* newParent) 121 static inline bool containsConsideringHostElements(const Node& newChild, const N ode& newParent)
122 { 122 {
123 return (newParent->isInShadowTree() || isInTemplateContent(newParent)) 123 return (newParent.isInShadowTree() || isInTemplateContent(newParent))
124 ? newChild->containsIncludingHostElements(newParent) 124 ? newChild.containsIncludingHostElements(newParent)
125 : newChild->contains(newParent); 125 : newChild.contains(&newParent);
126 } 126 }
127 127
128 static inline bool checkAcceptChild(ContainerNode* newParent, Node* newChild, No de* oldChild, const char* method, ExceptionState& es) 128 static inline bool checkAcceptChild(ContainerNode& newParent, Node* newChild, No de* oldChild, const char* method, ExceptionState& es)
129 { 129 {
130 // Not mentioned in spec: throw NotFoundError if newChild is null 130 // Not mentioned in spec: throw NotFoundError if newChild is null
131 if (!newChild) { 131 if (!newChild) {
132 es.throwDOMException(NotFoundError, ExceptionMessages::failedToExecute(m ethod, "Node", "The new child element is null.")); 132 es.throwDOMException(NotFoundError, ExceptionMessages::failedToExecute(m ethod, "Node", "The new child element is null."));
133 return false; 133 return false;
134 } 134 }
135 135
136 // Use common case fast path if possible. 136 // Use common case fast path if possible.
137 if ((newChild->isElementNode() || newChild->isTextNode()) && newParent->isEl ementNode()) { 137 if ((newChild->isElementNode() || newChild->isTextNode()) && newParent.isEle mentNode()) {
138 ASSERT(!newParent->isDocumentTypeNode()); 138 ASSERT(!newParent.isDocumentTypeNode());
139 ASSERT(isChildTypeAllowed(newParent, newChild)); 139 ASSERT(isChildTypeAllowed(newParent, *newChild));
140 if (containsConsideringHostElements(newChild, newParent)) { 140 if (containsConsideringHostElements(*newChild, newParent)) {
141 es.throwDOMException(HierarchyRequestError, ExceptionMessages::faile dToExecute(method, "Node", "The new child element contains the parent.")); 141 es.throwDOMException(HierarchyRequestError, ExceptionMessages::faile dToExecute(method, "Node", "The new child element contains the parent."));
142 return false; 142 return false;
143 } 143 }
144 return true; 144 return true;
145 } 145 }
146 146
147 // This should never happen, but also protect release builds from tree corru ption. 147 // This should never happen, but also protect release builds from tree corru ption.
148 ASSERT(!newChild->isPseudoElement()); 148 ASSERT(!newChild->isPseudoElement());
149 if (newChild->isPseudoElement()) { 149 if (newChild->isPseudoElement()) {
150 es.throwDOMException(HierarchyRequestError, ExceptionMessages::failedToE xecute(method, "Node", "The new child element is a pseudo-element.")); 150 es.throwDOMException(HierarchyRequestError, ExceptionMessages::failedToE xecute(method, "Node", "The new child element is a pseudo-element."));
151 return false; 151 return false;
152 } 152 }
153 153
154 if (containsConsideringHostElements(newChild, newParent)) { 154 if (containsConsideringHostElements(*newChild, newParent)) {
155 es.throwDOMException(HierarchyRequestError, ExceptionMessages::failedToE xecute(method, "Node", "The new child element contains the parent.")); 155 es.throwDOMException(HierarchyRequestError, ExceptionMessages::failedToE xecute(method, "Node", "The new child element contains the parent."));
156 return false; 156 return false;
157 } 157 }
158 158
159 if (oldChild && newParent->isDocumentNode()) { 159 if (oldChild && newParent.isDocumentNode()) {
160 if (!toDocument(newParent)->canReplaceChild(newChild, oldChild)) { 160 if (!toDocument(newParent).canReplaceChild(*newChild, *oldChild)) {
161 // FIXME: Adjust 'Document::canReplaceChild' to return some addition al detail (or an error message). 161 // FIXME: Adjust 'Document::canReplaceChild' to return some addition al detail (or an error message).
162 es.throwDOMException(HierarchyRequestError, ExceptionMessages::faile dToExecute(method, "ContainerNode")); 162 es.throwDOMException(HierarchyRequestError, ExceptionMessages::faile dToExecute(method, "ContainerNode"));
163 return false; 163 return false;
164 } 164 }
165 } else if (!isChildTypeAllowed(newParent, newChild)) { 165 } else if (!isChildTypeAllowed(newParent, *newChild)) {
166 es.throwDOMException(HierarchyRequestError, ExceptionMessages::failedToE xecute(method, "Node", "Nodes of type '" + newChild->nodeName() + "' may not be inserted inside nodes of type '" + newParent->nodeName() + "'.")); 166 es.throwDOMException(HierarchyRequestError, ExceptionMessages::failedToE xecute(method, "Node", "Nodes of type '" + newChild->nodeName() + "' may not be inserted inside nodes of type '" + newParent.nodeName() + "'."));
167 return false; 167 return false;
168 } 168 }
169 169
170 return true; 170 return true;
171 } 171 }
172 172
173 static inline bool checkAcceptChildGuaranteedNodeTypes(ContainerNode* newParent, Node* newChild, const char* method, ExceptionState& es) 173 static inline bool checkAcceptChildGuaranteedNodeTypes(ContainerNode& newParent, Node& newChild, const char* method, ExceptionState& es)
174 { 174 {
175 ASSERT(!newParent->isDocumentTypeNode()); 175 ASSERT(!newParent.isDocumentTypeNode());
176 ASSERT(isChildTypeAllowed(newParent, newChild)); 176 ASSERT(isChildTypeAllowed(newParent, newChild));
177 if (newChild->contains(newParent)) { 177 if (newChild.contains(&newParent)) {
178 es.throwDOMException(HierarchyRequestError, ExceptionMessages::failedToE xecute(method, "Node", "The new child element contains the parent.")); 178 es.throwDOMException(HierarchyRequestError, ExceptionMessages::failedToE xecute(method, "Node", "The new child element contains the parent."));
179 return false; 179 return false;
180 } 180 }
181 181
182 return true; 182 return true;
183 } 183 }
184 184
185 static inline bool checkAddChild(ContainerNode* newParent, Node* newChild, const char* method, ExceptionState& es) 185 static inline bool checkAddChild(ContainerNode& newParent, Node* newChild, const char* method, ExceptionState& es)
186 { 186 {
187 return checkAcceptChild(newParent, newChild, 0, method, es); 187 return checkAcceptChild(newParent, newChild, 0, method, es);
188 } 188 }
189 189
190 static inline bool checkReplaceChild(ContainerNode* newParent, Node* newChild, N ode* oldChild, const char* method, ExceptionState& es) 190 static inline bool checkReplaceChild(ContainerNode& newParent, Node* newChild, N ode& oldChild, const char* method, ExceptionState& es)
191 { 191 {
192 return checkAcceptChild(newParent, newChild, oldChild, method, es); 192 return checkAcceptChild(newParent, newChild, &oldChild, method, es);
193 } 193 }
194 194
195 void ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce ptionState& es) 195 void ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce ptionState& es)
196 { 196 {
197 // Check that this node is not "floating". 197 // Check that this node is not "floating".
198 // If it is, it can be deleted as a side effect of sending mutation events. 198 // If it is, it can be deleted as a side effect of sending mutation events.
199 ASSERT(refCount() || parentOrShadowHostNode()); 199 ASSERT(refCount() || parentOrShadowHostNode());
200 200
201 RefPtr<Node> protect(this); 201 RefPtr<Node> protect(this);
202 202
203 // insertBefore(node, 0) is equivalent to appendChild(node) 203 // insertBefore(node, 0) is equivalent to appendChild(node)
204 if (!refChild) { 204 if (!refChild) {
205 appendChild(newChild, es); 205 appendChild(newChild, es);
206 return; 206 return;
207 } 207 }
208 208
209 // Make sure adding the new child is OK. 209 // Make sure adding the new child is OK.
210 if (!checkAddChild(this, newChild.get(), insertBeforeMethodName, es)) 210 if (!checkAddChild(*this, newChild.get(), insertBeforeMethodName, es))
211 return; 211 return;
212 ASSERT(newChild);
212 213
213 // NotFoundError: Raised if refChild is not a child of this node 214 // NotFoundError: Raised if refChild is not a child of this node
214 if (refChild->parentNode() != this) { 215 if (refChild->parentNode() != this) {
215 es.throwDOMException(NotFoundError, ExceptionMessages::failedToExecute(i nsertBeforeMethodName, "Node", "The node before which the new node is to be inse rted is not a child of this node.")); 216 es.throwDOMException(NotFoundError, ExceptionMessages::failedToExecute(i nsertBeforeMethodName, "Node", "The node before which the new node is to be inse rted is not a child of this node."));
216 return; 217 return;
217 } 218 }
218 219
219 if (refChild->previousSibling() == newChild || refChild == newChild) // noth ing to do 220 if (refChild->previousSibling() == newChild || refChild == newChild) // noth ing to do
220 return; 221 return;
221 222
222 RefPtr<Node> next = refChild; 223 RefPtr<Node> next = refChild;
223 224
224 NodeVector targets; 225 NodeVector targets;
225 collectChildrenAndRemoveFromOldParent(newChild.get(), targets, es); 226 collectChildrenAndRemoveFromOldParent(*newChild, targets, es);
226 if (es.hadException()) 227 if (es.hadException())
227 return; 228 return;
228 if (targets.isEmpty()) 229 if (targets.isEmpty())
229 return; 230 return;
230 231
231 // We need this extra check because collectChildrenAndRemoveFromOldParent() can fire mutation events. 232 // We need this extra check because collectChildrenAndRemoveFromOldParent() can fire mutation events.
232 if (!checkAcceptChildGuaranteedNodeTypes(this, newChild.get(), insertBeforeM ethodName, es)) 233 if (!checkAcceptChildGuaranteedNodeTypes(*this, *newChild, insertBeforeMetho dName, es))
233 return; 234 return;
234 235
235 InspectorInstrumentation::willInsertDOMNode(this); 236 InspectorInstrumentation::willInsertDOMNode(this);
236 237
237 ChildListMutationScope mutation(*this); 238 ChildListMutationScope mutation(*this);
238 for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); + +it) { 239 for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); + +it) {
239 ASSERT(*it); 240 ASSERT(*it);
240 Node& child = **it; 241 Node& child = **it;
241 242
242 // Due to arbitrary code running in response to a DOM mutation event it' s 243 // Due to arbitrary code running in response to a DOM mutation event it' s
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 prev->setNextSibling(&newChild); 277 prev->setNextSibling(&newChild);
277 } else { 278 } else {
278 ASSERT(m_firstChild == nextChild); 279 ASSERT(m_firstChild == nextChild);
279 m_firstChild = &newChild; 280 m_firstChild = &newChild;
280 } 281 }
281 newChild.setParentOrShadowHostNode(this); 282 newChild.setParentOrShadowHostNode(this);
282 newChild.setPreviousSibling(prev); 283 newChild.setPreviousSibling(prev);
283 newChild.setNextSibling(&nextChild); 284 newChild.setNextSibling(&nextChild);
284 } 285 }
285 286
286 void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node* nextChil d) 287 void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node& nextChil d)
287 { 288 {
288 ASSERT(newChild); 289 ASSERT(newChild);
289 ASSERT(nextChild); 290 ASSERT(nextChild.parentNode() == this);
290 ASSERT(nextChild->parentNode() == this);
291 ASSERT(!newChild->isDocumentFragment()); 291 ASSERT(!newChild->isDocumentFragment());
292 ASSERT(!hasTagName(HTMLNames::templateTag)); 292 ASSERT(!hasTagName(HTMLNames::templateTag));
293 293
294 if (nextChild->previousSibling() == newChild || nextChild == newChild) // no thing to do 294 if (nextChild.previousSibling() == newChild || nextChild == newChild) // not hing to do
295 return; 295 return;
296 296
297 if (document() != newChild->document()) 297 if (document() != newChild->document())
298 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION); 298 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION);
299 299
300 insertBeforeCommon(*nextChild, *newChild); 300 insertBeforeCommon(nextChild, *newChild);
301 301
302 newChild->updateAncestorConnectedSubframeCountForInsertion(); 302 newChild->updateAncestorConnectedSubframeCountForInsertion();
303 303
304 ChildListMutationScope(*this).childAdded(*newChild); 304 ChildListMutationScope(*this).childAdded(*newChild);
305 305
306 childrenChanged(true, newChild->previousSibling(), nextChild, 1); 306 childrenChanged(true, newChild->previousSibling(), &nextChild, 1);
307 307
308 ChildNodeInsertionNotifier(*this).notify(*newChild); 308 ChildNodeInsertionNotifier(*this).notify(*newChild);
309 } 309 }
310 310
311 void ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce ptionState& es) 311 void ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce ptionState& es)
312 { 312 {
313 // Check that this node is not "floating". 313 // Check that this node is not "floating".
314 // If it is, it can be deleted as a side effect of sending mutation events. 314 // If it is, it can be deleted as a side effect of sending mutation events.
315 ASSERT(refCount() || parentOrShadowHostNode()); 315 ASSERT(refCount() || parentOrShadowHostNode());
316 316
317 RefPtr<Node> protect(this); 317 RefPtr<Node> protect(this);
318 318
319 if (oldChild == newChild) // nothing to do 319 if (oldChild == newChild) // nothing to do
320 return; 320 return;
321 321
322 if (!oldChild) { 322 if (!oldChild) {
323 es.throwDOMException(NotFoundError, ExceptionMessages::failedToExecute(r eplaceChildMethodName, "Node", "The node to be replaced is null.")); 323 es.throwDOMException(NotFoundError, ExceptionMessages::failedToExecute(r eplaceChildMethodName, "Node", "The node to be replaced is null."));
324 return; 324 return;
325 } 325 }
326 326
327 // Make sure replacing the old child with the new is ok 327 // Make sure replacing the old child with the new is ok
328 if (!checkReplaceChild(this, newChild.get(), oldChild, replaceChildMethodNam e, es)) 328 if (!checkReplaceChild(*this, newChild.get(), *oldChild, replaceChildMethodN ame, es))
329 return; 329 return;
330 330
331 // NotFoundError: Raised if oldChild is not a child of this node. 331 // NotFoundError: Raised if oldChild is not a child of this node.
332 if (oldChild->parentNode() != this) { 332 if (oldChild->parentNode() != this) {
333 es.throwDOMException(NotFoundError, ExceptionMessages::failedToExecute(r eplaceChildMethodName, "Node", "The node to be replaced is not a child of this n ode.")); 333 es.throwDOMException(NotFoundError, ExceptionMessages::failedToExecute(r eplaceChildMethodName, "Node", "The node to be replaced is not a child of this n ode."));
334 return; 334 return;
335 } 335 }
336 336
337 ChildListMutationScope mutation(*this); 337 ChildListMutationScope mutation(*this);
338 338
339 RefPtr<Node> next = oldChild->nextSibling(); 339 RefPtr<Node> next = oldChild->nextSibling();
340 340
341 // Remove the node we're replacing 341 // Remove the node we're replacing
342 RefPtr<Node> removedChild = oldChild; 342 RefPtr<Node> removedChild = oldChild;
343 removeChild(oldChild, es); 343 removeChild(oldChild, es);
344 if (es.hadException()) 344 if (es.hadException())
345 return; 345 return;
346 346
347 if (next && (next->previousSibling() == newChild || next == newChild)) // no thing to do 347 if (next && (next->previousSibling() == newChild || next == newChild)) // no thing to do
348 return; 348 return;
349 349
350 // Does this one more time because removeChild() fires a MutationEvent. 350 // Does this one more time because removeChild() fires a MutationEvent.
351 if (!checkReplaceChild(this, newChild.get(), oldChild, replaceChildMethodNam e, es)) 351 if (!checkReplaceChild(*this, newChild.get(), *oldChild, replaceChildMethodN ame, es))
352 return; 352 return;
353 353
354 NodeVector targets; 354 NodeVector targets;
355 collectChildrenAndRemoveFromOldParent(newChild.get(), targets, es); 355 collectChildrenAndRemoveFromOldParent(*newChild, targets, es);
356 if (es.hadException()) 356 if (es.hadException())
357 return; 357 return;
358 358
359 // Does this yet another check because collectChildrenAndRemoveFromOldParent () fires a MutationEvent. 359 // Does this yet another check because collectChildrenAndRemoveFromOldParent () fires a MutationEvent.
360 if (!checkReplaceChild(this, newChild.get(), oldChild, replaceChildMethodNam e, es)) 360 if (!checkReplaceChild(*this, newChild.get(), *oldChild, replaceChildMethodN ame, es))
361 return; 361 return;
362 362
363 InspectorInstrumentation::willInsertDOMNode(this); 363 InspectorInstrumentation::willInsertDOMNode(this);
364 364
365 // Add the new child(ren) 365 // Add the new child(ren)
366 for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); + +it) { 366 for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); + +it) {
367 ASSERT(*it); 367 ASSERT(*it);
368 Node& child = **it; 368 Node& child = **it;
369 369
370 // Due to arbitrary code running in response to a DOM mutation event it' s 370 // Due to arbitrary code running in response to a DOM mutation event it' s
(...skipping 28 matching lines...) Expand all
399 ChildListMutationScope(*child.parentNode()).willRemoveChild(child); 399 ChildListMutationScope(*child.parentNode()).willRemoveChild(child);
400 child.notifyMutationObserversNodeWillDetach(); 400 child.notifyMutationObserversNodeWillDetach();
401 dispatchChildRemovalEvents(child); 401 dispatchChildRemovalEvents(child);
402 child.document().nodeWillBeRemoved(child); // e.g. mutation event listener c an create a new range. 402 child.document().nodeWillBeRemoved(child); // e.g. mutation event listener c an create a new range.
403 ChildFrameDisconnector(child).disconnect(); 403 ChildFrameDisconnector(child).disconnect();
404 } 404 }
405 405
406 static void willRemoveChildren(ContainerNode& container) 406 static void willRemoveChildren(ContainerNode& container)
407 { 407 {
408 NodeVector children; 408 NodeVector children;
409 getChildNodes(&container, children); 409 getChildNodes(container, children);
410 410
411 ChildListMutationScope mutation(container); 411 ChildListMutationScope mutation(container);
412 for (NodeVector::const_iterator it = children.begin(); it != children.end(); it++) { 412 for (NodeVector::const_iterator it = children.begin(); it != children.end(); it++) {
413 ASSERT(*it); 413 ASSERT(*it);
414 Node& child = **it; 414 Node& child = **it;
415 mutation.willRemoveChild(child); 415 mutation.willRemoveChild(child);
416 child.notifyMutationObserversNodeWillDetach(); 416 child.notifyMutationObserversNodeWillDetach();
417 417
418 // fire removed from document mutation events. 418 // fire removed from document mutation events.
419 dispatchChildRemovalEvents(child); 419 dispatchChildRemovalEvents(child);
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 576
577 void ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionState& es) 577 void ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionState& es)
578 { 578 {
579 RefPtr<ContainerNode> protect(this); 579 RefPtr<ContainerNode> protect(this);
580 580
581 // Check that this node is not "floating". 581 // Check that this node is not "floating".
582 // If it is, it can be deleted as a side effect of sending mutation events. 582 // If it is, it can be deleted as a side effect of sending mutation events.
583 ASSERT(refCount() || parentOrShadowHostNode()); 583 ASSERT(refCount() || parentOrShadowHostNode());
584 584
585 // Make sure adding the new child is ok 585 // Make sure adding the new child is ok
586 if (!checkAddChild(this, newChild.get(), appendChildMethodName, es)) 586 if (!checkAddChild(*this, newChild.get(), appendChildMethodName, es))
587 return; 587 return;
588 ASSERT(newChild);
588 589
589 if (newChild == m_lastChild) // nothing to do 590 if (newChild == m_lastChild) // nothing to do
590 return; 591 return;
591 592
592 NodeVector targets; 593 NodeVector targets;
593 collectChildrenAndRemoveFromOldParent(newChild.get(), targets, es); 594 collectChildrenAndRemoveFromOldParent(*newChild, targets, es);
594 if (es.hadException()) 595 if (es.hadException())
595 return; 596 return;
596 597
597 if (targets.isEmpty()) 598 if (targets.isEmpty())
598 return; 599 return;
599 600
600 // We need this extra check because collectChildrenAndRemoveFromOldParent() can fire mutation events. 601 // We need this extra check because collectChildrenAndRemoveFromOldParent() can fire mutation events.
601 if (!checkAcceptChildGuaranteedNodeTypes(this, newChild.get(), appendChildMe thodName, es)) 602 if (!checkAcceptChildGuaranteedNodeTypes(*this, *newChild, appendChildMethod Name, es))
602 return; 603 return;
603 604
604 InspectorInstrumentation::willInsertDOMNode(this); 605 InspectorInstrumentation::willInsertDOMNode(this);
605 606
606 // Now actually add the child(ren) 607 // Now actually add the child(ren)
607 ChildListMutationScope mutation(*this); 608 ChildListMutationScope mutation(*this);
608 for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); + +it) { 609 for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); + +it) {
609 ASSERT(*it); 610 ASSERT(*it);
610 Node& child = **it; 611 Node& child = **it;
611 612
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 return true; 992 return true;
992 993
993 if (node->isElementNode() && toElement(node)->shadow()) 994 if (node->isElementNode() && toElement(node)->shadow())
994 return true; 995 return true;
995 996
996 return false; 997 return false;
997 } 998 }
998 #endif 999 #endif
999 1000
1000 } // namespace WebCore 1001 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698