18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2007 Apple Inc. All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *           (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef ContainerNodeAlgorithms_h
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define ContainerNodeAlgorithms_h
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Assertions.h>
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectclass Node;
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace Private {
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    template<class GenericNode, class GenericNodeContainer>
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer* container);
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Helper functions for TreeShared-derived classes, which have a 'Node' style interface
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// This applies to 'ContainerNode' and 'SVGElementInstance'
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate<class GenericNode, class GenericNodeContainer>
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid removeAllChildrenInContainer(GenericNodeContainer* container)
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // List of nodes to be deleted.
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GenericNode* head = 0;
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GenericNode* tail = 0;
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Private::addChildNodesToDeletionQueue<GenericNode, GenericNodeContainer>(head, tail, container);
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GenericNode* n;
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GenericNode* next;
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while ((n = head) != 0) {
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(n->m_deletionHasBegun);
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        next = n->nextSibling();
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        n->setNextSibling(0);
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        head = next;
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (next == 0)
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            tail = 0;
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (n->hasChildNodes())
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Private::addChildNodesToDeletionQueue<GenericNode, GenericNodeContainer>(head, tail, static_cast<GenericNodeContainer*>(n));
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        delete n;
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate<class GenericNode, class GenericNodeContainer>
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid appendChildToContainer(GenericNode* child, GenericNodeContainer* container)
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    child->setParent(container);
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GenericNode* lastChild = container->lastChild();
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (lastChild) {
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child->setPreviousSibling(lastChild);
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        lastChild->setNextSibling(child);
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        container->setFirstChild(child);
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    container->setLastChild(child);
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Helper methods for removeAllChildrenInContainer, hidden from WebCore namespace
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace Private {
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    template<class GenericNode, bool dispatchRemovalNotification>
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    struct NodeRemovalDispatcher {
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        static void dispatch(GenericNode*)
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // no-op, by default
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    template<class GenericNode>
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    struct NodeRemovalDispatcher<GenericNode, true> {
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        static void dispatch(GenericNode* node)
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (node->inDocument())
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                node->removedFromDocument();
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    template<class GenericNode>
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    struct ShouldDispatchRemovalNotification {
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        static const bool value = false;
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    template<>
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    struct ShouldDispatchRemovalNotification<Node> {
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        static const bool value = true;
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    template<class GenericNode, class GenericNodeContainer>
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer* container)
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We have to tell all children that their parent has died.
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        GenericNode* next = 0;
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (GenericNode* n = container->firstChild(); n != 0; n = next) {
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(!n->m_deletionHasBegun);
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            next = n->nextSibling();
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            n->setPreviousSibling(0);
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            n->setNextSibling(0);
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            n->setParent(0);
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!n->refCount()) {
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                n->m_deletionHasBegun = true;
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Add the node to the list of nodes to be deleted.
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Reuse the nextSibling pointer for this purpose.
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (tail)
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    tail->setNextSibling(n);
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                else
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    head = n;
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                tail = n;
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                NodeRemovalDispatcher<GenericNode, ShouldDispatchRemovalNotification<GenericNode>::value>::dispatch(n);
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        container->setFirstChild(0);
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        container->setLastChild(0);
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif // ContainerNodeAlgorithms_h
150