Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / animation / KeyframeEffectModel.h
index 78359d4..f189ccc 100644 (file)
 #ifndef KeyframeEffectModel_h
 #define KeyframeEffectModel_h
 
-#include "core/animation/AnimatableValue.h"
+#include "core/animation/AnimatableValueKeyframe.h"
 #include "core/animation/AnimationEffect.h"
+#include "core/animation/InterpolationEffect.h"
+#include "core/animation/StringKeyframe.h"
+#include "core/animation/TimedItem.h"
 #include "platform/animation/TimingFunction.h"
+#include "platform/heap/Handle.h"
 #include "wtf/HashMap.h"
 #include "wtf/HashSet.h"
 #include "wtf/PassOwnPtr.h"
 
 namespace WebCore {
 
-typedef HashSet<CSSPropertyID> PropertySet;
-
+class Element;
 class KeyframeEffectModelTest;
 
-// Represents the keyframes set through the API.
-class Keyframe : public RefCounted<Keyframe> {
-public:
-    static PassRefPtr<Keyframe> create()
-    {
-        return adoptRef(new Keyframe);
-    }
-    static bool compareOffsets(const RefPtr<Keyframe>& a, const RefPtr<Keyframe>& b)
-    {
-        return a->offset() < b->offset();
-    }
-    void setOffset(double offset) { m_offset = offset; }
-    double offset() const { return m_offset; }
-    void setComposite(AnimationEffect::CompositeOperation composite) { m_composite = composite; }
-    AnimationEffect::CompositeOperation composite() const { return m_composite; }
-    void setEasing(PassRefPtr<TimingFunction> easing) { m_easing = easing; }
-    TimingFunction* easing() const { return m_easing.get(); }
-    void setPropertyValue(CSSPropertyID, const AnimatableValue*);
-    void clearPropertyValue(CSSPropertyID);
-    const AnimatableValue* propertyValue(CSSPropertyID) const;
-    PropertySet properties() const;
-    PassRefPtr<Keyframe> clone() const { return adoptRef(new Keyframe(*this)); }
-    PassRefPtr<Keyframe> cloneWithOffset(double offset) const;
-private:
-    Keyframe();
-    Keyframe(const Keyframe&);
-    double m_offset;
-    AnimationEffect::CompositeOperation m_composite;
-    RefPtr<TimingFunction> m_easing;
-    typedef HashMap<CSSPropertyID, RefPtr<AnimatableValue> > PropertyValueMap;
-    PropertyValueMap m_propertyValues;
-};
-
-class KeyframeEffectModel FINAL : public AnimationEffect {
+class KeyframeEffectModelBase : public AnimationEffect {
 public:
-    class PropertySpecificKeyframe;
-    typedef Vector<RefPtr<Keyframe> > KeyframeVector;
-    typedef Vector<OwnPtr<PropertySpecificKeyframe> > PropertySpecificKeyframeVector;
     // FIXME: Implement accumulation.
-    static PassRefPtr<KeyframeEffectModel> create(const KeyframeVector& keyframes)
-    {
-        return adoptRef(new KeyframeEffectModel(keyframes));
-    }
 
-    virtual bool affects(CSSPropertyID property) OVERRIDE
-    {
-        ensureKeyframeGroups();
-        return m_keyframeGroups->contains(property);
-    }
-
-    // AnimationEffect implementation.
-    virtual PassOwnPtr<CompositableValueList> sample(int iteration, double fraction) const OVERRIDE;
-
-    // FIXME: Implement setFrames()
-    const KeyframeVector& getFrames() const { return m_keyframes; }
-
-    virtual bool isKeyframeEffectModel() const OVERRIDE { return true; }
+    typedef WillBeHeapVector<OwnPtrWillBeMember<Keyframe::PropertySpecificKeyframe> > PropertySpecificKeyframeVector;
+    class PropertySpecificKeyframeGroup : public NoBaseWillBeGarbageCollected<PropertySpecificKeyframeGroup> {
+    public:
+        void appendKeyframe(PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe>);
+        const PropertySpecificKeyframeVector& keyframes() const { return m_keyframes; }
 
-    PropertySet properties() const;
+        void trace(Visitor*);
 
-    class PropertySpecificKeyframe {
-    public:
-        PropertySpecificKeyframe(double offset, PassRefPtr<TimingFunction> easing, const AnimatableValue*, CompositeOperation);
-        double offset() const { return m_offset; }
-        const TimingFunction* easing() const { return m_easing.get(); }
-        const CompositableValue* value() const { return m_value.get(); }
-        PassOwnPtr<PropertySpecificKeyframe> cloneWithOffset(double offset) const;
     private:
-        // Used by cloneWithOffset().
-        PropertySpecificKeyframe(double offset, PassRefPtr<TimingFunction> easing, PassRefPtr<CompositableValue>);
-        double m_offset;
-        RefPtr<TimingFunction> m_easing;
-        RefPtr<CompositableValue> m_value;
-    };
+        void removeRedundantKeyframes();
+        void addSyntheticKeyframeIfRequired(const KeyframeEffectModelBase* context);
 
-    class PropertySpecificKeyframeGroup {
-    public:
-        void appendKeyframe(PassOwnPtr<PropertySpecificKeyframe>);
-        PassRefPtr<CompositableValue> sample(int iteration, double offset) const;
-        const PropertySpecificKeyframeVector& keyframes() const { return m_keyframes; }
-    private:
         PropertySpecificKeyframeVector m_keyframes;
-        void removeRedundantKeyframes();
-        void addSyntheticKeyframeIfRequired();
 
-        friend class KeyframeEffectModel;
+        friend class KeyframeEffectModelBase;
     };
 
+    bool isReplaceOnly();
+
+    PropertySet properties() const;
+
+    typedef WillBeHeapVector<RefPtrWillBeMember<Keyframe> > KeyframeVector;
+    const KeyframeVector& getFrames() const { return m_keyframes; }
+    // FIXME: Implement setFrames()
+
     const PropertySpecificKeyframeVector& getPropertySpecificKeyframes(CSSPropertyID id) const
     {
         ensureKeyframeGroups();
         return m_keyframeGroups->get(id)->keyframes();
     }
 
-private:
-    KeyframeEffectModel(const KeyframeVector& keyframes);
+    // AnimationEffect implementation.
+    virtual PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > sample(int iteration, double fraction, double iterationDuration) const OVERRIDE;
+
+    virtual bool isKeyframeEffectModel() const OVERRIDE { return true; }
+
+    virtual bool isAnimatableValueKeyframeEffectModel() const { return false; }
+    virtual bool isStringKeyframeEffectModel() const { return false; }
 
+    virtual void trace(Visitor*) OVERRIDE;
+
+    // FIXME: This is a hack used to resolve CSSValues to AnimatableValues while we have a valid handle on an element.
+    // This should be removed once StringKeyframes no longer uses InterpolableAnimatableValues.
+    void forceConversionsToAnimatableValues(Element* element)
+    {
+        ensureKeyframeGroups();
+        ensureInterpolationEffect(element);
+    }
+
+protected:
     static KeyframeVector normalizedKeyframes(const KeyframeVector& keyframes);
 
     // Lazily computes the groups of property-specific keyframes.
     void ensureKeyframeGroups() const;
+    void ensureInterpolationEffect(Element* = 0) const;
 
     KeyframeVector m_keyframes;
     // The spec describes filtering the normalized keyframes at sampling time
     // to get the 'property-specific keyframes'. For efficiency, we cache the
     // property-specific lists.
-    typedef HashMap<CSSPropertyID, OwnPtr<PropertySpecificKeyframeGroup> > KeyframeGroupMap;
-    mutable OwnPtr<KeyframeGroupMap> m_keyframeGroups;
+    typedef WillBeHeapHashMap<CSSPropertyID, OwnPtrWillBeMember<PropertySpecificKeyframeGroup> > KeyframeGroupMap;
+    mutable OwnPtrWillBeMember<KeyframeGroupMap> m_keyframeGroups;
+    mutable RefPtrWillBeMember<InterpolationEffect> m_interpolationEffect;
 
     friend class KeyframeEffectModelTest;
+
+    bool affects(CSSPropertyID property)
+    {
+        ensureKeyframeGroups();
+        return m_keyframeGroups->contains(property);
+    }
 };
 
-DEFINE_TYPE_CASTS(KeyframeEffectModel, AnimationEffect, value, value->isKeyframeEffectModel(), value.isKeyframeEffectModel());
+template <class Keyframe>
+class KeyframeEffectModel FINAL : public KeyframeEffectModelBase {
+public:
+    typedef WillBeHeapVector<RefPtrWillBeMember<Keyframe> > KeyframeVector;
+    static PassRefPtrWillBeRawPtr<KeyframeEffectModel<Keyframe> > create(const KeyframeVector& keyframes) { return adoptRefWillBeNoop(new KeyframeEffectModel(keyframes)); }
+
+private:
+    KeyframeEffectModel(const KeyframeVector& keyframes)
+    {
+        m_keyframes.appendVector(keyframes);
+    }
+
+    virtual bool isAnimatableValueKeyframeEffectModel() const { return false; }
+    virtual bool isStringKeyframeEffectModel() const { return false; }
+
+};
+
+typedef KeyframeEffectModelBase::KeyframeVector KeyframeVector;
+typedef KeyframeEffectModelBase::PropertySpecificKeyframeVector PropertySpecificKeyframeVector;
+
+typedef KeyframeEffectModel<AnimatableValueKeyframe> AnimatableValueKeyframeEffectModel;
+typedef AnimatableValueKeyframeEffectModel::KeyframeVector AnimatableValueKeyframeVector;
+typedef AnimatableValueKeyframeEffectModel::PropertySpecificKeyframeVector AnimatableValuePropertySpecificKeyframeVector;
+
+typedef KeyframeEffectModel<StringKeyframe> StringKeyframeEffectModel;
+typedef StringKeyframeEffectModel::KeyframeVector StringKeyframeVector;
+typedef StringKeyframeEffectModel::PropertySpecificKeyframeVector StringPropertySpecificKeyframeVector;
+
+DEFINE_TYPE_CASTS(KeyframeEffectModelBase, AnimationEffect, value, value->isKeyframeEffectModel(), value.isKeyframeEffectModel());
+DEFINE_TYPE_CASTS(AnimatableValueKeyframeEffectModel, KeyframeEffectModelBase, value, value->isAnimatableValueKeyframeEffectModel(), value.isAnimatableValueKeyframeEffectModel());
+
+inline const AnimatableValueKeyframeEffectModel* toAnimatableValueKeyframeEffectModel(const AnimationEffect* base)
+{
+    return toAnimatableValueKeyframeEffectModel(toKeyframeEffectModelBase(base));
+}
+
+inline AnimatableValueKeyframeEffectModel* toAnimatableValueKeyframeEffectModel(AnimationEffect* base)
+{
+    return toAnimatableValueKeyframeEffectModel(toKeyframeEffectModelBase(base));
+}
+
+template <>
+inline bool KeyframeEffectModel<AnimatableValueKeyframe>::isAnimatableValueKeyframeEffectModel() const { return true; }
+
+template <>
+inline bool KeyframeEffectModel<StringKeyframe>::isStringKeyframeEffectModel() const { return true; }
 
 } // namespace WebCore