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; |
662 removedChildren.reserveInitialCapacity(countChildren()); | 666 ScriptForbiddenScope forbidScript; |
663 while (m_firstChild) { | 667 |
664 removedChildren.append(m_firstChild); | 668 removedChildren.reserveInitialCapacity(childNodeCount()); |
665 removeBetween(0, m_firstChild->nextSibling(), *m_firstChild); | 669 |
670 while (RefPtrWillBeRawPtr<Node> child = 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); | |
adamk
2014/07/24 21:35:59
What's this about?
esprehn
2014/07/24 22:50:18
Nothing is protecting |this| in these parser metho
| |
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 | |
adamk
2014/07/24 21:35:59
Why are you changing this behavior in this patch?
esprehn
2014/07/24 22:50:18
I'm not changing any behavior, I moved childrenCha
| |
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 |