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

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

Issue 1854423002: ASSERT -> {DCHECK|DCHECK_XX}, ENABLE(ASSERT) -> DCHECK_IS_ON() in dom (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: mark svg/as-image/svg-nested.html crash on win Created 4 years, 8 months 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, 2013 Apple Inc. All rights reserved. 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved.
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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 return; 71 return;
72 } 72 }
73 nodes.append(&node); 73 nodes.append(&node);
74 if (ContainerNode* oldParent = node.parentNode()) 74 if (ContainerNode* oldParent = node.parentNode())
75 oldParent->removeChild(&node, exceptionState); 75 oldParent->removeChild(&node, exceptionState);
76 } 76 }
77 77
78 #if !ENABLE(OILPAN) 78 #if !ENABLE(OILPAN)
79 void ContainerNode::removeDetachedChildren() 79 void ContainerNode::removeDetachedChildren()
80 { 80 {
81 ASSERT(!connectedSubframeCount()); 81 DCHECK(!connectedSubframeCount());
82 ASSERT(needsAttach()); 82 DCHECK(needsAttach());
83 removeDetachedChildrenInContainer(*this); 83 removeDetachedChildrenInContainer(*this);
84 } 84 }
85 #endif 85 #endif
86 86
87 void ContainerNode::parserTakeAllChildrenFrom(ContainerNode& oldParent) 87 void ContainerNode::parserTakeAllChildrenFrom(ContainerNode& oldParent)
88 { 88 {
89 while (RawPtr<Node> child = oldParent.firstChild()) { 89 while (RawPtr<Node> child = oldParent.firstChild()) {
90 // Explicitly remove since appending can fail, but this loop shouldn't b e infinite. 90 // Explicitly remove since appending can fail, but this loop shouldn't b e infinite.
91 oldParent.parserRemoveChild(*child); 91 oldParent.parserRemoveChild(*child);
92 parserAppendChild(child.get()); 92 parserAppendChild(child.get());
93 } 93 }
94 } 94 }
95 95
96 ContainerNode::~ContainerNode() 96 ContainerNode::~ContainerNode()
97 { 97 {
98 ASSERT(needsAttach()); 98 DCHECK(needsAttach());
99 #if !ENABLE(OILPAN) 99 #if !ENABLE(OILPAN)
100 willBeDeletedFromDocument(); 100 willBeDeletedFromDocument();
101 removeDetachedChildren(); 101 removeDetachedChildren();
102 #endif 102 #endif
103 } 103 }
104 104
105 bool ContainerNode::isChildTypeAllowed(const Node& child) const 105 bool ContainerNode::isChildTypeAllowed(const Node& child) const
106 { 106 {
107 if (!child.isDocumentFragment()) 107 if (!child.isDocumentFragment())
108 return childTypeAllowed(child.getNodeType()); 108 return childTypeAllowed(child.getNodeType());
(...skipping 15 matching lines...) Expand all
124 bool ContainerNode::checkAcceptChild(const Node* newChild, const Node* oldChild, ExceptionState& exceptionState) const 124 bool ContainerNode::checkAcceptChild(const Node* newChild, const Node* oldChild, ExceptionState& exceptionState) const
125 { 125 {
126 // Not mentioned in spec: throw NotFoundError if newChild is null 126 // Not mentioned in spec: throw NotFoundError if newChild is null
127 if (!newChild) { 127 if (!newChild) {
128 exceptionState.throwDOMException(NotFoundError, "The new child element i s null."); 128 exceptionState.throwDOMException(NotFoundError, "The new child element i s null.");
129 return false; 129 return false;
130 } 130 }
131 131
132 // Use common case fast path if possible. 132 // Use common case fast path if possible.
133 if ((newChild->isElementNode() || newChild->isTextNode()) && isElementNode() ) { 133 if ((newChild->isElementNode() || newChild->isTextNode()) && isElementNode() ) {
134 ASSERT(isChildTypeAllowed(*newChild)); 134 DCHECK(isChildTypeAllowed(*newChild));
135 if (containsConsideringHostElements(*newChild)) { 135 if (containsConsideringHostElements(*newChild)) {
136 exceptionState.throwDOMException(HierarchyRequestError, "The new chi ld element contains the parent."); 136 exceptionState.throwDOMException(HierarchyRequestError, "The new chi ld element contains the parent.");
137 return false; 137 return false;
138 } 138 }
139 return true; 139 return true;
140 } 140 }
141 141
142 // This should never happen, but also protect release builds from tree corru ption. 142 // This should never happen, but also protect release builds from tree corru ption.
143 ASSERT(!newChild->isPseudoElement()); 143 DCHECK(!newChild->isPseudoElement());
144 if (newChild->isPseudoElement()) { 144 if (newChild->isPseudoElement()) {
145 exceptionState.throwDOMException(HierarchyRequestError, "The new child e lement is a pseudo-element."); 145 exceptionState.throwDOMException(HierarchyRequestError, "The new child e lement is a pseudo-element.");
146 return false; 146 return false;
147 } 147 }
148 148
149 return checkAcceptChildGuaranteedNodeTypes(*newChild, oldChild, exceptionSta te); 149 return checkAcceptChildGuaranteedNodeTypes(*newChild, oldChild, exceptionSta te);
150 } 150 }
151 151
152 bool ContainerNode::checkAcceptChildGuaranteedNodeTypes(const Node& newChild, co nst Node* oldChild, ExceptionState& exceptionState) const 152 bool ContainerNode::checkAcceptChildGuaranteedNodeTypes(const Node& newChild, co nst Node* oldChild, ExceptionState& exceptionState) const
153 { 153 {
154 if (isDocumentNode()) 154 if (isDocumentNode())
155 return toDocument(this)->canAcceptChild(newChild, oldChild, exceptionSta te); 155 return toDocument(this)->canAcceptChild(newChild, oldChild, exceptionSta te);
156 if (newChild.containsIncludingHostElements(*this)) { 156 if (newChild.containsIncludingHostElements(*this)) {
157 exceptionState.throwDOMException(HierarchyRequestError, "The new child e lement contains the parent."); 157 exceptionState.throwDOMException(HierarchyRequestError, "The new child e lement contains the parent.");
158 return false; 158 return false;
159 } 159 }
160 if (!isChildTypeAllowed(newChild)) { 160 if (!isChildTypeAllowed(newChild)) {
161 exceptionState.throwDOMException(HierarchyRequestError, "Nodes of type ' " + newChild.nodeName() + "' may not be inserted inside nodes of type '" + nodeN ame() + "'."); 161 exceptionState.throwDOMException(HierarchyRequestError, "Nodes of type ' " + newChild.nodeName() + "' may not be inserted inside nodes of type '" + nodeN ame() + "'.");
162 return false; 162 return false;
163 } 163 }
164 return true; 164 return true;
165 } 165 }
166 166
167 RawPtr<Node> ContainerNode::insertBefore(RawPtr<Node> newChild, Node* refChild, ExceptionState& exceptionState) 167 RawPtr<Node> ContainerNode::insertBefore(RawPtr<Node> newChild, Node* refChild, ExceptionState& exceptionState)
168 { 168 {
169 #if !ENABLE(OILPAN) 169 #if !ENABLE(OILPAN)
170 // Check that this node is not "floating". 170 // Check that this node is not "floating".
171 // If it is, it can be deleted as a side effect of sending mutation events. 171 // If it is, it can be deleted as a side effect of sending mutation events.
172 ASSERT(refCount() || parentOrShadowHostNode()); 172 DCHECK(refCount() || parentOrShadowHostNode());
173 #endif 173 #endif
174 174
175 RawPtr<Node> protect(this); 175 RawPtr<Node> protect(this);
176 176
177 // insertBefore(node, 0) is equivalent to appendChild(node) 177 // insertBefore(node, 0) is equivalent to appendChild(node)
178 if (!refChild) { 178 if (!refChild) {
179 return appendChild(newChild, exceptionState); 179 return appendChild(newChild, exceptionState);
180 } 180 }
181 181
182 // Make sure adding the new child is OK. 182 // Make sure adding the new child is OK.
183 if (!checkAcceptChild(newChild.get(), 0, exceptionState)) { 183 if (!checkAcceptChild(newChild.get(), 0, exceptionState)) {
184 if (exceptionState.hadException()) 184 if (exceptionState.hadException())
185 return nullptr; 185 return nullptr;
186 return newChild; 186 return newChild;
187 } 187 }
188 ASSERT(newChild); 188 DCHECK(newChild);
189 189
190 // NotFoundError: Raised if refChild is not a child of this node 190 // NotFoundError: Raised if refChild is not a child of this node
191 if (refChild->parentNode() != this) { 191 if (refChild->parentNode() != this) {
192 exceptionState.throwDOMException(NotFoundError, "The node before which t he new node is to be inserted is not a child of this node."); 192 exceptionState.throwDOMException(NotFoundError, "The node before which t he new node is to be inserted is not a child of this node.");
193 return nullptr; 193 return nullptr;
194 } 194 }
195 195
196 // Nothing to do. 196 // Nothing to do.
197 if (refChild->previousSibling() == newChild || refChild == newChild) 197 if (refChild->previousSibling() == newChild || refChild == newChild)
198 return newChild; 198 return newChild;
(...skipping 11 matching lines...) Expand all
210 if (!checkAcceptChildGuaranteedNodeTypes(*newChild, nullptr, exceptionState) ) { 210 if (!checkAcceptChildGuaranteedNodeTypes(*newChild, nullptr, exceptionState) ) {
211 if (exceptionState.hadException()) 211 if (exceptionState.hadException())
212 return nullptr; 212 return nullptr;
213 return newChild; 213 return newChild;
214 } 214 }
215 215
216 InspectorInstrumentation::willInsertDOMNode(this); 216 InspectorInstrumentation::willInsertDOMNode(this);
217 217
218 ChildListMutationScope mutation(*this); 218 ChildListMutationScope mutation(*this);
219 for (const auto& targetNode : targets) { 219 for (const auto& targetNode : targets) {
220 ASSERT(targetNode); 220 DCHECK(targetNode);
221 Node& child = *targetNode; 221 Node& child = *targetNode;
222 222
223 // Due to arbitrary code running in response to a DOM mutation event it' s 223 // Due to arbitrary code running in response to a DOM mutation event it' s
224 // possible that "next" is no longer a child of "this". 224 // possible that "next" is no longer a child of "this".
225 // It's also possible that "child" has been inserted elsewhere. 225 // It's also possible that "child" has been inserted elsewhere.
226 // In either of those cases, we'll just stop. 226 // In either of those cases, we'll just stop.
227 if (next->parentNode() != this) 227 if (next->parentNode() != this)
228 break; 228 break;
229 if (child.parentNode()) 229 if (child.parentNode())
230 break; 230 break;
(...skipping 12 matching lines...) Expand all
243 dispatchSubtreeModifiedEvent(); 243 dispatchSubtreeModifiedEvent();
244 244
245 return newChild; 245 return newChild;
246 } 246 }
247 247
248 void ContainerNode::insertBeforeCommon(Node& nextChild, Node& newChild) 248 void ContainerNode::insertBeforeCommon(Node& nextChild, Node& newChild)
249 { 249 {
250 EventDispatchForbiddenScope assertNoEventDispatch; 250 EventDispatchForbiddenScope assertNoEventDispatch;
251 ScriptForbiddenScope forbidScript; 251 ScriptForbiddenScope forbidScript;
252 252
253 ASSERT(!newChild.parentNode()); // Use insertBefore if you need to handle re parenting (and want DOM mutation events). 253 DCHECK(!newChild.parentNode()); // Use insertBefore if you need to handle re parenting (and want DOM mutation events).
254 ASSERT(!newChild.nextSibling()); 254 DCHECK(!newChild.nextSibling());
255 ASSERT(!newChild.previousSibling()); 255 DCHECK(!newChild.previousSibling());
256 ASSERT(!newChild.isShadowRoot()); 256 DCHECK(!newChild.isShadowRoot());
257 257
258 Node* prev = nextChild.previousSibling(); 258 Node* prev = nextChild.previousSibling();
259 ASSERT(m_lastChild != prev); 259 DCHECK_NE(m_lastChild, prev);
260 nextChild.setPreviousSibling(&newChild); 260 nextChild.setPreviousSibling(&newChild);
261 if (prev) { 261 if (prev) {
262 ASSERT(firstChild() != nextChild); 262 DCHECK_NE(firstChild(), nextChild);
263 ASSERT(prev->nextSibling() == nextChild); 263 DCHECK_EQ(prev->nextSibling(), nextChild);
264 prev->setNextSibling(&newChild); 264 prev->setNextSibling(&newChild);
265 } else { 265 } else {
266 ASSERT(firstChild() == nextChild); 266 DCHECK(firstChild() == nextChild);
267 m_firstChild = &newChild; 267 m_firstChild = &newChild;
268 } 268 }
269 newChild.setParentOrShadowHostNode(this); 269 newChild.setParentOrShadowHostNode(this);
270 newChild.setPreviousSibling(prev); 270 newChild.setPreviousSibling(prev);
271 newChild.setNextSibling(&nextChild); 271 newChild.setNextSibling(&nextChild);
272 } 272 }
273 273
274 void ContainerNode::appendChildCommon(Node& child) 274 void ContainerNode::appendChildCommon(Node& child)
275 { 275 {
276 child.setParentOrShadowHostNode(this); 276 child.setParentOrShadowHostNode(this);
(...skipping 12 matching lines...) Expand all
289 { 289 {
290 if (!isDocumentNode()) 290 if (!isDocumentNode())
291 return true; 291 return true;
292 // TODO(esprehn): Are there other conditions where the parser can create 292 // TODO(esprehn): Are there other conditions where the parser can create
293 // invalid trees? 293 // invalid trees?
294 return toDocument(*this).canAcceptChild(newChild, nullptr, IGNORE_EXCEPTION) ; 294 return toDocument(*this).canAcceptChild(newChild, nullptr, IGNORE_EXCEPTION) ;
295 } 295 }
296 296
297 void ContainerNode::parserInsertBefore(RawPtr<Node> newChild, Node& nextChild) 297 void ContainerNode::parserInsertBefore(RawPtr<Node> newChild, Node& nextChild)
298 { 298 {
299 ASSERT(newChild); 299 DCHECK(newChild);
300 ASSERT(nextChild.parentNode() == this); 300 DCHECK_EQ(nextChild.parentNode(), this);
301 ASSERT(!newChild->isDocumentFragment()); 301 DCHECK(!newChild->isDocumentFragment());
302 ASSERT(!isHTMLTemplateElement(this)); 302 DCHECK(!isHTMLTemplateElement(this));
303 303
304 if (nextChild.previousSibling() == newChild || &nextChild == newChild) // no thing to do 304 if (nextChild.previousSibling() == newChild || &nextChild == newChild) // no thing to do
305 return; 305 return;
306 306
307 if (!checkParserAcceptChild(*newChild)) 307 if (!checkParserAcceptChild(*newChild))
308 return; 308 return;
309 309
310 RawPtr<Node> protect(this); 310 RawPtr<Node> protect(this);
311 311
312 // FIXME: parserRemoveChild can run script which could then insert the 312 // FIXME: parserRemoveChild can run script which could then insert the
313 // newChild back into the page. Loop until the child is actually removed. 313 // newChild back into the page. Loop until the child is actually removed.
314 // See: fast/parser/execute-script-during-adoption-agency-removal.html 314 // See: fast/parser/execute-script-during-adoption-agency-removal.html
315 while (RawPtr<ContainerNode> parent = newChild->parentNode()) 315 while (RawPtr<ContainerNode> parent = newChild->parentNode())
316 parent->parserRemoveChild(*newChild); 316 parent->parserRemoveChild(*newChild);
317 317
318 if (nextChild.parentNode() != this) 318 if (nextChild.parentNode() != this)
319 return; 319 return;
320 320
321 if (document() != newChild->document()) 321 if (document() != newChild->document())
322 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION); 322 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION);
323 323
324 { 324 {
325 EventDispatchForbiddenScope assertNoEventDispatch; 325 EventDispatchForbiddenScope assertNoEventDispatch;
326 ScriptForbiddenScope forbidScript; 326 ScriptForbiddenScope forbidScript;
327 327
328 treeScope().adoptIfNeeded(*newChild); 328 treeScope().adoptIfNeeded(*newChild);
329 insertBeforeCommon(nextChild, *newChild); 329 insertBeforeCommon(nextChild, *newChild);
330 ASSERT(newChild->connectedSubframeCount() == 0); 330 DCHECK_EQ(newChild->connectedSubframeCount(), 0u);
331 ChildListMutationScope(*this).childAdded(*newChild); 331 ChildListMutationScope(*this).childAdded(*newChild);
332 } 332 }
333 333
334 notifyNodeInserted(*newChild, ChildrenChangeSourceParser); 334 notifyNodeInserted(*newChild, ChildrenChangeSourceParser);
335 } 335 }
336 336
337 RawPtr<Node> ContainerNode::replaceChild(RawPtr<Node> newChild, RawPtr<Node> old Child, ExceptionState& exceptionState) 337 RawPtr<Node> ContainerNode::replaceChild(RawPtr<Node> newChild, RawPtr<Node> old Child, ExceptionState& exceptionState)
338 { 338 {
339 #if !ENABLE(OILPAN) 339 #if !ENABLE(OILPAN)
340 // Check that this node is not "floating". 340 // Check that this node is not "floating".
341 // If it is, it can be deleted as a side effect of sending mutation events. 341 // If it is, it can be deleted as a side effect of sending mutation events.
342 ASSERT(refCount() || parentOrShadowHostNode()); 342 DCHECK(refCount() || parentOrShadowHostNode());
343 #endif 343 #endif
344 344
345 RawPtr<Node> protect(this); 345 RawPtr<Node> protect(this);
346 346
347 if (oldChild == newChild) // Nothing to do. 347 if (oldChild == newChild) // Nothing to do.
348 return oldChild; 348 return oldChild;
349 349
350 if (!oldChild) { 350 if (!oldChild) {
351 exceptionState.throwDOMException(NotFoundError, "The node to be replaced is null."); 351 exceptionState.throwDOMException(NotFoundError, "The node to be replaced is null.");
352 return nullptr; 352 return nullptr;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 if (!checkAcceptChild(newChild.get(), child.get(), exceptionState)) { 395 if (!checkAcceptChild(newChild.get(), child.get(), exceptionState)) {
396 if (exceptionState.hadException()) 396 if (exceptionState.hadException())
397 return nullptr; 397 return nullptr;
398 return child; 398 return child;
399 } 399 }
400 400
401 InspectorInstrumentation::willInsertDOMNode(this); 401 InspectorInstrumentation::willInsertDOMNode(this);
402 402
403 // Add the new child(ren). 403 // Add the new child(ren).
404 for (const auto& targetNode : targets) { 404 for (const auto& targetNode : targets) {
405 ASSERT(targetNode); 405 DCHECK(targetNode);
406 Node& child = *targetNode; 406 Node& child = *targetNode;
407 407
408 // Due to arbitrary code running in response to a DOM mutation event it' s 408 // Due to arbitrary code running in response to a DOM mutation event it' s
409 // possible that "next" is no longer a child of "this". 409 // possible that "next" is no longer a child of "this".
410 // It's also possible that "child" has been inserted elsewhere. 410 // It's also possible that "child" has been inserted elsewhere.
411 // In either of those cases, we'll just stop. 411 // In either of those cases, we'll just stop.
412 if (next && next->parentNode() != this) 412 if (next && next->parentNode() != this)
413 break; 413 break;
414 if (child.parentNode()) 414 if (child.parentNode())
415 break; 415 break;
(...skipping 11 matching lines...) Expand all
427 427
428 updateTreeAfterInsertion(child); 428 updateTreeAfterInsertion(child);
429 } 429 }
430 430
431 dispatchSubtreeModifiedEvent(); 431 dispatchSubtreeModifiedEvent();
432 return child; 432 return child;
433 } 433 }
434 434
435 void ContainerNode::willRemoveChild(Node& child) 435 void ContainerNode::willRemoveChild(Node& child)
436 { 436 {
437 ASSERT(child.parentNode() == this); 437 DCHECK_EQ(child.parentNode(), this);
438 ChildListMutationScope(*this).willRemoveChild(child); 438 ChildListMutationScope(*this).willRemoveChild(child);
439 child.notifyMutationObserversNodeWillDetach(); 439 child.notifyMutationObserversNodeWillDetach();
440 dispatchChildRemovalEvents(child); 440 dispatchChildRemovalEvents(child);
441 ChildFrameDisconnector(child).disconnect(); 441 ChildFrameDisconnector(child).disconnect();
442 if (document() != child.document()) { 442 if (document() != child.document()) {
443 // |child| was moved another document by DOM mutation event handler. 443 // |child| was moved another document by DOM mutation event handler.
444 return; 444 return;
445 } 445 }
446 446
447 // |nodeWillBeRemoved()| must be run after |ChildFrameDisconnector|, because 447 // |nodeWillBeRemoved()| must be run after |ChildFrameDisconnector|, because
448 // |ChildFrameDisconnector| can run script which may cause state that is to 448 // |ChildFrameDisconnector| can run script which may cause state that is to
449 // be invalidated by removing the node. 449 // be invalidated by removing the node.
450 ScriptForbiddenScope scriptForbiddenScope; 450 ScriptForbiddenScope scriptForbiddenScope;
451 EventDispatchForbiddenScope assertNoEventDispatch; 451 EventDispatchForbiddenScope assertNoEventDispatch;
452 // e.g. mutation event listener can create a new range. 452 // e.g. mutation event listener can create a new range.
453 document().nodeWillBeRemoved(child); 453 document().nodeWillBeRemoved(child);
454 } 454 }
455 455
456 void ContainerNode::willRemoveChildren() 456 void ContainerNode::willRemoveChildren()
457 { 457 {
458 NodeVector children; 458 NodeVector children;
459 getChildNodes(*this, children); 459 getChildNodes(*this, children);
460 460
461 ChildListMutationScope mutation(*this); 461 ChildListMutationScope mutation(*this);
462 for (const auto& node : children) { 462 for (const auto& node : children) {
463 ASSERT(node); 463 DCHECK(node);
464 Node& child = *node; 464 Node& child = *node;
465 mutation.willRemoveChild(child); 465 mutation.willRemoveChild(child);
466 child.notifyMutationObserversNodeWillDetach(); 466 child.notifyMutationObserversNodeWillDetach();
467 dispatchChildRemovalEvents(child); 467 dispatchChildRemovalEvents(child);
468 } 468 }
469 469
470 ChildFrameDisconnector(*this).disconnect(ChildFrameDisconnector::Descendants Only); 470 ChildFrameDisconnector(*this).disconnect(ChildFrameDisconnector::Descendants Only);
471 } 471 }
472 472
473 #if !ENABLE(OILPAN) 473 #if !ENABLE(OILPAN)
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 visitor->trace(m_firstChild); 545 visitor->trace(m_firstChild);
546 visitor->trace(m_lastChild); 546 visitor->trace(m_lastChild);
547 Node::trace(visitor); 547 Node::trace(visitor);
548 } 548 }
549 549
550 RawPtr<Node> ContainerNode::removeChild(RawPtr<Node> oldChild, ExceptionState& e xceptionState) 550 RawPtr<Node> ContainerNode::removeChild(RawPtr<Node> oldChild, ExceptionState& e xceptionState)
551 { 551 {
552 #if !ENABLE(OILPAN) 552 #if !ENABLE(OILPAN)
553 // Check that this node is not "floating". 553 // Check that this node is not "floating".
554 // If it is, it can be deleted as a side effect of sending mutation events. 554 // If it is, it can be deleted as a side effect of sending mutation events.
555 ASSERT(refCount() || parentOrShadowHostNode()); 555 DCHECK(refCount() || parentOrShadowHostNode());
556 #endif 556 #endif
557 557
558 RawPtr<Node> protect(this); 558 RawPtr<Node> protect(this);
559 559
560 // NotFoundError: Raised if oldChild is not a child of this node. 560 // NotFoundError: Raised if oldChild is not a child of this node.
561 // FIXME: We should never really get PseudoElements in here, but editing wil l sometimes 561 // FIXME: We should never really get PseudoElements in here, but editing wil l sometimes
562 // attempt to remove them still. We should fix that and enable this ASSERT. 562 // attempt to remove them still. We should fix that and enable this ASSERT.
563 // ASSERT(!oldChild->isPseudoElement()) 563 // DCHECK(!oldChild->isPseudoElement())
564 if (!oldChild || oldChild->parentNode() != this || oldChild->isPseudoElement ()) { 564 if (!oldChild || oldChild->parentNode() != this || oldChild->isPseudoElement ()) {
565 exceptionState.throwDOMException(NotFoundError, "The node to be removed is not a child of this node."); 565 exceptionState.throwDOMException(NotFoundError, "The node to be removed is not a child of this node.");
566 return nullptr; 566 return nullptr;
567 } 567 }
568 568
569 RawPtr<Node> child = oldChild; 569 RawPtr<Node> child = oldChild;
570 570
571 document().removeFocusedElementOfSubtree(child.get()); 571 document().removeFocusedElementOfSubtree(child.get());
572 572
573 // Events fired when blurring currently focused node might have moved this 573 // Events fired when blurring currently focused node might have moved this
(...skipping 22 matching lines...) Expand all
596 childrenChanged(ChildrenChange::forRemoval(*child, prev, next, ChildrenC hangeSourceAPI)); 596 childrenChanged(ChildrenChange::forRemoval(*child, prev, next, ChildrenC hangeSourceAPI));
597 } 597 }
598 dispatchSubtreeModifiedEvent(); 598 dispatchSubtreeModifiedEvent();
599 return child; 599 return child;
600 } 600 }
601 601
602 void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node& ol dChild) 602 void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node& ol dChild)
603 { 603 {
604 EventDispatchForbiddenScope assertNoEventDispatch; 604 EventDispatchForbiddenScope assertNoEventDispatch;
605 605
606 ASSERT(oldChild.parentNode() == this); 606 DCHECK_EQ(oldChild.parentNode(), this);
607 607
608 AttachContext context; 608 AttachContext context;
609 context.clearInvalidation = true; 609 context.clearInvalidation = true;
610 if (!oldChild.needsAttach()) 610 if (!oldChild.needsAttach())
611 oldChild.detach(context); 611 oldChild.detach(context);
612 612
613 if (nextChild) 613 if (nextChild)
614 nextChild->setPreviousSibling(previousChild); 614 nextChild->setPreviousSibling(previousChild);
615 if (previousChild) 615 if (previousChild)
616 previousChild->setNextSibling(nextChild); 616 previousChild->setNextSibling(nextChild);
617 if (m_firstChild == &oldChild) 617 if (m_firstChild == &oldChild)
618 m_firstChild = nextChild; 618 m_firstChild = nextChild;
619 if (m_lastChild == &oldChild) 619 if (m_lastChild == &oldChild)
620 m_lastChild = previousChild; 620 m_lastChild = previousChild;
621 621
622 oldChild.setPreviousSibling(nullptr); 622 oldChild.setPreviousSibling(nullptr);
623 oldChild.setNextSibling(nullptr); 623 oldChild.setNextSibling(nullptr);
624 oldChild.setParentOrShadowHostNode(nullptr); 624 oldChild.setParentOrShadowHostNode(nullptr);
625 625
626 document().adoptIfNeeded(oldChild); 626 document().adoptIfNeeded(oldChild);
627 } 627 }
628 628
629 void ContainerNode::parserRemoveChild(Node& oldChild) 629 void ContainerNode::parserRemoveChild(Node& oldChild)
630 { 630 {
631 ASSERT(oldChild.parentNode() == this); 631 DCHECK_EQ(oldChild.parentNode(), this);
632 ASSERT(!oldChild.isDocumentFragment()); 632 DCHECK(!oldChild.isDocumentFragment());
633 633
634 // This may cause arbitrary Javascript execution via onunload handlers. 634 // This may cause arbitrary Javascript execution via onunload handlers.
635 if (oldChild.connectedSubframeCount()) 635 if (oldChild.connectedSubframeCount())
636 ChildFrameDisconnector(oldChild).disconnect(); 636 ChildFrameDisconnector(oldChild).disconnect();
637 637
638 if (oldChild.parentNode() != this) 638 if (oldChild.parentNode() != this)
639 return; 639 return;
640 640
641 ChildListMutationScope(*this).willRemoveChild(oldChild); 641 ChildListMutationScope(*this).willRemoveChild(oldChild);
642 oldChild.notifyMutationObserversNodeWillDetach(); 642 oldChild.notifyMutationObserversNodeWillDetach();
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 dispatchSubtreeModifiedEvent(); 716 dispatchSubtreeModifiedEvent();
717 } 717 }
718 718
719 RawPtr<Node> ContainerNode::appendChild(RawPtr<Node> newChild, ExceptionState& e xceptionState) 719 RawPtr<Node> ContainerNode::appendChild(RawPtr<Node> newChild, ExceptionState& e xceptionState)
720 { 720 {
721 RawPtr<ContainerNode> protect(this); 721 RawPtr<ContainerNode> protect(this);
722 722
723 #if !ENABLE(OILPAN) 723 #if !ENABLE(OILPAN)
724 // Check that this node is not "floating". 724 // Check that this node is not "floating".
725 // If it is, it can be deleted as a side effect of sending mutation events. 725 // If it is, it can be deleted as a side effect of sending mutation events.
726 ASSERT(refCount() || parentOrShadowHostNode()); 726 DCHECK(refCount() || parentOrShadowHostNode());
727 #endif 727 #endif
728 728
729 // Make sure adding the new child is ok 729 // Make sure adding the new child is ok
730 if (!checkAcceptChild(newChild.get(), 0, exceptionState)) { 730 if (!checkAcceptChild(newChild.get(), 0, exceptionState)) {
731 if (exceptionState.hadException()) 731 if (exceptionState.hadException())
732 return nullptr; 732 return nullptr;
733 return newChild; 733 return newChild;
734 } 734 }
735 ASSERT(newChild); 735 DCHECK(newChild);
736 736
737 if (newChild == m_lastChild) // nothing to do 737 if (newChild == m_lastChild) // nothing to do
738 return newChild; 738 return newChild;
739 739
740 NodeVector targets; 740 NodeVector targets;
741 collectChildrenAndRemoveFromOldParent(*newChild, targets, exceptionState); 741 collectChildrenAndRemoveFromOldParent(*newChild, targets, exceptionState);
742 if (exceptionState.hadException()) 742 if (exceptionState.hadException())
743 return nullptr; 743 return nullptr;
744 744
745 if (targets.isEmpty()) 745 if (targets.isEmpty())
746 return newChild; 746 return newChild;
747 747
748 // We need this extra check because collectChildrenAndRemoveFromOldParent() can fire mutation events. 748 // We need this extra check because collectChildrenAndRemoveFromOldParent() can fire mutation events.
749 if (!checkAcceptChildGuaranteedNodeTypes(*newChild, nullptr, exceptionState) ) { 749 if (!checkAcceptChildGuaranteedNodeTypes(*newChild, nullptr, exceptionState) ) {
750 if (exceptionState.hadException()) 750 if (exceptionState.hadException())
751 return nullptr; 751 return nullptr;
752 return newChild; 752 return newChild;
753 } 753 }
754 754
755 InspectorInstrumentation::willInsertDOMNode(this); 755 InspectorInstrumentation::willInsertDOMNode(this);
756 756
757 // Now actually add the child(ren). 757 // Now actually add the child(ren).
758 ChildListMutationScope mutation(*this); 758 ChildListMutationScope mutation(*this);
759 for (const auto& targetNode : targets) { 759 for (const auto& targetNode : targets) {
760 ASSERT(targetNode); 760 DCHECK(targetNode);
761 Node& child = *targetNode; 761 Node& child = *targetNode;
762 762
763 // If the child has a parent again, just stop what we're doing, because 763 // If the child has a parent again, just stop what we're doing, because
764 // that means someone is doing something with DOM mutation -- can't re-p arent 764 // that means someone is doing something with DOM mutation -- can't re-p arent
765 // a child that already has a parent. 765 // a child that already has a parent.
766 if (child.parentNode()) 766 if (child.parentNode())
767 break; 767 break;
768 768
769 { 769 {
770 EventDispatchForbiddenScope assertNoEventDispatch; 770 EventDispatchForbiddenScope assertNoEventDispatch;
771 ScriptForbiddenScope forbidScript; 771 ScriptForbiddenScope forbidScript;
772 772
773 treeScope().adoptIfNeeded(child); 773 treeScope().adoptIfNeeded(child);
774 appendChildCommon(child); 774 appendChildCommon(child);
775 } 775 }
776 776
777 updateTreeAfterInsertion(child); 777 updateTreeAfterInsertion(child);
778 } 778 }
779 779
780 dispatchSubtreeModifiedEvent(); 780 dispatchSubtreeModifiedEvent();
781 return newChild; 781 return newChild;
782 } 782 }
783 783
784 void ContainerNode::parserAppendChild(RawPtr<Node> newChild) 784 void ContainerNode::parserAppendChild(RawPtr<Node> newChild)
785 { 785 {
786 ASSERT(newChild); 786 DCHECK(newChild);
787 ASSERT(!newChild->isDocumentFragment()); 787 DCHECK(!newChild->isDocumentFragment());
788 ASSERT(!isHTMLTemplateElement(this)); 788 DCHECK(!isHTMLTemplateElement(this));
789 789
790 if (!checkParserAcceptChild(*newChild)) 790 if (!checkParserAcceptChild(*newChild))
791 return; 791 return;
792 792
793 RawPtr<Node> protect(this); 793 RawPtr<Node> protect(this);
794 794
795 // FIXME: parserRemoveChild can run script which could then insert the 795 // FIXME: parserRemoveChild can run script which could then insert the
796 // newChild back into the page. Loop until the child is actually removed. 796 // newChild back into the page. Loop until the child is actually removed.
797 // See: fast/parser/execute-script-during-adoption-agency-removal.html 797 // See: fast/parser/execute-script-during-adoption-agency-removal.html
798 while (RawPtr<ContainerNode> parent = newChild->parentNode()) 798 while (RawPtr<ContainerNode> parent = newChild->parentNode())
799 parent->parserRemoveChild(*newChild); 799 parent->parserRemoveChild(*newChild);
800 800
801 if (document() != newChild->document()) 801 if (document() != newChild->document())
802 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION); 802 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION);
803 803
804 { 804 {
805 EventDispatchForbiddenScope assertNoEventDispatch; 805 EventDispatchForbiddenScope assertNoEventDispatch;
806 ScriptForbiddenScope forbidScript; 806 ScriptForbiddenScope forbidScript;
807 807
808 treeScope().adoptIfNeeded(*newChild); 808 treeScope().adoptIfNeeded(*newChild);
809 appendChildCommon(*newChild); 809 appendChildCommon(*newChild);
810 ASSERT(newChild->connectedSubframeCount() == 0); 810 DCHECK_EQ(newChild->connectedSubframeCount(), 0u);
811 ChildListMutationScope(*this).childAdded(*newChild); 811 ChildListMutationScope(*this).childAdded(*newChild);
812 } 812 }
813 813
814 notifyNodeInserted(*newChild, ChildrenChangeSourceParser); 814 notifyNodeInserted(*newChild, ChildrenChangeSourceParser);
815 } 815 }
816 816
817 void ContainerNode::notifyNodeInserted(Node& root, ChildrenChangeSource source) 817 void ContainerNode::notifyNodeInserted(Node& root, ChildrenChangeSource source)
818 { 818 {
819 ASSERT(!EventDispatchForbiddenScope::isEventDispatchForbidden()); 819 #if DCHECK_IS_ON()
820 ASSERT(!root.isShadowRoot()); 820 DCHECK(!EventDispatchForbiddenScope::isEventDispatchForbidden());
821 #endif
822 DCHECK(!root.isShadowRoot());
821 823
822 InspectorInstrumentation::didInsertDOMNode(&root); 824 InspectorInstrumentation::didInsertDOMNode(&root);
823 825
824 RawPtr<Node> protect(this); 826 RawPtr<Node> protect(this);
825 RawPtr<Node> protectNode(root); 827 RawPtr<Node> protectNode(root);
826 828
827 NodeVector postInsertionNotificationTargets; 829 NodeVector postInsertionNotificationTargets;
828 notifyNodeInsertedInternal(root, postInsertionNotificationTargets); 830 notifyNodeInsertedInternal(root, postInsertionNotificationTargets);
829 831
830 childrenChanged(ChildrenChange::forInsertion(root, source)); 832 childrenChanged(ChildrenChange::forInsertion(root, source));
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
868 notifyNodeRemoved(*shadowRoot); 870 notifyNodeRemoved(*shadowRoot);
869 } 871 }
870 } 872 }
871 873
872 void ContainerNode::attach(const AttachContext& context) 874 void ContainerNode::attach(const AttachContext& context)
873 { 875 {
874 AttachContext childrenContext(context); 876 AttachContext childrenContext(context);
875 childrenContext.resolvedStyle = nullptr; 877 childrenContext.resolvedStyle = nullptr;
876 878
877 for (Node* child = firstChild(); child; child = child->nextSibling()) { 879 for (Node* child = firstChild(); child; child = child->nextSibling()) {
878 ASSERT(child->needsAttach() || childAttachedAllowedWhenAttachingChildren (this)); 880 #if DCHECK_IS_ON()
881 DCHECK(child->needsAttach() || childAttachedAllowedWhenAttachingChildren (this));
882 #endif
879 if (child->needsAttach()) 883 if (child->needsAttach())
880 child->attach(childrenContext); 884 child->attach(childrenContext);
881 } 885 }
882 886
883 clearChildNeedsStyleRecalc(); 887 clearChildNeedsStyleRecalc();
884 Node::attach(context); 888 Node::attach(context);
885 } 889 }
886 890
887 void ContainerNode::detach(const AttachContext& context) 891 void ContainerNode::detach(const AttachContext& context)
888 { 892 {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
940 LayoutObject* next = nullptr; 944 LayoutObject* next = nullptr;
941 while (!next && o->parent()) { 945 while (!next && o->parent()) {
942 o = o->parent(); 946 o = o->parent();
943 next = o->nextSibling(); 947 next = o->nextSibling();
944 } 948 }
945 o = next; 949 o = next;
946 950
947 if (!o) 951 if (!o)
948 break; 952 break;
949 } 953 }
950 ASSERT(o); 954 DCHECK(o);
951 955
952 if (!o->isInline() || o->isAtomicInlineLevel()) { 956 if (!o->isInline() || o->isAtomicInlineLevel()) {
953 point = o->localToAbsolute(FloatPoint(), UseTransforms); 957 point = o->localToAbsolute(FloatPoint(), UseTransforms);
954 return true; 958 return true;
955 } 959 }
956 960
957 if (p->node() && p->node() == this && o->isText() && !o->isBR() && !toLa youtText(o)->hasTextBoxes()) { 961 if (p->node() && p->node() == this && o->isText() && !o->isBR() && !toLa youtText(o)->hasTextBoxes()) {
958 // Do nothing - skip unrendered whitespace that is a child or next s ibling of the anchor. 962 // Do nothing - skip unrendered whitespace that is a child or next s ibling of the anchor.
959 // FIXME: This fails to skip a whitespace sibling when there was als o a whitespace child (because p has moved). 963 // FIXME: This fails to skip a whitespace sibling when there was als o a whitespace child (because p has moved).
960 } else if ((o->isText() && !o->isBR()) || o->isAtomicInlineLevel()) { 964 } else if ((o->isText() && !o->isBR()) || o->isAtomicInlineLevel()) {
961 point = FloatPoint(); 965 point = FloatPoint();
962 if (o->isText()) { 966 if (o->isText()) {
963 if (toLayoutText(o)->firstTextBox()) 967 if (toLayoutText(o)->firstTextBox())
964 point.move(toLayoutText(o)->linesBoundingBox().x(), toLayout Text(o)->firstTextBox()->root().lineTop().toFloat()); 968 point.move(toLayoutText(o)->linesBoundingBox().x(), toLayout Text(o)->firstTextBox()->root().lineTop().toFloat());
965 point = o->localToAbsolute(point, UseTransforms); 969 point = o->localToAbsolute(point, UseTransforms);
966 } else { 970 } else {
967 ASSERT(o->isBox()); 971 DCHECK(o->isBox());
968 LayoutBox* box = toLayoutBox(o); 972 LayoutBox* box = toLayoutBox(o);
969 point.moveBy(box->location()); 973 point.moveBy(box->location());
970 point = o->container()->localToAbsolute(point, UseTransforms); 974 point = o->container()->localToAbsolute(point, UseTransforms);
971 } 975 }
972 return true; 976 return true;
973 } 977 }
974 } 978 }
975 979
976 // If the target doesn't have any children or siblings that could be used to calculate the scroll position, we must be 980 // If the target doesn't have any children or siblings that could be used to calculate the scroll position, we must be
977 // at the end of the document. Scroll to the bottom. FIXME: who said anythin g about scrolling? 981 // at the end of the document. Scroll to the bottom. FIXME: who said anythin g about scrolling?
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1039 if (o == layoutObject()) { 1043 if (o == layoutObject()) {
1040 return false; 1044 return false;
1041 } 1045 }
1042 o = o->parent(); 1046 o = o->parent();
1043 if (!o) 1047 if (!o)
1044 return false; 1048 return false;
1045 prev = o->previousSibling(); 1049 prev = o->previousSibling();
1046 } 1050 }
1047 o = prev; 1051 o = prev;
1048 } 1052 }
1049 ASSERT(o); 1053 DCHECK(o);
1050 if (o->isText() || o->isAtomicInlineLevel()) { 1054 if (o->isText() || o->isAtomicInlineLevel()) {
1051 point = FloatPoint(); 1055 point = FloatPoint();
1052 if (o->isText()) { 1056 if (o->isText()) {
1053 LayoutText* text = toLayoutText(o); 1057 LayoutText* text = toLayoutText(o);
1054 IntRect linesBox = text->linesBoundingBox(); 1058 IntRect linesBox = text->linesBoundingBox();
1055 if (!linesBox.maxX() && !linesBox.maxY()) 1059 if (!linesBox.maxX() && !linesBox.maxY())
1056 continue; 1060 continue;
1057 point.moveBy(linesBox.maxXMaxYCorner()); 1061 point.moveBy(linesBox.maxXMaxYCorner());
1058 point = o->localToAbsolute(point, UseTransforms); 1062 point = o->localToAbsolute(point, UseTransforms);
1059 } else { 1063 } else {
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
1232 1236
1233 NthIndexCache nthIndexCache(document()); 1237 NthIndexCache nthIndexCache(document());
1234 return selectorQuery->queryAll(*this); 1238 return selectorQuery->queryAll(*this);
1235 } 1239 }
1236 1240
1237 static void dispatchChildInsertionEvents(Node& child) 1241 static void dispatchChildInsertionEvents(Node& child)
1238 { 1242 {
1239 if (child.isInShadowTree()) 1243 if (child.isInShadowTree())
1240 return; 1244 return;
1241 1245
1242 ASSERT(!EventDispatchForbiddenScope::isEventDispatchForbidden()); 1246 #if DCHECK_IS_ON()
1247 DCHECK(!EventDispatchForbiddenScope::isEventDispatchForbidden());
1248 #endif
1243 1249
1244 RawPtr<Node> c(child); 1250 RawPtr<Node> c(child);
1245 RawPtr<Document> document(child.document()); 1251 RawPtr<Document> document(child.document());
1246 1252
1247 if (c->parentNode() && document->hasListenerType(Document::DOMNODEINSERTED_L ISTENER)) 1253 if (c->parentNode() && document->hasListenerType(Document::DOMNODEINSERTED_L ISTENER))
1248 c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNodeInse rted, true, c->parentNode())); 1254 c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNodeInse rted, true, c->parentNode()));
1249 1255
1250 // dispatch the DOMNodeInsertedIntoDocument event to all descendants 1256 // dispatch the DOMNodeInsertedIntoDocument event to all descendants
1251 if (c->inShadowIncludingDocument() && document->hasListenerType(Document::DO MNODEINSERTEDINTODOCUMENT_LISTENER)) { 1257 if (c->inShadowIncludingDocument() && document->hasListenerType(Document::DO MNODEINSERTEDINTODOCUMENT_LISTENER)) {
1252 for (; c; c = NodeTraversal::next(*c, &child)) 1258 for (; c; c = NodeTraversal::next(*c, &child))
1253 c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNode InsertedIntoDocument, false)); 1259 c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNode InsertedIntoDocument, false));
1254 } 1260 }
1255 } 1261 }
1256 1262
1257 static void dispatchChildRemovalEvents(Node& child) 1263 static void dispatchChildRemovalEvents(Node& child)
1258 { 1264 {
1259 if (child.isInShadowTree()) { 1265 if (child.isInShadowTree()) {
1260 InspectorInstrumentation::willRemoveDOMNode(&child); 1266 InspectorInstrumentation::willRemoveDOMNode(&child);
1261 return; 1267 return;
1262 } 1268 }
1263 1269
1264 ASSERT(!EventDispatchForbiddenScope::isEventDispatchForbidden()); 1270 #if DCHECK_IS_ON()
1271 DCHECK(!EventDispatchForbiddenScope::isEventDispatchForbidden());
1272 #endif
1265 1273
1266 InspectorInstrumentation::willRemoveDOMNode(&child); 1274 InspectorInstrumentation::willRemoveDOMNode(&child);
1267 1275
1268 RawPtr<Node> c(child); 1276 RawPtr<Node> c(child);
1269 RawPtr<Document> document(child.document()); 1277 RawPtr<Document> document(child.document());
1270 1278
1271 // Dispatch pre-removal mutation events. 1279 // Dispatch pre-removal mutation events.
1272 if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LI STENER)) { 1280 if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LI STENER)) {
1273 NodeChildRemovalTracker scope(child); 1281 NodeChildRemovalTracker scope(child);
1274 c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNodeRemo ved, true, c->parentNode())); 1282 c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNodeRemo ved, true, c->parentNode()));
1275 } 1283 }
1276 1284
1277 // Dispatch the DOMNodeRemovedFromDocument event to all descendants. 1285 // Dispatch the DOMNodeRemovedFromDocument event to all descendants.
1278 if (c->inShadowIncludingDocument() && document->hasListenerType(Document::DO MNODEREMOVEDFROMDOCUMENT_LISTENER)) { 1286 if (c->inShadowIncludingDocument() && document->hasListenerType(Document::DO MNODEREMOVEDFROMDOCUMENT_LISTENER)) {
1279 NodeChildRemovalTracker scope(child); 1287 NodeChildRemovalTracker scope(child);
1280 for (; c; c = NodeTraversal::next(*c, &child)) 1288 for (; c; c = NodeTraversal::next(*c, &child))
1281 c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNode RemovedFromDocument, false)); 1289 c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNode RemovedFromDocument, false));
1282 } 1290 }
1283 } 1291 }
1284 1292
1285 void ContainerNode::updateTreeAfterInsertion(Node& child) 1293 void ContainerNode::updateTreeAfterInsertion(Node& child)
1286 { 1294 {
1287 #if !ENABLE(OILPAN) 1295 #if !ENABLE(OILPAN)
1288 ASSERT(refCount()); 1296 DCHECK(refCount());
1289 ASSERT(child.refCount()); 1297 DCHECK(child.refCount());
1290 #endif 1298 #endif
1291 1299
1292 ChildListMutationScope(*this).childAdded(child); 1300 ChildListMutationScope(*this).childAdded(child);
1293 1301
1294 notifyNodeInserted(child); 1302 notifyNodeInserted(child);
1295 1303
1296 dispatchChildInsertionEvents(child); 1304 dispatchChildInsertionEvents(child);
1297 } 1305 }
1298 1306
1299 bool ContainerNode::hasRestyleFlagInternal(DynamicRestyleFlags mask) const 1307 bool ContainerNode::hasRestyleFlagInternal(DynamicRestyleFlags mask) const
1300 { 1308 {
1301 return rareData()->hasRestyleFlag(mask); 1309 return rareData()->hasRestyleFlag(mask);
1302 } 1310 }
1303 1311
1304 bool ContainerNode::hasRestyleFlagsInternal() const 1312 bool ContainerNode::hasRestyleFlagsInternal() const
1305 { 1313 {
1306 return rareData()->hasRestyleFlags(); 1314 return rareData()->hasRestyleFlags();
1307 } 1315 }
1308 1316
1309 void ContainerNode::setRestyleFlag(DynamicRestyleFlags mask) 1317 void ContainerNode::setRestyleFlag(DynamicRestyleFlags mask)
1310 { 1318 {
1311 ASSERT(isElementNode() || isShadowRoot()); 1319 DCHECK(isElementNode() || isShadowRoot());
1312 ensureRareData().setRestyleFlag(mask); 1320 ensureRareData().setRestyleFlag(mask);
1313 } 1321 }
1314 1322
1315 void ContainerNode::recalcChildStyle(StyleRecalcChange change) 1323 void ContainerNode::recalcChildStyle(StyleRecalcChange change)
1316 { 1324 {
1317 ASSERT(document().inStyleRecalc()); 1325 DCHECK(document().inStyleRecalc());
1318 ASSERT(change >= UpdatePseudoElements || childNeedsStyleRecalc()); 1326 DCHECK(change >= UpdatePseudoElements || childNeedsStyleRecalc());
1319 ASSERT(!needsStyleRecalc()); 1327 DCHECK(!needsStyleRecalc());
1320 1328
1321 // This loop is deliberately backwards because we use insertBefore in the la yout tree, and want to avoid 1329 // This loop is deliberately backwards because we use insertBefore in the la yout tree, and want to avoid
1322 // a potentially n^2 loop to find the insertion point while resolving style. Having us start from the last 1330 // a potentially n^2 loop to find the insertion point while resolving style. Having us start from the last
1323 // child and work our way back means in the common case, we'll find the inse rtion point in O(1) time. 1331 // child and work our way back means in the common case, we'll find the inse rtion point in O(1) time.
1324 // See crbug.com/288225 1332 // See crbug.com/288225
1325 StyleResolver& styleResolver = document().ensureStyleResolver(); 1333 StyleResolver& styleResolver = document().ensureStyleResolver();
1326 Text* lastTextNode = nullptr; 1334 Text* lastTextNode = nullptr;
1327 for (Node* child = lastChild(); child; child = child->previousSibling()) { 1335 for (Node* child = lastChild(); child; child = child->previousSibling()) {
1328 if (child->isTextNode()) { 1336 if (child->isTextNode()) {
1329 toText(child)->recalcTextStyle(change, lastTextNode); 1337 toText(child)->recalcTextStyle(change, lastTextNode);
(...skipping 26 matching lines...) Expand all
1356 if (((childrenAffectedByForwardPositionalRules() || childrenAffectedByIndire ctAdjacentRules()) && nodeAfterChange) 1364 if (((childrenAffectedByForwardPositionalRules() || childrenAffectedByIndire ctAdjacentRules()) && nodeAfterChange)
1357 || (childrenAffectedByBackwardPositionalRules() && nodeBeforeChange)) { 1365 || (childrenAffectedByBackwardPositionalRules() && nodeBeforeChange)) {
1358 setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::cre ate(StyleChangeReason::SiblingSelector)); 1366 setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::cre ate(StyleChangeReason::SiblingSelector));
1359 return; 1367 return;
1360 } 1368 }
1361 1369
1362 // :first-child. In the parser callback case, we don't have to check anythin g, since we were right the first time. 1370 // :first-child. In the parser callback case, we don't have to check anythin g, since we were right the first time.
1363 // In the DOM case, we only need to do something if |afterChange| is not 0. 1371 // In the DOM case, we only need to do something if |afterChange| is not 0.
1364 // |afterChange| is 0 in the parser case, so it works out that we'll skip th is block. 1372 // |afterChange| is 0 in the parser case, so it works out that we'll skip th is block.
1365 if (childrenAffectedByFirstChildRules() && nodeAfterChange) { 1373 if (childrenAffectedByFirstChildRules() && nodeAfterChange) {
1366 ASSERT(changeType != FinishedParsingChildren); 1374 DCHECK_NE(changeType, FinishedParsingChildren);
1367 // Find our new first child element. 1375 // Find our new first child element.
1368 Element* firstChildElement = ElementTraversal::firstChild(*this); 1376 Element* firstChildElement = ElementTraversal::firstChild(*this);
1369 1377
1370 // Find the first element after the change. 1378 // Find the first element after the change.
1371 Element* elementAfterChange = nodeAfterChange->isElementNode() ? toEleme nt(nodeAfterChange) : ElementTraversal::nextSibling(*nodeAfterChange); 1379 Element* elementAfterChange = nodeAfterChange->isElementNode() ? toEleme nt(nodeAfterChange) : ElementTraversal::nextSibling(*nodeAfterChange);
1372 1380
1373 // This is the element insertion as first child element case. 1381 // This is the element insertion as first child element case.
1374 if (changeType == SiblingElementInserted && elementAfterChange && firstC hildElement != elementAfterChange 1382 if (changeType == SiblingElementInserted && elementAfterChange && firstC hildElement != elementAfterChange
1375 && (!nodeBeforeChange || !nodeBeforeChange->isElementNode()) && elem entAfterChange->affectedByFirstChildRules()) { 1383 && (!nodeBeforeChange || !nodeBeforeChange->isElementNode()) && elem entAfterChange->affectedByFirstChildRules()) {
1376 elementAfterChange->setNeedsStyleRecalc(SubtreeStyleChange, StyleCha ngeReasonForTracing::create(StyleChangeReason::SiblingSelector)); 1384 elementAfterChange->setNeedsStyleRecalc(SubtreeStyleChange, StyleCha ngeReasonForTracing::create(StyleChangeReason::SiblingSelector));
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1459 1467
1460 // Takes an AtomicString in argument because it is common for elements to share the same set of class names. 1468 // Takes an AtomicString in argument because it is common for elements to share the same set of class names.
1461 // Therefore, the ClassNodeList factory function expects an AtomicString type. 1469 // Therefore, the ClassNodeList factory function expects an AtomicString type.
1462 RawPtr<ClassCollection> ContainerNode::getElementsByClassName(const AtomicString & classNames) 1470 RawPtr<ClassCollection> ContainerNode::getElementsByClassName(const AtomicString & classNames)
1463 { 1471 {
1464 return ensureCachedCollection<ClassCollection>(ClassCollectionType, classNam es); 1472 return ensureCachedCollection<ClassCollection>(ClassCollectionType, classNam es);
1465 } 1473 }
1466 1474
1467 RawPtr<RadioNodeList> ContainerNode::radioNodeList(const AtomicString& name, boo l onlyMatchImgElements) 1475 RawPtr<RadioNodeList> ContainerNode::radioNodeList(const AtomicString& name, boo l onlyMatchImgElements)
1468 { 1476 {
1469 ASSERT(isHTMLFormElement(this) || isHTMLFieldSetElement(this)); 1477 DCHECK(isHTMLFormElement(this) || isHTMLFieldSetElement(this));
1470 CollectionType type = onlyMatchImgElements ? RadioImgNodeListType : RadioNod eListType; 1478 CollectionType type = onlyMatchImgElements ? RadioImgNodeListType : RadioNod eListType;
1471 return ensureCachedCollection<RadioNodeList>(type, name); 1479 return ensureCachedCollection<RadioNodeList>(type, name);
1472 } 1480 }
1473 1481
1474 Element* ContainerNode::getElementById(const AtomicString& id) const 1482 Element* ContainerNode::getElementById(const AtomicString& id) const
1475 { 1483 {
1476 if (isInTreeScope()) { 1484 if (isInTreeScope()) {
1477 // Fast path if we are in a tree scope: call getElementById() on tree sc ope 1485 // Fast path if we are in a tree scope: call getElementById() on tree sc ope
1478 // and check if the matching element is in our subtree. 1486 // and check if the matching element is in our subtree.
1479 Element* element = treeScope().getElementById(id); 1487 Element* element = treeScope().getElementById(id);
1480 if (!element) 1488 if (!element)
1481 return nullptr; 1489 return nullptr;
1482 if (element->isDescendantOf(this)) 1490 if (element->isDescendantOf(this))
1483 return element; 1491 return element;
1484 } 1492 }
1485 1493
1486 // Fall back to traversing our subtree. In case of duplicate ids, the first element found will be returned. 1494 // Fall back to traversing our subtree. In case of duplicate ids, the first element found will be returned.
1487 for (Element& element : ElementTraversal::descendantsOf(*this)) { 1495 for (Element& element : ElementTraversal::descendantsOf(*this)) {
1488 if (element.getIdAttribute() == id) 1496 if (element.getIdAttribute() == id)
1489 return &element; 1497 return &element;
1490 } 1498 }
1491 return nullptr; 1499 return nullptr;
1492 } 1500 }
1493 1501
1494 NodeListsNodeData& ContainerNode::ensureNodeLists() 1502 NodeListsNodeData& ContainerNode::ensureNodeLists()
1495 { 1503 {
1496 return ensureRareData().ensureNodeLists(); 1504 return ensureRareData().ensureNodeLists();
1497 } 1505 }
1498 1506
1499 #if ENABLE(ASSERT) 1507 #if DCHECK_IS_ON()
1500 bool childAttachedAllowedWhenAttachingChildren(ContainerNode* node) 1508 bool childAttachedAllowedWhenAttachingChildren(ContainerNode* node)
1501 { 1509 {
1502 if (node->isShadowRoot()) 1510 if (node->isShadowRoot())
1503 return true; 1511 return true;
1504 1512
1505 if (node->isInsertionPoint()) 1513 if (node->isInsertionPoint())
1506 return true; 1514 return true;
1507 1515
1508 if (isHTMLSlotElement(node)) 1516 if (isHTMLSlotElement(node))
1509 return true; 1517 return true;
1510 1518
1511 if (node->isElementNode() && toElement(node)->shadow()) 1519 if (node->isElementNode() && toElement(node)->shadow())
1512 return true; 1520 return true;
1513 1521
1514 return false; 1522 return false;
1515 } 1523 }
1516 #endif 1524 #endif
1517 1525
1518 } // namespace blink 1526 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/dom/ContainerNode.h ('k') | third_party/WebKit/Source/core/dom/ContextFeatures.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698