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

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

Issue 2899613002: DOM: Fix an issue of reversed MutationRecoards. (Closed)
Patch Set: Created 3 years, 7 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
« no previous file with comments | « third_party/WebKit/Source/core/dom/ContainerNode.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights
6 * reserved. 6 * 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 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 kNotFoundError, 206 kNotFoundError,
207 "The node before which the new node is to " 207 "The node before which the new node is to "
208 "be inserted is not a child of this " 208 "be inserted is not a child of this "
209 "node."); 209 "node.");
210 return false; 210 return false;
211 } 211 }
212 return true; 212 return true;
213 } 213 }
214 214
215 template <typename Functor> 215 template <typename Functor>
216 void ContainerNode::InsertNodeVector(const NodeVector& targets, 216 void ContainerNode::InsertNodeVector(
217 Node* next, 217 const NodeVector& targets,
218 const Functor& mutator) { 218 Node* next,
219 const Functor& mutator,
220 NodeVector* post_insertion_notification_targets) {
221 DCHECK(post_insertion_notification_targets);
219 probe::willInsertDOMNode(this); 222 probe::willInsertDOMNode(this);
220 NodeVector post_insertion_notification_targets;
221 { 223 {
222 EventDispatchForbiddenScope assert_no_event_dispatch; 224 EventDispatchForbiddenScope assert_no_event_dispatch;
223 ScriptForbiddenScope forbid_script; 225 ScriptForbiddenScope forbid_script;
224 for (const auto& target_node : targets) { 226 for (const auto& target_node : targets) {
225 DCHECK(target_node); 227 DCHECK(target_node);
226 DCHECK(!target_node->parentNode()); 228 DCHECK(!target_node->parentNode());
227 Node& child = *target_node; 229 Node& child = *target_node;
228 mutator(*this, child, next); 230 mutator(*this, child, next);
229 ChildListMutationScope(*this).ChildAdded(child); 231 ChildListMutationScope(*this).ChildAdded(child);
230 if (GetDocument().ContainsV1ShadowTree()) 232 if (GetDocument().ContainsV1ShadowTree())
231 child.CheckSlotChangeAfterInserted(); 233 child.CheckSlotChangeAfterInserted();
232 probe::didInsertDOMNode(&child); 234 probe::didInsertDOMNode(&child);
233 NotifyNodeInsertedInternal(child, post_insertion_notification_targets); 235 NotifyNodeInsertedInternal(child, *post_insertion_notification_targets);
234 } 236 }
235 } 237 }
238 }
239
240 void ContainerNode::DidInsertNodeVector(
241 const NodeVector& targets,
242 Node* next,
243 const NodeVector& post_insertion_notification_targets) {
236 Node* unchanged_previous = 244 Node* unchanged_previous =
237 targets.size() > 0 ? targets[0]->previousSibling() : nullptr; 245 targets.size() > 0 ? targets[0]->previousSibling() : nullptr;
238 for (const auto& target_node : targets) { 246 for (const auto& target_node : targets) {
239 ChildrenChanged(ChildrenChange::ForInsertion( 247 ChildrenChanged(ChildrenChange::ForInsertion(
240 *target_node, unchanged_previous, next, kChildrenChangeSourceAPI)); 248 *target_node, unchanged_previous, next, kChildrenChangeSourceAPI));
241 } 249 }
242 for (const auto& descendant : post_insertion_notification_targets) { 250 for (const auto& descendant : post_insertion_notification_targets) {
243 if (descendant->isConnected()) 251 if (descendant->isConnected())
244 descendant->DidNotifySubtreeInsertionsToDocument(); 252 descendant->DidNotifySubtreeInsertionsToDocument();
245 } 253 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 // Make sure adding the new child is OK. 307 // Make sure adding the new child is OK.
300 if (!CheckAcceptChild(new_child, 0, exception_state)) 308 if (!CheckAcceptChild(new_child, 0, exception_state))
301 return new_child; 309 return new_child;
302 DCHECK(new_child); 310 DCHECK(new_child);
303 311
304 NodeVector targets; 312 NodeVector targets;
305 if (!CollectChildrenAndRemoveFromOldParentWithCheck( 313 if (!CollectChildrenAndRemoveFromOldParentWithCheck(
306 ref_child, nullptr, *new_child, targets, exception_state)) 314 ref_child, nullptr, *new_child, targets, exception_state))
307 return new_child; 315 return new_child;
308 316
309 ChildListMutationScope mutation(*this); 317 NodeVector post_insertion_notification_targets;
310 InsertNodeVector(targets, ref_child, AdoptAndInsertBefore()); 318 {
319 ChildListMutationScope mutation(*this);
320 InsertNodeVector(targets, ref_child, AdoptAndInsertBefore(),
321 &post_insertion_notification_targets);
322 }
323 DidInsertNodeVector(targets, ref_child, post_insertion_notification_targets);
311 return new_child; 324 return new_child;
312 } 325 }
313 326
314 void ContainerNode::InsertBeforeCommon(Node& next_child, Node& new_child) { 327 void ContainerNode::InsertBeforeCommon(Node& next_child, Node& new_child) {
315 #if DCHECK_IS_ON() 328 #if DCHECK_IS_ON()
316 DCHECK(EventDispatchForbiddenScope::IsEventDispatchForbidden()); 329 DCHECK(EventDispatchForbiddenScope::IsEventDispatchForbidden());
317 #endif 330 #endif
318 DCHECK(ScriptForbiddenScope::IsScriptForbidden()); 331 DCHECK(ScriptForbiddenScope::IsScriptForbidden());
319 // Use insertBefore if you need to handle reparenting (and want DOM mutation 332 // Use insertBefore if you need to handle reparenting (and want DOM mutation
320 // events). 333 // events).
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 // operation. 456 // operation.
444 // Though the following CollectChildrenAndRemoveFromOldParentWithCheck() also 457 // Though the following CollectChildrenAndRemoveFromOldParentWithCheck() also
445 // calls RemoveChild(), we'd like to call RemoveChild() here to make a 458 // calls RemoveChild(), we'd like to call RemoveChild() here to make a
446 // separated MutationRecord. 459 // separated MutationRecord.
447 if (ContainerNode* new_child_parent = new_child->parentNode()) { 460 if (ContainerNode* new_child_parent = new_child->parentNode()) {
448 new_child_parent->RemoveChild(new_child, exception_state); 461 new_child_parent->RemoveChild(new_child, exception_state);
449 if (exception_state.HadException()) 462 if (exception_state.HadException())
450 return nullptr; 463 return nullptr;
451 } 464 }
452 465
453 // 9. Let previousSibling be child’s previous sibling. 466 NodeVector targets;
454 // 11. Let removedNodes be the empty list. 467 NodeVector post_insertion_notification_targets;
455 // 15. Queue a mutation record of "childList" for target parent with 468 {
456 // addedNodes nodes, removedNodes removedNodes, nextSibling reference child, 469 // 9. Let previousSibling be child’s previous sibling.
457 // and previousSibling previousSibling. 470 // 11. Let removedNodes be the empty list.
458 ChildListMutationScope mutation(*this); 471 // 15. Queue a mutation record of "childList" for target parent with
472 // addedNodes nodes, removedNodes removedNodes, nextSibling reference child,
473 // and previousSibling previousSibling.
474 ChildListMutationScope mutation(*this);
459 475
460 // 12. If child’s parent is not null, run these substeps: 476 // 12. If child’s parent is not null, run these substeps:
461 // 1. Set removedNodes to a list solely containing child. 477 // 1. Set removedNodes to a list solely containing child.
462 // 2. Remove child from its parent with the suppress observers flag set. 478 // 2. Remove child from its parent with the suppress observers flag set.
463 if (ContainerNode* old_child_parent = old_child->parentNode()) { 479 if (ContainerNode* old_child_parent = old_child->parentNode()) {
464 old_child_parent->RemoveChild(old_child, exception_state); 480 old_child_parent->RemoveChild(old_child, exception_state);
465 if (exception_state.HadException()) 481 if (exception_state.HadException())
466 return nullptr; 482 return nullptr;
483 }
484
485 // Does this one more time because removeChild() fires a MutationEvent.
486 if (!CheckAcceptChild(new_child, old_child, exception_state))
487 return old_child;
488
489 // 13. Let nodes be node’s children if node is a DocumentFragment node, and
490 // a list containing solely node otherwise.
491 if (!CollectChildrenAndRemoveFromOldParentWithCheck(
492 next, old_child, *new_child, targets, exception_state))
493 return old_child;
494
495 // 10. Adopt node into parent’s node document.
496 // 14. Insert node into parent before reference child with the suppress
497 // observers flag set.
498 if (next) {
499 InsertNodeVector(targets, next, AdoptAndInsertBefore(),
500 &post_insertion_notification_targets);
501 } else {
502 InsertNodeVector(targets, nullptr, AdoptAndAppendChild(),
503 &post_insertion_notification_targets);
504 }
467 } 505 }
468 506 DidInsertNodeVector(targets, next, post_insertion_notification_targets);
469 // Does this one more time because removeChild() fires a MutationEvent.
470 if (!CheckAcceptChild(new_child, old_child, exception_state))
471 return old_child;
472
473 // 13. Let nodes be node’s children if node is a DocumentFragment node, and a
474 // list containing solely node otherwise.
475 NodeVector targets;
476 if (!CollectChildrenAndRemoveFromOldParentWithCheck(
477 next, old_child, *new_child, targets, exception_state))
478 return old_child;
479
480 // 10. Adopt node into parent’s node document.
481 // 14. Insert node into parent before reference child with the suppress
482 // observers flag set.
483 if (next)
484 InsertNodeVector(targets, next, AdoptAndInsertBefore());
485 else
486 InsertNodeVector(targets, nullptr, AdoptAndAppendChild());
487 507
488 // 16. Return child. 508 // 16. Return child.
489 return old_child; 509 return old_child;
490 } 510 }
491 511
492 void ContainerNode::WillRemoveChild(Node& child) { 512 void ContainerNode::WillRemoveChild(Node& child) {
493 DCHECK_EQ(child.parentNode(), this); 513 DCHECK_EQ(child.parentNode(), this);
494 ChildListMutationScope(*this).WillRemoveChild(child); 514 ChildListMutationScope(*this).WillRemoveChild(child);
495 child.NotifyMutationObserversNodeWillDetach(); 515 child.NotifyMutationObserversNodeWillDetach();
496 DispatchChildRemovalEvents(child); 516 DispatchChildRemovalEvents(child);
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 // Make sure adding the new child is ok 719 // Make sure adding the new child is ok
700 if (!CheckAcceptChild(new_child, 0, exception_state)) 720 if (!CheckAcceptChild(new_child, 0, exception_state))
701 return new_child; 721 return new_child;
702 DCHECK(new_child); 722 DCHECK(new_child);
703 723
704 NodeVector targets; 724 NodeVector targets;
705 if (!CollectChildrenAndRemoveFromOldParentWithCheck( 725 if (!CollectChildrenAndRemoveFromOldParentWithCheck(
706 nullptr, nullptr, *new_child, targets, exception_state)) 726 nullptr, nullptr, *new_child, targets, exception_state))
707 return new_child; 727 return new_child;
708 728
709 ChildListMutationScope mutation(*this); 729 NodeVector post_insertion_notification_targets;
710 InsertNodeVector(targets, nullptr, AdoptAndAppendChild()); 730 {
731 ChildListMutationScope mutation(*this);
732 InsertNodeVector(targets, nullptr, AdoptAndAppendChild(),
733 &post_insertion_notification_targets);
734 }
735 DidInsertNodeVector(targets, nullptr, post_insertion_notification_targets);
711 return new_child; 736 return new_child;
712 } 737 }
713 738
714 void ContainerNode::ParserAppendChild(Node* new_child) { 739 void ContainerNode::ParserAppendChild(Node* new_child) {
715 DCHECK(new_child); 740 DCHECK(new_child);
716 DCHECK(!new_child->IsDocumentFragment()); 741 DCHECK(!new_child->IsDocumentFragment());
717 DCHECK(!isHTMLTemplateElement(this)); 742 DCHECK(!isHTMLTemplateElement(this));
718 743
719 if (!CheckParserAcceptChild(*new_child)) 744 if (!CheckParserAcceptChild(*new_child))
720 return; 745 return;
(...skipping 849 matching lines...) Expand 10 before | Expand all | Expand 10 after
1570 return true; 1595 return true;
1571 1596
1572 if (node->IsElementNode() && ToElement(node)->Shadow()) 1597 if (node->IsElementNode() && ToElement(node)->Shadow())
1573 return true; 1598 return true;
1574 1599
1575 return false; 1600 return false;
1576 } 1601 }
1577 #endif 1602 #endif
1578 1603
1579 } // namespace blink 1604 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/dom/ContainerNode.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698