Chromium Code Reviews| 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 |