2008-11-04 Anders Carlsson <andersca@apple.com>
[webkit/qt.git] / WebCore / dom / ContainerNodeAlgorithms.h
blob55095a72e33ee741500e7f045e175b8104152ba2
1 /*
2 * Copyright (C) 2007 Apple Inc. All rights reserved.
3 * (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
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.
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.
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.
22 #ifndef ContainerNodeAlgorithms_h
23 #define ContainerNodeAlgorithms_h
25 #include <wtf/Assertions.h>
27 namespace WebCore {
29 class Node;
31 namespace Private {
33 template<class GenericNode, class GenericNodeContainer>
34 void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer* container);
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 void removeAllChildrenInContainer(GenericNodeContainer* container)
43 // List of nodes to be deleted.
44 GenericNode* head = 0;
45 GenericNode* tail = 0;
47 Private::addChildNodesToDeletionQueue<GenericNode, GenericNodeContainer>(head, tail, container);
49 GenericNode* n;
50 GenericNode* next;
51 while ((n = head) != 0) {
52 ASSERT(n->m_deletionHasBegun);
54 next = n->nextSibling();
55 n->setNextSibling(0);
57 head = next;
58 if (next == 0)
59 tail = 0;
61 if (n->hasChildNodes())
62 Private::addChildNodesToDeletionQueue<GenericNode, GenericNodeContainer>(head, tail, static_cast<GenericNodeContainer*>(n));
64 delete n;
68 template<class GenericNode, class GenericNodeContainer>
69 void appendChildToContainer(GenericNode* child, GenericNodeContainer* container)
71 child->setParent(container);
73 GenericNode* lastChild = container->lastChild();
74 if (lastChild) {
75 child->setPreviousSibling(lastChild);
76 lastChild->setNextSibling(child);
77 } else
78 container->setFirstChild(child);
80 container->setLastChild(child);
83 // Helper methods for removeAllChildrenInContainer, hidden from WebCore namespace
84 namespace Private {
86 template<class GenericNode, bool dispatchRemovalNotification>
87 struct NodeRemovalDispatcher {
88 static void dispatch(GenericNode*)
90 // no-op, by default
94 template<class GenericNode>
95 struct NodeRemovalDispatcher<GenericNode, true> {
96 static void dispatch(GenericNode* node)
98 if (node->inDocument())
99 node->removedFromDocument();
103 template<class GenericNode>
104 struct ShouldDispatchRemovalNotification {
105 static const bool value = false;
108 template<>
109 struct ShouldDispatchRemovalNotification<Node> {
110 static const bool value = true;
113 template<class GenericNode, class GenericNodeContainer>
114 void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer* container)
116 // We have to tell all children that their parent has died.
117 GenericNode* next = 0;
118 for (GenericNode* n = container->firstChild(); n != 0; n = next) {
119 ASSERT(!n->m_deletionHasBegun);
121 next = n->nextSibling();
122 n->setPreviousSibling(0);
123 n->setNextSibling(0);
124 n->setParent(0);
126 if (!n->refCount()) {
127 #ifndef NDEBUG
128 n->m_deletionHasBegun = true;
129 #endif
130 // Add the node to the list of nodes to be deleted.
131 // Reuse the nextSibling pointer for this purpose.
132 if (tail)
133 tail->setNextSibling(n);
134 else
135 head = n;
137 tail = n;
138 } else
139 NodeRemovalDispatcher<GenericNode, ShouldDispatchRemovalNotification<GenericNode>::value>::dispatch(n);
142 container->setFirstChild(0);
143 container->setLastChild(0);
147 } // namespace WebCore
149 #endif // ContainerNodeAlgorithms_h