a4672beb1a3dc4723b96d5567049a0f17ccc376a
[WebKit-https.git] / WebCore / svg / SVGElement.h
1 /*
2     Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3                   2004, 2005, 2006 Rob Buis <buis@kde.org>
4
5     This file is part of the KDE project
6
7     This library is free software; you can redistribute it and/or
8     modify it under the terms of the GNU Library General Public
9     License as published by the Free Software Foundation; either
10     version 2 of the License, or (at your option) any later version.
11
12     This library is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15     Library General Public License for more details.
16
17     You should have received a copy of the GNU Library General Public License
18     along with this library; see the file COPYING.LIB.  If not, write to
19     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20     Boston, MA 02110-1301, USA.
21 */
22
23 #ifndef SVGElement_h
24 #define SVGElement_h
25
26 #if ENABLE(SVG)
27 #include "Document.h"
28 #include "FloatRect.h"
29 #include "StyledElement.h"
30 #include "SVGAnimatedTemplate.h"
31 #include "SVGDocumentExtensions.h"
32 #include "SVGNames.h"
33
34 #define ANIMATED_PROPERTY_EMPTY_DECLARATIONS(BareType, NullType, UpperProperty, LowerProperty) \
35 public: \
36     virtual BareType LowerProperty() const { ASSERT_NOT_REACHED(); return NullType; } \
37     virtual void set##UpperProperty(BareType newValue) { ASSERT_NOT_REACHED(); }\
38     virtual BareType LowerProperty##BaseValue() const { ASSERT_NOT_REACHED(); return NullType; } \
39     virtual void set##UpperProperty##BaseValue(BareType newValue) { ASSERT_NOT_REACHED(); } \
40     virtual void start##UpperProperty() const { ASSERT_NOT_REACHED(); } \
41     virtual void stop##UpperProperty() { ASSERT_NOT_REACHED(); }
42
43 #define ANIMATED_PROPERTY_FORWARD_DECLARATIONS(ForwardClass, BareType, UpperProperty, LowerProperty) \
44 public: \
45     virtual BareType LowerProperty() const { return ForwardClass::LowerProperty(); } \
46     virtual void set##UpperProperty(BareType newValue) { ForwardClass::set##UpperProperty(newValue); } \
47     virtual BareType LowerProperty##BaseValue() const { return ForwardClass::LowerProperty##BaseValue(); } \
48     virtual void set##UpperProperty##BaseValue(BareType newValue) { ForwardClass::set##UpperProperty##BaseValue(newValue); } \
49     virtual void start##UpperProperty() const { ForwardClass::start##UpperProperty(); } \
50     virtual void stop##UpperProperty() { ForwardClass::stop##UpperProperty(); }
51
52 #define ANIMATED_PROPERTY_DECLARATIONS_INTERNAL(ClassType, ClassStorageType, BareType, StorageType, UpperProperty, LowerProperty) \
53 class SVGAnimatedTemplate##UpperProperty \
54 : public SVGAnimatedTemplate<BareType> \
55 { \
56 public: \
57     SVGAnimatedTemplate##UpperProperty(const ClassType*, const QualifiedName&); \
58     virtual ~SVGAnimatedTemplate##UpperProperty() { } \
59     virtual BareType baseVal() const; \
60     virtual void setBaseVal(BareType); \
61     virtual BareType animVal() const; \
62     virtual void setAnimVal(BareType); \
63     \
64 protected: \
65     ClassStorageType m_element; \
66 }; \
67 public: \
68     BareType LowerProperty() const; \
69     void set##UpperProperty(BareType); \
70     BareType LowerProperty##BaseValue() const; \
71     void set##UpperProperty##BaseValue(BareType); \
72     PassRefPtr<SVGAnimatedTemplate##UpperProperty> LowerProperty##Animated() const; \
73     void start##UpperProperty() const; \
74     void stop##UpperProperty(); \
75 \
76 private: \
77     StorageType m_##LowerProperty;
78
79 #define ANIMATED_PROPERTY_DEFINITIONS_INTERNAL(ClassName, ClassType, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName, StorageGetter, ContextElement) \
80 ClassName::SVGAnimatedTemplate##UpperProperty::SVGAnimatedTemplate##UpperProperty(const ClassType* element, const QualifiedName& attributeName) \
81 : SVGAnimatedTemplate<BareType>(attributeName), m_element(const_cast<ClassType*>(element)) { } \
82 \
83 BareType ClassName::SVGAnimatedTemplate##UpperProperty::baseVal() const \
84 { \
85     return m_element->LowerProperty##BaseValue(); \
86 } \
87 void ClassName::SVGAnimatedTemplate##UpperProperty::setBaseVal(BareType newBaseVal) \
88 { \
89     m_element->set##UpperProperty##BaseValue(newBaseVal); \
90 } \
91 BareType ClassName::SVGAnimatedTemplate##UpperProperty::animVal() const \
92 { \
93     return m_element->LowerProperty(); \
94 } \
95 void ClassName::SVGAnimatedTemplate##UpperProperty::setAnimVal(BareType newAnimVal) \
96 { \
97     m_element->set##UpperProperty(newAnimVal); \
98 } \
99 BareType ClassName::LowerProperty() const \
100 { \
101     return StorageGetter; \
102 } \
103 void ClassName::set##UpperProperty(BareType newValue) \
104 { \
105     m_##LowerProperty = newValue; \
106 } \
107 BareType ClassName::LowerProperty##BaseValue() const \
108 { \
109     const SVGElement* context = ContextElement; \
110     ASSERT(context); \
111     SVGDocumentExtensions* extensions = (context->document() ? context->document()->accessSVGExtensions() : 0); \
112     if (extensions && extensions->hasBaseValue<BareType>(context, AttrName)) \
113          return extensions->baseValue<BareType>(context, AttrName); \
114     return LowerProperty(); \
115 } \
116 void ClassName::set##UpperProperty##BaseValue(BareType newValue) \
117 { \
118     const SVGElement* context = ContextElement; \
119     ASSERT(context); \
120     SVGDocumentExtensions* extensions = (context->document() ? context->document()->accessSVGExtensions() : 0); \
121     if (extensions && extensions->hasBaseValue<BareType>(context, AttrName)) { \
122         extensions->setBaseValue<BareType>(context, AttrName, newValue); \
123         return; \
124     } \
125     /* Only update stored property, if not animating */ \
126     set##UpperProperty(newValue); \
127 } \
128 \
129 void ClassName::start##UpperProperty() const \
130 { \
131     const SVGElement* context = ContextElement; \
132     ASSERT(context); \
133     SVGDocumentExtensions* extensions = (context->document() ? context->document()->accessSVGExtensions() : 0); \
134     if (extensions) { \
135         ASSERT(!extensions->hasBaseValue<BareType>(context, AttrName)); \
136         extensions->setBaseValue<BareType>(context, AttrName, LowerProperty()); \
137     } \
138 } \
139 \
140 void ClassName::stop##UpperProperty() \
141 { \
142     const SVGElement* context = ContextElement; \
143     ASSERT(context); \
144     SVGDocumentExtensions* extensions = (context->document() ? context->document()->accessSVGExtensions() : 0); \
145     if (extensions) { \
146         ASSERT(extensions->hasBaseValue<BareType>(context, AttrName)); \
147         set##UpperProperty(extensions->baseValue<BareType>(context, AttrName)); \
148         extensions->removeBaseValue<BareType>(context, AttrName); \
149     } \
150 }
151
152 // These are the macros which will be used to declare/implement the svg animated properties...
153 #define ANIMATED_PROPERTY_DECLARATIONS_WITH_CONTEXT(ClassName, BareType, StorageType, UpperProperty, LowerProperty) \
154 ANIMATED_PROPERTY_DECLARATIONS_INTERNAL(SVGElement, RefPtr<SVGElement>, BareType, StorageType, UpperProperty, LowerProperty)
155
156 #define ANIMATED_PROPERTY_DECLARATIONS(ClassName, BareType, StorageType, UpperProperty, LowerProperty) \
157 ANIMATED_PROPERTY_DECLARATIONS_INTERNAL(ClassName, RefPtr<ClassName>, BareType, StorageType, UpperProperty, LowerProperty)
158
159 #define ANIMATED_PROPERTY_DEFINITIONS_WITH_CONTEXT(ClassName, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName, StorageGetter) \
160 ANIMATED_PROPERTY_DEFINITIONS_INTERNAL(ClassName, SVGElement, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName.localName(), StorageGetter, contextElement()) \
161 PassRefPtr<ClassName::SVGAnimatedTemplate##UpperProperty> ClassName::LowerProperty##Animated() const \
162 { \
163     const SVGElement* context = contextElement(); \
164     ASSERT(context); \
165     return lookupOrCreateWrapper<ClassName::SVGAnimatedTemplate##UpperProperty, SVGElement>(context, AttrName, AttrName.localName()); \
166 }
167
168 #define ANIMATED_PROPERTY_DEFINITIONS_WITH_CUSTOM_IDENTIFIER(ClassName, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName, AttrIdentifier, StorageGetter) \
169 ANIMATED_PROPERTY_DEFINITIONS_INTERNAL(ClassName, ClassName, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName.localName(), StorageGetter, this) \
170 PassRefPtr<ClassName::SVGAnimatedTemplate##UpperProperty> ClassName::LowerProperty##Animated() const \
171 { \
172     return lookupOrCreateWrapper<ClassName::SVGAnimatedTemplate##UpperProperty, ClassName>(this, AttrName, AttrIdentifier); \
173 }
174
175 #define ANIMATED_PROPERTY_DEFINITIONS(ClassName, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName, StorageGetter) \
176 ANIMATED_PROPERTY_DEFINITIONS_WITH_CUSTOM_IDENTIFIER(ClassName, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName, AttrName.localName(), StorageGetter)
177
178 namespace WebCore {
179
180     class SVGPreserveAspectRatio;
181     class SVGSVGElement;
182
183     class SVGElement : public StyledElement {
184     public:
185         SVGElement(const QualifiedName&, Document*);
186         virtual ~SVGElement();
187         virtual bool isSVGElement() const { return true; }
188         virtual bool isSupported(StringImpl* feature, StringImpl* version) const;
189         
190         String id() const;
191         void setId(const String&, ExceptionCode&);
192         String xmlbase() const;
193         void setXmlbase(const String&, ExceptionCode&);
194
195         SVGSVGElement* ownerSVGElement() const;
196         SVGElement* viewportElement() const;
197
198         virtual void parseMappedAttribute(MappedAttribute*);
199
200         virtual bool isStyled() const { return false; }
201         virtual bool isStyledTransformable() const { return false; }
202         virtual bool isStyledLocatable() const { return false; }
203         virtual bool isSVG() const { return false; }
204         virtual bool isFilterEffect() const { return false; }
205         virtual bool isGradientStop() const { return false; }
206         virtual bool isTextContent() const { return false; }
207
208         virtual bool isShadowNode() const { return m_shadowParent; }
209         virtual Node* shadowParentNode() { return m_shadowParent; }
210         void setShadowParentNode(Node* node) { m_shadowParent = node; }
211         virtual Node* eventParentNode() { return isShadowNode() ? shadowParentNode() : parentNode(); }
212
213         // For SVGTests
214         virtual bool isValid() const { return true; }
215   
216         virtual void finishParsingChildren();
217         virtual bool rendererIsNeeded(RenderStyle*) { return false; }
218         virtual bool childShouldCreateRenderer(Node*) const;
219
220         virtual void insertedIntoDocument();
221         virtual void buildPendingResource() { }
222
223         virtual void svgAttributeChanged(const QualifiedName&) { }
224         virtual void attributeChanged(Attribute*, bool preserveDecls = false);
225
226         void sendSVGLoadEventIfPossible(bool sendParentLoadEvents = false);
227
228         // Forwarded properties (declared/defined anywhere else in the inheritance structure)
229
230         // -> For SVGURIReference
231         ANIMATED_PROPERTY_EMPTY_DECLARATIONS(String, String(), Href, href)
232
233         // -> For SVGFitToViewBox
234         ANIMATED_PROPERTY_EMPTY_DECLARATIONS(FloatRect, FloatRect(), ViewBox, viewBox)    
235         ANIMATED_PROPERTY_EMPTY_DECLARATIONS(SVGPreserveAspectRatio*, 0, PreserveAspectRatio, preserveAspectRatio)
236
237         // -> For SVGExternalResourcesRequired
238         ANIMATED_PROPERTY_EMPTY_DECLARATIONS(bool, false, ExternalResourcesRequired, externalResourcesRequired)
239
240         virtual bool dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec, bool tempEvent = false);
241
242     private:
243         void addSVGEventListener(const AtomicString& eventType, const Attribute*);
244         virtual bool haveLoadedRequiredResources();
245
246         Node* m_shadowParent;
247     };
248
249 } // namespace WebCore 
250
251 #endif // ENABLE(SVG)
252 #endif // SVGElement_h