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#include "EventTarget.h"
25#include "TreeShared.h"
26
27namespace WebCore {
28
29namespace Private {
30template<class GenericNode, class GenericNodeContainer>
31void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer& container);
32};
33
34class Document;
35class SVGElement;
36class SVGElementInstanceList;
37class SVGElement;
38class SVGUseElement;
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    virtual ~SVGElementInstance();
46
47    void setParentNode(SVGElementInstance* instance) { m_parentInstance = instance; }
48
49    virtual EventTargetInterface eventTargetInterface() const override;
50    virtual ScriptExecutionContext* scriptExecutionContext() const override;
51
52    virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture) override;
53    virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) override;
54    virtual void removeAllEventListeners() override;
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    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(), wheel);
124    DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforecut);
125    DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), cut);
126    DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforecopy);
127    DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), copy);
128    DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforepaste);
129    DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), paste);
130    DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragenter);
131    DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragover);
132    DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragleave);
133    DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), drop);
134    DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragstart);
135    DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), drag);
136    DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragend);
137    DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), reset);
138    DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), resize);
139    DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), scroll);
140    DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), search);
141    DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), select);
142    DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), selectstart);
143    DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), submit);
144    DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), unload);
145
146private:
147    friend class SVGUseElement;
148    friend class TreeShared<SVGElementInstance>;
149
150    SVGElementInstance(SVGUseElement*, SVGUseElement*, PassRefPtr<SVGElement> originalElement);
151
152    void removedLastRef();
153    bool hasTreeSharedParent() const { return !!m_parentInstance; }
154
155    virtual Node* toNode() override;
156
157    void appendChild(PassRefPtr<SVGElementInstance> child);
158    void setShadowTreeElement(SVGElement*);
159
160    template<class GenericNode, class GenericNodeContainer>
161    friend void appendChildToContainer(GenericNode* child, GenericNodeContainer& container);
162
163    template<class GenericNode, class GenericNodeContainer>
164    friend void removeDetachedChildrenInContainer(GenericNodeContainer&);
165
166    template<class GenericNode, class GenericNodeContainer>
167    friend void Private::addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer& container);
168
169    bool hasChildNodes() const { return m_firstChild; }
170
171    void setFirstChild(SVGElementInstance* child) { m_firstChild = child; }
172    void setLastChild(SVGElementInstance* child) { m_lastChild = child; }
173
174    void setNextSibling(SVGElementInstance* sibling) { m_nextSibling = sibling; }
175    void setPreviousSibling(SVGElementInstance* sibling) { m_previousSibling = sibling; }
176
177    virtual void refEventTarget() override { ref(); }
178    virtual void derefEventTarget() override { deref(); }
179    virtual EventTargetData* eventTargetData() override;
180    virtual EventTargetData& ensureEventTargetData() override;
181
182    SVGElementInstance* m_parentInstance;
183
184    SVGUseElement* m_correspondingUseElement;
185    SVGUseElement* m_directUseElement;
186    RefPtr<SVGElement> m_element;
187    RefPtr<SVGElement> m_shadowTreeElement;
188
189    SVGElementInstance* m_previousSibling;
190    SVGElementInstance* m_nextSibling;
191
192    SVGElementInstance* m_firstChild;
193    SVGElementInstance* m_lastChild;
194};
195
196} // namespace WebCore
197
198#endif
199