Home | History | Annotate | Download | only in dom
      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