#ifndef KeyframeEffectModel_h
#define KeyframeEffectModel_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 "heap/Handle.h"
#include "platform/animation/TimingFunction.h"
#include "wtf/HashMap.h"
#include "wtf/HashSet.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/Vector.h"
namespace WebCore {
class KeyframeEffectModelTest;
class KeyframeEffectModelBase : public AnimationEffect {
public:
typedef WillBeHeapVector<OwnPtrWillBeMember<Keyframe::PropertySpecificKeyframe> > PropertySpecificKeyframeVector;
class PropertySpecificKeyframeGroup : public NoBaseWillBeGarbageCollected<PropertySpecificKeyframeGroup> {
public:
void appendKeyframe(PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe>);
const PropertySpecificKeyframeVector& keyframes() const { return m_keyframes; }
void trace(Visitor*);
private:
void removeRedundantKeyframes();
void addSyntheticKeyframeIfRequired(const KeyframeEffectModelBase* context);
PropertySpecificKeyframeVector m_keyframes;
friend class KeyframeEffectModelBase;
};
bool isReplaceOnly();
PropertySet properties() const;
typedef WillBeHeapVector<RefPtrWillBeMember<Keyframe> > KeyframeVector;
const KeyframeVector& getFrames() const { return m_keyframes; }
const PropertySpecificKeyframeVector& getPropertySpecificKeyframes(CSSPropertyID id) const
{
ensureKeyframeGroups();
return m_keyframeGroups->get(id)->keyframes();
}
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;
protected:
static KeyframeVector normalizedKeyframes(const KeyframeVector& keyframes);
void ensureKeyframeGroups() const;
void ensureInterpolationEffect() const;
KeyframeVector m_keyframes;
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);
}
};
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; }
}
#endif