OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 G* * Redistributions in binary form must reproduce the above | 10 G* * Redistributions in binary form must reproduce the above |
(...skipping 15 matching lines...) Expand all Loading... | |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 #ifndef NewSVGAnimatedProperty_h | 31 #ifndef NewSVGAnimatedProperty_h |
32 #define NewSVGAnimatedProperty_h | 32 #define NewSVGAnimatedProperty_h |
33 | 33 |
34 #include "bindings/v8/ExceptionStatePlaceholder.h" | 34 #include "bindings/v8/ExceptionStatePlaceholder.h" |
35 #include "bindings/v8/ScriptWrappable.h" | 35 #include "bindings/v8/ScriptWrappable.h" |
36 #include "core/dom/ExceptionCode.h" | |
36 #include "core/svg/SVGParsingError.h" | 37 #include "core/svg/SVGParsingError.h" |
37 #include "core/svg/properties/NewSVGPropertyTearOff.h" | 38 #include "core/svg/properties/NewSVGPropertyTearOff.h" |
38 #include "core/svg/properties/SVGPropertyInfo.h" | 39 #include "core/svg/properties/SVGPropertyInfo.h" |
39 #include "wtf/Noncopyable.h" | 40 #include "wtf/Noncopyable.h" |
40 #include "wtf/PassRefPtr.h" | 41 #include "wtf/PassRefPtr.h" |
41 #include "wtf/RefCounted.h" | 42 #include "wtf/RefCounted.h" |
42 | 43 |
43 namespace WebCore { | 44 namespace WebCore { |
44 | 45 |
45 class SVGElement; | 46 class SVGElement; |
46 | 47 |
47 class NewSVGAnimatedPropertyBase : public RefCounted<NewSVGAnimatedPropertyBase> { | 48 class NewSVGAnimatedPropertyBase : public RefCounted<NewSVGAnimatedPropertyBase> { |
48 public: | 49 public: |
49 virtual ~NewSVGAnimatedPropertyBase(); | 50 virtual ~NewSVGAnimatedPropertyBase(); |
50 | 51 |
51 virtual NewSVGPropertyBase* baseValueBase() = 0; | 52 virtual NewSVGPropertyBase* baseValueBase() = 0; |
52 virtual NewSVGPropertyBase* currentValueBase() = 0; | 53 virtual NewSVGPropertyBase* currentValueBase() = 0; |
53 | 54 |
54 virtual void animationStarted() = 0; | 55 virtual void animationStarted(); |
55 virtual PassRefPtr<NewSVGPropertyBase> createAnimatedValue() = 0; | 56 virtual PassRefPtr<NewSVGPropertyBase> createAnimatedValue() = 0; |
56 virtual void setAnimatedValue(PassRefPtr<NewSVGPropertyBase>) = 0; | 57 virtual void setAnimatedValue(PassRefPtr<NewSVGPropertyBase>) = 0; |
57 virtual void animationEnded() = 0; | 58 virtual void animationEnded(); |
58 virtual void animValWillChange() = 0; | 59 virtual void animValWillChange(); |
59 virtual void animValDidChange() = 0; | 60 virtual void animValDidChange(); |
60 | 61 |
61 virtual bool needsSynchronizeAttribute() = 0; | 62 virtual bool needsSynchronizeAttribute() = 0; |
62 void synchronizeAttribute(); | 63 virtual void synchronizeAttribute(); |
63 | 64 |
64 AnimatedPropertyType type() const | 65 AnimatedPropertyType type() const |
65 { | 66 { |
66 return m_type; | 67 return m_type; |
67 } | 68 } |
68 | 69 |
69 SVGElement* contextElement() | 70 SVGElement* contextElement() |
70 { | 71 { |
71 return m_contextElement; | 72 return m_contextElement; |
72 } | 73 } |
73 | 74 |
74 const QualifiedName& attributeName() const | 75 const QualifiedName& attributeName() const |
75 { | 76 { |
76 return m_attributeName; | 77 return m_attributeName; |
77 } | 78 } |
78 | 79 |
80 bool isAnimating() const | |
81 { | |
82 return m_isAnimating; | |
83 } | |
84 | |
85 bool isReadOnly() const | |
86 { | |
87 return m_isReadOnly; | |
88 } | |
89 | |
90 void setReadOnly() | |
91 { | |
92 m_isReadOnly = true; | |
93 } | |
94 | |
79 protected: | 95 protected: |
80 NewSVGAnimatedPropertyBase(AnimatedPropertyType, SVGElement*, const Qualifie dName& attributeName); | 96 NewSVGAnimatedPropertyBase(AnimatedPropertyType, SVGElement*, const Qualifie dName& attributeName); |
81 | 97 |
82 private: | 98 private: |
83 const AnimatedPropertyType m_type; | 99 const AnimatedPropertyType m_type; |
100 bool m_isReadOnly; | |
101 bool m_isAnimating; | |
84 | 102 |
85 // This reference is kept alive from V8 wrapper | 103 // This reference is kept alive from V8 wrapper |
86 SVGElement* m_contextElement; | 104 SVGElement* m_contextElement; |
87 | 105 |
88 const QualifiedName& m_attributeName; | 106 const QualifiedName& m_attributeName; |
89 | 107 |
90 WTF_MAKE_NONCOPYABLE(NewSVGAnimatedPropertyBase); | 108 WTF_MAKE_NONCOPYABLE(NewSVGAnimatedPropertyBase); |
91 }; | 109 }; |
92 | 110 |
93 template <typename Property> | 111 template <typename Property> |
94 class NewSVGAnimatedProperty : public NewSVGAnimatedPropertyBase { | 112 class NewSVGAnimatedPropertyCommon : public NewSVGAnimatedPropertyBase { |
95 public: | 113 public: |
96 typedef typename Property::TearOffType TearOffType; | |
97 | |
98 static PassRefPtr<NewSVGAnimatedProperty<Property> > create(SVGElement* cont extElement, const QualifiedName& attributeName, PassRefPtr<Property> initialValu e) | |
99 { | |
100 return adoptRef(new NewSVGAnimatedProperty<Property>(contextElement, att ributeName, initialValue)); | |
101 } | |
102 | |
103 ~NewSVGAnimatedProperty() | |
104 { | |
105 ASSERT(!isAnimating()); | |
106 } | |
107 | |
108 bool isReadOnly() const | |
109 { | |
110 return m_isReadOnly; | |
111 } | |
112 | |
113 void setReadOnly() | |
114 { | |
115 m_isReadOnly = true; | |
116 } | |
117 | |
118 Property* baseValue() | 114 Property* baseValue() |
119 { | 115 { |
120 return m_baseValue.get(); | 116 return m_baseValue.get(); |
121 } | 117 } |
122 | 118 |
123 virtual NewSVGPropertyBase* baseValueBase() | 119 virtual NewSVGPropertyBase* baseValueBase() OVERRIDE |
124 { | 120 { |
125 return baseValue(); | 121 return baseValue(); |
126 } | 122 } |
127 | 123 |
128 Property* currentValue() | 124 Property* currentValue() |
129 { | 125 { |
130 return m_currentValue ? m_currentValue.get() : m_baseValue.get(); | 126 return m_currentValue ? m_currentValue.get() : m_baseValue.get(); |
131 } | 127 } |
132 | 128 |
133 virtual NewSVGPropertyBase* currentValueBase() | 129 virtual NewSVGPropertyBase* currentValueBase() OVERRIDE |
134 { | 130 { |
135 return currentValue(); | 131 return currentValue(); |
136 } | 132 } |
137 | 133 |
138 void setBaseValueAsString(const String& value, SVGParsingError& parseError) | 134 void setBaseValueAsString(const String& value, SVGParsingError& parseError) |
139 { | 135 { |
140 TrackExceptionState es; | 136 TrackExceptionState es; |
141 | 137 |
142 m_baseValue->setValueAsString(value, es); | 138 m_baseValue->setValueAsString(value, es); |
143 | 139 |
144 if (es.hadException()) | 140 if (es.hadException()) |
145 parseError = ParsingAttributeFailedError; | 141 parseError = ParsingAttributeFailedError; |
146 } | 142 } |
147 | 143 |
148 bool isAnimating() const | 144 virtual PassRefPtr<NewSVGPropertyBase> createAnimatedValue() OVERRIDE |
149 { | |
150 return m_isAnimating; | |
151 } | |
152 | |
153 virtual void animationStarted() | |
154 { | |
155 ASSERT(!isAnimating()); | |
156 m_isAnimating = true; | |
157 } | |
158 | |
159 virtual PassRefPtr<NewSVGPropertyBase> createAnimatedValue() | |
160 { | 145 { |
161 return m_baseValue->clone(); | 146 return m_baseValue->clone(); |
162 } | 147 } |
163 | 148 |
164 virtual void setAnimatedValue(PassRefPtr<NewSVGPropertyBase> value) | 149 virtual void setAnimatedValue(PassRefPtr<NewSVGPropertyBase> passValue) OVER RIDE |
165 { | 150 { |
166 ASSERT(isAnimating()); | 151 ASSERT(isAnimating()); |
167 | 152 |
168 // FIXME: add type check | 153 RefPtr<NewSVGPropertyBase> value = passValue; |
169 m_currentValue = static_pointer_cast<Property>(value); | 154 ASSERT(value->type() == Property::classType()); |
170 | 155 m_currentValue = static_pointer_cast<Property>(value.release()); |
171 if (m_animValTearOff) | |
172 m_animValTearOff->setTarget(m_currentValue); | |
173 } | 156 } |
174 | 157 |
175 virtual void animationEnded() | 158 virtual void animationEnded() OVERRIDE |
176 { | 159 { |
177 ASSERT(isAnimating()); | 160 NewSVGAnimatedPropertyBase::animationEnded(); |
178 m_isAnimating = false; | |
179 | 161 |
180 ASSERT(m_currentValue); | 162 ASSERT(m_currentValue); |
181 m_currentValue.clear(); | 163 m_currentValue.clear(); |
182 | |
183 if (m_animValTearOff) | |
184 m_animValTearOff->setTarget(m_baseValue); | |
185 } | 164 } |
186 | 165 |
187 virtual void animValWillChange() | 166 protected: |
167 NewSVGAnimatedPropertyCommon(SVGElement* contextElement, const QualifiedName & attributeName, PassRefPtr<Property> initialValue) | |
168 : NewSVGAnimatedPropertyBase(Property::classType(), contextElement, attr ibuteName) | |
169 , m_baseValue(initialValue) | |
188 { | 170 { |
189 ASSERT(isAnimating()); | |
190 } | 171 } |
191 | 172 |
192 virtual void animValDidChange() | 173 private: |
174 RefPtr<Property> m_baseValue; | |
175 RefPtr<Property> m_currentValue; | |
176 }; | |
177 | |
178 // Implementation of SVGAnimatedProperty which have tear-off value types. | |
haraken
2014/01/09 11:09:23
have => has
kouhei (in TOK)
2014/01/10 08:16:10
Done.
| |
179 // This is for classes which return special type for its "animVal". | |
180 // Examples are SVGAnimatedLength, SVGAnimatedRect, SVGAnimated*List, etc. | |
181 template <typename Property, typename TearOffType = typename Property::TearOffTy pe> | |
182 class NewSVGAnimatedProperty : public NewSVGAnimatedPropertyCommon<Property> { | |
183 public: | |
184 static PassRefPtr<NewSVGAnimatedProperty<Property> > create(SVGElement* cont extElement, const QualifiedName& attributeName, PassRefPtr<Property> initialValu e) | |
193 { | 185 { |
194 ASSERT(isAnimating()); | 186 return adoptRef(new NewSVGAnimatedProperty<Property>(contextElement, att ributeName, initialValue)); |
195 } | 187 } |
196 | 188 |
197 virtual bool needsSynchronizeAttribute() | 189 virtual void setAnimatedValue(PassRefPtr<NewSVGPropertyBase> value) OVERRIDE |
190 { | |
191 NewSVGAnimatedPropertyCommon<Property>::setAnimatedValue(value); | |
192 updateAnimValTearOffIfNeeded(); | |
193 } | |
194 | |
195 virtual void animationEnded() OVERRIDE | |
196 { | |
197 NewSVGAnimatedPropertyCommon<Property>::animationEnded(); | |
198 updateAnimValTearOffIfNeeded(); | |
199 } | |
200 | |
201 virtual bool needsSynchronizeAttribute() OVERRIDE | |
198 { | 202 { |
199 // DOM attribute synchronization is only needed if tear-off is being tou ched from javascript or the property is being animated. | 203 // DOM attribute synchronization is only needed if tear-off is being tou ched from javascript or the property is being animated. |
200 // This prevents unnecessary attribute creation on target element. | 204 // This prevents unnecessary attribute creation on target element. |
201 return m_baseValTearOff || isAnimating(); | 205 return m_baseValTearOff || this->isAnimating(); |
202 } | 206 } |
203 | 207 |
204 // SVGAnimated* DOM Spec implementations: | 208 // SVGAnimated* DOM Spec implementations: |
205 | 209 |
206 // baseVal()/animVal() are only to be used from SVG DOM implementation. | 210 // baseVal()/animVal() are only to be used from SVG DOM implementation. |
207 // Use currentValue() from C++ code. | 211 // Use currentValue() from C++ code. |
208 virtual TearOffType* baseVal() | 212 virtual TearOffType* baseVal() OVERRIDE |
209 { | 213 { |
210 if (!m_baseValTearOff) | 214 if (!m_baseValTearOff) |
211 m_baseValTearOff = TearOffType::create(m_baseValue, contextElement() , PropertyIsNotAnimVal, attributeName()); | 215 m_baseValTearOff = TearOffType::create(this->baseValue(), this->cont extElement(), PropertyIsNotAnimVal, this->attributeName()); |
212 | 216 |
213 return m_baseValTearOff.get(); | 217 return m_baseValTearOff.get(); |
214 } | 218 } |
215 | 219 |
216 TearOffType* animVal() | 220 TearOffType* animVal() |
217 { | 221 { |
218 if (!m_animValTearOff) | 222 if (!m_animValTearOff) |
219 m_animValTearOff = TearOffType::create(currentValue(), contextElemen t(), PropertyIsAnimVal, attributeName()); | 223 m_animValTearOff = TearOffType::create(this->currentValue(), this->c ontextElement(), PropertyIsAnimVal, this->attributeName()); |
220 | 224 |
221 return m_animValTearOff.get(); | 225 return m_animValTearOff.get(); |
222 } | 226 } |
223 | 227 |
224 protected: | 228 protected: |
225 NewSVGAnimatedProperty(SVGElement* contextElement, const QualifiedName& attr ibuteName, PassRefPtr<Property> initialValue) | 229 NewSVGAnimatedProperty(SVGElement* contextElement, const QualifiedName& attr ibuteName, PassRefPtr<Property> initialValue) |
226 : NewSVGAnimatedPropertyBase(Property::classType(), contextElement, attr ibuteName) | 230 : NewSVGAnimatedPropertyCommon<Property>(contextElement, attributeName, initialValue) |
227 , m_isReadOnly(false) | |
228 , m_isAnimating(false) | |
229 , m_baseValue(initialValue) | |
230 { | 231 { |
231 } | 232 } |
232 | 233 |
233 private: | 234 private: |
234 bool m_isReadOnly; | 235 void updateAnimValTearOffIfNeeded() |
235 bool m_isAnimating; | 236 { |
237 if (m_animValTearOff) | |
238 m_animValTearOff->setTarget(this->currentValue()); | |
239 } | |
236 | 240 |
237 // When still (not animated): | 241 // When still (not animated): |
238 // Both m_animValTearOff and m_baseValTearOff target m_baseValue. | 242 // Both m_animValTearOff and m_baseValTearOff target m_baseValue. |
239 // When animated: | 243 // When animated: |
240 // m_animValTearOff targets m_currentValue. | 244 // m_animValTearOff targets m_currentValue. |
241 // m_baseValTearOff targets m_baseValue. | 245 // m_baseValTearOff targets m_baseValue. |
242 RefPtr<Property> m_baseValue; | |
243 RefPtr<Property> m_currentValue; | |
244 RefPtr<TearOffType> m_baseValTearOff; | 246 RefPtr<TearOffType> m_baseValTearOff; |
245 RefPtr<TearOffType> m_animValTearOff; | 247 RefPtr<TearOffType> m_animValTearOff; |
246 }; | 248 }; |
247 | 249 |
250 // Implementation of SVGAnimatedProperty which use primitive types. | |
haraken
2014/01/09 11:09:23
use => uses
kouhei (in TOK)
2014/01/10 08:16:10
Done.
| |
251 // This is for classes which return primitive type for its "animVal". | |
252 // Examples are SVGAnimatedBoolean, SVGAnimatedNumber, etc. | |
253 // This is implemented as template specialization used when TearOffType is set t o void. | |
254 template <typename Property> | |
255 class NewSVGAnimatedProperty<Property, void> : public NewSVGAnimatedPropertyComm on<Property> { | |
256 public: | |
257 typedef typename Property::PrimitiveType PrimitiveType; | |
258 | |
259 static PassRefPtr<NewSVGAnimatedProperty<Property> > create(SVGElement* cont extElement, const QualifiedName& attributeName, PassRefPtr<Property> initialValu e) | |
260 { | |
261 return adoptRef(new NewSVGAnimatedProperty<Property>(contextElement, att ributeName, initialValue)); | |
262 } | |
263 | |
264 virtual bool needsSynchronizeAttribute() OVERRIDE | |
265 { | |
266 // DOM attribute synchronization is only needed if tear-off is being tou ched from javascript or the property is being animated. | |
267 // This prevents unnecessary attribute creation on target element. | |
268 return m_baseValueUpdated || this->isAnimating(); | |
269 } | |
270 | |
271 virtual void synchronizeAttribute() OVERRIDE | |
272 { | |
273 NewSVGAnimatedPropertyBase::synchronizeAttribute(); | |
274 m_baseValueUpdated = false; | |
275 } | |
276 | |
277 // SVGAnimated* DOM Spec implementations: | |
278 | |
279 // baseVal()/setBaseVal()/animVal() are only to be used from SVG DOM impleme ntation. | |
280 // Use currentValue() from C++ code. | |
281 PrimitiveType baseVal() | |
282 { | |
283 return this->baseValue()->value(); | |
284 } | |
285 | |
286 void setBaseVal(PrimitiveType value, WebCore::ExceptionState& exceptionState ) | |
287 { | |
288 if (this->isReadOnly()) { | |
289 exceptionState.throwDOMException(NoModificationAllowedError, "The at tribute is read-only."); | |
290 return; | |
291 } | |
292 | |
293 this->baseValue()->setValue(value); | |
294 | |
295 ASSERT(this->attributeName() != nullQName()); | |
296 this->contextElement()->invalidateSVGAttributes(); | |
297 this->contextElement()->svgAttributeChanged(this->attributeName()); | |
298 | |
299 m_baseValueUpdated = true; | |
300 } | |
301 | |
302 PrimitiveType animVal() | |
303 { | |
304 return this->currentValue()->value(); | |
305 } | |
306 | |
307 protected: | |
308 NewSVGAnimatedProperty(SVGElement* contextElement, const QualifiedName& attr ibuteName, PassRefPtr<Property> initialValue) | |
309 : NewSVGAnimatedPropertyCommon<Property>(contextElement, attributeName, initialValue) | |
310 , m_baseValueUpdated(false) | |
311 { | |
312 } | |
313 | |
314 bool m_baseValueUpdated; | |
315 }; | |
316 | |
248 } | 317 } |
249 | 318 |
250 #endif // NewSVGAnimatedProperty_h | 319 #endif // NewSVGAnimatedProperty_h |
OLD | NEW |