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