| 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. |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 void ContainerNode::parserInsertBefore(PassRefPtrWillBeRawPtr<Node> newChild, No
de& nextChild) | 296 void ContainerNode::parserInsertBefore(PassRefPtrWillBeRawPtr<Node> newChild, No
de& nextChild) |
| 297 { | 297 { |
| 298 ASSERT(newChild); | 298 ASSERT(newChild); |
| 299 ASSERT(nextChild.parentNode() == this); | 299 ASSERT(nextChild.parentNode() == this); |
| 300 ASSERT(!newChild->isDocumentFragment()); | 300 ASSERT(!newChild->isDocumentFragment()); |
| 301 ASSERT(!isHTMLTemplateElement(this)); | 301 ASSERT(!isHTMLTemplateElement(this)); |
| 302 | 302 |
| 303 if (nextChild.previousSibling() == newChild || &nextChild == newChild) // no
thing to do | 303 if (nextChild.previousSibling() == newChild || &nextChild == newChild) // no
thing to do |
| 304 return; | 304 return; |
| 305 | 305 |
| 306 RefPtrWillBeRawPtr<Node> protect(this); |
| 307 |
| 306 if (document() != newChild->document()) | 308 if (document() != newChild->document()) |
| 307 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION); | 309 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION); |
| 308 | 310 |
| 309 insertBeforeCommon(nextChild, *newChild); | 311 insertBeforeCommon(nextChild, *newChild); |
| 310 | 312 |
| 311 newChild->updateAncestorConnectedSubframeCountForInsertion(); | 313 newChild->updateAncestorConnectedSubframeCountForInsertion(); |
| 312 | 314 |
| 313 ChildListMutationScope(*this).childAdded(*newChild); | 315 ChildListMutationScope(*this).childAdded(*newChild); |
| 314 | 316 |
| 315 ChildrenChange change = {ChildInserted, newChild->previousSibling(), &nextCh
ild, ChildrenChangeSourceParser}; | 317 notifyNodeInserted(*newChild, ChildrenChangeSourceParser); |
| 316 childrenChanged(change); | |
| 317 | |
| 318 notifyNodeInserted(*newChild); | |
| 319 } | 318 } |
| 320 | 319 |
| 321 PassRefPtrWillBeRawPtr<Node> ContainerNode::replaceChild(PassRefPtrWillBeRawPtr<
Node> newChild, PassRefPtrWillBeRawPtr<Node> oldChild, ExceptionState& exception
State) | 320 PassRefPtrWillBeRawPtr<Node> ContainerNode::replaceChild(PassRefPtrWillBeRawPtr<
Node> newChild, PassRefPtrWillBeRawPtr<Node> oldChild, ExceptionState& exception
State) |
| 322 { | 321 { |
| 323 #if !ENABLE(OILPAN) | 322 #if !ENABLE(OILPAN) |
| 324 // Check that this node is not "floating". | 323 // Check that this node is not "floating". |
| 325 // If it is, it can be deleted as a side effect of sending mutation events. | 324 // If it is, it can be deleted as a side effect of sending mutation events. |
| 326 ASSERT(refCount() || parentOrShadowHostNode()); | 325 ASSERT(refCount() || parentOrShadowHostNode()); |
| 327 #endif | 326 #endif |
| 328 | 327 |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 exceptionState.throwDOMException(NotFoundError, "The node to be removed
is no longer a child of this node. Perhaps it was moved in response to a mutatio
n?"); | 560 exceptionState.throwDOMException(NotFoundError, "The node to be removed
is no longer a child of this node. Perhaps it was moved in response to a mutatio
n?"); |
| 562 return nullptr; | 561 return nullptr; |
| 563 } | 562 } |
| 564 | 563 |
| 565 { | 564 { |
| 566 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; | 565 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; |
| 567 | 566 |
| 568 Node* prev = child->previousSibling(); | 567 Node* prev = child->previousSibling(); |
| 569 Node* next = child->nextSibling(); | 568 Node* next = child->nextSibling(); |
| 570 removeBetween(prev, next, *child); | 569 removeBetween(prev, next, *child); |
| 570 notifyNodeRemoved(*child); |
| 571 ChildrenChange change = {ChildRemoved, prev, next, ChildrenChangeSourceA
PI}; | 571 ChildrenChange change = {ChildRemoved, prev, next, ChildrenChangeSourceA
PI}; |
| 572 childrenChanged(change); | 572 childrenChanged(change); |
| 573 notifyNodeRemoved(*child); | |
| 574 } | 573 } |
| 575 dispatchSubtreeModifiedEvent(); | 574 dispatchSubtreeModifiedEvent(); |
| 576 return child; | 575 return child; |
| 577 } | 576 } |
| 578 | 577 |
| 579 void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node& ol
dChild) | 578 void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node& ol
dChild) |
| 580 { | 579 { |
| 581 NoEventDispatchAssertion assertNoEventDispatch; | 580 NoEventDispatchAssertion assertNoEventDispatch; |
| 582 | 581 |
| 583 ASSERT(oldChild.parentNode() == this); | 582 ASSERT(oldChild.parentNode() == this); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 610 Node* next = oldChild.nextSibling(); | 609 Node* next = oldChild.nextSibling(); |
| 611 | 610 |
| 612 oldChild.updateAncestorConnectedSubframeCountForRemoval(); | 611 oldChild.updateAncestorConnectedSubframeCountForRemoval(); |
| 613 | 612 |
| 614 ChildListMutationScope(*this).willRemoveChild(oldChild); | 613 ChildListMutationScope(*this).willRemoveChild(oldChild); |
| 615 oldChild.notifyMutationObserversNodeWillDetach(); | 614 oldChild.notifyMutationObserversNodeWillDetach(); |
| 616 | 615 |
| 617 removeBetween(prev, next, oldChild); | 616 removeBetween(prev, next, oldChild); |
| 618 | 617 |
| 619 ChildrenChange change = {ChildRemoved, prev, next, ChildrenChangeSourceParse
r}; | 618 ChildrenChange change = {ChildRemoved, prev, next, ChildrenChangeSourceParse
r}; |
| 619 notifyNodeRemoved(oldChild); |
| 620 childrenChanged(change); | 620 childrenChanged(change); |
| 621 notifyNodeRemoved(oldChild); | |
| 622 } | 621 } |
| 623 | 622 |
| 624 // this differs from other remove functions because it forcibly removes all the
children, | 623 // this differs from other remove functions because it forcibly removes all the
children, |
| 625 // regardless of read-only status or event exceptions, e.g. | 624 // regardless of read-only status or event exceptions, e.g. |
| 626 void ContainerNode::removeChildren() | 625 void ContainerNode::removeChildren() |
| 627 { | 626 { |
| 628 if (!m_firstChild) | 627 if (!m_firstChild) |
| 629 return; | 628 return; |
| 630 | 629 |
| 631 // The container node can be removed from event handlers. | 630 // The container node can be removed from event handlers. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 646 // Exclude this node when looking for removed focusedElement since only | 645 // Exclude this node when looking for removed focusedElement since only |
| 647 // children will be removed. | 646 // children will be removed. |
| 648 // This must be later than willRemoveChildren, which might change focus | 647 // This must be later than willRemoveChildren, which might change focus |
| 649 // state of a child. | 648 // state of a child. |
| 650 document().removeFocusedElementOfSubtree(this, true); | 649 document().removeFocusedElementOfSubtree(this, true); |
| 651 | 650 |
| 652 // Removing a node from a selection can cause widget updates. | 651 // Removing a node from a selection can cause widget updates. |
| 653 document().nodeChildrenWillBeRemoved(*this); | 652 document().nodeChildrenWillBeRemoved(*this); |
| 654 } | 653 } |
| 655 | 654 |
| 656 | 655 // FIXME: Remove this NodeVector. Right now WebPluginContainerImpl::m_elemen
t is a |
| 656 // raw ptr which means the code below can drop the last ref to a plugin elem
ent and |
| 657 // then the code in UpdateSuspendScope::performDeferredWidgetTreeOperations
will |
| 658 // try to destroy the plugin which will be a use-after-free. We should use a
RefPtr |
| 659 // in the WebPluginContainerImpl instead. |
| 657 NodeVector removedChildren; | 660 NodeVector removedChildren; |
| 658 { | 661 { |
| 659 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; | 662 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; |
| 663 |
| 660 { | 664 { |
| 661 NoEventDispatchAssertion assertNoEventDispatch; | 665 NoEventDispatchAssertion assertNoEventDispatch; |
| 666 ScriptForbiddenScope forbidScript; |
| 667 |
| 662 removedChildren.reserveInitialCapacity(countChildren()); | 668 removedChildren.reserveInitialCapacity(countChildren()); |
| 663 while (m_firstChild) { | 669 |
| 664 removedChildren.append(m_firstChild); | 670 while (RefPtrWillBeRawPtr<Node> child = m_firstChild) { |
| 665 removeBetween(0, m_firstChild->nextSibling(), *m_firstChild); | 671 removeBetween(0, child->nextSibling(), *child); |
| 672 removedChildren.append(child.get()); |
| 673 notifyNodeRemoved(*child); |
| 666 } | 674 } |
| 667 } | 675 } |
| 668 | 676 |
| 669 ChildrenChange change = {AllChildrenRemoved, nullptr, nullptr, ChildrenC
hangeSourceAPI}; | 677 ChildrenChange change = {AllChildrenRemoved, nullptr, nullptr, ChildrenC
hangeSourceAPI}; |
| 670 childrenChanged(change); | 678 childrenChanged(change); |
| 671 | |
| 672 for (size_t i = 0; i < removedChildren.size(); ++i) | |
| 673 notifyNodeRemoved(*removedChildren[i]); | |
| 674 } | 679 } |
| 675 | 680 |
| 676 dispatchSubtreeModifiedEvent(); | 681 dispatchSubtreeModifiedEvent(); |
| 677 } | 682 } |
| 678 | 683 |
| 679 PassRefPtrWillBeRawPtr<Node> ContainerNode::appendChild(PassRefPtrWillBeRawPtr<N
ode> newChild, ExceptionState& exceptionState) | 684 PassRefPtrWillBeRawPtr<Node> ContainerNode::appendChild(PassRefPtrWillBeRawPtr<N
ode> newChild, ExceptionState& exceptionState) |
| 680 { | 685 { |
| 681 RefPtrWillBeRawPtr<ContainerNode> protect(this); | 686 RefPtrWillBeRawPtr<ContainerNode> protect(this); |
| 682 | 687 |
| 683 #if !ENABLE(OILPAN) | 688 #if !ENABLE(OILPAN) |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 741 return newChild; | 746 return newChild; |
| 742 } | 747 } |
| 743 | 748 |
| 744 void ContainerNode::parserAppendChild(PassRefPtrWillBeRawPtr<Node> newChild) | 749 void ContainerNode::parserAppendChild(PassRefPtrWillBeRawPtr<Node> newChild) |
| 745 { | 750 { |
| 746 ASSERT(newChild); | 751 ASSERT(newChild); |
| 747 ASSERT(!newChild->parentNode()); // Use appendChild if you need to handle re
parenting (and want DOM mutation events). | 752 ASSERT(!newChild->parentNode()); // Use appendChild if you need to handle re
parenting (and want DOM mutation events). |
| 748 ASSERT(!newChild->isDocumentFragment()); | 753 ASSERT(!newChild->isDocumentFragment()); |
| 749 ASSERT(!isHTMLTemplateElement(this)); | 754 ASSERT(!isHTMLTemplateElement(this)); |
| 750 | 755 |
| 756 RefPtrWillBeRawPtr<Node> protect(this); |
| 757 |
| 751 if (document() != newChild->document()) | 758 if (document() != newChild->document()) |
| 752 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION); | 759 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION); |
| 753 | 760 |
| 754 Node* last = m_lastChild; | |
| 755 | |
| 756 { | 761 { |
| 757 NoEventDispatchAssertion assertNoEventDispatch; | 762 NoEventDispatchAssertion assertNoEventDispatch; |
| 758 ScriptForbiddenScope forbidScript; | 763 ScriptForbiddenScope forbidScript; |
| 759 | 764 |
| 760 treeScope().adoptIfNeeded(*newChild); | 765 treeScope().adoptIfNeeded(*newChild); |
| 761 appendChildCommon(*newChild); | 766 appendChildCommon(*newChild); |
| 762 newChild->updateAncestorConnectedSubframeCountForInsertion(); | 767 newChild->updateAncestorConnectedSubframeCountForInsertion(); |
| 763 ChildListMutationScope(*this).childAdded(*newChild); | 768 ChildListMutationScope(*this).childAdded(*newChild); |
| 764 } | 769 } |
| 765 | 770 |
| 766 ChildrenChange change = {ChildInserted, last, nullptr, ChildrenChangeSourceP
arser}; | 771 notifyNodeInserted(*newChild, ChildrenChangeSourceParser); |
| 767 childrenChanged(change); | |
| 768 notifyNodeInserted(*newChild); | |
| 769 } | 772 } |
| 770 | 773 |
| 771 void ContainerNode::notifyNodeInserted(Node& root) | 774 void ContainerNode::notifyNodeInserted(Node& root, ChildrenChangeSource source) |
| 772 { | 775 { |
| 773 ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden()); | 776 ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden()); |
| 774 | 777 |
| 775 InspectorInstrumentation::didInsertDOMNode(&root); | 778 InspectorInstrumentation::didInsertDOMNode(&root); |
| 776 | 779 |
| 777 RefPtrWillBeRawPtr<Node> protect(this); | 780 RefPtrWillBeRawPtr<Node> protect(this); |
| 778 RefPtrWillBeRawPtr<Node> protectNode(root); | 781 RefPtrWillBeRawPtr<Node> protectNode(root); |
| 779 | 782 |
| 780 NodeVector postInsertionNotificationTargets; | 783 NodeVector postInsertionNotificationTargets; |
| 781 notifyNodeInsertedInternal(root, postInsertionNotificationTargets); | 784 notifyNodeInsertedInternal(root, postInsertionNotificationTargets); |
| 782 | 785 |
| 786 // ShadowRoots are not real children, we don't need to tell host that it's |
| 787 // children changed when one is added. |
| 788 // FIXME: We should have a separate code path for ShadowRoot since it only |
| 789 // needs to call insertedInto and the rest of this logic is not needed. |
| 790 if (!root.isShadowRoot()) { |
| 791 ChildrenChange change = {ChildInserted, root.previousSibling(), root.nex
tSibling(), source}; |
| 792 childrenChanged(change); |
| 793 } |
| 794 |
| 783 for (size_t i = 0; i < postInsertionNotificationTargets.size(); ++i) { | 795 for (size_t i = 0; i < postInsertionNotificationTargets.size(); ++i) { |
| 784 Node* targetNode = postInsertionNotificationTargets[i].get(); | 796 Node* targetNode = postInsertionNotificationTargets[i].get(); |
| 785 if (targetNode->inDocument()) | 797 if (targetNode->inDocument()) |
| 786 targetNode->didNotifySubtreeInsertionsToDocument(); | 798 targetNode->didNotifySubtreeInsertionsToDocument(); |
| 787 } | 799 } |
| 788 } | 800 } |
| 789 | 801 |
| 790 void ContainerNode::notifyNodeInsertedInternal(Node& root, NodeVector& postInser
tionNotificationTargets) | 802 void ContainerNode::notifyNodeInsertedInternal(Node& root, NodeVector& postInser
tionNotificationTargets) |
| 791 { | 803 { |
| 792 NoEventDispatchAssertion assertNoEventDispatch; | 804 NoEventDispatchAssertion assertNoEventDispatch; |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1184 | 1196 |
| 1185 void ContainerNode::updateTreeAfterInsertion(Node& child) | 1197 void ContainerNode::updateTreeAfterInsertion(Node& child) |
| 1186 { | 1198 { |
| 1187 #if !ENABLE(OILPAN) | 1199 #if !ENABLE(OILPAN) |
| 1188 ASSERT(refCount()); | 1200 ASSERT(refCount()); |
| 1189 ASSERT(child.refCount()); | 1201 ASSERT(child.refCount()); |
| 1190 #endif | 1202 #endif |
| 1191 | 1203 |
| 1192 ChildListMutationScope(*this).childAdded(child); | 1204 ChildListMutationScope(*this).childAdded(child); |
| 1193 | 1205 |
| 1194 ChildrenChange change = {ChildInserted, child.previousSibling(), child.nextS
ibling(), ChildrenChangeSourceAPI}; | |
| 1195 childrenChanged(change); | |
| 1196 | |
| 1197 notifyNodeInserted(child); | 1206 notifyNodeInserted(child); |
| 1198 | 1207 |
| 1199 dispatchChildInsertionEvents(child); | 1208 dispatchChildInsertionEvents(child); |
| 1200 } | 1209 } |
| 1201 | 1210 |
| 1202 bool ContainerNode::hasRestyleFlagInternal(DynamicRestyleFlags mask) const | 1211 bool ContainerNode::hasRestyleFlagInternal(DynamicRestyleFlags mask) const |
| 1203 { | 1212 { |
| 1204 return rareData()->hasRestyleFlag(mask); | 1213 return rareData()->hasRestyleFlag(mask); |
| 1205 } | 1214 } |
| 1206 | 1215 |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1387 return true; | 1396 return true; |
| 1388 | 1397 |
| 1389 if (node->isElementNode() && toElement(node)->shadow()) | 1398 if (node->isElementNode() && toElement(node)->shadow()) |
| 1390 return true; | 1399 return true; |
| 1391 | 1400 |
| 1392 return false; | 1401 return false; |
| 1393 } | 1402 } |
| 1394 #endif | 1403 #endif |
| 1395 | 1404 |
| 1396 } // namespace blink | 1405 } // namespace blink |
| OLD | NEW |