| 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 Apple Inc. All rights reserv
ed. | 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. |
| 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 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 void ContainerNode::parserInsertBefore(PassRefPtrWillBeRawPtr<Node> newChild, No
de& nextChild) | 287 void ContainerNode::parserInsertBefore(PassRefPtrWillBeRawPtr<Node> newChild, No
de& nextChild) |
| 288 { | 288 { |
| 289 ASSERT(newChild); | 289 ASSERT(newChild); |
| 290 ASSERT(nextChild.parentNode() == this); | 290 ASSERT(nextChild.parentNode() == this); |
| 291 ASSERT(!newChild->isDocumentFragment()); | 291 ASSERT(!newChild->isDocumentFragment()); |
| 292 ASSERT(!isHTMLTemplateElement(this)); | 292 ASSERT(!isHTMLTemplateElement(this)); |
| 293 | 293 |
| 294 if (nextChild.previousSibling() == newChild || &nextChild == newChild) // no
thing to do | 294 if (nextChild.previousSibling() == newChild || &nextChild == newChild) // no
thing to do |
| 295 return; | 295 return; |
| 296 | 296 |
| 297 RefPtrWillBeRawPtr<Node> protect(this); |
| 298 |
| 297 if (document() != newChild->document()) | 299 if (document() != newChild->document()) |
| 298 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION); | 300 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION); |
| 299 | 301 |
| 300 insertBeforeCommon(nextChild, *newChild); | 302 insertBeforeCommon(nextChild, *newChild); |
| 301 | 303 |
| 302 newChild->updateAncestorConnectedSubframeCountForInsertion(); | 304 newChild->updateAncestorConnectedSubframeCountForInsertion(); |
| 303 | 305 |
| 304 ChildListMutationScope(*this).childAdded(*newChild); | 306 ChildListMutationScope(*this).childAdded(*newChild); |
| 305 | 307 |
| 306 childrenChanged(true, newChild->previousSibling(), &nextChild, 1); | 308 notifyNodeInserted(*newChild, ChildrenChangeSourceParser); |
| 307 | |
| 308 notifyNodeInserted(*newChild); | |
| 309 } | 309 } |
| 310 | 310 |
| 311 void ContainerNode::replaceChild(PassRefPtrWillBeRawPtr<Node> newChild, Node* ol
dChild, ExceptionState& exceptionState) | 311 void ContainerNode::replaceChild(PassRefPtrWillBeRawPtr<Node> newChild, Node* ol
dChild, ExceptionState& exceptionState) |
| 312 { | 312 { |
| 313 #if !ENABLE(OILPAN) | 313 #if !ENABLE(OILPAN) |
| 314 // Check that this node is not "floating". | 314 // Check that this node is not "floating". |
| 315 // If it is, it can be deleted as a side effect of sending mutation events. | 315 // If it is, it can be deleted as a side effect of sending mutation events. |
| 316 ASSERT(refCount() || parentOrShadowHostNode()); | 316 ASSERT(refCount() || parentOrShadowHostNode()); |
| 317 #endif | 317 #endif |
| 318 | 318 |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 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?"); | 475 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?"); |
| 476 return; | 476 return; |
| 477 } | 477 } |
| 478 | 478 |
| 479 { | 479 { |
| 480 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; | 480 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; |
| 481 | 481 |
| 482 Node* prev = child->previousSibling(); | 482 Node* prev = child->previousSibling(); |
| 483 Node* next = child->nextSibling(); | 483 Node* next = child->nextSibling(); |
| 484 removeBetween(prev, next, *child); | 484 removeBetween(prev, next, *child); |
| 485 notifyNodeRemoved(*child); |
| 485 childrenChanged(false, prev, next, -1); | 486 childrenChanged(false, prev, next, -1); |
| 486 notifyNodeRemoved(*child); | |
| 487 } | 487 } |
| 488 dispatchSubtreeModifiedEvent(); | 488 dispatchSubtreeModifiedEvent(); |
| 489 } | 489 } |
| 490 | 490 |
| 491 void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node& ol
dChild) | 491 void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node& ol
dChild) |
| 492 { | 492 { |
| 493 NoEventDispatchAssertion assertNoEventDispatch; | 493 NoEventDispatchAssertion assertNoEventDispatch; |
| 494 | 494 |
| 495 ASSERT(oldChild.parentNode() == this); | 495 ASSERT(oldChild.parentNode() == this); |
| 496 | 496 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 // Exclude this node when looking for removed focusedElement since only | 557 // Exclude this node when looking for removed focusedElement since only |
| 558 // children will be removed. | 558 // children will be removed. |
| 559 // This must be later than willRemoveChildren, which might change focus | 559 // This must be later than willRemoveChildren, which might change focus |
| 560 // state of a child. | 560 // state of a child. |
| 561 document().removeFocusedElementOfSubtree(this, true); | 561 document().removeFocusedElementOfSubtree(this, true); |
| 562 | 562 |
| 563 // Removing a node from a selection can cause widget updates. | 563 // Removing a node from a selection can cause widget updates. |
| 564 document().nodeChildrenWillBeRemoved(*this); | 564 document().nodeChildrenWillBeRemoved(*this); |
| 565 } | 565 } |
| 566 | 566 |
| 567 | 567 // FIXME: Remove this NodeVector. Right now WebPluginContainerImpl::m_elemen
t is a |
| 568 // raw ptr which means the code below can drop the last ref to a plugin elem
ent and |
| 569 // then the code in UpdateSuspendScope::performDeferredWidgetTreeOperations
will |
| 570 // try to destroy the plugin which will be a use-after-free. We should use a
RefPtr |
| 571 // in the WebPluginContainerImpl instead. |
| 568 NodeVector removedChildren; | 572 NodeVector removedChildren; |
| 569 { | 573 { |
| 570 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; | 574 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; |
| 575 |
| 571 { | 576 { |
| 572 NoEventDispatchAssertion assertNoEventDispatch; | 577 NoEventDispatchAssertion assertNoEventDispatch; |
| 578 ScriptForbiddenScope forbidScript; |
| 579 |
| 573 removedChildren.reserveInitialCapacity(countChildren()); | 580 removedChildren.reserveInitialCapacity(countChildren()); |
| 574 while (m_firstChild) { | 581 |
| 575 removedChildren.append(m_firstChild); | 582 while (RefPtrWillBeRawPtr<Node> child = m_firstChild) { |
| 576 removeBetween(0, m_firstChild->nextSibling(), *m_firstChild); | 583 removeBetween(0, child->nextSibling(), *child); |
| 584 removedChildren.append(child.get()); |
| 585 notifyNodeRemoved(*child); |
| 577 } | 586 } |
| 578 } | 587 } |
| 579 | 588 |
| 580 childrenChanged(false, 0, 0, -static_cast<int>(removedChildren.size())); | 589 childrenChanged(false, 0, 0, -static_cast<int>(removedChildren.size())); |
| 581 | |
| 582 for (size_t i = 0; i < removedChildren.size(); ++i) | |
| 583 notifyNodeRemoved(*removedChildren[i]); | |
| 584 } | 590 } |
| 585 | 591 |
| 586 dispatchSubtreeModifiedEvent(); | 592 dispatchSubtreeModifiedEvent(); |
| 587 } | 593 } |
| 588 | 594 |
| 589 void ContainerNode::appendChild(PassRefPtrWillBeRawPtr<Node> newChild, Exception
State& exceptionState) | 595 void ContainerNode::appendChild(PassRefPtrWillBeRawPtr<Node> newChild, Exception
State& exceptionState) |
| 590 { | 596 { |
| 591 RefPtrWillBeRawPtr<ContainerNode> protect(this); | 597 RefPtrWillBeRawPtr<ContainerNode> protect(this); |
| 592 | 598 |
| 593 #if !ENABLE(OILPAN) | 599 #if !ENABLE(OILPAN) |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 dispatchSubtreeModifiedEvent(); | 650 dispatchSubtreeModifiedEvent(); |
| 645 } | 651 } |
| 646 | 652 |
| 647 void ContainerNode::parserAppendChild(PassRefPtrWillBeRawPtr<Node> newChild) | 653 void ContainerNode::parserAppendChild(PassRefPtrWillBeRawPtr<Node> newChild) |
| 648 { | 654 { |
| 649 ASSERT(newChild); | 655 ASSERT(newChild); |
| 650 ASSERT(!newChild->parentNode()); // Use appendChild if you need to handle re
parenting (and want DOM mutation events). | 656 ASSERT(!newChild->parentNode()); // Use appendChild if you need to handle re
parenting (and want DOM mutation events). |
| 651 ASSERT(!newChild->isDocumentFragment()); | 657 ASSERT(!newChild->isDocumentFragment()); |
| 652 ASSERT(!isHTMLTemplateElement(this)); | 658 ASSERT(!isHTMLTemplateElement(this)); |
| 653 | 659 |
| 660 RefPtrWillBeRawPtr<Node> protect(this); |
| 661 |
| 654 if (document() != newChild->document()) | 662 if (document() != newChild->document()) |
| 655 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION); | 663 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION); |
| 656 | 664 |
| 657 Node* last = m_lastChild; | |
| 658 | |
| 659 { | 665 { |
| 660 NoEventDispatchAssertion assertNoEventDispatch; | 666 NoEventDispatchAssertion assertNoEventDispatch; |
| 661 ScriptForbiddenScope forbidScript; | 667 ScriptForbiddenScope forbidScript; |
| 662 | 668 |
| 663 treeScope().adoptIfNeeded(*newChild); | 669 treeScope().adoptIfNeeded(*newChild); |
| 664 appendChildCommon(*newChild); | 670 appendChildCommon(*newChild); |
| 665 newChild->updateAncestorConnectedSubframeCountForInsertion(); | 671 newChild->updateAncestorConnectedSubframeCountForInsertion(); |
| 666 ChildListMutationScope(*this).childAdded(*newChild); | 672 ChildListMutationScope(*this).childAdded(*newChild); |
| 667 } | 673 } |
| 668 | 674 |
| 669 childrenChanged(true, last, 0, 1); | 675 notifyNodeInserted(*newChild, ChildrenChangeSourceParser); |
| 670 notifyNodeInserted(*newChild); | |
| 671 } | 676 } |
| 672 | 677 |
| 673 void ContainerNode::notifyNodeInserted(Node& root) | 678 void ContainerNode::notifyNodeInserted(Node& root, ChildrenChangeSource source) |
| 674 { | 679 { |
| 675 ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden()); | 680 ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden()); |
| 676 | 681 |
| 677 InspectorInstrumentation::didInsertDOMNode(&root); | 682 InspectorInstrumentation::didInsertDOMNode(&root); |
| 678 | 683 |
| 679 RefPtrWillBeRawPtr<Node> protect(this); | 684 RefPtrWillBeRawPtr<Node> protect(this); |
| 680 RefPtrWillBeRawPtr<Node> protectNode(root); | 685 RefPtrWillBeRawPtr<Node> protectNode(root); |
| 681 | 686 |
| 682 NodeVector postInsertionNotificationTargets; | 687 NodeVector postInsertionNotificationTargets; |
| 683 notifyNodeInsertedInternal(root, postInsertionNotificationTargets); | 688 notifyNodeInsertedInternal(root, postInsertionNotificationTargets); |
| 684 | 689 |
| 690 // ShadowRoots are not real children, we don't need to tell host that it's |
| 691 // children changed when one is added. |
| 692 // FIXME: We should have a separate code path for ShadowRoot since it only |
| 693 // needs to call insertedInto and the rest of this logic is not needed. |
| 694 if (!root.isShadowRoot()) { |
| 695 childrenChanged(source == ChildrenChangeSourceParser, root.previousSibli
ng(), root.nextSibling(), 1); |
| 696 } |
| 697 |
| 685 for (size_t i = 0; i < postInsertionNotificationTargets.size(); ++i) { | 698 for (size_t i = 0; i < postInsertionNotificationTargets.size(); ++i) { |
| 686 Node* targetNode = postInsertionNotificationTargets[i].get(); | 699 Node* targetNode = postInsertionNotificationTargets[i].get(); |
| 687 if (targetNode->inDocument()) | 700 if (targetNode->inDocument()) |
| 688 targetNode->didNotifySubtreeInsertionsToDocument(); | 701 targetNode->didNotifySubtreeInsertionsToDocument(); |
| 689 } | 702 } |
| 690 } | 703 } |
| 691 | 704 |
| 692 void ContainerNode::notifyNodeInsertedInternal(Node& root, NodeVector& postInser
tionNotificationTargets) | 705 void ContainerNode::notifyNodeInsertedInternal(Node& root, NodeVector& postInser
tionNotificationTargets) |
| 693 { | 706 { |
| 694 NoEventDispatchAssertion assertNoEventDispatch; | 707 NoEventDispatchAssertion assertNoEventDispatch; |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1086 | 1099 |
| 1087 void ContainerNode::updateTreeAfterInsertion(Node& child) | 1100 void ContainerNode::updateTreeAfterInsertion(Node& child) |
| 1088 { | 1101 { |
| 1089 #if !ENABLE(OILPAN) | 1102 #if !ENABLE(OILPAN) |
| 1090 ASSERT(refCount()); | 1103 ASSERT(refCount()); |
| 1091 ASSERT(child.refCount()); | 1104 ASSERT(child.refCount()); |
| 1092 #endif | 1105 #endif |
| 1093 | 1106 |
| 1094 ChildListMutationScope(*this).childAdded(child); | 1107 ChildListMutationScope(*this).childAdded(child); |
| 1095 | 1108 |
| 1096 childrenChanged(false, child.previousSibling(), child.nextSibling(), 1); | |
| 1097 | |
| 1098 notifyNodeInserted(child); | 1109 notifyNodeInserted(child); |
| 1099 | 1110 |
| 1100 dispatchChildInsertionEvents(child); | 1111 dispatchChildInsertionEvents(child); |
| 1101 } | 1112 } |
| 1102 | 1113 |
| 1103 bool ContainerNode::hasRestyleFlagInternal(DynamicRestyleFlags mask) const | 1114 bool ContainerNode::hasRestyleFlagInternal(DynamicRestyleFlags mask) const |
| 1104 { | 1115 { |
| 1105 return rareData()->hasRestyleFlag(mask); | 1116 return rareData()->hasRestyleFlag(mask); |
| 1106 } | 1117 } |
| 1107 | 1118 |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1286 return true; | 1297 return true; |
| 1287 | 1298 |
| 1288 if (node->isElementNode() && toElement(node)->shadow()) | 1299 if (node->isElementNode() && toElement(node)->shadow()) |
| 1289 return true; | 1300 return true; |
| 1290 | 1301 |
| 1291 return false; | 1302 return false; |
| 1292 } | 1303 } |
| 1293 #endif | 1304 #endif |
| 1294 | 1305 |
| 1295 } // namespace WebCore | 1306 } // namespace WebCore |
| OLD | NEW |