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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 #include "core/rendering/RenderText.h" | 42 #include "core/rendering/RenderText.h" |
43 #include "core/rendering/RenderTheme.h" | 43 #include "core/rendering/RenderTheme.h" |
44 #include "core/rendering/RenderView.h" | 44 #include "core/rendering/RenderView.h" |
45 #include "core/rendering/RenderWidget.h" | 45 #include "core/rendering/RenderWidget.h" |
46 #include "wtf/Vector.h" | 46 #include "wtf/Vector.h" |
47 | 47 |
48 using namespace std; | 48 using namespace std; |
49 | 49 |
50 namespace WebCore { | 50 namespace WebCore { |
51 | 51 |
52 static void dispatchChildInsertionEvents(Node*); | 52 static void dispatchChildInsertionEvents(Node&); |
53 static void dispatchChildRemovalEvents(Node*); | 53 static void dispatchChildRemovalEvents(Node&); |
54 static void updateTreeAfterInsertion(ContainerNode&, Node&); | 54 static void updateTreeAfterInsertion(ContainerNode&, Node&); |
55 | 55 |
56 ChildNodesLazySnapshot* ChildNodesLazySnapshot::latestSnapshot = 0; | 56 ChildNodesLazySnapshot* ChildNodesLazySnapshot::latestSnapshot = 0; |
57 | 57 |
58 #ifndef NDEBUG | 58 #ifndef NDEBUG |
59 unsigned NoEventDispatchAssertion::s_count = 0; | 59 unsigned NoEventDispatchAssertion::s_count = 0; |
60 #endif | 60 #endif |
61 | 61 |
62 static const char appendChildMethodName[] = "appendChild"; | 62 static const char appendChildMethodName[] = "appendChild"; |
63 static const char insertBeforeMethodName[] = "insertBefore"; | 63 static const char insertBeforeMethodName[] = "insertBefore"; |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 return; | 227 return; |
228 if (targets.isEmpty()) | 228 if (targets.isEmpty()) |
229 return; | 229 return; |
230 | 230 |
231 // We need this extra check because collectChildrenAndRemoveFromOldParent()
can fire mutation events. | 231 // We need this extra check because collectChildrenAndRemoveFromOldParent()
can fire mutation events. |
232 if (!checkAcceptChildGuaranteedNodeTypes(this, newChild.get(), insertBeforeM
ethodName, es)) | 232 if (!checkAcceptChildGuaranteedNodeTypes(this, newChild.get(), insertBeforeM
ethodName, es)) |
233 return; | 233 return; |
234 | 234 |
235 InspectorInstrumentation::willInsertDOMNode(this); | 235 InspectorInstrumentation::willInsertDOMNode(this); |
236 | 236 |
237 ChildListMutationScope mutation(this); | 237 ChildListMutationScope mutation(*this); |
238 for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); +
+it) { | 238 for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); +
+it) { |
239 ASSERT(*it); | 239 ASSERT(*it); |
240 Node& child = **it; | 240 Node& child = **it; |
241 | 241 |
242 // Due to arbitrary code running in response to a DOM mutation event it'
s | 242 // Due to arbitrary code running in response to a DOM mutation event it'
s |
243 // possible that "next" is no longer a child of "this". | 243 // possible that "next" is no longer a child of "this". |
244 // It's also possible that "child" has been inserted elsewhere. | 244 // It's also possible that "child" has been inserted elsewhere. |
245 // In either of those cases, we'll just stop. | 245 // In either of those cases, we'll just stop. |
246 if (next->parentNode() != this) | 246 if (next->parentNode() != this) |
247 break; | 247 break; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 if (document() != newChild->document()) | 297 if (document() != newChild->document()) |
298 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION); | 298 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION); |
299 | 299 |
300 insertBeforeCommon(*nextChild, *newChild); | 300 insertBeforeCommon(*nextChild, *newChild); |
301 | 301 |
302 newChild->updateAncestorConnectedSubframeCountForInsertion(); | 302 newChild->updateAncestorConnectedSubframeCountForInsertion(); |
303 | 303 |
304 ChildListMutationScope(this).childAdded(newChild.get()); | 304 ChildListMutationScope(*this).childAdded(*newChild); |
305 | 305 |
306 childrenChanged(true, newChild->previousSibling(), nextChild, 1); | 306 childrenChanged(true, newChild->previousSibling(), nextChild, 1); |
307 | 307 |
308 ChildNodeInsertionNotifier(*this).notify(*newChild); | 308 ChildNodeInsertionNotifier(*this).notify(*newChild); |
309 } | 309 } |
310 | 310 |
311 void ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce
ptionState& es) | 311 void ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce
ptionState& es) |
312 { | 312 { |
313 // Check that this node is not "floating". | 313 // Check that this node is not "floating". |
314 // If it is, it can be deleted as a side effect of sending mutation events. | 314 // If it is, it can be deleted as a side effect of sending mutation events. |
(...skipping 12 matching lines...) Expand all Loading... |
327 // Make sure replacing the old child with the new is ok | 327 // Make sure replacing the old child with the new is ok |
328 if (!checkReplaceChild(this, newChild.get(), oldChild, replaceChildMethodNam
e, es)) | 328 if (!checkReplaceChild(this, newChild.get(), oldChild, replaceChildMethodNam
e, es)) |
329 return; | 329 return; |
330 | 330 |
331 // NotFoundError: Raised if oldChild is not a child of this node. | 331 // NotFoundError: Raised if oldChild is not a child of this node. |
332 if (oldChild->parentNode() != this) { | 332 if (oldChild->parentNode() != this) { |
333 es.throwDOMException(NotFoundError, ExceptionMessages::failedToExecute(r
eplaceChildMethodName, "Node", "The node to be replaced is not a child of this n
ode.")); | 333 es.throwDOMException(NotFoundError, ExceptionMessages::failedToExecute(r
eplaceChildMethodName, "Node", "The node to be replaced is not a child of this n
ode.")); |
334 return; | 334 return; |
335 } | 335 } |
336 | 336 |
337 ChildListMutationScope mutation(this); | 337 ChildListMutationScope mutation(*this); |
338 | 338 |
339 RefPtr<Node> next = oldChild->nextSibling(); | 339 RefPtr<Node> next = oldChild->nextSibling(); |
340 | 340 |
341 // Remove the node we're replacing | 341 // Remove the node we're replacing |
342 RefPtr<Node> removedChild = oldChild; | 342 RefPtr<Node> removedChild = oldChild; |
343 removeChild(oldChild, es); | 343 removeChild(oldChild, es); |
344 if (es.hadException()) | 344 if (es.hadException()) |
345 return; | 345 return; |
346 | 346 |
347 if (next && (next->previousSibling() == newChild || next == newChild)) // no
thing to do | 347 if (next && (next->previousSibling() == newChild || next == newChild)) // no
thing to do |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 else | 386 else |
387 appendChildToContainer(child, *this); | 387 appendChildToContainer(child, *this); |
388 } | 388 } |
389 | 389 |
390 updateTreeAfterInsertion(*this, child); | 390 updateTreeAfterInsertion(*this, child); |
391 } | 391 } |
392 | 392 |
393 dispatchSubtreeModifiedEvent(); | 393 dispatchSubtreeModifiedEvent(); |
394 } | 394 } |
395 | 395 |
396 static void willRemoveChild(Node* child) | 396 static void willRemoveChild(Node& child) |
397 { | 397 { |
398 ASSERT(child->parentNode()); | 398 ASSERT(child.parentNode()); |
399 ChildListMutationScope(child->parentNode()).willRemoveChild(child); | 399 ChildListMutationScope(*child.parentNode()).willRemoveChild(child); |
400 child->notifyMutationObserversNodeWillDetach(); | 400 child.notifyMutationObserversNodeWillDetach(); |
401 dispatchChildRemovalEvents(child); | 401 dispatchChildRemovalEvents(child); |
402 child->document().nodeWillBeRemoved(child); // e.g. mutation event listener
can create a new range. | 402 child.document().nodeWillBeRemoved(&child); // e.g. mutation event listener
can create a new range. |
403 ChildFrameDisconnector(child).disconnect(); | 403 ChildFrameDisconnector(child).disconnect(); |
404 } | 404 } |
405 | 405 |
406 static void willRemoveChildren(ContainerNode* container) | 406 static void willRemoveChildren(ContainerNode& container) |
407 { | 407 { |
408 NodeVector children; | 408 NodeVector children; |
409 getChildNodes(container, children); | 409 getChildNodes(&container, children); |
410 | 410 |
411 ChildListMutationScope mutation(container); | 411 ChildListMutationScope mutation(container); |
412 for (NodeVector::const_iterator it = children.begin(); it != children.end();
it++) { | 412 for (NodeVector::const_iterator it = children.begin(); it != children.end();
it++) { |
413 Node* child = it->get(); | 413 ASSERT(*it); |
| 414 Node& child = **it; |
414 mutation.willRemoveChild(child); | 415 mutation.willRemoveChild(child); |
415 child->notifyMutationObserversNodeWillDetach(); | 416 child.notifyMutationObserversNodeWillDetach(); |
416 | 417 |
417 // fire removed from document mutation events. | 418 // fire removed from document mutation events. |
418 dispatchChildRemovalEvents(child); | 419 dispatchChildRemovalEvents(child); |
419 } | 420 } |
420 | 421 |
421 ChildFrameDisconnector(container).disconnect(ChildFrameDisconnector::Descend
antsOnly); | 422 ChildFrameDisconnector(container).disconnect(ChildFrameDisconnector::Descend
antsOnly); |
422 } | 423 } |
423 | 424 |
424 void ContainerNode::disconnectDescendantFrames() | 425 void ContainerNode::disconnectDescendantFrames() |
425 { | 426 { |
426 ChildFrameDisconnector(this).disconnect(); | 427 ChildFrameDisconnector(*this).disconnect(); |
427 } | 428 } |
428 | 429 |
429 void ContainerNode::removeChild(Node* oldChild, ExceptionState& es) | 430 void ContainerNode::removeChild(Node* oldChild, ExceptionState& es) |
430 { | 431 { |
431 // Check that this node is not "floating". | 432 // Check that this node is not "floating". |
432 // If it is, it can be deleted as a side effect of sending mutation events. | 433 // If it is, it can be deleted as a side effect of sending mutation events. |
433 ASSERT(refCount() || parentOrShadowHostNode()); | 434 ASSERT(refCount() || parentOrShadowHostNode()); |
434 | 435 |
435 RefPtr<Node> protect(this); | 436 RefPtr<Node> protect(this); |
436 | 437 |
(...skipping 10 matching lines...) Expand all Loading... |
447 if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExist
s(&document())) | 448 if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExist
s(&document())) |
448 fullscreen->removeFullScreenElementOfSubtree(child.get()); | 449 fullscreen->removeFullScreenElementOfSubtree(child.get()); |
449 | 450 |
450 // Events fired when blurring currently focused node might have moved this | 451 // Events fired when blurring currently focused node might have moved this |
451 // child into a different parent. | 452 // child into a different parent. |
452 if (child->parentNode() != this) { | 453 if (child->parentNode() != this) { |
453 es.throwDOMException(NotFoundError, ExceptionMessages::failedToExecute("
removeChild", "Node", "The node to be removed is no longer a child of this node.
Perhaps it was moved in a 'blur' event handler?")); | 454 es.throwDOMException(NotFoundError, ExceptionMessages::failedToExecute("
removeChild", "Node", "The node to be removed is no longer a child of this node.
Perhaps it was moved in a 'blur' event handler?")); |
454 return; | 455 return; |
455 } | 456 } |
456 | 457 |
457 willRemoveChild(child.get()); | 458 willRemoveChild(*child); |
458 | 459 |
459 // Mutation events might have moved this child into a different parent. | 460 // Mutation events might have moved this child into a different parent. |
460 if (child->parentNode() != this) { | 461 if (child->parentNode() != this) { |
461 es.throwDOMException(NotFoundError, ExceptionMessages::failedToExecute("
removeChild", "Node", "The node to be removed is no longer a child of this node.
Perhaps it was moved in response to a mutation?")); | 462 es.throwDOMException(NotFoundError, ExceptionMessages::failedToExecute("
removeChild", "Node", "The node to be removed is no longer a child of this node.
Perhaps it was moved in response to a mutation?")); |
462 return; | 463 return; |
463 } | 464 } |
464 | 465 |
465 { | 466 { |
466 RenderWidget::UpdateSuspendScope suspendWidgetHierarchyUpdates; | 467 RenderWidget::UpdateSuspendScope suspendWidgetHierarchyUpdates; |
467 | 468 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 void ContainerNode::parserRemoveChild(Node& oldChild) | 504 void ContainerNode::parserRemoveChild(Node& oldChild) |
504 { | 505 { |
505 ASSERT(oldChild.parentNode() == this); | 506 ASSERT(oldChild.parentNode() == this); |
506 ASSERT(!oldChild.isDocumentFragment()); | 507 ASSERT(!oldChild.isDocumentFragment()); |
507 | 508 |
508 Node* prev = oldChild.previousSibling(); | 509 Node* prev = oldChild.previousSibling(); |
509 Node* next = oldChild.nextSibling(); | 510 Node* next = oldChild.nextSibling(); |
510 | 511 |
511 oldChild.updateAncestorConnectedSubframeCountForRemoval(); | 512 oldChild.updateAncestorConnectedSubframeCountForRemoval(); |
512 | 513 |
513 ChildListMutationScope(this).willRemoveChild(&oldChild); | 514 ChildListMutationScope(*this).willRemoveChild(oldChild); |
514 oldChild.notifyMutationObserversNodeWillDetach(); | 515 oldChild.notifyMutationObserversNodeWillDetach(); |
515 | 516 |
516 removeBetween(prev, next, oldChild); | 517 removeBetween(prev, next, oldChild); |
517 | 518 |
518 childrenChanged(true, prev, next, -1); | 519 childrenChanged(true, prev, next, -1); |
519 ChildNodeRemovalNotifier(*this).notify(oldChild); | 520 ChildNodeRemovalNotifier(*this).notify(oldChild); |
520 } | 521 } |
521 | 522 |
522 // this differs from other remove functions because it forcibly removes all the
children, | 523 // this differs from other remove functions because it forcibly removes all the
children, |
523 // regardless of read-only status or event exceptions, e.g. | 524 // regardless of read-only status or event exceptions, e.g. |
524 void ContainerNode::removeChildren() | 525 void ContainerNode::removeChildren() |
525 { | 526 { |
526 if (!m_firstChild) | 527 if (!m_firstChild) |
527 return; | 528 return; |
528 | 529 |
529 // The container node can be removed from event handlers. | 530 // The container node can be removed from event handlers. |
530 RefPtr<ContainerNode> protect(this); | 531 RefPtr<ContainerNode> protect(this); |
531 | 532 |
532 if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExist
s(&document())) | 533 if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExist
s(&document())) |
533 fullscreen->removeFullScreenElementOfSubtree(this, true); | 534 fullscreen->removeFullScreenElementOfSubtree(this, true); |
534 | 535 |
535 // Do any prep work needed before actually starting to detach | 536 // Do any prep work needed before actually starting to detach |
536 // and remove... e.g. stop loading frames, fire unload events. | 537 // and remove... e.g. stop loading frames, fire unload events. |
537 willRemoveChildren(protect.get()); | 538 willRemoveChildren(*this); |
538 | 539 |
539 { | 540 { |
540 // Removing focus can cause frames to load, either via events (focusout,
blur) | 541 // Removing focus can cause frames to load, either via events (focusout,
blur) |
541 // or widget updates (e.g., for <embed>). | 542 // or widget updates (e.g., for <embed>). |
542 SubframeLoadingDisabler disabler(this); | 543 SubframeLoadingDisabler disabler(this); |
543 | 544 |
544 // Exclude this node when looking for removed focusedElement since only | 545 // Exclude this node when looking for removed focusedElement since only |
545 // children will be removed. | 546 // children will be removed. |
546 // This must be later than willRemoveChildren, which might change focus | 547 // This must be later than willRemoveChildren, which might change focus |
547 // state of a child. | 548 // state of a child. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 if (targets.isEmpty()) | 595 if (targets.isEmpty()) |
595 return; | 596 return; |
596 | 597 |
597 // We need this extra check because collectChildrenAndRemoveFromOldParent()
can fire mutation events. | 598 // We need this extra check because collectChildrenAndRemoveFromOldParent()
can fire mutation events. |
598 if (!checkAcceptChildGuaranteedNodeTypes(this, newChild.get(), appendChildMe
thodName, es)) | 599 if (!checkAcceptChildGuaranteedNodeTypes(this, newChild.get(), appendChildMe
thodName, es)) |
599 return; | 600 return; |
600 | 601 |
601 InspectorInstrumentation::willInsertDOMNode(this); | 602 InspectorInstrumentation::willInsertDOMNode(this); |
602 | 603 |
603 // Now actually add the child(ren) | 604 // Now actually add the child(ren) |
604 ChildListMutationScope mutation(this); | 605 ChildListMutationScope mutation(*this); |
605 for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); +
+it) { | 606 for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); +
+it) { |
606 ASSERT(*it); | 607 ASSERT(*it); |
607 Node& child = **it; | 608 Node& child = **it; |
608 | 609 |
609 // If the child has a parent again, just stop what we're doing, because | 610 // If the child has a parent again, just stop what we're doing, because |
610 // that means someone is doing something with DOM mutation -- can't re-p
arent | 611 // that means someone is doing something with DOM mutation -- can't re-p
arent |
611 // a child that already has a parent. | 612 // a child that already has a parent. |
612 if (child.parentNode()) | 613 if (child.parentNode()) |
613 break; | 614 break; |
614 | 615 |
(...skipping 24 matching lines...) Expand all Loading... |
639 Node* last = m_lastChild; | 640 Node* last = m_lastChild; |
640 { | 641 { |
641 NoEventDispatchAssertion assertNoEventDispatch; | 642 NoEventDispatchAssertion assertNoEventDispatch; |
642 // FIXME: This method should take a PassRefPtr. | 643 // FIXME: This method should take a PassRefPtr. |
643 appendChildToContainer(*newChild, *this); | 644 appendChildToContainer(*newChild, *this); |
644 treeScope().adoptIfNeeded(*newChild); | 645 treeScope().adoptIfNeeded(*newChild); |
645 } | 646 } |
646 | 647 |
647 newChild->updateAncestorConnectedSubframeCountForInsertion(); | 648 newChild->updateAncestorConnectedSubframeCountForInsertion(); |
648 | 649 |
649 ChildListMutationScope(this).childAdded(newChild.get()); | 650 ChildListMutationScope(*this).childAdded(*newChild); |
650 | 651 |
651 childrenChanged(true, last, 0, 1); | 652 childrenChanged(true, last, 0, 1); |
652 ChildNodeInsertionNotifier(*this).notify(*newChild); | 653 ChildNodeInsertionNotifier(*this).notify(*newChild); |
653 } | 654 } |
654 | 655 |
655 void ContainerNode::attach(const AttachContext& context) | 656 void ContainerNode::attach(const AttachContext& context) |
656 { | 657 { |
657 attachChildren(context); | 658 attachChildren(context); |
658 clearChildNeedsStyleRecalc(); | 659 clearChildNeedsStyleRecalc(); |
659 Node::attach(context); | 660 Node::attach(context); |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
909 | 910 |
910 Node *ContainerNode::childNode(unsigned index) const | 911 Node *ContainerNode::childNode(unsigned index) const |
911 { | 912 { |
912 unsigned i; | 913 unsigned i; |
913 Node *n = firstChild(); | 914 Node *n = firstChild(); |
914 for (i = 0; n != 0 && i < index; i++) | 915 for (i = 0; n != 0 && i < index; i++) |
915 n = n->nextSibling(); | 916 n = n->nextSibling(); |
916 return n; | 917 return n; |
917 } | 918 } |
918 | 919 |
919 static void dispatchChildInsertionEvents(Node* child) | 920 static void dispatchChildInsertionEvents(Node& child) |
920 { | 921 { |
921 if (child->isInShadowTree()) | 922 if (child.isInShadowTree()) |
922 return; | 923 return; |
923 | 924 |
924 ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden()); | 925 ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden()); |
925 | 926 |
926 RefPtr<Node> c = child; | 927 RefPtr<Node> c(child); |
927 RefPtr<Document> document(child->document()); | 928 RefPtr<Document> document(child.document()); |
928 | 929 |
929 if (c->parentNode() && document->hasListenerType(Document::DOMNODEINSERTED_L
ISTENER)) | 930 if (c->parentNode() && document->hasListenerType(Document::DOMNODEINSERTED_L
ISTENER)) |
930 c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNodeInse
rted, true, c->parentNode())); | 931 c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNodeInse
rted, true, c->parentNode())); |
931 | 932 |
932 // dispatch the DOMNodeInsertedIntoDocument event to all descendants | 933 // dispatch the DOMNodeInsertedIntoDocument event to all descendants |
933 if (c->inDocument() && document->hasListenerType(Document::DOMNODEINSERTEDIN
TODOCUMENT_LISTENER)) { | 934 if (c->inDocument() && document->hasListenerType(Document::DOMNODEINSERTEDIN
TODOCUMENT_LISTENER)) { |
934 for (; c; c = NodeTraversal::next(c.get(), child)) | 935 for (; c; c = NodeTraversal::next(c.get(), &child)) |
935 c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNode
InsertedIntoDocument, false)); | 936 c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNode
InsertedIntoDocument, false)); |
936 } | 937 } |
937 } | 938 } |
938 | 939 |
939 static void dispatchChildRemovalEvents(Node* child) | 940 static void dispatchChildRemovalEvents(Node& child) |
940 { | 941 { |
941 if (child->isInShadowTree()) { | 942 if (child.isInShadowTree()) { |
942 InspectorInstrumentation::willRemoveDOMNode(child); | 943 InspectorInstrumentation::willRemoveDOMNode(&child); |
943 return; | 944 return; |
944 } | 945 } |
945 | 946 |
946 ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden()); | 947 ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden()); |
947 | 948 |
948 InspectorInstrumentation::willRemoveDOMNode(child); | 949 InspectorInstrumentation::willRemoveDOMNode(&child); |
949 | 950 |
950 RefPtr<Node> c = child; | 951 RefPtr<Node> c(child); |
951 RefPtr<Document> document(child->document()); | 952 RefPtr<Document> document(child.document()); |
952 | 953 |
953 // dispatch pre-removal mutation events | 954 // dispatch pre-removal mutation events |
954 if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LI
STENER)) { | 955 if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LI
STENER)) { |
955 NodeChildRemovalTracker scope(child); | 956 NodeChildRemovalTracker scope(&child); |
956 c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNodeRemo
ved, true, c->parentNode())); | 957 c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNodeRemo
ved, true, c->parentNode())); |
957 } | 958 } |
958 | 959 |
959 // dispatch the DOMNodeRemovedFromDocument event to all descendants | 960 // dispatch the DOMNodeRemovedFromDocument event to all descendants |
960 if (c->inDocument() && document->hasListenerType(Document::DOMNODEREMOVEDFRO
MDOCUMENT_LISTENER)) { | 961 if (c->inDocument() && document->hasListenerType(Document::DOMNODEREMOVEDFRO
MDOCUMENT_LISTENER)) { |
961 NodeChildRemovalTracker scope(child); | 962 NodeChildRemovalTracker scope(&child); |
962 for (; c; c = NodeTraversal::next(c.get(), child)) | 963 for (; c; c = NodeTraversal::next(c.get(), &child)) |
963 c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNode
RemovedFromDocument, false)); | 964 c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNode
RemovedFromDocument, false)); |
964 } | 965 } |
965 } | 966 } |
966 | 967 |
967 static void updateTreeAfterInsertion(ContainerNode& parent, Node& child) | 968 static void updateTreeAfterInsertion(ContainerNode& parent, Node& child) |
968 { | 969 { |
969 ASSERT(parent.refCount()); | 970 ASSERT(parent.refCount()); |
970 ASSERT(child.refCount()); | 971 ASSERT(child.refCount()); |
971 | 972 |
972 ChildListMutationScope(&parent).childAdded(&child); | 973 ChildListMutationScope(parent).childAdded(child); |
973 | 974 |
974 parent.childrenChanged(false, child.previousSibling(), child.nextSibling(),
1); | 975 parent.childrenChanged(false, child.previousSibling(), child.nextSibling(),
1); |
975 | 976 |
976 ChildNodeInsertionNotifier(parent).notify(child); | 977 ChildNodeInsertionNotifier(parent).notify(child); |
977 | 978 |
978 dispatchChildInsertionEvents(&child); | 979 dispatchChildInsertionEvents(child); |
979 } | 980 } |
980 | 981 |
981 #ifndef NDEBUG | 982 #ifndef NDEBUG |
982 bool childAttachedAllowedWhenAttachingChildren(ContainerNode* node) | 983 bool childAttachedAllowedWhenAttachingChildren(ContainerNode* node) |
983 { | 984 { |
984 if (node->isShadowRoot()) | 985 if (node->isShadowRoot()) |
985 return true; | 986 return true; |
986 | 987 |
987 if (node->isInsertionPoint()) | 988 if (node->isInsertionPoint()) |
988 return true; | 989 return true; |
989 | 990 |
990 if (node->isElementNode() && toElement(node)->shadow()) | 991 if (node->isElementNode() && toElement(node)->shadow()) |
991 return true; | 992 return true; |
992 | 993 |
993 return false; | 994 return false; |
994 } | 995 } |
995 #endif | 996 #endif |
996 | 997 |
997 } // namespace WebCore | 998 } // namespace WebCore |
OLD | NEW |