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 #include "bindings/v8/ScriptWrappable.h"
     25 #include "core/dom/EventTarget.h"
     26 #include "core/platform/TreeShared.h"
     27 
     28 namespace WebCore {
     29 
     30 namespace Private {
     31 template<class GenericNode, class GenericNodeContainer>
     32 void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer* container);
     33 };
     34 
     35 class Document;
     36 class SVGElement;
     37 class SVGElementInstanceList;
     38 class SVGUseElement;
     39 
     40 // SVGElementInstance mimics Node, but without providing all its functionality
     41 class SVGElementInstance : public EventTarget, public ScriptWrappable, public TreeShared<SVGElementInstance> {
     42 public:
     43     static PassRefPtr<SVGElementInstance> create(SVGUseElement* correspondingUseElement, SVGUseElement* directUseElement, PassRefPtr<SVGElement> originalElement);
     44 
     45     virtual ~SVGElementInstance();
     46 
     47     void setParentOrShadowHostNode(SVGElementInstance* instance) { m_parentInstance = instance; }
     48 
     49     virtual const AtomicString& interfaceName() const;
     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 
     56     using EventTarget::dispatchEvent;
     57     virtual bool dispatchEvent(PassRefPtr<Event>) OVERRIDE;
     58 
     59     SVGElement* correspondingElement() const { return m_element.get(); }
     60     SVGUseElement* correspondingUseElement() const { return m_correspondingUseElement; }
     61     SVGUseElement* directUseElement() const { return m_directUseElement; }
     62     SVGElement* shadowTreeElement() const { return m_shadowTreeElement.get(); }
     63 
     64     void detach();
     65 
     66     SVGElementInstance* parentNode() const { return m_parentInstance; }
     67     PassRefPtr<SVGElementInstanceList> childNodes();
     68 
     69     SVGElementInstance* previousSibling() const { return m_previousSibling; }
     70     SVGElementInstance* nextSibling() const { return m_nextSibling; }
     71 
     72     SVGElementInstance* firstChild() const { return m_firstChild; }
     73     SVGElementInstance* lastChild() const { return m_lastChild; }
     74 
     75     inline Document* ownerDocument() const;
     76 
     77     class InvalidationGuard {
     78         WTF_MAKE_NONCOPYABLE(InvalidationGuard);
     79     public:
     80         InvalidationGuard(SVGElement* element) : m_element(element) { }
     81         ~InvalidationGuard() { SVGElementInstance::invalidateAllInstancesOfElement(m_element); }
     82     private:
     83         SVGElement* m_element;
     84     };
     85 
     86     class InstanceUpdateBlocker {
     87         WTF_MAKE_NONCOPYABLE(InstanceUpdateBlocker);
     88     public:
     89         InstanceUpdateBlocker(SVGElement* targetElement);
     90         ~InstanceUpdateBlocker();
     91 
     92     private:
     93         SVGElement* m_targetElement;
     94     };
     95 
     96     static void invalidateAllInstancesOfElement(SVGElement*);
     97 
     98     using TreeShared<SVGElementInstance>::ref;
     99     using TreeShared<SVGElementInstance>::deref;
    100 
    101     // EventTarget API
    102     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), abort);
    103     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), blur);
    104     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), change);
    105     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), click);
    106     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), contextmenu);
    107     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dblclick);
    108     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), error);
    109     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), focus);
    110     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), input);
    111     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keydown);
    112     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keypress);
    113     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keyup);
    114     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), load);
    115     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousedown);
    116     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseenter);
    117     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseleave);
    118     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousemove);
    119     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseout);
    120     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseover);
    121     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseup);
    122     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousewheel);
    123     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforecut);
    124     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), cut);
    125     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforecopy);
    126     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), copy);
    127     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforepaste);
    128     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), paste);
    129     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragenter);
    130     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragover);
    131     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragleave);
    132     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), drop);
    133     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragstart);
    134     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), drag);
    135     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragend);
    136     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), reset);
    137     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), resize);
    138     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), scroll);
    139     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), search);
    140     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), select);
    141     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), selectstart);
    142     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), submit);
    143     DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), unload);
    144 
    145 private:
    146     friend class SVGUseElement;
    147     friend class TreeShared<SVGElementInstance>;
    148 
    149     SVGElementInstance(SVGUseElement*, SVGUseElement*, PassRefPtr<SVGElement> originalElement);
    150 
    151     void removedLastRef();
    152     bool hasTreeSharedParent() const { return !!m_parentInstance; }
    153 
    154     virtual Node* toNode();
    155 
    156     void appendChild(PassRefPtr<SVGElementInstance> child);
    157     void setShadowTreeElement(SVGElement*);
    158 
    159     template<class GenericNode, class GenericNodeContainer>
    160     friend void appendChildToContainer(GenericNode* child, GenericNodeContainer* container);
    161 
    162     template<class GenericNode, class GenericNodeContainer>
    163     friend void removeDetachedChildrenInContainer(GenericNodeContainer*);
    164 
    165     template<class GenericNode, class GenericNodeContainer>
    166     friend void Private::addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer* container);
    167 
    168     bool hasChildNodes() const { return m_firstChild; }
    169 
    170     void setFirstChild(SVGElementInstance* child) { m_firstChild = child; }
    171     void setLastChild(SVGElementInstance* child) { m_lastChild = child; }
    172 
    173     void setNextSibling(SVGElementInstance* sibling) { m_nextSibling = sibling; }
    174     void setPreviousSibling(SVGElementInstance* sibling) { m_previousSibling = sibling; }
    175 
    176     virtual void refEventTarget() { ref(); }
    177     virtual void derefEventTarget() { deref(); }
    178     virtual EventTargetData* eventTargetData();
    179     virtual EventTargetData* ensureEventTargetData();
    180 
    181     SVGElementInstance* m_parentInstance;
    182 
    183     SVGUseElement* m_correspondingUseElement;
    184     SVGUseElement* m_directUseElement;
    185     RefPtr<SVGElement> m_element;
    186     RefPtr<SVGElement> m_shadowTreeElement;
    187 
    188     SVGElementInstance* m_previousSibling;
    189     SVGElementInstance* m_nextSibling;
    190 
    191     SVGElementInstance* m_firstChild;
    192     SVGElementInstance* m_lastChild;
    193 };
    194 
    195 } // namespace WebCore
    196 
    197 #endif
    198