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 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 | 560 |
561 // Exclude this node when looking for the focused or full screen Node since | 561 // Exclude this node when looking for the focused or full screen Node since |
562 // only children will be removed. | 562 // only children will be removed. |
563 // FIXME: We should call these inside the loop below. Right now you can focu
s | 563 // FIXME: We should call these inside the loop below. Right now you can focu
s |
564 // a node with mutation events and it'll never get blured. | 564 // a node with mutation events and it'll never get blured. |
565 document()->removeFocusedNodeOfSubtree(this, true); | 565 document()->removeFocusedNodeOfSubtree(this, true); |
566 document()->removeFullScreenElementOfSubtree(this, true); | 566 document()->removeFullScreenElementOfSubtree(this, true); |
567 | 567 |
568 ChildListMutationScope mutation(this); | 568 ChildListMutationScope mutation(this); |
569 NodeVector removedChildren; | 569 NodeVector removedChildren; |
570 { | 570 while (RefPtr<Node> child = m_firstChild) { |
| 571 // Dispatch synchronous events like mutation and unload events. |
| 572 dispatchChildRemovalEvents(child.get()); |
| 573 ChildFrameDisconnector(child.get()).disconnect(); |
| 574 |
| 575 // FIXME: In theory this can fire focus events when the selection |
| 576 // changes, but there's no obvious way to test it. |
| 577 document()->nodeWillBeRemoved(child.get()); |
| 578 |
| 579 // If an event moved the child start over. |
| 580 if (child != m_firstChild) |
| 581 continue; |
| 582 |
| 583 // The widget tree must be updated between each removal so script |
| 584 // cannot run before the tree is in a consistent state. |
571 WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates; | 585 WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates; |
| 586 mutation.willRemoveChild(child.get()); |
| 587 child->notifyMutationObserversNodeWillDetach(); |
| 588 removeBetween(0, child->nextSibling(), child.get()); |
| 589 removedChildren.append(child.release()); |
| 590 } |
572 | 591 |
573 while (RefPtr<Node> child = m_firstChild) { | 592 // FIXME: We could avoid walking all the children twice by calling |
574 // Dispatch synchronous events like mutation and unload events. | 593 // notify inside the loop and childrenChanged after but that would mean |
575 dispatchChildRemovalEvents(child.get()); | 594 // calling childrenChanged in a different order than all other methods. |
576 ChildFrameDisconnector(child.get()).disconnect(); | 595 // Figure out if this is safe. |
577 | 596 childrenChanged(false, 0, 0, -static_cast<int>(removedChildren.size())); |
578 // FIXME: In theory this can fire focus events when the selection | 597 for (size_t i = 0; i < removedChildren.size(); ++i) |
579 // changes, but there's no obvious way to test it. | 598 ChildNodeRemovalNotifier(this).notify(removedChildren[i].get()); |
580 document()->nodeWillBeRemoved(child.get()); | |
581 | |
582 // If an event moved the child start over. | |
583 if (child != m_firstChild) | |
584 continue; | |
585 | |
586 mutation.willRemoveChild(child.get()); | |
587 child->notifyMutationObserversNodeWillDetach(); | |
588 removeBetween(0, child->nextSibling(), child.get()); | |
589 removedChildren.append(child.release()); | |
590 } | |
591 | |
592 // FIXME: We could avoid walking all the children twice by calling | |
593 // notify inside the loop and childrenChanged after but that would mean | |
594 // calling childrenChanged in a different order than all other methods. | |
595 // Figure out if this is safe. | |
596 childrenChanged(false, 0, 0, -static_cast<int>(removedChildren.size())); | |
597 for (size_t i = 0; i < removedChildren.size(); ++i) | |
598 ChildNodeRemovalNotifier(this).notify(removedChildren[i].get()); | |
599 } | |
600 | 599 |
601 dispatchSubtreeModifiedEvent(); | 600 dispatchSubtreeModifiedEvent(); |
602 } | 601 } |
603 | 602 |
604 bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, At
tachBehavior attachBehavior) | 603 bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, At
tachBehavior attachBehavior) |
605 { | 604 { |
606 RefPtr<ContainerNode> protect(this); | 605 RefPtr<ContainerNode> protect(this); |
607 | 606 |
608 // Check that this node is not "floating". | 607 // Check that this node is not "floating". |
609 // If it is, it can be deleted as a side effect of sending mutation events. | 608 // If it is, it can be deleted as a side effect of sending mutation events. |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
938 return true; | 937 return true; |
939 | 938 |
940 if (node->isElementNode() && toElement(node)->shadow()) | 939 if (node->isElementNode() && toElement(node)->shadow()) |
941 return true; | 940 return true; |
942 | 941 |
943 return false; | 942 return false; |
944 } | 943 } |
945 #endif | 944 #endif |
946 | 945 |
947 } // namespace WebCore | 946 } // namespace WebCore |
OLD | NEW |