Chromium Code Reviews| Index: Source/core/svg/properties/NewSVGAnimatedProperty.h |
| diff --git a/Source/core/svg/properties/NewSVGAnimatedProperty.h b/Source/core/svg/properties/NewSVGAnimatedProperty.h |
| index 40d6c5730e811377855a55ce8486f3caaf3df747..b12e816d398afaa2a9d1b5754df87495e78bf2d0 100644 |
| --- a/Source/core/svg/properties/NewSVGAnimatedProperty.h |
| +++ b/Source/core/svg/properties/NewSVGAnimatedProperty.h |
| @@ -33,6 +33,7 @@ G* * Redistributions in binary form must reproduce the above |
| #include "bindings/v8/ExceptionStatePlaceholder.h" |
| #include "bindings/v8/ScriptWrappable.h" |
| +#include "core/dom/ExceptionCode.h" |
| #include "core/svg/SVGParsingError.h" |
| #include "core/svg/properties/NewSVGPropertyTearOff.h" |
| #include "core/svg/properties/SVGPropertyInfo.h" |
| @@ -51,15 +52,15 @@ public: |
| virtual NewSVGPropertyBase* baseValueBase() = 0; |
| virtual NewSVGPropertyBase* currentValueBase() = 0; |
| - virtual void animationStarted() = 0; |
| + virtual void animationStarted(); |
| virtual PassRefPtr<NewSVGPropertyBase> createAnimatedValue() = 0; |
| virtual void setAnimatedValue(PassRefPtr<NewSVGPropertyBase>) = 0; |
| - virtual void animationEnded() = 0; |
| - virtual void animValWillChange() = 0; |
| - virtual void animValDidChange() = 0; |
| + virtual void animationEnded(); |
| + virtual void animValWillChange(); |
| + virtual void animValDidChange(); |
| virtual bool needsSynchronizeAttribute() = 0; |
| - void synchronizeAttribute(); |
| + virtual void synchronizeAttribute(); |
| AnimatedPropertyType type() const |
| { |
| @@ -76,11 +77,28 @@ public: |
| return m_attributeName; |
| } |
| + bool isAnimating() const |
| + { |
| + return m_isAnimating; |
| + } |
| + |
| + bool isReadOnly() const |
| + { |
| + return m_isReadOnly; |
| + } |
| + |
| + void setReadOnly() |
| + { |
| + m_isReadOnly = true; |
| + } |
| + |
| protected: |
| NewSVGAnimatedPropertyBase(AnimatedPropertyType, SVGElement*, const QualifiedName& attributeName); |
| private: |
| const AnimatedPropertyType m_type; |
| + bool m_isReadOnly; |
| + bool m_isAnimating; |
| // This reference is kept alive from V8 wrapper |
| SVGElement* m_contextElement; |
| @@ -91,36 +109,14 @@ private: |
| }; |
| template <typename Property> |
| -class NewSVGAnimatedProperty : public NewSVGAnimatedPropertyBase { |
| +class NewSVGAnimatedPropertyCommon : public NewSVGAnimatedPropertyBase { |
| public: |
| - typedef typename Property::TearOffType TearOffType; |
| - |
| - static PassRefPtr<NewSVGAnimatedProperty<Property> > create(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<Property> initialValue) |
| - { |
| - return adoptRef(new NewSVGAnimatedProperty<Property>(contextElement, attributeName, initialValue)); |
| - } |
| - |
| - ~NewSVGAnimatedProperty() |
| - { |
| - ASSERT(!isAnimating()); |
| - } |
| - |
| - bool isReadOnly() const |
| - { |
| - return m_isReadOnly; |
| - } |
| - |
| - void setReadOnly() |
| - { |
| - m_isReadOnly = true; |
| - } |
| - |
| Property* baseValue() |
| { |
| return m_baseValue.get(); |
| } |
| - virtual NewSVGPropertyBase* baseValueBase() |
| + virtual NewSVGPropertyBase* baseValueBase() OVERRIDE |
| { |
| return baseValue(); |
| } |
| @@ -130,7 +126,7 @@ public: |
| return m_currentValue ? m_currentValue.get() : m_baseValue.get(); |
| } |
| - virtual NewSVGPropertyBase* currentValueBase() |
| + virtual NewSVGPropertyBase* currentValueBase() OVERRIDE |
| { |
| return currentValue(); |
| } |
| @@ -145,70 +141,78 @@ public: |
| parseError = ParsingAttributeFailedError; |
| } |
| - bool isAnimating() const |
| - { |
| - return m_isAnimating; |
| - } |
| - |
| - virtual void animationStarted() |
| - { |
| - ASSERT(!isAnimating()); |
| - m_isAnimating = true; |
| - } |
| - |
| - virtual PassRefPtr<NewSVGPropertyBase> createAnimatedValue() |
| + virtual PassRefPtr<NewSVGPropertyBase> createAnimatedValue() OVERRIDE |
| { |
| return m_baseValue->clone(); |
| } |
| - virtual void setAnimatedValue(PassRefPtr<NewSVGPropertyBase> value) |
| + virtual void setAnimatedValue(PassRefPtr<NewSVGPropertyBase> passValue) OVERRIDE |
| { |
| ASSERT(isAnimating()); |
| - // FIXME: add type check |
| - m_currentValue = static_pointer_cast<Property>(value); |
| - |
| - if (m_animValTearOff) |
| - m_animValTearOff->setTarget(m_currentValue); |
| + RefPtr<NewSVGPropertyBase> value = passValue; |
| + ASSERT(value->type() == Property::classType()); |
| + m_currentValue = static_pointer_cast<Property>(value.release()); |
| } |
| - virtual void animationEnded() |
| + virtual void animationEnded() OVERRIDE |
| { |
| - ASSERT(isAnimating()); |
| - m_isAnimating = false; |
| + NewSVGAnimatedPropertyBase::animationEnded(); |
| ASSERT(m_currentValue); |
| m_currentValue.clear(); |
| + } |
| - if (m_animValTearOff) |
| - m_animValTearOff->setTarget(m_baseValue); |
| +protected: |
| + NewSVGAnimatedPropertyCommon(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<Property> initialValue) |
| + : NewSVGAnimatedPropertyBase(Property::classType(), contextElement, attributeName) |
| + , m_baseValue(initialValue) |
| + { |
| } |
| - virtual void animValWillChange() |
| +private: |
| + RefPtr<Property> m_baseValue; |
| + RefPtr<Property> m_currentValue; |
| +}; |
| + |
| +// 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.
|
| +// This is for classes which return special type for its "animVal". |
| +// Examples are SVGAnimatedLength, SVGAnimatedRect, SVGAnimated*List, etc. |
| +template <typename Property, typename TearOffType = typename Property::TearOffType> |
| +class NewSVGAnimatedProperty : public NewSVGAnimatedPropertyCommon<Property> { |
| +public: |
| + static PassRefPtr<NewSVGAnimatedProperty<Property> > create(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<Property> initialValue) |
| { |
| - ASSERT(isAnimating()); |
| + return adoptRef(new NewSVGAnimatedProperty<Property>(contextElement, attributeName, initialValue)); |
| } |
| - virtual void animValDidChange() |
| + virtual void setAnimatedValue(PassRefPtr<NewSVGPropertyBase> value) OVERRIDE |
| { |
| - ASSERT(isAnimating()); |
| + NewSVGAnimatedPropertyCommon<Property>::setAnimatedValue(value); |
| + updateAnimValTearOffIfNeeded(); |
| + } |
| + |
| + virtual void animationEnded() OVERRIDE |
| + { |
| + NewSVGAnimatedPropertyCommon<Property>::animationEnded(); |
| + updateAnimValTearOffIfNeeded(); |
| } |
| - virtual bool needsSynchronizeAttribute() |
| + virtual bool needsSynchronizeAttribute() OVERRIDE |
| { |
| // DOM attribute synchronization is only needed if tear-off is being touched from javascript or the property is being animated. |
| // This prevents unnecessary attribute creation on target element. |
| - return m_baseValTearOff || isAnimating(); |
| + return m_baseValTearOff || this->isAnimating(); |
| } |
| // SVGAnimated* DOM Spec implementations: |
| // baseVal()/animVal() are only to be used from SVG DOM implementation. |
| // Use currentValue() from C++ code. |
| - virtual TearOffType* baseVal() |
| + virtual TearOffType* baseVal() OVERRIDE |
| { |
| if (!m_baseValTearOff) |
| - m_baseValTearOff = TearOffType::create(m_baseValue, contextElement(), PropertyIsNotAnimVal, attributeName()); |
| + m_baseValTearOff = TearOffType::create(this->baseValue(), this->contextElement(), PropertyIsNotAnimVal, this->attributeName()); |
| return m_baseValTearOff.get(); |
| } |
| @@ -216,35 +220,100 @@ public: |
| TearOffType* animVal() |
| { |
| if (!m_animValTearOff) |
| - m_animValTearOff = TearOffType::create(currentValue(), contextElement(), PropertyIsAnimVal, attributeName()); |
| + m_animValTearOff = TearOffType::create(this->currentValue(), this->contextElement(), PropertyIsAnimVal, this->attributeName()); |
| return m_animValTearOff.get(); |
| } |
| protected: |
| NewSVGAnimatedProperty(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<Property> initialValue) |
| - : NewSVGAnimatedPropertyBase(Property::classType(), contextElement, attributeName) |
| - , m_isReadOnly(false) |
| - , m_isAnimating(false) |
| - , m_baseValue(initialValue) |
| + : NewSVGAnimatedPropertyCommon<Property>(contextElement, attributeName, initialValue) |
| { |
| } |
| private: |
| - bool m_isReadOnly; |
| - bool m_isAnimating; |
| + void updateAnimValTearOffIfNeeded() |
| + { |
| + if (m_animValTearOff) |
| + m_animValTearOff->setTarget(this->currentValue()); |
| + } |
| // When still (not animated): |
| // Both m_animValTearOff and m_baseValTearOff target m_baseValue. |
| // When animated: |
| // m_animValTearOff targets m_currentValue. |
| // m_baseValTearOff targets m_baseValue. |
| - RefPtr<Property> m_baseValue; |
| - RefPtr<Property> m_currentValue; |
| RefPtr<TearOffType> m_baseValTearOff; |
| RefPtr<TearOffType> m_animValTearOff; |
| }; |
| +// 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.
|
| +// This is for classes which return primitive type for its "animVal". |
| +// Examples are SVGAnimatedBoolean, SVGAnimatedNumber, etc. |
| +// This is implemented as template specialization used when TearOffType is set to void. |
| +template <typename Property> |
| +class NewSVGAnimatedProperty<Property, void> : public NewSVGAnimatedPropertyCommon<Property> { |
| +public: |
| + typedef typename Property::PrimitiveType PrimitiveType; |
| + |
| + static PassRefPtr<NewSVGAnimatedProperty<Property> > create(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<Property> initialValue) |
| + { |
| + return adoptRef(new NewSVGAnimatedProperty<Property>(contextElement, attributeName, initialValue)); |
| + } |
| + |
| + virtual bool needsSynchronizeAttribute() OVERRIDE |
| + { |
| + // DOM attribute synchronization is only needed if tear-off is being touched from javascript or the property is being animated. |
| + // This prevents unnecessary attribute creation on target element. |
| + return m_baseValueUpdated || this->isAnimating(); |
| + } |
| + |
| + virtual void synchronizeAttribute() OVERRIDE |
| + { |
| + NewSVGAnimatedPropertyBase::synchronizeAttribute(); |
| + m_baseValueUpdated = false; |
| + } |
| + |
| + // SVGAnimated* DOM Spec implementations: |
| + |
| + // baseVal()/setBaseVal()/animVal() are only to be used from SVG DOM implementation. |
| + // Use currentValue() from C++ code. |
| + PrimitiveType baseVal() |
| + { |
| + return this->baseValue()->value(); |
| + } |
| + |
| + void setBaseVal(PrimitiveType value, WebCore::ExceptionState& exceptionState) |
| + { |
| + if (this->isReadOnly()) { |
| + exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only."); |
| + return; |
| + } |
| + |
| + this->baseValue()->setValue(value); |
| + |
| + ASSERT(this->attributeName() != nullQName()); |
| + this->contextElement()->invalidateSVGAttributes(); |
| + this->contextElement()->svgAttributeChanged(this->attributeName()); |
| + |
| + m_baseValueUpdated = true; |
| + } |
| + |
| + PrimitiveType animVal() |
| + { |
| + return this->currentValue()->value(); |
| + } |
| + |
| +protected: |
| + NewSVGAnimatedProperty(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<Property> initialValue) |
| + : NewSVGAnimatedPropertyCommon<Property>(contextElement, attributeName, initialValue) |
| + , m_baseValueUpdated(false) |
| + { |
| + } |
| + |
| + bool m_baseValueUpdated; |
| +}; |
| + |
| } |
| #endif // NewSVGAnimatedProperty_h |