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>
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
);
51 while ((n
= head
) != 0) {
52 ASSERT(n
->m_deletionHasBegun
);
54 next
= n
->nextSibling();
61 if (n
->hasChildNodes())
62 Private::addChildNodesToDeletionQueue
<GenericNode
, GenericNodeContainer
>(head
, tail
, static_cast<GenericNodeContainer
*>(n
));
68 template<class GenericNode
, class GenericNodeContainer
>
69 void appendChildToContainer(GenericNode
* child
, GenericNodeContainer
* container
)
71 child
->setParent(container
);
73 GenericNode
* lastChild
= container
->lastChild();
75 child
->setPreviousSibling(lastChild
);
76 lastChild
->setNextSibling(child
);
78 container
->setFirstChild(child
);
80 container
->setLastChild(child
);
83 // Helper methods for removeAllChildrenInContainer, hidden from WebCore namespace
86 template<class GenericNode
, bool dispatchRemovalNotification
>
87 struct NodeRemovalDispatcher
{
88 static void dispatch(GenericNode
*)
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;
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);
126 if (!n
->refCount()) {
128 n
->m_deletionHasBegun
= true;
130 // Add the node to the list of nodes to be deleted.
131 // Reuse the nextSibling pointer for this purpose.
133 tail
->setNextSibling(n
);
139 NodeRemovalDispatcher
<GenericNode
, ShouldDispatchRemovalNotification
<GenericNode
>::value
>::dispatch(n
);
142 container
->setFirstChild(0);
143 container
->setLastChild(0);
147 } // namespace WebCore
149 #endif // ContainerNodeAlgorithms_h