| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |