Home | History | Annotate | Download | only in dom
      1 /*
      2  * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org)
      3  *           (C) 1999 Antti Koivisto (koivisto (at) kde.org)
      4  *           (C) 2001 Dirk Mueller (mueller (at) kde.org)
      5  * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Apple Inc. All rights reserved.
      6  *
      7  * This library is free software; you can redistribute it and/or
      8  * modify it under the terms of the GNU Library General Public
      9  * License as published by the Free Software Foundation; either
     10  * version 2 of the License, or (at your option) any later version.
     11  *
     12  * This library is distributed in the hope that it will be useful,
     13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15  * Library General Public License for more details.
     16  *
     17  * You should have received a copy of the GNU Library General Public License
     18  * along with this library; see the file COPYING.LIB.  If not, write to
     19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     20  * Boston, MA 02110-1301, USA.
     21  *
     22  */
     23 
     24 #ifndef ContainerNode_h
     25 #define ContainerNode_h
     26 
     27 #include "Node.h"
     28 
     29 namespace WebCore {
     30 
     31 class FloatPoint;
     32 
     33 typedef void (*NodeCallback)(Node*);
     34 
     35 namespace Private {
     36     template<class GenericNode, class GenericNodeContainer>
     37     void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer* container);
     38 };
     39 
     40 class ContainerNode : public Node {
     41 public:
     42     virtual ~ContainerNode();
     43 
     44     Node* firstChild() const { return m_firstChild; }
     45     Node* lastChild() const { return m_lastChild; }
     46 
     47     bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&, bool shouldLazyAttach = false);
     48     bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&, bool shouldLazyAttach = false);
     49     bool removeChild(Node* child, ExceptionCode&);
     50     bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&, bool shouldLazyAttach = false);
     51 
     52     // These methods are only used during parsing.
     53     // They don't send DOM mutation events or handle reparenting.
     54     // However, arbitrary code may be run by beforeload handlers.
     55     void parserAddChild(PassRefPtr<Node>);
     56     void parserRemoveChild(Node*);
     57     void parserInsertBefore(PassRefPtr<Node> newChild, Node* refChild);
     58 
     59     bool hasChildNodes() const { return m_firstChild; }
     60     virtual void attach();
     61     virtual void detach();
     62     virtual void willRemove();
     63     virtual IntRect getRect() const;
     64     virtual void setFocus(bool = true);
     65     virtual void setActive(bool active = true, bool pause = false);
     66     virtual void setHovered(bool = true);
     67     unsigned childNodeCount() const;
     68     Node* childNode(unsigned index) const;
     69 
     70     virtual void insertedIntoDocument();
     71     virtual void removedFromDocument();
     72     virtual void insertedIntoTree(bool deep);
     73     virtual void removedFromTree(bool deep);
     74     virtual void childrenChanged(bool createdByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
     75 
     76     // FIXME: It's not good to have two functions with such similar names, especially public functions.
     77     // How do removeChildren and removeAllChildren differ?
     78     void removeChildren();
     79     void removeAllChildren();
     80     void takeAllChildrenFrom(ContainerNode*);
     81 
     82     void cloneChildNodes(ContainerNode* clone);
     83 
     84     bool dispatchBeforeLoadEvent(const String& sourceURL);
     85 
     86     static void queuePostAttachCallback(NodeCallback, Node*);
     87     static bool postAttachCallbacksAreSuspended();
     88 
     89 protected:
     90     ContainerNode(Document*, ConstructionType = CreateContainer);
     91 
     92     void suspendPostAttachCallbacks();
     93     void resumePostAttachCallbacks();
     94 
     95     template<class GenericNode, class GenericNodeContainer>
     96     friend void appendChildToContainer(GenericNode* child, GenericNodeContainer* container);
     97 
     98     template<class GenericNode, class GenericNodeContainer>
     99     friend void Private::addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer* container);
    100 
    101     void setFirstChild(Node* child) { m_firstChild = child; }
    102     void setLastChild(Node* child) { m_lastChild = child; }
    103 
    104 private:
    105     // Never call this function directly.  If you're trying to call this
    106     // function, your code is either wrong or you're supposed to call
    107     // parserAddChild.  Please do not call parserAddChild unless you are the
    108     // parser!
    109     virtual void deprecatedParserAddChild(PassRefPtr<Node>);
    110 
    111     void removeBetween(Node* previousChild, Node* nextChild, Node* oldChild);
    112     void insertBeforeCommon(Node* nextChild, Node* oldChild);
    113 
    114     static void dispatchPostAttachCallbacks();
    115 
    116     bool getUpperLeftCorner(FloatPoint&) const;
    117     bool getLowerRightCorner(FloatPoint&) const;
    118 
    119     Node* m_firstChild;
    120     Node* m_lastChild;
    121 };
    122 
    123 inline ContainerNode* toContainerNode(Node* node)
    124 {
    125     ASSERT(!node || node->isContainerNode());
    126     return static_cast<ContainerNode*>(node);
    127 }
    128 
    129 inline const ContainerNode* toContainerNode(const Node* node)
    130 {
    131     ASSERT(!node || node->isContainerNode());
    132     return static_cast<const ContainerNode*>(node);
    133 }
    134 
    135 // This will catch anyone doing an unnecessary cast.
    136 void toContainerNode(const ContainerNode*);
    137 
    138 inline ContainerNode::ContainerNode(Document* document, ConstructionType type)
    139     : Node(document, type)
    140     , m_firstChild(0)
    141     , m_lastChild(0)
    142 {
    143 }
    144 
    145 inline unsigned Node::childNodeCount() const
    146 {
    147     if (!isContainerNode())
    148         return 0;
    149     return toContainerNode(this)->childNodeCount();
    150 }
    151 
    152 inline Node* Node::childNode(unsigned index) const
    153 {
    154     if (!isContainerNode())
    155         return 0;
    156     return toContainerNode(this)->childNode(index);
    157 }
    158 
    159 inline Node* Node::firstChild() const
    160 {
    161     if (!isContainerNode())
    162         return 0;
    163     return toContainerNode(this)->firstChild();
    164 }
    165 
    166 inline Node* Node::lastChild() const
    167 {
    168     if (!isContainerNode())
    169         return 0;
    170     return toContainerNode(this)->lastChild();
    171 }
    172 
    173 } // namespace WebCore
    174 
    175 #endif // ContainerNode_h
    176