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 | |
pdr.
2014/01/10 18:57:32
Just FYI: I think these isReadOnly/setReadOnly met
kouhei (in TOK)
2014/01/14 04:12:50
Yes. These were unused, but I found some cases whe
| |
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); |
97 void commitChange(); | |
81 | 98 |
82 private: | 99 private: |
83 const AnimatedPropertyType m_type; | 100 const AnimatedPropertyType m_type; |
101 bool m_isReadOnly; | |
102 bool m_isAnimating; | |
84 | 103 |
85 // This reference is kept alive from V8 wrapper | 104 // This reference is kept alive from V8 wrapper |
86 SVGElement* m_contextElement; | 105 SVGElement* m_contextElement; |
87 | 106 |
88 const QualifiedName& m_attributeName; | 107 const QualifiedName& m_attributeName; |
89 | 108 |
90 WTF_MAKE_NONCOPYABLE(NewSVGAnimatedPropertyBase); | 109 WTF_MAKE_NONCOPYABLE(NewSVGAnimatedPropertyBase); |
91 }; | 110 }; |
92 | 111 |
93 template <typename Property> | 112 template <typename Property> |
94 class NewSVGAnimatedProperty : public NewSVGAnimatedPropertyBase { | 113 class NewSVGAnimatedPropertyCommon : public NewSVGAnimatedPropertyBase { |
95 public: | 114 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() | 115 Property* baseValue() |
119 { | 116 { |
120 return m_baseValue.get(); | 117 return m_baseValue.get(); |
121 } | 118 } |
122 | 119 |
123 virtual NewSVGPropertyBase* baseValueBase() | 120 virtual NewSVGPropertyBase* baseValueBase() OVERRIDE |
124 { | 121 { |
125 return baseValue(); | 122 return baseValue(); |
126 } | 123 } |
127 | 124 |
128 Property* currentValue() | 125 Property* currentValue() |
129 { | 126 { |
130 return m_currentValue ? m_currentValue.get() : m_baseValue.get(); | 127 return m_currentValue ? m_currentValue.get() : m_baseValue.get(); |
131 } | 128 } |
132 | 129 |
133 virtual NewSVGPropertyBase* currentValueBase() | 130 virtual NewSVGPropertyBase* currentValueBase() OVERRIDE |
134 { | 131 { |
135 return currentValue(); | 132 return currentValue(); |
136 } | 133 } |
137 | 134 |
138 void setBaseValueAsString(const String& value, SVGParsingError& parseError) | 135 void setBaseValueAsString(const String& value, SVGParsingError& parseError) |
139 { | 136 { |
140 TrackExceptionState es; | 137 TrackExceptionState es; |
141 | 138 |
142 m_baseValue->setValueAsString(value, es); | 139 m_baseValue->setValueAsString(value, es); |
140 commitChange(); | |
143 | 141 |
144 if (es.hadException()) | 142 if (es.hadException()) |
145 parseError = ParsingAttributeFailedError; | 143 parseError = ParsingAttributeFailedError; |
146 } | 144 } |
147 | 145 |
148 bool isAnimating() const | 146 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 { | 147 { |
161 return m_baseValue->clone(); | 148 return m_baseValue->clone(); |
162 } | 149 } |
163 | 150 |
164 virtual void setAnimatedValue(PassRefPtr<NewSVGPropertyBase> value) | 151 virtual void setAnimatedValue(PassRefPtr<NewSVGPropertyBase> passValue) OVER RIDE |
165 { | 152 { |
166 ASSERT(isAnimating()); | 153 ASSERT(isAnimating()); |
167 | 154 |
168 // FIXME: add type check | 155 RefPtr<NewSVGPropertyBase> value = passValue; |
169 m_currentValue = static_pointer_cast<Property>(value); | 156 ASSERT(value->type() == Property::classType()); |
170 | 157 m_currentValue = static_pointer_cast<Property>(value.release()); |
171 if (m_animValTearOff) | |
172 m_animValTearOff->setTarget(m_currentValue); | |
173 } | 158 } |
174 | 159 |
175 virtual void animationEnded() | 160 virtual void animationEnded() OVERRIDE |
176 { | 161 { |
177 ASSERT(isAnimating()); | 162 NewSVGAnimatedPropertyBase::animationEnded(); |
178 m_isAnimating = false; | |
179 | 163 |
180 ASSERT(m_currentValue); | 164 ASSERT(m_currentValue); |
181 m_currentValue.clear(); | 165 m_currentValue.clear(); |
182 | |
183 if (m_animValTearOff) | |
184 m_animValTearOff->setTarget(m_baseValue); | |
185 } | 166 } |
186 | 167 |
187 virtual void animValWillChange() | 168 protected: |
169 NewSVGAnimatedPropertyCommon(SVGElement* contextElement, const QualifiedName & attributeName, PassRefPtr<Property> initialValue) | |
170 : NewSVGAnimatedPropertyBase(Property::classType(), contextElement, attr ibuteName) | |
171 , m_baseValue(initialValue) | |
188 { | 172 { |
189 ASSERT(isAnimating()); | |
190 } | 173 } |
191 | 174 |
192 virtual void animValDidChange() | 175 private: |
176 RefPtr<Property> m_baseValue; | |
177 RefPtr<Property> m_currentValue; | |
178 }; | |
179 | |
180 // Implementation of SVGAnimatedProperty which has tear-off value types. | |
181 // This is for classes which return special type for its "animVal". | |
182 // Examples are SVGAnimatedLength, SVGAnimatedRect, SVGAnimated*List, etc. | |
183 template <typename Property, typename TearOffType = typename Property::TearOffTy pe> | |
184 class NewSVGAnimatedProperty : public NewSVGAnimatedPropertyCommon<Property> { | |
185 public: | |
186 static PassRefPtr<NewSVGAnimatedProperty<Property> > create(SVGElement* cont extElement, const QualifiedName& attributeName, PassRefPtr<Property> initialValu e) | |
193 { | 187 { |
194 ASSERT(isAnimating()); | 188 return adoptRef(new NewSVGAnimatedProperty<Property>(contextElement, att ributeName, initialValue)); |
195 } | 189 } |
196 | 190 |
197 virtual bool needsSynchronizeAttribute() | 191 virtual void setAnimatedValue(PassRefPtr<NewSVGPropertyBase> value) OVERRIDE |
192 { | |
193 NewSVGAnimatedPropertyCommon<Property>::setAnimatedValue(value); | |
194 updateAnimValTearOffIfNeeded(); | |
195 } | |
196 | |
197 virtual void animationEnded() OVERRIDE | |
198 { | |
199 NewSVGAnimatedPropertyCommon<Property>::animationEnded(); | |
200 updateAnimValTearOffIfNeeded(); | |
201 } | |
202 | |
203 virtual bool needsSynchronizeAttribute() OVERRIDE | |
198 { | 204 { |
199 // DOM attribute synchronization is only needed if tear-off is being tou ched from javascript or the property is being animated. | 205 // 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. | 206 // This prevents unnecessary attribute creation on target element. |
201 return m_baseValTearOff || isAnimating(); | 207 return m_baseValTearOff || this->isAnimating(); |
202 } | 208 } |
203 | 209 |
204 // SVGAnimated* DOM Spec implementations: | 210 // SVGAnimated* DOM Spec implementations: |
205 | 211 |
206 // baseVal()/animVal() are only to be used from SVG DOM implementation. | 212 // baseVal()/animVal() are only to be used from SVG DOM implementation. |
207 // Use currentValue() from C++ code. | 213 // Use currentValue() from C++ code. |
208 virtual TearOffType* baseVal() | 214 virtual TearOffType* baseVal() OVERRIDE |
209 { | 215 { |
210 if (!m_baseValTearOff) | 216 if (!m_baseValTearOff) |
211 m_baseValTearOff = TearOffType::create(m_baseValue, contextElement() , PropertyIsNotAnimVal, attributeName()); | 217 m_baseValTearOff = TearOffType::create(this->baseValue(), this->cont extElement(), PropertyIsNotAnimVal, this->attributeName()); |
212 | 218 |
213 return m_baseValTearOff.get(); | 219 return m_baseValTearOff.get(); |
214 } | 220 } |
215 | 221 |
216 TearOffType* animVal() | 222 TearOffType* animVal() |
217 { | 223 { |
218 if (!m_animValTearOff) | 224 if (!m_animValTearOff) |
219 m_animValTearOff = TearOffType::create(currentValue(), contextElemen t(), PropertyIsAnimVal, attributeName()); | 225 m_animValTearOff = TearOffType::create(this->currentValue(), this->c ontextElement(), PropertyIsAnimVal, this->attributeName()); |
220 | 226 |
221 return m_animValTearOff.get(); | 227 return m_animValTearOff.get(); |
222 } | 228 } |
223 | 229 |
224 protected: | 230 protected: |
225 NewSVGAnimatedProperty(SVGElement* contextElement, const QualifiedName& attr ibuteName, PassRefPtr<Property> initialValue) | 231 NewSVGAnimatedProperty(SVGElement* contextElement, const QualifiedName& attr ibuteName, PassRefPtr<Property> initialValue) |
226 : NewSVGAnimatedPropertyBase(Property::classType(), contextElement, attr ibuteName) | 232 : NewSVGAnimatedPropertyCommon<Property>(contextElement, attributeName, initialValue) |
227 , m_isReadOnly(false) | |
228 , m_isAnimating(false) | |
229 , m_baseValue(initialValue) | |
230 { | 233 { |
231 } | 234 } |
232 | 235 |
233 private: | 236 private: |
234 bool m_isReadOnly; | 237 void updateAnimValTearOffIfNeeded() |
235 bool m_isAnimating; | 238 { |
239 if (m_animValTearOff) | |
240 m_animValTearOff->setTarget(this->currentValue()); | |
241 } | |
236 | 242 |
237 // When still (not animated): | 243 // When still (not animated): |
238 // Both m_animValTearOff and m_baseValTearOff target m_baseValue. | 244 // Both m_animValTearOff and m_baseValTearOff target m_baseValue. |
239 // When animated: | 245 // When animated: |
240 // m_animValTearOff targets m_currentValue. | 246 // m_animValTearOff targets m_currentValue. |
241 // m_baseValTearOff targets m_baseValue. | 247 // m_baseValTearOff targets m_baseValue. |
242 RefPtr<Property> m_baseValue; | |
243 RefPtr<Property> m_currentValue; | |
244 RefPtr<TearOffType> m_baseValTearOff; | 248 RefPtr<TearOffType> m_baseValTearOff; |
245 RefPtr<TearOffType> m_animValTearOff; | 249 RefPtr<TearOffType> m_animValTearOff; |
246 }; | 250 }; |
247 | 251 |
252 // Implementation of SVGAnimatedProperty which uses primitive types. | |
253 // This is for classes which return primitive type for its "animVal". | |
254 // Examples are SVGAnimatedBoolean, SVGAnimatedNumber, etc. | |
255 // This is implemented as template specialization used when TearOffType is set t o void. | |
256 template <typename Property> | |
257 class NewSVGAnimatedProperty<Property, void> : public NewSVGAnimatedPropertyComm on<Property> { | |
258 public: | |
259 typedef typename Property::PrimitiveType PrimitiveType; | |
260 | |
261 static PassRefPtr<NewSVGAnimatedProperty<Property> > create(SVGElement* cont extElement, const QualifiedName& attributeName, PassRefPtr<Property> initialValu e) | |
262 { | |
263 return adoptRef(new NewSVGAnimatedProperty<Property>(contextElement, att ributeName, initialValue)); | |
264 } | |
265 | |
266 virtual bool needsSynchronizeAttribute() OVERRIDE | |
267 { | |
268 // DOM attribute synchronization is only needed if tear-off is being tou ched from javascript or the property is being animated. | |
269 // This prevents unnecessary attribute creation on target element. | |
270 return m_baseValueUpdated || this->isAnimating(); | |
271 } | |
272 | |
273 virtual void synchronizeAttribute() OVERRIDE | |
274 { | |
275 NewSVGAnimatedPropertyBase::synchronizeAttribute(); | |
276 m_baseValueUpdated = false; | |
277 } | |
278 | |
279 // SVGAnimated* DOM Spec implementations: | |
280 | |
281 // baseVal()/setBaseVal()/animVal() are only to be used from SVG DOM impleme ntation. | |
282 // Use currentValue() from C++ code. | |
283 PrimitiveType baseVal() | |
284 { | |
285 return this->baseValue()->value(); | |
286 } | |
287 | |
288 void setBaseVal(PrimitiveType value, WebCore::ExceptionState& exceptionState ) | |
289 { | |
290 if (this->isReadOnly()) { | |
291 exceptionState.throwDOMException(NoModificationAllowedError, "The at tribute is read-only."); | |
292 return; | |
293 } | |
294 | |
295 this->baseValue()->setValue(value); | |
296 | |
297 ASSERT(this->attributeName() != nullQName()); | |
298 this->contextElement()->invalidateSVGAttributes(); | |
299 this->contextElement()->svgAttributeChanged(this->attributeName()); | |
300 | |
301 m_baseValueUpdated = true; | |
302 } | |
303 | |
304 PrimitiveType animVal() | |
305 { | |
306 return this->currentValue()->value(); | |
307 } | |
308 | |
309 protected: | |
310 NewSVGAnimatedProperty(SVGElement* contextElement, const QualifiedName& attr ibuteName, PassRefPtr<Property> initialValue) | |
311 : NewSVGAnimatedPropertyCommon<Property>(contextElement, attributeName, initialValue) | |
312 , m_baseValueUpdated(false) | |
313 { | |
314 } | |
315 | |
316 bool m_baseValueUpdated; | |
317 }; | |
318 | |
248 } | 319 } |
249 | 320 |
250 #endif // NewSVGAnimatedProperty_h | 321 #endif // NewSVGAnimatedProperty_h |
OLD | NEW |