summaryrefslogtreecommitdiff
path: root/Source/WebCore/platform/animation
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/animation')
-rw-r--r--Source/WebCore/platform/animation/Animation.cpp95
-rw-r--r--Source/WebCore/platform/animation/Animation.h123
-rw-r--r--Source/WebCore/platform/animation/AnimationList.cpp10
-rw-r--r--Source/WebCore/platform/animation/AnimationList.h21
-rw-r--r--Source/WebCore/platform/animation/AnimationTrigger.h147
-rw-r--r--Source/WebCore/platform/animation/AnimationUtilities.h5
-rw-r--r--Source/WebCore/platform/animation/TimingFunction.cpp58
-rw-r--r--Source/WebCore/platform/animation/TimingFunction.h220
8 files changed, 511 insertions, 168 deletions
diff --git a/Source/WebCore/platform/animation/Animation.cpp b/Source/WebCore/platform/animation/Animation.cpp
index 333f1d828..1affdd8a1 100644
--- a/Source/WebCore/platform/animation/Animation.cpp
+++ b/Source/WebCore/platform/animation/Animation.cpp
@@ -22,19 +22,24 @@
#include "config.h"
#include "Animation.h"
+#include <wtf/NeverDestroyed.h>
+
namespace WebCore {
Animation::Animation()
- : m_name(initialAnimationName())
+ : m_name(initialName())
, m_property(CSSPropertyInvalid)
, m_mode(AnimateAll)
- , m_iterationCount(initialAnimationIterationCount())
- , m_delay(initialAnimationDelay())
- , m_duration(initialAnimationDuration())
- , m_timingFunction(initialAnimationTimingFunction())
- , m_direction(initialAnimationDirection())
- , m_fillMode(initialAnimationFillMode())
- , m_playState(initialAnimationPlayState())
+ , m_iterationCount(initialIterationCount())
+ , m_delay(initialDelay())
+ , m_duration(initialDuration())
+ , m_timingFunction(initialTimingFunction())
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+ , m_trigger(initialTrigger())
+#endif
+ , m_direction(initialDirection())
+ , m_fillMode(initialFillMode())
+ , m_playState(initialPlayState())
, m_delaySet(false)
, m_directionSet(false)
, m_durationSet(false)
@@ -44,6 +49,9 @@ Animation::Animation()
, m_playStateSet(false)
, m_propertySet(false)
, m_timingFunctionSet(false)
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+ , m_triggerSet(false)
+#endif
, m_isNone(false)
{
}
@@ -51,12 +59,16 @@ Animation::Animation()
Animation::Animation(const Animation& o)
: RefCounted<Animation>()
, m_name(o.m_name)
+ , m_nameStyleScopeOrdinal(o.m_nameStyleScopeOrdinal)
, m_property(o.m_property)
, m_mode(o.m_mode)
, m_iterationCount(o.m_iterationCount)
, m_delay(o.m_delay)
, m_duration(o.m_duration)
, m_timingFunction(o.m_timingFunction)
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+ , m_trigger(o.m_trigger)
+#endif
, m_direction(o.m_direction)
, m_fillMode(o.m_fillMode)
, m_playState(o.m_playState)
@@ -69,6 +81,9 @@ Animation::Animation(const Animation& o)
, m_playStateSet(o.m_playStateSet)
, m_propertySet(o.m_propertySet)
, m_timingFunctionSet(o.m_timingFunctionSet)
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+ , m_triggerSet(o.m_triggerSet)
+#endif
, m_isNone(o.m_isNone)
{
}
@@ -76,15 +91,22 @@ Animation::Animation(const Animation& o)
Animation& Animation::operator=(const Animation& o)
{
m_name = o.m_name;
+ m_nameStyleScopeOrdinal = o.m_nameStyleScopeOrdinal;
m_property = o.m_property;
m_mode = o.m_mode;
m_iterationCount = o.m_iterationCount;
m_delay = o.m_delay;
m_duration = o.m_duration;
m_timingFunction = o.m_timingFunction;
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+ m_trigger = o.m_trigger;
+#endif
m_direction = o.m_direction;
m_fillMode = o.m_fillMode;
m_playState = o.m_playState;
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+ m_trigger = o.m_trigger;
+#endif
m_delaySet = o.m_delaySet;
m_directionSet = o.m_directionSet;
@@ -95,6 +117,9 @@ Animation& Animation::operator=(const Animation& o)
m_playStateSet = o.m_playStateSet;
m_propertySet = o.m_propertySet;
m_timingFunctionSet = o.m_timingFunctionSet;
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+ m_triggerSet = o.m_triggerSet;
+#endif
m_isNone = o.m_isNone;
return *this;
@@ -104,39 +129,43 @@ Animation::~Animation()
{
}
-bool Animation::animationsMatch(const Animation* o, bool matchPlayStates) const
+bool Animation::animationsMatch(const Animation& other, bool matchPlayStates) const
{
- if (!o)
- return false;
-
- bool result = m_name == o->m_name
- && m_property == o->m_property
- && m_mode == o->m_mode
- && m_iterationCount == o->m_iterationCount
- && m_delay == o->m_delay
- && m_duration == o->m_duration
- && *(m_timingFunction.get()) == *(o->m_timingFunction.get())
- && m_direction == o->m_direction
- && m_fillMode == o->m_fillMode
- && m_delaySet == o->m_delaySet
- && m_directionSet == o->m_directionSet
- && m_durationSet == o->m_durationSet
- && m_fillModeSet == o->m_fillModeSet
- && m_iterationCountSet == o->m_iterationCountSet
- && m_nameSet == o->m_nameSet
- && m_propertySet == o->m_propertySet
- && m_timingFunctionSet == o->m_timingFunctionSet
- && m_isNone == o->m_isNone;
+ bool result = m_name == other.m_name
+ && m_nameStyleScopeOrdinal == other.m_nameStyleScopeOrdinal
+ && m_property == other.m_property
+ && m_mode == other.m_mode
+ && m_iterationCount == other.m_iterationCount
+ && m_delay == other.m_delay
+ && m_duration == other.m_duration
+ && *(m_timingFunction.get()) == *(other.m_timingFunction.get())
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+ && *(m_trigger.get()) == *(other.m_trigger.get())
+#endif
+ && m_direction == other.m_direction
+ && m_fillMode == other.m_fillMode
+ && m_delaySet == other.m_delaySet
+ && m_directionSet == other.m_directionSet
+ && m_durationSet == other.m_durationSet
+ && m_fillModeSet == other.m_fillModeSet
+ && m_iterationCountSet == other.m_iterationCountSet
+ && m_nameSet == other.m_nameSet
+ && m_propertySet == other.m_propertySet
+ && m_timingFunctionSet == other.m_timingFunctionSet
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+ && m_triggerSet == other.m_triggerSet
+#endif
+ && m_isNone == other.m_isNone;
if (!result)
return false;
- return !matchPlayStates || (m_playState == o->m_playState && m_playStateSet == o->m_playStateSet);
+ return !matchPlayStates || (m_playState == other.m_playState && m_playStateSet == other.m_playStateSet);
}
-const String& Animation::initialAnimationName()
+const String& Animation::initialName()
{
- DEFINE_STATIC_LOCAL(String, initialValue, (ASCIILiteral("none")));
+ static NeverDestroyed<String> initialValue(ASCIILiteral("none"));
return initialValue;
}
diff --git a/Source/WebCore/platform/animation/Animation.h b/Source/WebCore/platform/animation/Animation.h
index bc23996c6..669cc24af 100644
--- a/Source/WebCore/platform/animation/Animation.h
+++ b/Source/WebCore/platform/animation/Animation.h
@@ -2,7 +2,7 @@
* Copyright (C) 2000 Lars Knoll (knoll@kde.org)
* (C) 2000 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003-2017 Apple Inc. All rights reserved.
* Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
*
* This library is free software; you can redistribute it and/or
@@ -22,24 +22,25 @@
*
*/
-#ifndef Animation_h
-#define Animation_h
+#pragma once
#include "CSSPropertyNames.h"
#include "RenderStyleConstants.h"
+#include "StyleScope.h"
#include "TimingFunction.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/text/WTFString.h>
+
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+#include "AnimationTrigger.h"
+#endif
namespace WebCore {
class Animation : public RefCounted<Animation> {
public:
- ~Animation();
+ WEBCORE_EXPORT ~Animation();
- static PassRefPtr<Animation> create() { return adoptRef(new Animation); }
- static PassRefPtr<Animation> create(const Animation& other) { return adoptRef(new Animation(other)); }
+ static Ref<Animation> create() { return adoptRef(*new Animation); }
+ static Ref<Animation> create(const Animation& other) { return adoptRef(*new Animation(other)); }
bool isDelaySet() const { return m_delaySet; }
bool isDirectionSet() const { return m_directionSet; }
@@ -50,18 +51,26 @@ public:
bool isPlayStateSet() const { return m_playStateSet; }
bool isPropertySet() const { return m_propertySet; }
bool isTimingFunctionSet() const { return m_timingFunctionSet; }
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+ bool isTriggerSet() const { return m_triggerSet; }
+#endif
// Flags this to be the special "none" animation (animation-name: none)
bool isNoneAnimation() const { return m_isNone; }
+
// We can make placeholder Animation objects to keep the comma-separated lists
// of properties in sync. isValidAnimation means this is not a placeholder.
bool isValidAnimation() const { return !m_isNone && !m_name.isEmpty(); }
bool isEmpty() const
{
- return (!m_directionSet && !m_durationSet && !m_fillModeSet
- && !m_nameSet && !m_playStateSet && !m_iterationCountSet
- && !m_delaySet && !m_timingFunctionSet && !m_propertySet);
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+ if (m_triggerSet)
+ return false;
+#endif
+ return !m_directionSet && !m_durationSet && !m_fillModeSet
+ && !m_nameSet && !m_playStateSet && !m_iterationCountSet
+ && !m_delaySet && !m_timingFunctionSet && !m_propertySet;
}
bool isEmptyOrZeroDuration() const
@@ -78,6 +87,9 @@ public:
void clearPlayState() { m_playStateSet = AnimPlayStatePlaying; }
void clearProperty() { m_propertySet = false; }
void clearTimingFunction() { m_timingFunctionSet = false; }
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+ void clearTrigger() { m_triggerSet = false; }
+#endif
void clearAll()
{
@@ -90,15 +102,14 @@ public:
clearPlayState();
clearProperty();
clearTimingFunction();
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+ clearTrigger();
+#endif
}
double delay() const { return m_delay; }
- enum AnimationMode {
- AnimateAll,
- AnimateNone,
- AnimateSingleProperty
- };
+ enum AnimationMode { AnimateAll, AnimateNone, AnimateSingleProperty, AnimateUnknownProperty };
enum AnimationDirection {
AnimationDirectionNormal,
@@ -116,76 +127,100 @@ public:
enum { IterationCountInfinite = -1 };
double iterationCount() const { return m_iterationCount; }
const String& name() const { return m_name; }
+ Style::ScopeOrdinal nameStyleScopeOrdinal() const { return m_nameStyleScopeOrdinal; }
EAnimPlayState playState() const { return static_cast<EAnimPlayState>(m_playState); }
CSSPropertyID property() const { return m_property; }
- const PassRefPtr<TimingFunction> timingFunction() const { return m_timingFunction; }
+ const String& unknownProperty() const { return m_unknownProperty; }
+ TimingFunction* timingFunction() const { return m_timingFunction.get(); }
AnimationMode animationMode() const { return m_mode; }
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+ AnimationTrigger* trigger() const { return m_trigger.get(); }
+#endif
void setDelay(double c) { m_delay = c; m_delaySet = true; }
void setDirection(AnimationDirection d) { m_direction = d; m_directionSet = true; }
void setDuration(double d) { ASSERT(d >= 0); m_duration = d; m_durationSet = true; }
void setFillMode(unsigned f) { m_fillMode = f; m_fillModeSet = true; }
void setIterationCount(double c) { m_iterationCount = c; m_iterationCountSet = true; }
- void setName(const String& n) { m_name = n; m_nameSet = true; }
+ void setName(const String& name, Style::ScopeOrdinal scope = Style::ScopeOrdinal::Element)
+ {
+ m_name = name;
+ m_nameStyleScopeOrdinal = scope;
+ m_nameSet = true;
+ }
void setPlayState(EAnimPlayState d) { m_playState = d; m_playStateSet = true; }
void setProperty(CSSPropertyID t) { m_property = t; m_propertySet = true; }
- void setTimingFunction(PassRefPtr<TimingFunction> f) { m_timingFunction = f; m_timingFunctionSet = true; }
+ void setUnknownProperty(const String& property) { m_unknownProperty = property; }
+ void setTimingFunction(RefPtr<TimingFunction>&& function) { m_timingFunction = WTFMove(function); m_timingFunctionSet = true; }
void setAnimationMode(AnimationMode mode) { m_mode = mode; }
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+ void setTrigger(RefPtr<AnimationTrigger>&& trigger) { m_trigger = WTFMove(trigger); m_triggerSet = true; }
+#endif
void setIsNoneAnimation(bool n) { m_isNone = n; }
Animation& operator=(const Animation& o);
// return true if all members of this class match (excluding m_next)
- bool animationsMatch(const Animation*, bool matchPlayStates = true) const;
+ bool animationsMatch(const Animation&, bool matchPlayStates = true) const;
// return true every Animation in the chain (defined by m_next) match
- bool operator==(const Animation& o) const { return animationsMatch(&o); }
+ bool operator==(const Animation& o) const { return animationsMatch(o); }
bool operator!=(const Animation& o) const { return !(*this == o); }
bool fillsBackwards() const { return m_fillModeSet && (m_fillMode == AnimationFillModeBackwards || m_fillMode == AnimationFillModeBoth); }
bool fillsForwards() const { return m_fillModeSet && (m_fillMode == AnimationFillModeForwards || m_fillMode == AnimationFillModeBoth); }
private:
- Animation();
+ WEBCORE_EXPORT Animation();
Animation(const Animation& o);
String m_name;
+ Style::ScopeOrdinal m_nameStyleScopeOrdinal { Style::ScopeOrdinal::Element };
CSSPropertyID m_property;
+ String m_unknownProperty;
AnimationMode m_mode;
double m_iterationCount;
double m_delay;
double m_duration;
RefPtr<TimingFunction> m_timingFunction;
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+ RefPtr<AnimationTrigger> m_trigger;
+#endif
unsigned m_direction : 2; // AnimationDirection
unsigned m_fillMode : 2;
- unsigned m_playState : 2;
- bool m_delaySet : 1;
- bool m_directionSet : 1;
- bool m_durationSet : 1;
- bool m_fillModeSet : 1;
+ unsigned m_playState : 2;
+
+ bool m_delaySet : 1;
+ bool m_directionSet : 1;
+ bool m_durationSet : 1;
+ bool m_fillModeSet : 1;
bool m_iterationCountSet : 1;
- bool m_nameSet : 1;
- bool m_playStateSet : 1;
- bool m_propertySet : 1;
+ bool m_nameSet : 1;
+ bool m_playStateSet : 1;
+ bool m_propertySet : 1;
bool m_timingFunctionSet : 1;
-
- bool m_isNone : 1;
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+ bool m_triggerSet : 1;
+#endif
+
+ bool m_isNone : 1;
public:
- static double initialAnimationDelay() { return 0; }
- static AnimationDirection initialAnimationDirection() { return AnimationDirectionNormal; }
- static double initialAnimationDuration() { return 0; }
- static unsigned initialAnimationFillMode() { return AnimationFillModeNone; }
- static double initialAnimationIterationCount() { return 1.0; }
- static const String& initialAnimationName();
- static EAnimPlayState initialAnimationPlayState() { return AnimPlayStatePlaying; }
- static CSSPropertyID initialAnimationProperty() { return CSSPropertyInvalid; }
- static const PassRefPtr<TimingFunction> initialAnimationTimingFunction() { return CubicBezierTimingFunction::create(); }
+ static double initialDelay() { return 0; }
+ static AnimationDirection initialDirection() { return AnimationDirectionNormal; }
+ static double initialDuration() { return 0; }
+ static unsigned initialFillMode() { return AnimationFillModeNone; }
+ static double initialIterationCount() { return 1.0; }
+ static const String& initialName();
+ static EAnimPlayState initialPlayState() { return AnimPlayStatePlaying; }
+ static CSSPropertyID initialProperty() { return CSSPropertyInvalid; }
+ static Ref<TimingFunction> initialTimingFunction() { return CubicBezierTimingFunction::create(); }
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+ static Ref<AnimationTrigger> initialTrigger() { return AutoAnimationTrigger::create(); }
+#endif
};
} // namespace WebCore
-
-#endif // Animation_h
diff --git a/Source/WebCore/platform/animation/AnimationList.cpp b/Source/WebCore/platform/animation/AnimationList.cpp
index 625d79015..0a3202254 100644
--- a/Source/WebCore/platform/animation/AnimationList.cpp
+++ b/Source/WebCore/platform/animation/AnimationList.cpp
@@ -26,15 +26,16 @@ namespace WebCore {
#define FILL_UNSET_PROPERTY(test, propGet, propSet) \
for (i = 0; i < size() && animation(i).test(); ++i) { } \
-if (i < size() && i != 0) { \
+if (i) { \
for (size_t j = 0; i < size(); ++i, ++j) \
animation(i).propSet(animation(j).propGet()); \
}
AnimationList::AnimationList(const AnimationList& other)
{
- for (size_t i = 0; i < other.size(); ++i)
- m_animations.append(Animation::create(other.animation(i)));
+ m_animations.reserveInitialCapacity(other.size());
+ for (auto& animation : other.m_animations)
+ m_animations.uncheckedAppend(Animation::create(animation.get()));
}
void AnimationList::fillUnsetProperties()
@@ -55,9 +56,10 @@ bool AnimationList::operator==(const AnimationList& other) const
{
if (size() != other.size())
return false;
- for (size_t i = 0; i < size(); ++i)
+ for (size_t i = 0; i < size(); ++i) {
if (animation(i) != other.animation(i))
return false;
+ }
return true;
}
diff --git a/Source/WebCore/platform/animation/AnimationList.h b/Source/WebCore/platform/animation/AnimationList.h
index c84cb9b1d..ea7c9b78a 100644
--- a/Source/WebCore/platform/animation/AnimationList.h
+++ b/Source/WebCore/platform/animation/AnimationList.h
@@ -22,8 +22,7 @@
*
*/
-#ifndef AnimationList_h
-#define AnimationList_h
+#pragma once
#include "Animation.h"
#include <wtf/RefPtr.h>
@@ -36,6 +35,7 @@ class AnimationList {
public:
AnimationList() { }
AnimationList(const AnimationList&);
+ AnimationList(AnimationList&&) = default;
void fillUnsetProperties();
bool operator==(const AnimationList&) const;
@@ -49,22 +49,17 @@ public:
void resize(size_t n) { m_animations.resize(n); }
void remove(size_t i) { m_animations.remove(i); }
- void append(PassRefPtr<Animation> animation)
- {
- ASSERT(animation);
- m_animations.append(animation);
- }
-
- Animation& animation(size_t i) { return *m_animations[i]; }
- const Animation& animation(size_t i) const { return *m_animations[i]; }
+ void append(Ref<Animation>&& animation) { m_animations.append(WTFMove(animation)); }
+
+ Animation& animation(size_t i) { return m_animations[i].get(); }
+ const Animation& animation(size_t i) const { return m_animations[i].get(); }
private:
AnimationList& operator=(const AnimationList&);
+ AnimationList& operator=(AnimationList&&) = default;
- Vector<RefPtr<Animation>> m_animations;
+ Vector<Ref<Animation>> m_animations;
};
} // namespace WebCore
-
-#endif // AnimationList_h
diff --git a/Source/WebCore/platform/animation/AnimationTrigger.h b/Source/WebCore/platform/animation/AnimationTrigger.h
new file mode 100644
index 000000000..5ea01b20b
--- /dev/null
+++ b/Source/WebCore/platform/animation/AnimationTrigger.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+
+#include "Length.h"
+#include <wtf/Ref.h>
+#include <wtf/RefCounted.h>
+#include <wtf/TypeCasts.h>
+
+namespace WebCore {
+
+class AnimationTrigger : public RefCounted<AnimationTrigger> {
+public:
+ virtual Ref<AnimationTrigger> clone() const = 0;
+
+ virtual ~AnimationTrigger() { }
+
+ enum class AnimationTriggerType { AutoAnimationTriggerType, ScrollAnimationTriggerType };
+ AnimationTriggerType type() const { return m_type; }
+
+ bool isAutoAnimationTrigger() const { return m_type == AnimationTriggerType::AutoAnimationTriggerType; }
+ bool isScrollAnimationTrigger() const { return m_type == AnimationTriggerType::ScrollAnimationTriggerType; }
+
+ virtual bool operator==(const AnimationTrigger& other) = 0;
+
+protected:
+ AnimationTrigger(AnimationTriggerType type)
+ : m_type(type)
+ {
+ }
+
+ AnimationTriggerType m_type;
+};
+
+class AutoAnimationTrigger final : public AnimationTrigger {
+public:
+ static Ref<AutoAnimationTrigger> create()
+ {
+ return adoptRef(*new AutoAnimationTrigger);
+ }
+
+ bool operator==(const AnimationTrigger& other) final
+ {
+ return other.isAutoAnimationTrigger();
+ }
+
+private:
+ AutoAnimationTrigger()
+ : AnimationTrigger(AnimationTriggerType::AutoAnimationTriggerType)
+ {
+ }
+
+ Ref<AnimationTrigger> clone() const final
+ {
+ return adoptRef(*new AutoAnimationTrigger);
+ }
+};
+
+class ScrollAnimationTrigger final : public AnimationTrigger {
+public:
+ static Ref<ScrollAnimationTrigger> create(Length startValue, Length endValue)
+ {
+ return adoptRef(*new ScrollAnimationTrigger(startValue, endValue));
+ }
+
+ bool operator==(const AnimationTrigger& other) final
+ {
+ if (!other.isScrollAnimationTrigger())
+ return false;
+
+ const ScrollAnimationTrigger* otherTrigger = static_cast<const ScrollAnimationTrigger*>(&other);
+ return m_startValue == otherTrigger->m_startValue
+ && m_endValue == otherTrigger->m_endValue
+ && m_hasEndValue == otherTrigger->m_hasEndValue;
+ }
+
+ Length startValue() const { return m_startValue; }
+
+ void setStartValue(Length value)
+ {
+ m_startValue = value;
+ }
+
+ Length endValue() const { return m_endValue; }
+
+ void setEndValue(Length value)
+ {
+ m_endValue = value;
+ }
+
+ bool hasEndValue() const { return !m_endValue.isAuto() && m_endValue.value() > m_startValue.value(); }
+
+private:
+ explicit ScrollAnimationTrigger(Length startValue, Length endValue)
+ : AnimationTrigger(AnimationTriggerType::ScrollAnimationTriggerType)
+ , m_startValue(startValue)
+ {
+ if (!endValue.isAuto() && endValue.value() > startValue.value())
+ m_endValue = endValue;
+ }
+
+ Ref<AnimationTrigger> clone() const final
+ {
+ return adoptRef(*new ScrollAnimationTrigger(m_startValue, m_endValue));
+ }
+
+ Length m_startValue;
+ Length m_endValue;
+ bool m_hasEndValue;
+};
+
+} // namespace WebCore
+
+#define SPECIALIZE_TYPE_TRAITS_ANIMATION_TRIGGER(ToClassName, TriggerTest) \
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToClassName) \
+static bool isType(const WebCore::AnimationTrigger& trigger) { return trigger.TriggerTest(); } \
+SPECIALIZE_TYPE_TRAITS_END()
+
+SPECIALIZE_TYPE_TRAITS_ANIMATION_TRIGGER(AutoAnimationTrigger, isAutoAnimationTrigger);
+SPECIALIZE_TYPE_TRAITS_ANIMATION_TRIGGER(ScrollAnimationTrigger, isScrollAnimationTrigger);
+
+#endif
diff --git a/Source/WebCore/platform/animation/AnimationUtilities.h b/Source/WebCore/platform/animation/AnimationUtilities.h
index 7a4f6f58a..dc4942df5 100644
--- a/Source/WebCore/platform/animation/AnimationUtilities.h
+++ b/Source/WebCore/platform/animation/AnimationUtilities.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -28,7 +28,6 @@
#include "IntPoint.h"
#include "LayoutUnit.h"
-#include <wtf/MathExtras.h>
namespace WebCore {
diff --git a/Source/WebCore/platform/animation/TimingFunction.cpp b/Source/WebCore/platform/animation/TimingFunction.cpp
new file mode 100644
index 000000000..c0cc4be76
--- /dev/null
+++ b/Source/WebCore/platform/animation/TimingFunction.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TimingFunction.h"
+
+#include "TextStream.h"
+
+namespace WebCore {
+
+TextStream& operator<<(TextStream& ts, const TimingFunction& timingFunction)
+{
+ switch (timingFunction.type()) {
+ case TimingFunction::LinearFunction:
+ ts << "linear";
+ break;
+ case TimingFunction::CubicBezierFunction: {
+ auto& function = static_cast<const CubicBezierTimingFunction&>(timingFunction);
+ ts << "cubic-bezier(" << function.x1() << ", " << function.y1() << ", " << function.x2() << ", " << function.y2() << ")";
+ break;
+ }
+ case TimingFunction::StepsFunction: {
+ auto& function = static_cast<const StepsTimingFunction&>(timingFunction);
+ ts << "steps(" << function.numberOfSteps() << ", " << (function.stepAtStart() ? "start" : "end") << ")";
+ break;
+ }
+ case TimingFunction::SpringFunction: {
+ auto& function = static_cast<const SpringTimingFunction&>(timingFunction);
+ ts << "spring(" << function.mass() << " " << function.stiffness() << " " << function.damping() << " " << function.initialVelocity() << ")";
+ break;
+ }
+ }
+ return ts;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/animation/TimingFunction.h b/Source/WebCore/platform/animation/TimingFunction.h
index 611399340..fcaa3c3ff 100644
--- a/Source/WebCore/platform/animation/TimingFunction.h
+++ b/Source/WebCore/platform/animation/TimingFunction.h
@@ -22,109 +22,108 @@
*
*/
-#ifndef TimingFunction_h
-#define TimingFunction_h
+#pragma once
+#include <wtf/Ref.h>
#include <wtf/RefCounted.h>
namespace WebCore {
+class TextStream;
+
class TimingFunction : public RefCounted<TimingFunction> {
public:
+ virtual Ref<TimingFunction> clone() const = 0;
- enum TimingFunctionType {
- LinearFunction, CubicBezierFunction, StepsFunction
- };
-
virtual ~TimingFunction() { }
+ enum TimingFunctionType { LinearFunction, CubicBezierFunction, StepsFunction, SpringFunction };
TimingFunctionType type() const { return m_type; }
-
+
bool isLinearTimingFunction() const { return m_type == LinearFunction; }
bool isCubicBezierTimingFunction() const { return m_type == CubicBezierFunction; }
bool isStepsTimingFunction() const { return m_type == StepsFunction; }
-
- virtual bool operator==(const TimingFunction& other) = 0;
+ bool isSpringTimingFunction() const { return m_type == SpringFunction; }
+
+ virtual bool operator==(const TimingFunction&) const = 0;
+ bool operator!=(const TimingFunction& other) const { return !(*this == other); }
protected:
- TimingFunction(TimingFunctionType type)
+ explicit TimingFunction(TimingFunctionType type)
: m_type(type)
{
}
-
+
+private:
TimingFunctionType m_type;
};
-class LinearTimingFunction : public TimingFunction {
+class LinearTimingFunction final : public TimingFunction {
public:
- static PassRefPtr<LinearTimingFunction> create()
+ static Ref<LinearTimingFunction> create()
{
- return adoptRef(new LinearTimingFunction);
+ return adoptRef(*new LinearTimingFunction);
}
- virtual ~LinearTimingFunction() { }
-
- virtual bool operator==(const TimingFunction& other) override
+ bool operator==(const TimingFunction& other) const final
{
return other.isLinearTimingFunction();
}
-
+
private:
LinearTimingFunction()
: TimingFunction(LinearFunction)
{
}
+
+ Ref<TimingFunction> clone() const final
+ {
+ return adoptRef(*new LinearTimingFunction);
+ }
};
-
-class CubicBezierTimingFunction : public TimingFunction {
+
+class CubicBezierTimingFunction final : public TimingFunction {
public:
- enum TimingFunctionPreset {
- Ease,
- EaseIn,
- EaseOut,
- EaseInOut,
- Custom
- };
+ enum TimingFunctionPreset { Ease, EaseIn, EaseOut, EaseInOut, Custom };
- static PassRefPtr<CubicBezierTimingFunction> create(double x1, double y1, double x2, double y2)
+ static Ref<CubicBezierTimingFunction> create(double x1, double y1, double x2, double y2)
{
- return adoptRef(new CubicBezierTimingFunction(Custom, x1, y1, x2, y2));
+ return adoptRef(*new CubicBezierTimingFunction(Custom, x1, y1, x2, y2));
}
- static PassRefPtr<CubicBezierTimingFunction> create()
+ static Ref<CubicBezierTimingFunction> create()
{
- return adoptRef(new CubicBezierTimingFunction());
+ return adoptRef(*new CubicBezierTimingFunction());
}
- static PassRefPtr<CubicBezierTimingFunction> create(TimingFunctionPreset preset)
+ static Ref<CubicBezierTimingFunction> create(TimingFunctionPreset preset)
{
switch (preset) {
case Ease:
- return adoptRef(new CubicBezierTimingFunction());
+ return adoptRef(*new CubicBezierTimingFunction);
case EaseIn:
- return adoptRef(new CubicBezierTimingFunction(EaseIn, 0.42, 0.0, 1.0, 1.0));
+ return adoptRef(*new CubicBezierTimingFunction(EaseIn, 0.42, 0.0, 1.0, 1.0));
case EaseOut:
- return adoptRef(new CubicBezierTimingFunction(EaseOut, 0.0, 0.0, 0.58, 1.0));
+ return adoptRef(*new CubicBezierTimingFunction(EaseOut, 0.0, 0.0, 0.58, 1.0));
case EaseInOut:
- return adoptRef(new CubicBezierTimingFunction(EaseInOut, 0.42, 0.0, 0.58, 1.0));
- default:
- ASSERT_NOT_REACHED();
- return 0;
+ return adoptRef(*new CubicBezierTimingFunction(EaseInOut, 0.42, 0.0, 0.58, 1.0));
+ case Custom:
+ break;
}
+ ASSERT_NOT_REACHED();
+ return adoptRef(*new CubicBezierTimingFunction);
}
- virtual ~CubicBezierTimingFunction() { }
-
- virtual bool operator==(const TimingFunction& other) override
- {
- if (other.isCubicBezierTimingFunction()) {
- const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimingFunction*>(&other);
- if (m_timingFunctionPreset != Custom)
- return m_timingFunctionPreset == ctf->m_timingFunctionPreset;
-
- return m_x1 == ctf->m_x1 && m_y1 == ctf->m_y1 && m_x2 == ctf->m_x2 && m_y2 == ctf->m_y2;
- }
- return false;
+ bool operator==(const TimingFunction& other) const final
+ {
+ if (!other.isCubicBezierTimingFunction())
+ return false;
+ auto& otherCubic = static_cast<const CubicBezierTimingFunction&>(other);
+ if (m_timingFunctionPreset != otherCubic.m_timingFunctionPreset)
+ return false;
+ if (m_timingFunctionPreset != Custom)
+ return true;
+ return m_x1 == otherCubic.m_x1 && m_y1 == otherCubic.m_y1 && m_x2 == otherCubic.m_x2 && m_y2 == otherCubic.m_y2;
}
double x1() const { return m_x1; }
@@ -132,19 +131,28 @@ public:
double x2() const { return m_x2; }
double y2() const { return m_y2; }
+ void setValues(double x1, double y1, double x2, double y2)
+ {
+ m_x1 = x1;
+ m_y1 = y1;
+ m_x2 = x2;
+ m_y2 = y2;
+ }
+
TimingFunctionPreset timingFunctionPreset() const { return m_timingFunctionPreset; }
-
- static const CubicBezierTimingFunction* defaultTimingFunction()
+ void setTimingFunctionPreset(TimingFunctionPreset preset) { m_timingFunctionPreset = preset; }
+
+ static const CubicBezierTimingFunction& defaultTimingFunction()
{
- static const CubicBezierTimingFunction* dtf = create().leakRef();
- return dtf;
+ static const CubicBezierTimingFunction& function = create().leakRef();
+ return function;
}
- PassRefPtr<CubicBezierTimingFunction> createReversed() const
+ Ref<CubicBezierTimingFunction> createReversed() const
{
return create(1.0 - m_x2, 1.0 - m_y2, 1.0 - m_x1, 1.0 - m_y1);
}
-
+
private:
explicit CubicBezierTimingFunction(TimingFunctionPreset preset = Ease, double x1 = 0.25, double y1 = 0.1, double x2 = 0.25, double y2 = 1.0)
: TimingFunction(CubicBezierFunction)
@@ -156,6 +164,11 @@ private:
{
}
+ Ref<TimingFunction> clone() const final
+ {
+ return adoptRef(*new CubicBezierTimingFunction(m_timingFunctionPreset, m_x1, m_y1, m_x2, m_y2));
+ }
+
double m_x1;
double m_y1;
double m_x2;
@@ -163,27 +176,31 @@ private:
TimingFunctionPreset m_timingFunctionPreset;
};
-class StepsTimingFunction : public TimingFunction {
+class StepsTimingFunction final : public TimingFunction {
public:
- static PassRefPtr<StepsTimingFunction> create(int steps, bool stepAtStart)
+ static Ref<StepsTimingFunction> create(int steps, bool stepAtStart)
{
- return adoptRef(new StepsTimingFunction(steps, stepAtStart));
+ return adoptRef(*new StepsTimingFunction(steps, stepAtStart));
+ }
+ static Ref<StepsTimingFunction> create()
+ {
+ return adoptRef(*new StepsTimingFunction(1, true));
}
- virtual ~StepsTimingFunction() { }
-
- virtual bool operator==(const TimingFunction& other) override
+ bool operator==(const TimingFunction& other) const final
{
- if (other.isStepsTimingFunction()) {
- const StepsTimingFunction* stf = static_cast<const StepsTimingFunction*>(&other);
- return m_steps == stf->m_steps && m_stepAtStart == stf->m_stepAtStart;
- }
- return false;
+ if (!other.isStepsTimingFunction())
+ return false;
+ auto& otherSteps = static_cast<const StepsTimingFunction&>(other);
+ return m_steps == otherSteps.m_steps && m_stepAtStart == otherSteps.m_stepAtStart;
}
int numberOfSteps() const { return m_steps; }
+ void setNumberOfSteps(int steps) { m_steps = steps; }
+
bool stepAtStart() const { return m_stepAtStart; }
-
+ void setStepAtStart(bool stepAtStart) { m_stepAtStart = stepAtStart; }
+
private:
StepsTimingFunction(int steps, bool stepAtStart)
: TimingFunction(StepsFunction)
@@ -191,11 +208,72 @@ private:
, m_stepAtStart(stepAtStart)
{
}
+
+ Ref<TimingFunction> clone() const final
+ {
+ return adoptRef(*new StepsTimingFunction(m_steps, m_stepAtStart));
+ }
int m_steps;
bool m_stepAtStart;
};
+
+class SpringTimingFunction final : public TimingFunction {
+public:
+ static Ref<SpringTimingFunction> create(double mass, double stiffness, double damping, double initialVelocity)
+ {
+ return adoptRef(*new SpringTimingFunction(mass, stiffness, damping, initialVelocity));
+ }
+
+ static Ref<SpringTimingFunction> create()
+ {
+ // This create() function should only be used by the argument decoders, and it is expected that
+ // real values will be filled in using setValues().
+ return create(0, 0, 0, 0);
+ }
-} // namespace WebCore
+ bool operator==(const TimingFunction& other) const final
+ {
+ if (!other.isSpringTimingFunction())
+ return false;
+ auto& otherSpring = static_cast<const SpringTimingFunction&>(other);
+ return m_mass == otherSpring.m_mass && m_stiffness == otherSpring.m_stiffness && m_damping == otherSpring.m_damping && m_initialVelocity == otherSpring.m_initialVelocity;
+ }
+
+ double mass() const { return m_mass; }
+ double stiffness() const { return m_stiffness; }
+ double damping() const { return m_damping; }
+ double initialVelocity() const { return m_initialVelocity; }
+
+ void setValues(double mass, double stiffness, double damping, double initialVelocity)
+ {
+ m_mass = mass;
+ m_stiffness = stiffness;
+ m_damping = damping;
+ m_initialVelocity = initialVelocity;
+ }
+
+private:
+ explicit SpringTimingFunction(double mass, double stiffness, double damping, double initialVelocity)
+ : TimingFunction(SpringFunction)
+ , m_mass(mass)
+ , m_stiffness(stiffness)
+ , m_damping(damping)
+ , m_initialVelocity(initialVelocity)
+ {
+ }
+
+ Ref<TimingFunction> clone() const final
+ {
+ return adoptRef(*new SpringTimingFunction(m_mass, m_stiffness, m_damping, m_initialVelocity));
+ }
-#endif // TimingFunction_h
+ double m_mass;
+ double m_stiffness;
+ double m_damping;
+ double m_initialVelocity;
+};
+
+WEBCORE_EXPORT TextStream& operator<<(TextStream&, const TimingFunction&);
+
+} // namespace WebCore