1 /* 2 * Copyright (C) 2007 Apple Inc. All rights reserved. 3 * (C) 2008 Nikolas Zimmermann <zimmermann (at) kde.org> 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public License 16 * along with this library; see the file COPYING.LIB. If not, write to 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 * 20 */ 21 22 #ifndef ContainerNodeAlgorithms_h 23 #define ContainerNodeAlgorithms_h 24 25 #include "core/dom/Document.h" 26 #include "wtf/Assertions.h" 27 28 namespace WebCore { 29 30 namespace Private { 31 32 template<class GenericNode, class GenericNodeContainer> 33 void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer&); 34 35 } 36 37 #if !ENABLE(OILPAN) 38 // Helper functions for TreeShared-derived classes, which have a 'Node' style interface 39 // This applies to 'ContainerNode' and 'SVGElementInstance' 40 template<class GenericNode, class GenericNodeContainer> 41 inline void removeDetachedChildrenInContainer(GenericNodeContainer& container) 42 { 43 // List of nodes to be deleted. 44 GenericNode* head = 0; 45 GenericNode* tail = 0; 46 47 Private::addChildNodesToDeletionQueue<GenericNode, GenericNodeContainer>(head, tail, container); 48 49 GenericNode* n; 50 GenericNode* next; 51 while ((n = head) != 0) { 52 ASSERT_WITH_SECURITY_IMPLICATION(n->m_deletionHasBegun); 53 54 next = n->nextSibling(); 55 n->setNextSibling(0); 56 57 head = next; 58 if (next == 0) 59 tail = 0; 60 61 if (n->hasChildren()) 62 Private::addChildNodesToDeletionQueue<GenericNode, GenericNodeContainer>(head, tail, static_cast<GenericNodeContainer&>(*n)); 63 64 delete n; 65 } 66 } 67 #endif 68 69 // Helper methods for removeDetachedChildrenInContainer, hidden from WebCore namespace 70 namespace Private { 71 72 template<class GenericNode, class GenericNodeContainer> 73 void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer& container) 74 { 75 // We have to tell all children that their parent has died. 76 GenericNode* next = 0; 77 for (GenericNode* n = container.firstChild(); n; n = next) { 78 ASSERT_WITH_SECURITY_IMPLICATION(!n->m_deletionHasBegun); 79 80 next = n->nextSibling(); 81 n->setNextSibling(0); 82 n->setParentOrShadowHostNode(0); 83 container.setFirstChild(next); 84 if (next) 85 next->setPreviousSibling(0); 86 87 if (!n->refCount()) { 88 #if SECURITY_ASSERT_ENABLED 89 n->m_deletionHasBegun = true; 90 #endif 91 // Add the node to the list of nodes to be deleted. 92 // Reuse the nextSibling pointer for this purpose. 93 if (tail) 94 tail->setNextSibling(n); 95 else 96 head = n; 97 98 tail = n; 99 } else { 100 RefPtrWillBeRawPtr<GenericNode> protect(n); // removedFromDocument may remove all references to this node. 101 container.document().adoptIfNeeded(*n); 102 if (n->inDocument()) 103 container.notifyNodeRemoved(*n); 104 } 105 } 106 107 container.setLastChild(0); 108 } 109 110 } // namespace Private 111 112 } // namespace WebCore 113 114 #endif // ContainerNodeAlgorithms_h 115