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

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

Issue 1770523002: Track connected subframes per-Document instead of per-Node. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix various crashes but still doesn't refcount tracked nodes (and needs to) Created 4 years, 9 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.
11 * 11 *
12 * This library is distributed in the hope that it will be useful, 12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details. 15 * Library General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU Library General Public License 17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to 18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA. 20 * Boston, MA 02110-1301, USA.
21 */ 21 */
22 22
23 #include "core/dom/ContainerNode.h" 23 #include "core/dom/ContainerNode.h"
24 24
25 #include "bindings/core/v8/ExceptionState.h" 25 #include "bindings/core/v8/ExceptionState.h"
26 #include "core/dom/ChildFrameDisconnector.h"
27 #include "core/dom/ChildListMutationScope.h" 26 #include "core/dom/ChildListMutationScope.h"
28 #include "core/dom/ClassCollection.h" 27 #include "core/dom/ClassCollection.h"
29 #include "core/dom/ElementTraversal.h" 28 #include "core/dom/ElementTraversal.h"
30 #include "core/dom/ExceptionCode.h" 29 #include "core/dom/ExceptionCode.h"
31 #include "core/dom/NameNodeList.h" 30 #include "core/dom/NameNodeList.h"
32 #include "core/dom/NodeChildRemovalTracker.h" 31 #include "core/dom/NodeChildRemovalTracker.h"
33 #include "core/dom/NodeComputedStyle.h" 32 #include "core/dom/NodeComputedStyle.h"
34 #include "core/dom/NodeRareData.h" 33 #include "core/dom/NodeRareData.h"
35 #include "core/dom/NodeTraversal.h" 34 #include "core/dom/NodeTraversal.h"
36 #include "core/dom/NthIndexCache.h" 35 #include "core/dom/NthIndexCache.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 return; 70 return;
72 } 71 }
73 nodes.append(&node); 72 nodes.append(&node);
74 if (ContainerNode* oldParent = node.parentNode()) 73 if (ContainerNode* oldParent = node.parentNode())
75 oldParent->removeChild(&node, exceptionState); 74 oldParent->removeChild(&node, exceptionState);
76 } 75 }
77 76
78 #if !ENABLE(OILPAN) 77 #if !ENABLE(OILPAN)
79 void ContainerNode::removeDetachedChildren() 78 void ContainerNode::removeDetachedChildren()
80 { 79 {
81 ASSERT(!connectedSubframeCount());
82 ASSERT(needsAttach()); 80 ASSERT(needsAttach());
83 removeDetachedChildrenInContainer(*this); 81 removeDetachedChildrenInContainer(*this);
84 } 82 }
85 #endif 83 #endif
86 84
87 void ContainerNode::parserTakeAllChildrenFrom(ContainerNode& oldParent) 85 void ContainerNode::parserTakeAllChildrenFrom(ContainerNode& oldParent)
88 { 86 {
89 while (RefPtrWillBeRawPtr<Node> child = oldParent.firstChild()) { 87 while (RefPtrWillBeRawPtr<Node> child = oldParent.firstChild()) {
90 // Explicitly remove since appending can fail, but this loop shouldn't b e infinite. 88 // Explicitly remove since appending can fail, but this loop shouldn't b e infinite.
91 oldParent.parserRemoveChild(*child); 89 oldParent.parserRemoveChild(*child);
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 318
321 if (document() != newChild->document()) 319 if (document() != newChild->document())
322 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION); 320 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION);
323 321
324 { 322 {
325 EventDispatchForbiddenScope assertNoEventDispatch; 323 EventDispatchForbiddenScope assertNoEventDispatch;
326 ScriptForbiddenScope forbidScript; 324 ScriptForbiddenScope forbidScript;
327 325
328 treeScope().adoptIfNeeded(*newChild); 326 treeScope().adoptIfNeeded(*newChild);
329 insertBeforeCommon(nextChild, *newChild); 327 insertBeforeCommon(nextChild, *newChild);
330 newChild->updateAncestorConnectedSubframeCountForInsertion(); 328 ASSERT(!document().subframeTracker().hasConnectedSubframes(*newChild));
331 ChildListMutationScope(*this).childAdded(*newChild); 329 ChildListMutationScope(*this).childAdded(*newChild);
332 } 330 }
333 331
334 notifyNodeInserted(*newChild, ChildrenChangeSourceParser); 332 notifyNodeInserted(*newChild, ChildrenChangeSourceParser);
335 } 333 }
336 334
337 PassRefPtrWillBeRawPtr<Node> ContainerNode::replaceChild(PassRefPtrWillBeRawPtr< Node> newChild, PassRefPtrWillBeRawPtr<Node> oldChild, ExceptionState& exception State) 335 PassRefPtrWillBeRawPtr<Node> ContainerNode::replaceChild(PassRefPtrWillBeRawPtr< Node> newChild, PassRefPtrWillBeRawPtr<Node> oldChild, ExceptionState& exception State)
338 { 336 {
339 #if !ENABLE(OILPAN) 337 #if !ENABLE(OILPAN)
340 // Check that this node is not "floating". 338 // Check that this node is not "floating".
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 dispatchSubtreeModifiedEvent(); 429 dispatchSubtreeModifiedEvent();
432 return child; 430 return child;
433 } 431 }
434 432
435 void ContainerNode::willRemoveChild(Node& child) 433 void ContainerNode::willRemoveChild(Node& child)
436 { 434 {
437 ASSERT(child.parentNode() == this); 435 ASSERT(child.parentNode() == this);
438 ChildListMutationScope(*this).willRemoveChild(child); 436 ChildListMutationScope(*this).willRemoveChild(child);
439 child.notifyMutationObserversNodeWillDetach(); 437 child.notifyMutationObserversNodeWillDetach();
440 dispatchChildRemovalEvents(child); 438 dispatchChildRemovalEvents(child);
441 ChildFrameDisconnector(child).disconnect(); 439 // TODO(dcheng): Is it possible for document() to be null here?
440 document().subframeTracker().disconnectSubframesAt(child);
442 if (document() != child.document()) { 441 if (document() != child.document()) {
443 // |child| was moved another document by DOM mutation event handler. 442 // |child| was moved another document by DOM mutation event handler.
444 return; 443 return;
445 } 444 }
446 445
447 // |nodeWillBeRemoved()| must be run after |ChildFrameDisconnector|, because 446 // |nodeWillBeRemoved()| must be run after |ChildFrameDisconnector|, because
448 // |ChildFrameDisconnector| can run script which may cause state that is to 447 // |ChildFrameDisconnector| can run script which may cause state that is to
449 // be invalidated by removing the node. 448 // be invalidated by removing the node.
450 ScriptForbiddenScope scriptForbiddenScope; 449 ScriptForbiddenScope scriptForbiddenScope;
451 EventDispatchForbiddenScope assertNoEventDispatch; 450 EventDispatchForbiddenScope assertNoEventDispatch;
452 // e.g. mutation event listener can create a new range. 451 // e.g. mutation event listener can create a new range.
453 document().nodeWillBeRemoved(child); 452 document().nodeWillBeRemoved(child);
454 } 453 }
455 454
456 void ContainerNode::willRemoveChildren() 455 void ContainerNode::willRemoveChildren()
457 { 456 {
458 NodeVector children; 457 NodeVector children;
459 getChildNodes(*this, children); 458 getChildNodes(*this, children);
460 459
461 ChildListMutationScope mutation(*this); 460 ChildListMutationScope mutation(*this);
462 for (const auto& node : children) { 461 for (const auto& node : children) {
463 ASSERT(node); 462 ASSERT(node);
464 Node& child = *node; 463 Node& child = *node;
465 mutation.willRemoveChild(child); 464 mutation.willRemoveChild(child);
466 child.notifyMutationObserversNodeWillDetach(); 465 child.notifyMutationObserversNodeWillDetach();
467 dispatchChildRemovalEvents(child); 466 dispatchChildRemovalEvents(child);
468 } 467 }
469 468
470 ChildFrameDisconnector(*this).disconnect(ChildFrameDisconnector::Descendants Only); 469 // TODO(dcheng): Is it possible for document() to be null here?
470 document().subframeTracker().disconnectSubframesAt(*this, SubframeTracker::D escendantsOnly);
471 } 471 }
472 472
473 #if !ENABLE(OILPAN) 473 #if !ENABLE(OILPAN)
474 void ContainerNode::removeDetachedChildrenInContainer(ContainerNode& container) 474 void ContainerNode::removeDetachedChildrenInContainer(ContainerNode& container)
475 { 475 {
476 // List of nodes to be deleted. 476 // List of nodes to be deleted.
477 Node* head = nullptr; 477 Node* head = nullptr;
478 Node* tail = nullptr; 478 Node* tail = nullptr;
479 479
480 addChildNodesToDeletionQueue(head, tail, container); 480 addChildNodesToDeletionQueue(head, tail, container);
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 ASSERT(oldChild.parentNode() == this);
632 ASSERT(!oldChild.isDocumentFragment()); 632 ASSERT(!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 document().subframeTracker().disconnectSubframesAt(*this);
636 ChildFrameDisconnector(oldChild).disconnect();
637 636
638 if (oldChild.parentNode() != this) 637 if (oldChild.parentNode() != this)
639 return; 638 return;
640 639
641 ChildListMutationScope(*this).willRemoveChild(oldChild); 640 ChildListMutationScope(*this).willRemoveChild(oldChild);
642 oldChild.notifyMutationObserversNodeWillDetach(); 641 oldChild.notifyMutationObserversNodeWillDetach();
643 642
644 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; 643 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates;
645 DocumentOrderedMap::RemoveScope treeRemoveScope; 644 DocumentOrderedMap::RemoveScope treeRemoveScope;
646 645
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 799
801 if (document() != newChild->document()) 800 if (document() != newChild->document())
802 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION); 801 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION);
803 802
804 { 803 {
805 EventDispatchForbiddenScope assertNoEventDispatch; 804 EventDispatchForbiddenScope assertNoEventDispatch;
806 ScriptForbiddenScope forbidScript; 805 ScriptForbiddenScope forbidScript;
807 806
808 treeScope().adoptIfNeeded(*newChild); 807 treeScope().adoptIfNeeded(*newChild);
809 appendChildCommon(*newChild); 808 appendChildCommon(*newChild);
810 newChild->updateAncestorConnectedSubframeCountForInsertion(); 809 ASSERT(!document().subframeTracker().hasConnectedSubframes(*newChild));
811 ChildListMutationScope(*this).childAdded(*newChild); 810 ChildListMutationScope(*this).childAdded(*newChild);
812 } 811 }
813 812
814 notifyNodeInserted(*newChild, ChildrenChangeSourceParser); 813 notifyNodeInserted(*newChild, ChildrenChangeSourceParser);
815 } 814 }
816 815
817 void ContainerNode::notifyNodeInserted(Node& root, ChildrenChangeSource source) 816 void ContainerNode::notifyNodeInserted(Node& root, ChildrenChangeSource source)
818 { 817 {
819 ASSERT(!EventDispatchForbiddenScope::isEventDispatchForbidden()); 818 ASSERT(!EventDispatchForbiddenScope::isEventDispatchForbidden());
820 ASSERT(!root.isShadowRoot()); 819 ASSERT(!root.isShadowRoot());
(...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after
1509 return true; 1508 return true;
1510 1509
1511 if (node->isElementNode() && toElement(node)->shadow()) 1510 if (node->isElementNode() && toElement(node)->shadow())
1512 return true; 1511 return true;
1513 1512
1514 return false; 1513 return false;
1515 } 1514 }
1516 #endif 1515 #endif
1517 1516
1518 } // namespace blink 1517 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/dom/ChildFrameDisconnector.cpp ('k') | third_party/WebKit/Source/core/dom/Document.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698