Home | History | Annotate | Download | only in svg
      1 /*
      2  * Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann (at) kde.org>
      3  * Copyright (C) 2011 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
      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 #ifndef SVGElementInstance_h
     22 #define SVGElementInstance_h
     23 
     24 #if ENABLE(SVG)
     25 #include "EventTarget.h"
     26 #include "SVGElement.h"
     27 #include "TreeShared.h"
     28 
     29 namespace WebCore {
     30 
     31 namespace Private {
     32 template<class GenericNode, class GenericNodeContainer>
     33 void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer* container);
     34 };
     35 
     36 class SVGUseElement;
     37 class SVGElementInstanceList;
     38 
     39 // SVGElementInstance mimics Node, but without providing all its functionality
     40 class SVGElementInstance : public TreeShared<SVGElementInstance>,
     41                            public EventTarget {
     42 public:
     43     static PassRefPtr<SVGElementInstance> create(SVGUseElement* correspondingUseElement, SVGUseElement* directUseElement, PassRefPtr<SVGElement> originalElement)
     44     {
     45         return adoptRef(new SVGElementInstance(correspondingUseElement, directUseElement, originalElement));
     46     }
     47 
     48     virtual ~SVGElementInstance();
     49 
     50     virtual ScriptExecutionContext* scriptExecutionContext() const;
     51 
     52     virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
     53     virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
     54     virtual void removeAllEventListeners();
     55     using EventTarget::dispatchEvent;
     56     virtual bool dispatchEvent(PassRefPtr<Event>);
     57 
     58     SVGElement* correspondingElement() const { return m_element.get(); }
     59     SVGUseElement* correspondingUseElement() const { return m_correspondingUseElement; }
     60     SVGUseElement* directUseElement() const { return m_directUseElement; }
     61     SVGElement* shadowTreeElement() const { return m_shadowTreeElement.get(); }
     62     void clearUseElements()
     63     {
     64         m_directUseElement = 0;
     65         m_correspondingUseElement = 0;
     66     }
     67 
     68     SVGElementInstance* parentNode() const { return parent(); }
     69     PassRefPtr<SVGElementInstanceList> childNodes();
     70 
     71     SVGElementInstance* previousSibling() const { return m_previousSibling; }
     72     SVGElementInstance* nextSibling() const { return m_nextSibling; }
     73 
     74     SVGElementInstance* firstChild() const { return m_firstChild; }
     75     SVGElementInstance* lastChild() const { return m_lastChild; }
     76 
     77     Document* ownerDocument() const { return m_element ? m_element->ownerDocument() : 0; }
     78 
     79     static void invalidateAllInstancesOfElement(SVGElement*);
     80 
     81     using TreeShared<SVGElementInstance>::ref;
     82     using TreeShared<SVGElementInstance>::deref;
     83 
     84     // EventTarget API
     85     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), abort);
     86     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), blur);
     87     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), change);
     88     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), click);
     89     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), contextmenu);
     90     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dblclick);
     91     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), error);
     92     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), focus);
     93     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), input);
     94     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keydown);
     95     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keypress);
     96     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keyup);
     97     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), load);
     98     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousedown);
     99     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousemove);
    100     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseout);
    101     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseover);
    102     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseup);
    103     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousewheel);
    104     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforecut);
    105     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), cut);
    106     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforecopy);
    107     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), copy);
    108     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforepaste);
    109     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), paste);
    110     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragenter);
    111     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragover);
    112     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragleave);
    113     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), drop);
    114     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragstart);
    115     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), drag);
    116     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragend);
    117     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), reset);
    118     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), resize);
    119     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), scroll);
    120     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), search);
    121     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), select);
    122     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), selectstart);
    123     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), submit);
    124     DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), unload);
    125 
    126 private:
    127     friend class SVGUseElement;
    128 
    129     SVGElementInstance(SVGUseElement*, SVGUseElement*, PassRefPtr<SVGElement> originalElement);
    130 
    131     virtual Node* toNode() { return shadowTreeElement(); }
    132     virtual SVGElementInstance* toSVGElementInstance() { return this; }
    133 
    134     void appendChild(PassRefPtr<SVGElementInstance> child);
    135     void setShadowTreeElement(SVGElement*);
    136 
    137     template<class GenericNode, class GenericNodeContainer>
    138     friend void appendChildToContainer(GenericNode* child, GenericNodeContainer* container);
    139 
    140     template<class GenericNode, class GenericNodeContainer>
    141     friend void removeAllChildrenInContainer(GenericNodeContainer* container);
    142 
    143     template<class GenericNode, class GenericNodeContainer>
    144     friend void Private::addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer* container);
    145 
    146     bool hasChildNodes() const { return m_firstChild; }
    147 
    148     void setFirstChild(SVGElementInstance* child) { m_firstChild = child; }
    149     void setLastChild(SVGElementInstance* child) { m_lastChild = child; }
    150 
    151     void setNextSibling(SVGElementInstance* sibling) { m_nextSibling = sibling; }
    152     void setPreviousSibling(SVGElementInstance* sibling) { m_previousSibling = sibling; }
    153 
    154     virtual void refEventTarget() { ref(); }
    155     virtual void derefEventTarget() { deref(); }
    156     virtual EventTargetData* eventTargetData();
    157     virtual EventTargetData* ensureEventTargetData();
    158 
    159     SVGUseElement* m_correspondingUseElement;
    160     SVGUseElement* m_directUseElement;
    161     RefPtr<SVGElement> m_element;
    162     RefPtr<SVGElement> m_shadowTreeElement;
    163 
    164     SVGElementInstance* m_previousSibling;
    165     SVGElementInstance* m_nextSibling;
    166 
    167     SVGElementInstance* m_firstChild;
    168     SVGElementInstance* m_lastChild;
    169 };
    170 
    171 } // namespace WebCore
    172 
    173 #endif // ENABLE(SVG)
    174 #endif
    175