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;
38
39// SVGElementInstance mimics Node, but without providing all its functionality
40class SVGElementInstance : public TreeShared<SVGElementInstance>,
41                           public EventTarget {
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    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
126private:
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