diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:41 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:41 -0800 |
commit | 648161bb0edfc3d43db63caed5cc5213bc6cb78f (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /WebCore/page/animation | |
parent | a65af38181ac7d34544586bdb5cd004de93897ad (diff) | |
download | external_webkit-648161bb0edfc3d43db63caed5cc5213bc6cb78f.zip external_webkit-648161bb0edfc3d43db63caed5cc5213bc6cb78f.tar.gz external_webkit-648161bb0edfc3d43db63caed5cc5213bc6cb78f.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'WebCore/page/animation')
-rw-r--r-- | WebCore/page/animation/AnimationBase.cpp | 815 | ||||
-rw-r--r-- | WebCore/page/animation/AnimationBase.h | 254 | ||||
-rw-r--r-- | WebCore/page/animation/AnimationController.cpp | 298 | ||||
-rw-r--r-- | WebCore/page/animation/AnimationController.h | 78 | ||||
-rw-r--r-- | WebCore/page/animation/CompositeAnimation.cpp | 594 | ||||
-rw-r--r-- | WebCore/page/animation/CompositeAnimation.h | 77 | ||||
-rw-r--r-- | WebCore/page/animation/ImplicitAnimation.cpp | 203 | ||||
-rw-r--r-- | WebCore/page/animation/ImplicitAnimation.h | 88 | ||||
-rw-r--r-- | WebCore/page/animation/KeyframeAnimation.cpp | 293 | ||||
-rw-r--r-- | WebCore/page/animation/KeyframeAnimation.h | 92 |
10 files changed, 0 insertions, 2792 deletions
diff --git a/WebCore/page/animation/AnimationBase.cpp b/WebCore/page/animation/AnimationBase.cpp deleted file mode 100644 index fc28469..0000000 --- a/WebCore/page/animation/AnimationBase.cpp +++ /dev/null @@ -1,815 +0,0 @@ -/* - * Copyright (C) 2007 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 "AnimationBase.h" - -#include "AnimationController.h" -#include "CSSPropertyNames.h" -#include "CString.h" -#include "CompositeAnimation.h" -#include "Document.h" -#include "EventNames.h" -#include "FloatConversion.h" -#include "Frame.h" -#include "IdentityTransformOperation.h" -#include "ImplicitAnimation.h" -#include "KeyframeAnimation.h" -#include "MatrixTransformOperation.h" -#include "RenderObject.h" -#include "RenderStyle.h" -#include "SystemTime.h" -#include "UnitBezier.h" - -namespace WebCore { - -static const double cAnimationTimerDelay = 0.025; - -// The epsilon value we pass to UnitBezier::solve given that the animation is going to run over |dur| seconds. The longer the -// animation, the more precision we need in the timing function result to avoid ugly discontinuities. -static inline double solveEpsilon(double duration) -{ - return 1.0 / (200.0 * duration); -} - -static inline double solveCubicBezierFunction(double p1x, double p1y, double p2x, double p2y, double t, double duration) -{ - // Convert from input time to parametric value in curve, then from - // that to output time. - UnitBezier bezier(p1x, p1y, p2x, p2y); - return bezier.solve(t, solveEpsilon(duration)); -} - -void AnimationTimerCallback::timerFired(Timer<AnimationTimerBase>*) -{ - m_anim->animationTimerCallbackFired(m_eventType, m_elapsedTime); -} - -static inline int blendFunc(const AnimationBase* anim, int from, int to, double progress) -{ - return int(from + (to - from) * progress); -} - -static inline double blendFunc(const AnimationBase* anim, double from, double to, double progress) -{ - return from + (to - from) * progress; -} - -static inline float blendFunc(const AnimationBase* anim, float from, float to, double progress) -{ - return narrowPrecisionToFloat(from + (to - from) * progress); -} - -static inline Color blendFunc(const AnimationBase* anim, const Color& from, const Color& to, double progress) -{ - return Color(blendFunc(anim, from.red(), to.red(), progress), - blendFunc(anim, from.green(), to.green(), progress), - blendFunc(anim, from.blue(), to.blue(), progress), - blendFunc(anim, from.alpha(), to.alpha(), progress)); -} - -static inline Length blendFunc(const AnimationBase* anim, const Length& from, const Length& to, double progress) -{ - return to.blend(from, progress); -} - -static inline IntSize blendFunc(const AnimationBase* anim, const IntSize& from, const IntSize& to, double progress) -{ - return IntSize(blendFunc(anim, from.width(), to.width(), progress), - blendFunc(anim, from.height(), to.height(), progress)); -} - -static inline ShadowData* blendFunc(const AnimationBase* anim, const ShadowData* from, const ShadowData* to, double progress) -{ - ASSERT(from && to); - return new ShadowData(blendFunc(anim, from->x, to->x, progress), blendFunc(anim, from->y, to->y, progress), - blendFunc(anim, from->blur, to->blur, progress), blendFunc(anim, from->color, to->color, progress)); -} - -static inline TransformOperations blendFunc(const AnimationBase* anim, const TransformOperations& from, const TransformOperations& to, double progress) -{ - TransformOperations result; - - // If we have a transform function list, use that to do a per-function animation. Otherwise do a Matrix animation - if (anim->isTransformFunctionListValid()) { - unsigned fromSize = from.operations().size(); - unsigned toSize = to.operations().size(); - unsigned size = max(fromSize, toSize); - for (unsigned i = 0; i < size; i++) { - RefPtr<TransformOperation> fromOp = (i < fromSize) ? from.operations()[i].get() : 0; - RefPtr<TransformOperation> toOp = (i < toSize) ? to.operations()[i].get() : 0; - RefPtr<TransformOperation> blendedOp = toOp ? toOp->blend(fromOp.get(), progress) : (fromOp ? fromOp->blend(0, progress, true) : 0); - if (blendedOp) - result.operations().append(blendedOp); - else { - RefPtr<TransformOperation> identityOp = IdentityTransformOperation::create(); - if (progress > 0.5) - result.operations().append(toOp ? toOp : identityOp); - else - result.operations().append(fromOp ? fromOp : identityOp); - } - } - } else { - // Convert the TransformOperations into matrices - IntSize size = anim->renderer()->borderBox().size(); - AffineTransform fromT; - AffineTransform toT; - from.apply(size, fromT); - to.apply(size, toT); - - toT.blend(fromT, progress); - - // Append the result - result.operations().append(MatrixTransformOperation::create(toT.a(), toT.b(), toT.c(), toT.d(), toT.e(), toT.f())); - } - return result; -} - -static inline EVisibility blendFunc(const AnimationBase* anim, EVisibility from, EVisibility to, double progress) -{ - // Any non-zero result means we consider the object to be visible. Only at 0 do we consider the object to be - // invisible. The invisible value we use (HIDDEN vs. COLLAPSE) depends on the specified from/to values. - double fromVal = from == VISIBLE ? 1. : 0.; - double toVal = to == VISIBLE ? 1. : 0.; - if (fromVal == toVal) - return to; - double result = blendFunc(anim, fromVal, toVal, progress); - return result > 0. ? VISIBLE : (to != VISIBLE ? to : from); -} - -class PropertyWrapperBase { -public: - PropertyWrapperBase(int prop) - : m_prop(prop) - { - } - - virtual ~PropertyWrapperBase() { } - virtual bool equals(const RenderStyle* a, const RenderStyle* b) const = 0; - virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const = 0; - - int property() const { return m_prop; } - -private: - int m_prop; -}; - -template <typename T> -class PropertyWrapperGetter : public PropertyWrapperBase { -public: - PropertyWrapperGetter(int prop, T (RenderStyle::*getter)() const) - : PropertyWrapperBase(prop) - , m_getter(getter) - { - } - - virtual bool equals(const RenderStyle* a, const RenderStyle* b) const - { - // If the style pointers are the same, don't bother doing the test. - // If either is null, return false. If both are null, return true. - if (!a && !b || a == b) - return true; - if (!a || !b) - return false; - return (a->*m_getter)() == (b->*m_getter)(); - } - -protected: - T (RenderStyle::*m_getter)() const; -}; - -template <typename T> -class PropertyWrapper : public PropertyWrapperGetter<T> { -public: - PropertyWrapper(int prop, T (RenderStyle::*getter)() const, void (RenderStyle::*setter)(T)) - : PropertyWrapperGetter<T>(prop, getter) - , m_setter(setter) - { - } - - virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const - { - (dst->*m_setter)(blendFunc(anim, (a->*PropertyWrapperGetter<T>::m_getter)(), (b->*PropertyWrapperGetter<T>::m_getter)(), progress)); - } - -protected: - void (RenderStyle::*m_setter)(T); -}; - -class PropertyWrapperShadow : public PropertyWrapperGetter<ShadowData*> { -public: - PropertyWrapperShadow(int prop, ShadowData* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(ShadowData*, bool)) - : PropertyWrapperGetter<ShadowData*>(prop, getter) - , m_setter(setter) - { - } - - virtual bool equals(const RenderStyle* a, const RenderStyle* b) const - { - ShadowData* shadowA = (a->*m_getter)(); - ShadowData* shadowB = (b->*m_getter)(); - - if (!shadowA && shadowB || shadowA && !shadowB) - return false; - if (shadowA && shadowB && (*shadowA != *shadowB)) - return false; - return true; - } - - virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const - { - ShadowData* shadowA = (a->*m_getter)(); - ShadowData* shadowB = (b->*m_getter)(); - ShadowData defaultShadowData(0, 0, 0, Color::transparent); - - if (!shadowA) - shadowA = &defaultShadowData; - if (!shadowB) - shadowB = &defaultShadowData; - - (dst->*m_setter)(blendFunc(anim, shadowA, shadowB, progress), false); - } - -private: - void (RenderStyle::*m_setter)(ShadowData*, bool); -}; - -class PropertyWrapperMaybeInvalidColor : public PropertyWrapperBase { -public: - PropertyWrapperMaybeInvalidColor(int prop, const Color& (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&)) - : PropertyWrapperBase(prop) - , m_getter(getter) - , m_setter(setter) - { - } - - virtual bool equals(const RenderStyle* a, const RenderStyle* b) const - { - Color fromColor = (a->*m_getter)(); - Color toColor = (b->*m_getter)(); - if (!fromColor.isValid()) - fromColor = a->color(); - if (!toColor.isValid()) - toColor = b->color(); - - return fromColor == toColor; - } - - virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const - { - Color fromColor = (a->*m_getter)(); - Color toColor = (b->*m_getter)(); - if (!fromColor.isValid()) - fromColor = a->color(); - if (!toColor.isValid()) - toColor = b->color(); - (dst->*m_setter)(blendFunc(anim, fromColor, toColor, progress)); - } - -private: - const Color& (RenderStyle::*m_getter)() const; - void (RenderStyle::*m_setter)(const Color&); -}; - -static Vector<PropertyWrapperBase*>* gPropertyWrappers = 0; -static int gPropertyWrapperMap[numCSSProperties]; - -static void ensurePropertyMap() -{ - // FIXME: This data is never destroyed. Maybe we should ref count it and toss it when the last AnimationController is destroyed? - if (gPropertyWrappers == 0) { - gPropertyWrappers = new Vector<PropertyWrapperBase*>(); - - // build the list of property wrappers to do the comparisons and blends - gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyLeft, &RenderStyle::left, &RenderStyle::setLeft)); - gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyRight, &RenderStyle::right, &RenderStyle::setRight)); - gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyTop, &RenderStyle::top, &RenderStyle::setTop)); - gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyBottom, &RenderStyle::bottom, &RenderStyle::setBottom)); - gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWidth, &RenderStyle::width, &RenderStyle::setWidth)); - gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyHeight, &RenderStyle::height, &RenderStyle::setHeight)); - gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyBorderLeftWidth, &RenderStyle::borderLeftWidth, &RenderStyle::setBorderLeftWidth)); - gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyBorderRightWidth, &RenderStyle::borderRightWidth, &RenderStyle::setBorderRightWidth)); - gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyBorderTopWidth, &RenderStyle::borderTopWidth, &RenderStyle::setBorderTopWidth)); - gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyBorderBottomWidth, &RenderStyle::borderBottomWidth, &RenderStyle::setBorderBottomWidth)); - gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMarginLeft, &RenderStyle::marginLeft, &RenderStyle::setMarginLeft)); - gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMarginRight, &RenderStyle::marginRight, &RenderStyle::setMarginRight)); - gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMarginTop, &RenderStyle::marginTop, &RenderStyle::setMarginTop)); - gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMarginBottom, &RenderStyle::marginBottom, &RenderStyle::setMarginBottom)); - gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyPaddingLeft, &RenderStyle::paddingLeft, &RenderStyle::setPaddingLeft)); - gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyPaddingRight, &RenderStyle::paddingRight, &RenderStyle::setPaddingRight)); - gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyPaddingTop, &RenderStyle::paddingTop, &RenderStyle::setPaddingTop)); - gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyPaddingBottom, &RenderStyle::paddingBottom, &RenderStyle::setPaddingBottom)); - gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyOpacity, &RenderStyle::opacity, &RenderStyle::setOpacity)); - gPropertyWrappers->append(new PropertyWrapper<const Color&>(CSSPropertyColor, &RenderStyle::color, &RenderStyle::setColor)); - gPropertyWrappers->append(new PropertyWrapper<const Color&>(CSSPropertyBackgroundColor, &RenderStyle::backgroundColor, &RenderStyle::setBackgroundColor)); - gPropertyWrappers->append(new PropertyWrapper<int>(CSSPropertyFontSize, &RenderStyle::fontSize, &RenderStyle::setBlendedFontSize)); - gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyWebkitColumnRuleWidth, &RenderStyle::columnRuleWidth, &RenderStyle::setColumnRuleWidth)); - gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyWebkitColumnGap, &RenderStyle::columnGap, &RenderStyle::setColumnGap)); - gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyWebkitColumnCount, &RenderStyle::columnCount, &RenderStyle::setColumnCount)); - gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyWebkitColumnWidth, &RenderStyle::columnWidth, &RenderStyle::setColumnWidth)); - gPropertyWrappers->append(new PropertyWrapper<short>(CSSPropertyWebkitBorderHorizontalSpacing, &RenderStyle::horizontalBorderSpacing, &RenderStyle::setHorizontalBorderSpacing)); - gPropertyWrappers->append(new PropertyWrapper<short>(CSSPropertyWebkitBorderVerticalSpacing, &RenderStyle::verticalBorderSpacing, &RenderStyle::setVerticalBorderSpacing)); - gPropertyWrappers->append(new PropertyWrapper<int>(CSSPropertyZIndex, &RenderStyle::zIndex, &RenderStyle::setZIndex)); - gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyLineHeight, &RenderStyle::lineHeight, &RenderStyle::setLineHeight)); - gPropertyWrappers->append(new PropertyWrapper<int>(CSSPropertyOutlineOffset, &RenderStyle::outlineOffset, &RenderStyle::setOutlineOffset)); - gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyOutlineWidth, &RenderStyle::outlineWidth, &RenderStyle::setOutlineWidth)); - gPropertyWrappers->append(new PropertyWrapper<int>(CSSPropertyLetterSpacing, &RenderStyle::letterSpacing, &RenderStyle::setLetterSpacing)); - gPropertyWrappers->append(new PropertyWrapper<int>(CSSPropertyWordSpacing, &RenderStyle::wordSpacing, &RenderStyle::setWordSpacing)); - gPropertyWrappers->append(new PropertyWrapper<const TransformOperations&>(CSSPropertyWebkitTransform, &RenderStyle::transform, &RenderStyle::setTransform)); - gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWebkitTransformOriginX, &RenderStyle::transformOriginX, &RenderStyle::setTransformOriginX)); - gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWebkitTransformOriginY, &RenderStyle::transformOriginY, &RenderStyle::setTransformOriginY)); - gPropertyWrappers->append(new PropertyWrapper<const IntSize&>(CSSPropertyWebkitBorderTopLeftRadius, &RenderStyle::borderTopLeftRadius, &RenderStyle::setBorderTopLeftRadius)); - gPropertyWrappers->append(new PropertyWrapper<const IntSize&>(CSSPropertyWebkitBorderTopRightRadius, &RenderStyle::borderTopRightRadius, &RenderStyle::setBorderTopRightRadius)); - gPropertyWrappers->append(new PropertyWrapper<const IntSize&>(CSSPropertyWebkitBorderBottomLeftRadius, &RenderStyle::borderBottomLeftRadius, &RenderStyle::setBorderBottomLeftRadius)); - gPropertyWrappers->append(new PropertyWrapper<const IntSize&>(CSSPropertyWebkitBorderBottomRightRadius, &RenderStyle::borderBottomRightRadius, &RenderStyle::setBorderBottomRightRadius)); - gPropertyWrappers->append(new PropertyWrapper<EVisibility>(CSSPropertyVisibility, &RenderStyle::visibility, &RenderStyle::setVisibility)); - gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyZoom, &RenderStyle::zoom, &RenderStyle::setZoom)); - gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyWebkitColumnRuleColor, &RenderStyle::columnRuleColor, &RenderStyle::setColumnRuleColor)); - gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyWebkitTextStrokeColor, &RenderStyle::textStrokeColor, &RenderStyle::setTextStrokeColor)); - gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyWebkitTextFillColor, &RenderStyle::textFillColor, &RenderStyle::setTextFillColor)); - gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyBorderLeftColor, &RenderStyle::borderLeftColor, &RenderStyle::setBorderLeftColor)); - gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyBorderRightColor, &RenderStyle::borderRightColor, &RenderStyle::setBorderRightColor)); - gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyBorderTopColor, &RenderStyle::borderTopColor, &RenderStyle::setBorderTopColor)); - gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyBorderBottomColor, &RenderStyle::borderBottomColor, &RenderStyle::setBorderBottomColor)); - gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyOutlineColor, &RenderStyle::outlineColor, &RenderStyle::setOutlineColor)); - - // These are for shadows - gPropertyWrappers->append(new PropertyWrapperShadow(CSSPropertyWebkitBoxShadow, &RenderStyle::boxShadow, &RenderStyle::setBoxShadow)); - gPropertyWrappers->append(new PropertyWrapperShadow(CSSPropertyTextShadow, &RenderStyle::textShadow, &RenderStyle::setTextShadow)); - -#if ENABLE(SVG) - gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyFillOpacity, &RenderStyle::fillOpacity, &RenderStyle::setFillOpacity)); - gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyFloodOpacity, &RenderStyle::floodOpacity, &RenderStyle::setFloodOpacity)); - gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyStrokeOpacity, &RenderStyle::strokeOpacity, &RenderStyle::setStrokeOpacity)); -#endif - - // Make sure unused slots have a value - for (unsigned int i = 0; i < (unsigned int) numCSSProperties; ++i) - gPropertyWrapperMap[i] = CSSPropertyInvalid; - - size_t n = gPropertyWrappers->size(); - for (unsigned int i = 0; i < n; ++i) { - ASSERT((*gPropertyWrappers)[i]->property() - firstCSSProperty < numCSSProperties); - gPropertyWrapperMap[(*gPropertyWrappers)[i]->property() - firstCSSProperty] = i; - } - } -} - -AnimationBase::AnimationBase(const Animation* transition, RenderObject* renderer, CompositeAnimation* compAnim) - : m_animState(AnimationStateNew) - , m_iteration(0) - , m_isAnimating(false) - , m_waitedForResponse(false) - , m_startTime(0) - , m_pauseTime(-1) - , m_object(renderer) - , m_animationTimerCallback(const_cast<AnimationBase*>(this)) - , m_animation(const_cast<Animation*>(transition)) - , m_compAnim(compAnim) - , m_transformFunctionListValid(false) -{ -} - -AnimationBase::~AnimationBase() -{ - if (m_animState == AnimationStateStartWaitStyleAvailable) - m_compAnim->setWaitingForStyleAvailable(false); -} - -bool AnimationBase::propertiesEqual(int prop, const RenderStyle* a, const RenderStyle* b) -{ - ensurePropertyMap(); - if (prop == cAnimateAll) { - size_t n = gPropertyWrappers->size(); - for (unsigned int i = 0; i < n; ++i) { - if (!(*gPropertyWrappers)[i]->equals(a, b)) - return false; - } - } else { - int propIndex = prop - firstCSSProperty; - - if (propIndex >= 0 && propIndex < numCSSProperties) { - int i = gPropertyWrapperMap[propIndex]; - return i >= 0 ? (*gPropertyWrappers)[i]->equals(a, b) : true; - } - } - return true; -} - -int AnimationBase::getPropertyAtIndex(int i) -{ - ensurePropertyMap(); - if (i < 0 || i >= static_cast<int>(gPropertyWrappers->size())) - return CSSPropertyInvalid; - - return (*gPropertyWrappers)[i]->property(); -} - -int AnimationBase::getNumProperties() -{ - ensurePropertyMap(); - return gPropertyWrappers->size(); -} - -// Returns true if we need to start animation timers -bool AnimationBase::blendProperties(const AnimationBase* anim, int prop, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) -{ - ASSERT(prop != cAnimateAll); - // FIXME: Why can this happen? - - ensurePropertyMap(); - if (prop == cAnimateAll) { - bool needsTimer = false; - - size_t n = gPropertyWrappers->size(); - for (unsigned int i = 0; i < n; ++i) { - PropertyWrapperBase* wrapper = (*gPropertyWrappers)[i]; - if (!wrapper->equals(a, b)) { - wrapper->blend(anim, dst, a, b, progress); - needsTimer = true; - } - } - return needsTimer; - } - - int propIndex = prop - firstCSSProperty; - if (propIndex >= 0 && propIndex < numCSSProperties) { - int i = gPropertyWrapperMap[propIndex]; - if (i >= 0) { - PropertyWrapperBase* wrapper = (*gPropertyWrappers)[i]; - wrapper->blend(anim, dst, a, b, progress); - return true; - } - } - - return false; -} - -void AnimationBase::setChanged(Node* node) -{ - ASSERT(!node || (node->document() && !node->document()->inPageCache())); - node->setChanged(AnimationStyleChange); -} - -double AnimationBase::duration() const -{ - return m_animation->duration(); -} - -bool AnimationBase::playStatePlaying() const -{ - return m_animation && m_animation->playState() == AnimPlayStatePlaying; -} - -bool AnimationBase::animationsMatch(const Animation* anim) const -{ - return m_animation->animationsMatch(anim); -} - -void AnimationBase::updateStateMachine(AnimStateInput input, double param) -{ - // If we get AnimationStateInputRestartAnimation then we force a new animation, regardless of state. - if (input == AnimationStateInputMakeNew) { - if (m_animState == AnimationStateStartWaitStyleAvailable) - m_compAnim->setWaitingForStyleAvailable(false); - m_animState = AnimationStateNew; - m_startTime = 0; - m_pauseTime = -1; - m_waitedForResponse = false; - endAnimation(false); - return; - } - - if (input == AnimationStateInputRestartAnimation) { - cancelTimers(); - if (m_animState == AnimationStateStartWaitStyleAvailable) - m_compAnim->setWaitingForStyleAvailable(false); - m_animState = AnimationStateNew; - m_startTime = 0; - m_pauseTime = -1; - endAnimation(false); - - if (!paused()) - updateStateMachine(AnimationStateInputStartAnimation, -1); - return; - } - - if (input == AnimationStateInputEndAnimation) { - cancelTimers(); - if (m_animState == AnimationStateStartWaitStyleAvailable) - m_compAnim->setWaitingForStyleAvailable(false); - m_animState = AnimationStateDone; - endAnimation(true); - return; - } - - if (input == AnimationStateInputPauseOverride) { - if (m_animState == AnimationStateStartWaitResponse) { - // If we are in AnimationStateStartWaitResponse, the animation will get canceled before - // we get a response, so move to the next state. - endAnimation(false); - updateStateMachine(AnimationStateInputStartTimeSet, currentTime()); - } - return; - } - - if (input == AnimationStateInputResumeOverride) { - if (m_animState == AnimationStateLooping || m_animState == AnimationStateEnding) { - // Start the animation - startAnimation(m_startTime); - } - return; - } - - // Execute state machine - switch(m_animState) { - case AnimationStateNew: - ASSERT(input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunnning || input == AnimationStateInputPlayStatePaused); - if (input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunnning) { - // Set the start timer to the initial delay (0 if no delay) - m_waitedForResponse = false; - m_animState = AnimationStateStartWaitTimer; - m_animationTimerCallback.startTimer(m_animation->delay(), eventNames().webkitAnimationStartEvent, m_animation->delay()); - } - break; - case AnimationStateStartWaitTimer: - ASSERT(input == AnimationStateInputStartTimerFired || input == AnimationStateInputPlayStatePaused); - - if (input == AnimationStateInputStartTimerFired) { - ASSERT(param >= 0); - // Start timer has fired, tell the animation to start and wait for it to respond with start time - m_animState = AnimationStateStartWaitStyleAvailable; - m_compAnim->setWaitingForStyleAvailable(true); - - // Trigger a render so we can start the animation - setChanged(m_object->element()); - m_object->animation()->startUpdateRenderingDispatcher(); - } else { - ASSERT(!paused()); - // We're waiting for the start timer to fire and we got a pause. Cancel the timer, pause and wait - m_pauseTime = currentTime(); - cancelTimers(); - m_animState = AnimationStatePausedWaitTimer; - } - break; - case AnimationStateStartWaitStyleAvailable: - ASSERT(input == AnimationStateInputStyleAvailable || input == AnimationStateInputPlayStatePaused); - - m_compAnim->setWaitingForStyleAvailable(false); - - if (input == AnimationStateInputStyleAvailable) { - // Start timer has fired, tell the animation to start and wait for it to respond with start time - m_animState = AnimationStateStartWaitResponse; - - overrideAnimations(); - - // Send start event, if needed - onAnimationStart(0); // The elapsedTime is always 0 here - - // Start the animation - if (overridden() || !startAnimation(0)) { - // We're not going to get a startTime callback, so fire the start time here - m_animState = AnimationStateStartWaitResponse; - updateStateMachine(AnimationStateInputStartTimeSet, currentTime()); - } else - m_waitedForResponse = true; - } else { - ASSERT(!paused()); - // We're waiting for the a notification that the style has been setup. If we're asked to wait - // at this point, the style must have been processed, so we can deal with this like we would - // for WAIT_RESPONSE, except that we don't need to do an endAnimation(). - m_pauseTime = 0; - m_animState = AnimationStateStartWaitResponse; - } - break; - case AnimationStateStartWaitResponse: - ASSERT(input == AnimationStateInputStartTimeSet || input == AnimationStateInputPlayStatePaused); - - if (input == AnimationStateInputStartTimeSet) { - ASSERT(param >= 0); - // We have a start time, set it, unless the startTime is already set - if (m_startTime <= 0) - m_startTime = param; - - // Decide when the end or loop event needs to fire - primeEventTimers(); - - // Trigger a render so we can start the animation - setChanged(m_object->element()); - m_object->animation()->startUpdateRenderingDispatcher(); - } else { - // We are pausing while waiting for a start response. Cancel the animation and wait. When - // we unpause, we will act as though the start timer just fired - m_pauseTime = 0; - endAnimation(false); - m_animState = AnimationStatePausedWaitResponse; - } - break; - case AnimationStateLooping: - ASSERT(input == AnimationStateInputLoopTimerFired || input == AnimationStateInputPlayStatePaused); - - if (input == AnimationStateInputLoopTimerFired) { - ASSERT(param >= 0); - // Loop timer fired, loop again or end. - onAnimationIteration(param); - primeEventTimers(); - } else { - // We are pausing while running. Cancel the animation and wait - m_pauseTime = currentTime(); - cancelTimers(); - endAnimation(false); - m_animState = AnimationStatePausedRun; - } - break; - case AnimationStateEnding: - ASSERT(input == AnimationStateInputEndTimerFired || input == AnimationStateInputPlayStatePaused); - - if (input == AnimationStateInputEndTimerFired) { - ASSERT(param >= 0); - // End timer fired, finish up - onAnimationEnd(param); - - resumeOverriddenAnimations(); - - // Fire off another style change so we can set the final value - setChanged(m_object->element()); - m_animState = AnimationStateDone; - m_object->animation()->startUpdateRenderingDispatcher(); - // |this| may be deleted here when we've been called from timerFired() - } else { - // We are pausing while running. Cancel the animation and wait - m_pauseTime = currentTime(); - cancelTimers(); - endAnimation(false); - m_animState = AnimationStatePausedRun; - } - // |this| may be deleted here - break; - case AnimationStatePausedWaitTimer: - ASSERT(input == AnimationStateInputPlayStateRunnning); - ASSERT(paused()); - // Update the times - m_startTime += currentTime() - m_pauseTime; - m_pauseTime = -1; - - // we were waiting for the start timer to fire, go back and wait again - m_animState = AnimationStateNew; - updateStateMachine(AnimationStateInputStartAnimation, 0); - break; - case AnimationStatePausedWaitResponse: - case AnimationStatePausedRun: - // We treat these two cases the same. The only difference is that, when we are in - // AnimationStatePausedWaitResponse, we don't yet have a valid startTime, so we send 0 to startAnimation. - // When the AnimationStateInputStartTimeSet comes in and we were in AnimationStatePausedRun, we will notice - // that we have already set the startTime and will ignore it. - ASSERT(input == AnimationStateInputPlayStateRunnning); - ASSERT(paused()); - // Update the times - if (m_animState == AnimationStatePausedRun) - m_startTime += currentTime() - m_pauseTime; - else - m_startTime = 0; - m_pauseTime = -1; - - // We were waiting for a begin time response from the animation, go back and wait again - m_animState = AnimationStateStartWaitResponse; - - // Start the animation - if (overridden() || !startAnimation(m_startTime)) { - // We're not going to get a startTime callback, so fire the start time here - updateStateMachine(AnimationStateInputStartTimeSet, currentTime()); - } else - m_waitedForResponse = true; - break; - case AnimationStateDone: - // We're done. Stay in this state until we are deleted - break; - } - // |this| may be deleted here if we came out of AnimationStateEnding when we've been called from timerFired() -} - -void AnimationBase::animationTimerCallbackFired(const AtomicString& eventType, double elapsedTime) -{ - ASSERT(m_object->document() && !m_object->document()->inPageCache()); - - // FIXME: use an enum - if (eventType == eventNames().webkitAnimationStartEvent) - updateStateMachine(AnimationStateInputStartTimerFired, elapsedTime); - else if (eventType == eventNames().webkitAnimationIterationEvent) - updateStateMachine(AnimationStateInputLoopTimerFired, elapsedTime); - else if (eventType == eventNames().webkitAnimationEndEvent) { - updateStateMachine(AnimationStateInputEndTimerFired, elapsedTime); - // |this| may be deleted here - } -} - -void AnimationBase::updatePlayState(bool run) -{ - if (paused() == run || isNew()) - updateStateMachine(run ? AnimationStateInputPlayStateRunnning : AnimationStateInputPlayStatePaused, -1); -} - -double AnimationBase::progress(double scale, double offset, const TimingFunction* tf) const -{ - if (preActive()) - return 0; - - double elapsedTime = running() ? (currentTime() - m_startTime) : (m_pauseTime - m_startTime); - if (running() && elapsedTime < 0) - return 0; - - double dur = m_animation->duration(); - if (m_animation->iterationCount() > 0) - dur *= m_animation->iterationCount(); - - if (postActive() || !m_animation->duration() || (m_animation->iterationCount() > 0 && elapsedTime >= dur)) - return 1.0; - - // Compute the fractional time, taking into account direction. - // There is no need to worry about iterations, we assume that we would have - // short circuited above if we were done. - double fractionalTime = elapsedTime / m_animation->duration(); - int integralTime = static_cast<int>(fractionalTime); - fractionalTime -= integralTime; - - if (m_animation->direction() && (integralTime & 1)) - fractionalTime = 1 - fractionalTime; - - if (scale != 1 || offset) - fractionalTime = (fractionalTime - offset) * scale; - - if (!tf) - tf = &m_animation->timingFunction(); - - if (tf->type() == LinearTimingFunction) - return fractionalTime; - - // Cubic bezier. - double result = solveCubicBezierFunction(tf->x1(), - tf->y1(), - tf->x2(), - tf->y2(), - fractionalTime, m_animation->duration()); - return result; -} - -void AnimationBase::primeEventTimers() -{ - // Decide when the end or loop event needs to fire - double ct = currentTime(); - const double elapsedDuration = ct - m_startTime; - ASSERT(elapsedDuration >= 0); - - double totalDuration = -1; - if (m_animation->iterationCount() > 0) - totalDuration = m_animation->duration() * m_animation->iterationCount(); - - double durationLeft = 0; - double nextIterationTime = totalDuration; - if (totalDuration < 0 || elapsedDuration < totalDuration) { - durationLeft = m_animation->duration() - fmod(elapsedDuration, m_animation->duration()); - nextIterationTime = elapsedDuration + durationLeft; - } - - // At this point, we may have 0 durationLeft, if we've gotten the event late and we are already - // past totalDuration. In this case we still fire an end timer before processing the end. - // This defers the call to sendAnimationEvents to avoid re-entrant calls that destroy - // the RenderObject, and therefore |this| before we're done with it. - if (totalDuration < 0 || nextIterationTime < totalDuration) { - // We are not at the end yet, send a loop event - ASSERT(nextIterationTime > 0); - m_animState = AnimationStateLooping; - m_animationTimerCallback.startTimer(durationLeft, eventNames().webkitAnimationIterationEvent, nextIterationTime); - } else { - // We are at the end, send an end event - m_animState = AnimationStateEnding; - m_animationTimerCallback.startTimer(durationLeft, eventNames().webkitAnimationEndEvent, nextIterationTime); - } -} - -} // namespace WebCore diff --git a/WebCore/page/animation/AnimationBase.h b/WebCore/page/animation/AnimationBase.h deleted file mode 100644 index 925c0d5..0000000 --- a/WebCore/page/animation/AnimationBase.h +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (C) 2007 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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. - */ - -#ifndef AnimationBase_h -#define AnimationBase_h - -#include "AtomicString.h" -#include "Timer.h" -#include <wtf/HashMap.h> - -namespace WebCore { - -class Animation; -class AnimationBase; -class AnimationController; -class CompositeAnimation; -class Element; -class Node; -class RenderObject; -class RenderStyle; -class TimingFunction; - -class AnimationTimerBase { -public: - AnimationTimerBase(AnimationBase* anim) - : m_timer(this, &AnimationTimerBase::timerFired) - , m_anim(anim) - { - m_timer.startOneShot(0); - } - - virtual ~AnimationTimerBase() { } - - void startTimer(double timeout = 0) - { - m_timer.startOneShot(timeout); - } - - void cancelTimer() - { - m_timer.stop(); - } - - virtual void timerFired(Timer<AnimationTimerBase>*) = 0; - -private: - Timer<AnimationTimerBase> m_timer; - -protected: - AnimationBase* m_anim; -}; - -class AnimationTimerCallback : public AnimationTimerBase { -public: - AnimationTimerCallback(AnimationBase* anim) - : AnimationTimerBase(anim) - , m_elapsedTime(0) - { - } - - virtual ~AnimationTimerCallback() { } - - virtual void timerFired(Timer<AnimationTimerBase>*); - - void startTimer(double timeout, const AtomicString& eventType, double elapsedTime) - { - m_eventType = eventType; - m_elapsedTime = elapsedTime; - AnimationTimerBase::startTimer(timeout); - } - -private: - AtomicString m_eventType; - double m_elapsedTime; -}; - -class AnimationBase : public RefCounted<AnimationBase> { - friend class CompositeAnimationPrivate; - -public: - AnimationBase(const Animation* transition, RenderObject* renderer, CompositeAnimation* compAnim); - virtual ~AnimationBase(); - - RenderObject* renderer() const { return m_object; } - double startTime() const { return m_startTime; } - double duration() const; - - void cancelTimers() - { - m_animationTimerCallback.cancelTimer(); - } - - // Animations and Transitions go through the states below. When entering the STARTED state - // the animation is started. This may or may not require deferred response from the animator. - // If so, we stay in this state until that response is received (and it returns the start time). - // Otherwise, we use the current time as the start time and go immediately to AnimationStateLooping - // or AnimationStateEnding. - enum AnimState { - AnimationStateNew, // animation just created, animation not running yet - AnimationStateStartWaitTimer, // start timer running, waiting for fire - AnimationStateStartWaitStyleAvailable, // waiting for style setup so we can start animations - AnimationStateStartWaitResponse, // animation started, waiting for response - AnimationStateLooping, // response received, animation running, loop timer running, waiting for fire - AnimationStateEnding, // received, animation running, end timer running, waiting for fire - AnimationStatePausedWaitTimer, // in pause mode when animation started - AnimationStatePausedWaitResponse, // animation paused when in STARTING state - AnimationStatePausedRun, // animation paused when in LOOPING or ENDING state - AnimationStateDone // end timer fired, animation finished and removed - }; - - enum AnimStateInput { - AnimationStateInputMakeNew, // reset back to new from any state - AnimationStateInputStartAnimation, // animation requests a start - AnimationStateInputRestartAnimation, // force a restart from any state - AnimationStateInputStartTimerFired, // start timer fired - AnimationStateInputStyleAvailable, // style is setup, ready to start animating - AnimationStateInputStartTimeSet, // m_startTime was set - AnimationStateInputLoopTimerFired, // loop timer fired - AnimationStateInputEndTimerFired, // end timer fired - AnimationStateInputPauseOverride, // pause an animation due to override - AnimationStateInputResumeOverride, // resume an overridden animation - AnimationStateInputPlayStateRunnning, // play state paused -> running - AnimationStateInputPlayStatePaused, // play state running -> paused - AnimationStateInputEndAnimation // force an end from any state - }; - - // Called when animation is in AnimationStateNew to start animation - void updateStateMachine(AnimStateInput, double param); - - // Animation has actually started, at passed time - void onAnimationStartResponse(double startTime); - - // Called to change to or from paused state - void updatePlayState(bool running); - bool playStatePlaying() const; - - bool waitingToStart() const { return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer; } - bool preActive() const - { - return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer || m_animState == AnimationStateStartWaitStyleAvailable || m_animState == AnimationStateStartWaitResponse; - } - - bool postActive() const { return m_animState == AnimationStateDone; } - bool active() const { return !postActive() && !preActive(); } - bool running() const { return !isNew() && !postActive(); } - bool paused() const { return m_pauseTime >= 0; } - bool isNew() const { return m_animState == AnimationStateNew; } - bool waitingForStartTime() const { return m_animState == AnimationStateStartWaitResponse; } - bool waitingForStyleAvailable() const { return m_animState == AnimationStateStartWaitStyleAvailable; } - - // "animating" means that something is running that requires a timer to keep firing - // (e.g. a software animation) - void setAnimating(bool inAnimating = true) { m_isAnimating = inAnimating; } - bool isAnimating() const { return m_isAnimating; } - - double progress(double scale, double offset, const TimingFunction*) const; - - virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* currentStyle, - const RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle) { } - - virtual bool shouldFireEvents() const { return false; } - - void animationTimerCallbackFired(const AtomicString& eventType, double elapsedTime); - - bool animationsMatch(const Animation*) const; - - void setAnimation(const Animation* anim) { m_animation = const_cast<Animation*>(anim); } - - // Return true if this animation is overridden. This will only be the case for - // ImplicitAnimations and is used to determine whether or not we should force - // set the start time. If an animation is overridden, it will probably not get - // back the AnimationStateInputStartTimeSet input. - virtual bool overridden() const { return false; } - - // Does this animation/transition involve the given property? - virtual bool affectsProperty(int property) const { return false; } - bool isAnimatingProperty(int property, bool isRunningNow) const - { - if (isRunningNow) - return (!waitingToStart() && !postActive()) && affectsProperty(property); - - return !postActive() && affectsProperty(property); - } - - bool isTransformFunctionListValid() const { return m_transformFunctionListValid; } - -protected: - virtual void overrideAnimations() { } - virtual void resumeOverriddenAnimations() { } - - CompositeAnimation* compositeAnimation() { return m_compAnim; } - - // These are called when the corresponding timer fires so subclasses can do any extra work - virtual void onAnimationStart(double elapsedTime) { } - virtual void onAnimationIteration(double elapsedTime) { } - virtual void onAnimationEnd(double elapsedTime) { } - virtual bool startAnimation(double beginTime) { return false; } - virtual void endAnimation(bool reset) { } - - void primeEventTimers(); - - static bool propertiesEqual(int prop, const RenderStyle* a, const RenderStyle* b); - static int getPropertyAtIndex(int); - static int getNumProperties(); - - // Return true if we need to start software animation timers - static bool blendProperties(const AnimationBase* anim, int prop, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress); - - static void setChanged(Node*); - -protected: - AnimState m_animState; - int m_iteration; - - bool m_isAnimating; // transition/animation requires continual timer firing - bool m_waitedForResponse; - double m_startTime; - double m_pauseTime; - RenderObject* m_object; - - AnimationTimerCallback m_animationTimerCallback; - RefPtr<Animation> m_animation; - CompositeAnimation* m_compAnim; - bool m_transformFunctionListValid; -}; - -} // namespace WebCore - -#endif // AnimationBase_h diff --git a/WebCore/page/animation/AnimationController.cpp b/WebCore/page/animation/AnimationController.cpp deleted file mode 100644 index d449afe..0000000 --- a/WebCore/page/animation/AnimationController.cpp +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (C) 2007 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 "AnimationController.h" -#include "CompositeAnimation.h" -#include "Frame.h" -#include "Timer.h" - -namespace WebCore { - -static const double cAnimationTimerDelay = 0.025; - -class AnimationControllerPrivate { -public: - AnimationControllerPrivate(Frame*); - ~AnimationControllerPrivate(); - - CompositeAnimation* accessCompositeAnimation(RenderObject*); - bool clear(RenderObject*); - - void animationTimerFired(Timer<AnimationControllerPrivate>*); - void updateAnimationTimer(); - - void updateRenderingDispatcherFired(Timer<AnimationControllerPrivate>*); - void startUpdateRenderingDispatcher(); - - bool hasAnimations() const { return !m_compositeAnimations.isEmpty(); } - - void suspendAnimations(Document*); - void resumeAnimations(Document*); - - void styleAvailable(); - - bool isAnimatingPropertyOnRenderer(RenderObject*, int property, bool isRunningNow) const; - -private: - typedef HashMap<RenderObject*, CompositeAnimation*> RenderObjectAnimationMap; - - RenderObjectAnimationMap m_compositeAnimations; - Timer<AnimationControllerPrivate> m_animationTimer; - Timer<AnimationControllerPrivate> m_updateRenderingDispatcher; - Frame* m_frame; -}; - -AnimationControllerPrivate::AnimationControllerPrivate(Frame* frame) - : m_animationTimer(this, &AnimationControllerPrivate::animationTimerFired) - , m_updateRenderingDispatcher(this, &AnimationControllerPrivate::updateRenderingDispatcherFired) - , m_frame(frame) -{ -} - -AnimationControllerPrivate::~AnimationControllerPrivate() -{ - deleteAllValues(m_compositeAnimations); -} - -CompositeAnimation* AnimationControllerPrivate::accessCompositeAnimation(RenderObject* renderer) -{ - CompositeAnimation* animation = m_compositeAnimations.get(renderer); - if (!animation) { - animation = new CompositeAnimation(m_frame->animation()); - m_compositeAnimations.set(renderer, animation); - } - return animation; -} - -bool AnimationControllerPrivate::clear(RenderObject* renderer) -{ - // Return false if we didn't do anything OR we are suspended (so we don't try to - // do a setChanged() when suspended). - CompositeAnimation* animation = m_compositeAnimations.take(renderer); - if (!animation) - return false; - animation->resetTransitions(renderer); - bool wasSuspended = animation->isSuspended(); - delete animation; - return !wasSuspended; -} - -void AnimationControllerPrivate::styleAvailable() -{ - RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end(); - for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) - it->second->styleAvailable(); -} - -void AnimationControllerPrivate::updateAnimationTimer() -{ - bool isAnimating = false; - - RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end(); - for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) { - CompositeAnimation* compAnim = it->second; - if (!compAnim->isSuspended() && compAnim->isAnimating()) { - isAnimating = true; - break; - } - } - - if (isAnimating) { - if (!m_animationTimer.isActive()) - m_animationTimer.startRepeating(cAnimationTimerDelay); - } else if (m_animationTimer.isActive()) - m_animationTimer.stop(); -} - -void AnimationControllerPrivate::updateRenderingDispatcherFired(Timer<AnimationControllerPrivate>*) -{ - if (m_frame && m_frame->document()) - m_frame->document()->updateRendering(); -} - -void AnimationControllerPrivate::startUpdateRenderingDispatcher() -{ - if (!m_updateRenderingDispatcher.isActive()) - m_updateRenderingDispatcher.startOneShot(0); -} - -void AnimationControllerPrivate::animationTimerFired(Timer<AnimationControllerPrivate>* timer) -{ - // When the timer fires, all we do is call setChanged on all DOM nodes with running animations and then do an immediate - // updateRendering. It will then call back to us with new information. - bool isAnimating = false; - RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end(); - for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) { - CompositeAnimation* compAnim = it->second; - if (!compAnim->isSuspended() && compAnim->isAnimating()) { - isAnimating = true; - compAnim->setAnimating(false); - - Node* node = it->first->element(); - ASSERT(!node || (node->document() && !node->document()->inPageCache())); - node->setChanged(AnimationStyleChange); - } - } - - m_frame->document()->updateRendering(); - - updateAnimationTimer(); -} - -bool AnimationControllerPrivate::isAnimatingPropertyOnRenderer(RenderObject* renderer, int property, bool isRunningNow) const -{ - CompositeAnimation* animation = m_compositeAnimations.get(renderer); - if (!animation) - return false; - - return animation->isAnimatingProperty(property, isRunningNow); -} - -void AnimationControllerPrivate::suspendAnimations(Document* document) -{ - RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end(); - for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) { - RenderObject* renderer = it->first; - CompositeAnimation* compAnim = it->second; - if (renderer->document() == document) - compAnim->suspendAnimations(); - } - - updateAnimationTimer(); -} - -void AnimationControllerPrivate::resumeAnimations(Document* document) -{ - RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end(); - for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) { - RenderObject* renderer = it->first; - CompositeAnimation* compAnim = it->second; - if (renderer->document() == document) - compAnim->resumeAnimations(); - } - - updateAnimationTimer(); -} - -AnimationController::AnimationController(Frame* frame) - : m_data(new AnimationControllerPrivate(frame)) - , m_numStyleAvailableWaiters(0) -{ -} - -AnimationController::~AnimationController() -{ - delete m_data; -} - -void AnimationController::cancelAnimations(RenderObject* renderer) -{ - if (!m_data->hasAnimations()) - return; - - if (m_data->clear(renderer)) { - Node* node = renderer->element(); - ASSERT(!node || (node->document() && !node->document()->inPageCache())); - node->setChanged(AnimationStyleChange); - } -} - -PassRefPtr<RenderStyle> AnimationController::updateAnimations(RenderObject* renderer, RenderStyle* newStyle) -{ - // Don't do anything if we're in the cache - if (!renderer->document() || renderer->document()->inPageCache()) - return newStyle; - - RenderStyle* oldStyle = renderer->style(); - - if ((!oldStyle || (!oldStyle->animations() && !oldStyle->transitions())) && (!newStyle->animations() && !newStyle->transitions())) - return newStyle; - - // Fetch our current set of implicit animations from a hashtable. We then compare them - // against the animations in the style and make sure we're in sync. If destination values - // have changed, we reset the animation. We then do a blend to get new values and we return - // a new style. - ASSERT(renderer->element()); // FIXME: We do not animate generated content yet. - - CompositeAnimation* rendererAnimations = m_data->accessCompositeAnimation(renderer); - RefPtr<RenderStyle> blendedStyle = rendererAnimations->animate(renderer, oldStyle, newStyle); - - m_data->updateAnimationTimer(); - - if (blendedStyle != newStyle) { - // If the animations/transitions change opacity or transform, we neeed to update - // the style to impose the stacking rules. Note that this is also - // done in CSSStyleSelector::adjustRenderStyle(). - if (blendedStyle->hasAutoZIndex() && (blendedStyle->opacity() < 1.0f || blendedStyle->hasTransform())) - blendedStyle->setZIndex(0); - } - return blendedStyle.release(); -} - -void AnimationController::setAnimationStartTime(RenderObject* renderer, double t) -{ - CompositeAnimation* rendererAnimations = m_data->accessCompositeAnimation(renderer); - rendererAnimations->setAnimationStartTime(t); -} - -void AnimationController::setTransitionStartTime(RenderObject* renderer, int property, double t) -{ - CompositeAnimation* rendererAnimations = m_data->accessCompositeAnimation(renderer); - rendererAnimations->setTransitionStartTime(property, t); -} - -bool AnimationController::isAnimatingPropertyOnRenderer(RenderObject* renderer, int property, bool isRunningNow) const -{ - return m_data->isAnimatingPropertyOnRenderer(renderer, property, isRunningNow); -} - -void AnimationController::suspendAnimations(Document* document) -{ - m_data->suspendAnimations(document); -} - -void AnimationController::resumeAnimations(Document* document) -{ - m_data->resumeAnimations(document); -} - -void AnimationController::startUpdateRenderingDispatcher() -{ - m_data->startUpdateRenderingDispatcher(); -} - -void AnimationController::styleAvailable() -{ - if (!m_numStyleAvailableWaiters) - return; - - m_data->styleAvailable(); -} - -} // namespace WebCore diff --git a/WebCore/page/animation/AnimationController.h b/WebCore/page/animation/AnimationController.h deleted file mode 100644 index bc13a2a..0000000 --- a/WebCore/page/animation/AnimationController.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2007 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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. - */ - -#ifndef AnimationController_h -#define AnimationController_h - -#include <wtf/Forward.h> - -namespace WebCore { - -class AnimationControllerPrivate; -class Document; -class Frame; -class RenderObject; -class RenderStyle; - -class AnimationController { -public: - AnimationController(Frame*); - ~AnimationController(); - - void cancelAnimations(RenderObject*); - PassRefPtr<RenderStyle> updateAnimations(RenderObject*, RenderStyle* newStyle); - - void setAnimationStartTime(RenderObject*, double t); - void setTransitionStartTime(RenderObject*, int property, double t); - - bool isAnimatingPropertyOnRenderer(RenderObject*, int property, bool isRunningNow) const; - - void suspendAnimations(Document*); - void resumeAnimations(Document*); - void updateAnimationTimer(); - - void startUpdateRenderingDispatcher(); - - void styleAvailable(); - - void setWaitingForStyleAvailable(bool waiting) - { - if (waiting) - m_numStyleAvailableWaiters++; - else - m_numStyleAvailableWaiters--; - } - -private: - AnimationControllerPrivate* m_data; - unsigned m_numStyleAvailableWaiters; -}; - -} // namespace WebCore - -#endif // AnimationController_h diff --git a/WebCore/page/animation/CompositeAnimation.cpp b/WebCore/page/animation/CompositeAnimation.cpp deleted file mode 100644 index 2ae68d9..0000000 --- a/WebCore/page/animation/CompositeAnimation.cpp +++ /dev/null @@ -1,594 +0,0 @@ -/* - * Copyright (C) 2007 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 "CompositeAnimation.h" - -#include "AnimationController.h" -#include "CSSPropertyNames.h" -#include "ImplicitAnimation.h" -#include "KeyframeAnimation.h" -#include "RenderObject.h" -#include "RenderStyle.h" - -namespace WebCore { - -class CompositeAnimationPrivate { -public: - CompositeAnimationPrivate(AnimationController* animationController, CompositeAnimation* compositeAnimation) - : m_isSuspended(false) - , m_animationController(animationController) - , m_compositeAnimation(compositeAnimation) - , m_numStyleAvailableWaiters(0) - { - } - - ~CompositeAnimationPrivate(); - - PassRefPtr<RenderStyle> animate(RenderObject*, RenderStyle* currentStyle, RenderStyle* targetStyle); - - void setAnimating(bool); - bool isAnimating() const; - - const KeyframeAnimation* getAnimationForProperty(int property) const; - - void resetTransitions(RenderObject*); - void resetAnimations(RenderObject*); - - void cleanupFinishedAnimations(RenderObject*); - - void setAnimationStartTime(double t); - void setTransitionStartTime(int property, double t); - - void suspendAnimations(); - void resumeAnimations(); - bool isSuspended() const { return m_isSuspended; } - - void overrideImplicitAnimations(int property); - void resumeOverriddenImplicitAnimations(int property); - - void styleAvailable(); - - bool isAnimatingProperty(int property, bool isRunningNow) const; - - void setWaitingForStyleAvailable(bool); - -protected: - void updateTransitions(RenderObject*, RenderStyle* currentStyle, RenderStyle* targetStyle); - void updateKeyframeAnimations(RenderObject*, RenderStyle* currentStyle, RenderStyle* targetStyle); - -private: - typedef HashMap<int, RefPtr<ImplicitAnimation> > CSSPropertyTransitionsMap; - typedef HashMap<AtomicStringImpl*, RefPtr<KeyframeAnimation> > AnimationNameMap; - - CSSPropertyTransitionsMap m_transitions; - AnimationNameMap m_keyframeAnimations; - bool m_isSuspended; - AnimationController* m_animationController; - CompositeAnimation* m_compositeAnimation; - unsigned m_numStyleAvailableWaiters; -}; - -CompositeAnimationPrivate::~CompositeAnimationPrivate() -{ - m_transitions.clear(); - m_keyframeAnimations.clear(); -} - -void CompositeAnimationPrivate::updateTransitions(RenderObject* renderer, RenderStyle* currentStyle, RenderStyle* targetStyle) -{ - // If currentStyle is null, we don't do transitions - if (!currentStyle || !targetStyle->transitions()) - return; - - // Check to see if we need to update the active transitions - for (size_t i = 0; i < targetStyle->transitions()->size(); ++i) { - const Animation* anim = targetStyle->transitions()->animation(i); - bool isActiveTransition = anim->duration() || anim->delay() > 0; - - int prop = anim->property(); - - if (prop == cAnimateNone) - continue; - - bool all = prop == cAnimateAll; - - // Handle both the 'all' and single property cases. For the single prop case, we make only one pass - // through the loop. - for (int propertyIndex = 0; propertyIndex < AnimationBase::getNumProperties(); ++propertyIndex) { - if (all) { - // Get the next property - prop = AnimationBase::getPropertyAtIndex(propertyIndex); - } - - // ImplicitAnimations are always hashed by actual properties, never cAnimateAll - ASSERT(prop > firstCSSProperty && prop < (firstCSSProperty + numCSSProperties)); - - // If there is a running animation for this property, the transition is overridden - // and we have to use the unanimatedStyle from the animation. We do the test - // against the unanimated style here, but we "override" the transition later. - const KeyframeAnimation* keyframeAnim = getAnimationForProperty(prop); - RenderStyle* fromStyle = keyframeAnim ? keyframeAnim->unanimatedStyle() : currentStyle; - - // See if there is a current transition for this prop - ImplicitAnimation* implAnim = m_transitions.get(prop).get(); - bool equal = true; - - if (implAnim) { - // This implAnim might not be an already running transition. It might be - // newly added to the list in a previous iteration. This would happen if - // you have both an explicit transition-property and 'all' in the same - // list. In this case, the latter one overrides the earlier one, so we - // behave as though this is a running animation being replaced. - if (!isActiveTransition) - m_transitions.remove(prop); - else if (!implAnim->isTargetPropertyEqual(prop, targetStyle)) { - m_transitions.remove(prop); - equal = false; - } - } else { - // We need to start a transition if it is active and the properties don't match - equal = !isActiveTransition || AnimationBase::propertiesEqual(prop, fromStyle, targetStyle); - } - - if (!equal) { - // Add the new transition - m_transitions.set(prop, ImplicitAnimation::create(const_cast<Animation*>(anim), prop, renderer, m_compositeAnimation, fromStyle)); - } - - // We only need one pass for the single prop case - if (!all) - break; - } - } -} - -void CompositeAnimationPrivate::updateKeyframeAnimations(RenderObject* renderer, RenderStyle* currentStyle, RenderStyle* targetStyle) -{ - // Nothing to do if we don't have any animations, and didn't have any before - if (m_keyframeAnimations.isEmpty() && !targetStyle->hasAnimations()) - return; - - // Nothing to do if the current and target animations are the same - if (currentStyle && currentStyle->hasAnimations() && targetStyle->hasAnimations() && *(currentStyle->animations()) == *(targetStyle->animations())) - return; - - // Mark all existing animations as no longer active - AnimationNameMap::const_iterator kfend = m_keyframeAnimations.end(); - for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it) - it->second->setIndex(-1); - - // Now mark any still active animations as active and add any new animations - if (targetStyle->animations()) { - int numAnims = targetStyle->animations()->size(); - for (int i = 0; i < numAnims; ++i) { - const Animation* anim = targetStyle->animations()->animation(i); - AtomicString animationName(anim->name()); - - if (!anim->isValidAnimation()) - continue; - - // See if there is a current animation for this name - RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(animationName.impl()); - - if (keyframeAnim) { - // There is one so it is still active - - // Animations match, but play states may differ. update if needed - keyframeAnim->updatePlayState(anim->playState() == AnimPlayStatePlaying); - - // Set the saved animation to this new one, just in case the play state has changed - keyframeAnim->setAnimation(anim); - keyframeAnim->setIndex(i); - } else if ((anim->duration() || anim->delay()) && anim->iterationCount()) { - keyframeAnim = KeyframeAnimation::create(const_cast<Animation*>(anim), renderer, i, m_compositeAnimation, currentStyle ? currentStyle : targetStyle); - m_keyframeAnimations.set(keyframeAnim->name().impl(), keyframeAnim); - } - } - } - - // Make a list of animations to be removed - Vector<AtomicStringImpl*> animsToBeRemoved; - kfend = m_keyframeAnimations.end(); - for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it) { - KeyframeAnimation* keyframeAnim = it->second.get(); - if (keyframeAnim->index() < 0) - animsToBeRemoved.append(keyframeAnim->name().impl()); - } - - // Now remove the animations from the list - for (size_t j = 0; j < animsToBeRemoved.size(); ++j) - m_keyframeAnimations.remove(animsToBeRemoved[j]); -} - -PassRefPtr<RenderStyle> CompositeAnimationPrivate::animate(RenderObject* renderer, RenderStyle* currentStyle, RenderStyle* targetStyle) -{ - RefPtr<RenderStyle> resultStyle; - - // Update animations first so we can see if any transitions are overridden - updateKeyframeAnimations(renderer, currentStyle, targetStyle); - - // We don't do any transitions if we don't have a currentStyle (on startup) - updateTransitions(renderer, currentStyle, targetStyle); - - if (currentStyle) { - // Now that we have transition objects ready, let them know about the new goal state. We want them - // to fill in a RenderStyle*& only if needed. - CSSPropertyTransitionsMap::const_iterator end = m_transitions.end(); - for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) { - if (ImplicitAnimation* anim = it->second.get()) - anim->animate(m_compositeAnimation, renderer, currentStyle, targetStyle, resultStyle); - } - } - - // Now that we have animation objects ready, let them know about the new goal state. We want them - // to fill in a RenderStyle*& only if needed. - if (targetStyle->hasAnimations()) { - for (size_t i = 0; i < targetStyle->animations()->size(); ++i) { - const Animation* anim = targetStyle->animations()->animation(i); - - if (anim->isValidAnimation()) { - AtomicString animationName(anim->name()); - RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(animationName.impl()); - if (keyframeAnim) - keyframeAnim->animate(m_compositeAnimation, renderer, currentStyle, targetStyle, resultStyle); - } - } - } - - cleanupFinishedAnimations(renderer); - - return resultStyle ? resultStyle.release() : targetStyle; -} - -// "animating" means that something is running that requires the timer to keep firing -void CompositeAnimationPrivate::setAnimating(bool animating) -{ - CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end(); - for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) { - ImplicitAnimation* transition = it->second.get(); - transition->setAnimating(animating); - } - - AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end(); - for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) { - KeyframeAnimation* anim = it->second.get(); - anim->setAnimating(animating); - } -} - -bool CompositeAnimationPrivate::isAnimating() const -{ - CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end(); - for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) { - ImplicitAnimation* transition = it->second.get(); - if (transition && transition->isAnimating() && transition->running()) - return true; - } - - AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end(); - for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) { - KeyframeAnimation* anim = it->second.get(); - if (anim && !anim->paused() && anim->isAnimating() && anim->active()) - return true; - } - - return false; -} - -const KeyframeAnimation* CompositeAnimationPrivate::getAnimationForProperty(int property) const -{ - const KeyframeAnimation* retval = 0; - - // We want to send back the last animation with the property if there are multiples. - // So we need to iterate through all animations - AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end(); - for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) { - const KeyframeAnimation* anim = it->second.get(); - if (anim->hasAnimationForProperty(property)) - retval = anim; - } - - return retval; -} - -void CompositeAnimationPrivate::resetTransitions(RenderObject* renderer) -{ - m_transitions.clear(); -} - -void CompositeAnimationPrivate::resetAnimations(RenderObject*) -{ - m_keyframeAnimations.clear(); -} - -void CompositeAnimationPrivate::cleanupFinishedAnimations(RenderObject* renderer) -{ - if (isSuspended()) - return; - - // Make a list of transitions to be deleted - Vector<int> finishedTransitions; - CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end(); - - for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) { - ImplicitAnimation* anim = it->second.get(); - if (!anim) - continue; - if (anim->postActive()) - finishedTransitions.append(anim->animatingProperty()); - } - - // Delete them - size_t finishedTransitionCount = finishedTransitions.size(); - for (size_t i = 0; i < finishedTransitionCount; ++i) - m_transitions.remove(finishedTransitions[i]); - - // Make a list of animations to be deleted - Vector<AtomicStringImpl*> finishedAnimations; - AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end(); - - for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) { - KeyframeAnimation* anim = it->second.get(); - if (!anim) - continue; - if (anim->postActive()) - finishedAnimations.append(anim->name().impl()); - } - - // Delete them - size_t finishedAnimationCount = finishedAnimations.size(); - for (size_t i = 0; i < finishedAnimationCount; ++i) - m_keyframeAnimations.remove(finishedAnimations[i]); -} - -void CompositeAnimationPrivate::setAnimationStartTime(double t) -{ - // Set start time on all animations waiting for it - AnimationNameMap::const_iterator end = m_keyframeAnimations.end(); - for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != end; ++it) { - KeyframeAnimation* anim = it->second.get(); - if (anim && anim->waitingForStartTime()) - anim->updateStateMachine(AnimationBase::AnimationStateInputStartTimeSet, t); - } -} - -void CompositeAnimationPrivate::setTransitionStartTime(int property, double t) -{ - // Set the start time for given property transition - CSSPropertyTransitionsMap::const_iterator end = m_transitions.end(); - for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) { - ImplicitAnimation* anim = it->second.get(); - if (anim && anim->waitingForStartTime() && anim->animatingProperty() == property) - anim->updateStateMachine(AnimationBase::AnimationStateInputStartTimeSet, t); - } -} - -void CompositeAnimationPrivate::suspendAnimations() -{ - if (m_isSuspended) - return; - - m_isSuspended = true; - - AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end(); - for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) { - if (KeyframeAnimation* anim = it->second.get()) - anim->updatePlayState(false); - } - - CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end(); - for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) { - ImplicitAnimation* anim = it->second.get(); - if (anim && anim->hasStyle()) - anim->updatePlayState(false); - } -} - -void CompositeAnimationPrivate::resumeAnimations() -{ - if (!m_isSuspended) - return; - - m_isSuspended = false; - - AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end(); - for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) { - KeyframeAnimation* anim = it->second.get(); - if (anim && anim->playStatePlaying()) - anim->updatePlayState(true); - } - - CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end(); - for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) { - ImplicitAnimation* anim = it->second.get(); - if (anim && anim->hasStyle()) - anim->updatePlayState(true); - } -} - -void CompositeAnimationPrivate::overrideImplicitAnimations(int property) -{ - CSSPropertyTransitionsMap::const_iterator end = m_transitions.end(); - for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) { - ImplicitAnimation* anim = it->second.get(); - if (anim && anim->animatingProperty() == property) - anim->setOverridden(true); - } -} - -void CompositeAnimationPrivate::resumeOverriddenImplicitAnimations(int property) -{ - CSSPropertyTransitionsMap::const_iterator end = m_transitions.end(); - for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) { - ImplicitAnimation* anim = it->second.get(); - if (anim && anim->animatingProperty() == property) - anim->setOverridden(false); - } -} - -static inline bool compareAnimationIndices(RefPtr<KeyframeAnimation> a, const RefPtr<KeyframeAnimation> b) -{ - return a->index() < b->index(); -} - -void CompositeAnimationPrivate::styleAvailable() -{ - if (m_numStyleAvailableWaiters == 0) - return; - - // We have to go through animations in the order in which they appear in - // the style, because order matters for additivity. - Vector<RefPtr<KeyframeAnimation> > animations(m_keyframeAnimations.size()); - copyValuesToVector(m_keyframeAnimations, animations); - - if (animations.size() > 1) - std::stable_sort(animations.begin(), animations.end(), compareAnimationIndices); - - for (size_t i = 0; i < animations.size(); ++i) { - KeyframeAnimation* anim = animations[i].get(); - if (anim && anim->waitingForStyleAvailable()) - anim->updateStateMachine(AnimationBase::AnimationStateInputStyleAvailable, -1); - } - - CSSPropertyTransitionsMap::const_iterator end = m_transitions.end(); - for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) { - ImplicitAnimation* anim = it->second.get(); - if (anim && anim->waitingForStyleAvailable()) - anim->updateStateMachine(AnimationBase::AnimationStateInputStyleAvailable, -1); - } -} - -bool CompositeAnimationPrivate::isAnimatingProperty(int property, bool isRunningNow) const -{ - AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end(); - for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) { - KeyframeAnimation* anim = it->second.get(); - if (anim && anim->isAnimatingProperty(property, isRunningNow)) - return true; - } - - CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end(); - for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) { - ImplicitAnimation* anim = it->second.get(); - if (anim && anim->isAnimatingProperty(property, isRunningNow)) - return true; - } - return false; -} - -void CompositeAnimationPrivate::setWaitingForStyleAvailable(bool waiting) -{ - if (waiting) - m_numStyleAvailableWaiters++; - else - m_numStyleAvailableWaiters--; - m_animationController->setWaitingForStyleAvailable(waiting); -} - -CompositeAnimation::CompositeAnimation(AnimationController* animationController) - : m_data(new CompositeAnimationPrivate(animationController, this)) -{ -} - -CompositeAnimation::~CompositeAnimation() -{ - delete m_data; -} - -PassRefPtr<RenderStyle> CompositeAnimation::animate(RenderObject* renderer, RenderStyle* currentStyle, RenderStyle* targetStyle) -{ - return m_data->animate(renderer, currentStyle, targetStyle); -} - -bool CompositeAnimation::isAnimating() const -{ - return m_data->isAnimating(); -} - -void CompositeAnimation::setWaitingForStyleAvailable(bool b) -{ - m_data->setWaitingForStyleAvailable(b); -} - -void CompositeAnimation::resetTransitions(RenderObject* renderer) -{ - m_data->resetTransitions(renderer); -} - -void CompositeAnimation::suspendAnimations() -{ - m_data->suspendAnimations(); -} - -void CompositeAnimation::resumeAnimations() -{ - m_data->resumeAnimations(); -} - -bool CompositeAnimation::isSuspended() const -{ - return m_data->isSuspended(); -} - -void CompositeAnimation::styleAvailable() -{ - m_data->styleAvailable(); -} - -void CompositeAnimation::setAnimating(bool b) -{ - m_data->setAnimating(b); -} - -bool CompositeAnimation::isAnimatingProperty(int property, bool isRunningNow) const -{ - return m_data->isAnimatingProperty(property, isRunningNow); -} - -void CompositeAnimation::setAnimationStartTime(double t) -{ - m_data->setAnimationStartTime(t); -} - -void CompositeAnimation::setTransitionStartTime(int property, double t) -{ - m_data->setTransitionStartTime(property, t); -} - -void CompositeAnimation::overrideImplicitAnimations(int property) -{ - m_data->overrideImplicitAnimations(property); -} - -void CompositeAnimation::resumeOverriddenImplicitAnimations(int property) -{ - m_data->resumeOverriddenImplicitAnimations(property); -} - -} // namespace WebCore diff --git a/WebCore/page/animation/CompositeAnimation.h b/WebCore/page/animation/CompositeAnimation.h deleted file mode 100644 index 13f1179..0000000 --- a/WebCore/page/animation/CompositeAnimation.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2007 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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. - */ - -#ifndef CompositeAnimation_h -#define CompositeAnimation_h - -#include "AtomicString.h" - -#include <wtf/HashMap.h> -#include <wtf/Noncopyable.h> - -namespace WebCore { - -class CompositeAnimationPrivate; -class AnimationController; -class RenderObject; -class RenderStyle; - -// A CompositeAnimation represents a collection of animations that are running -// on a single RenderObject, such as a number of properties transitioning at once. -class CompositeAnimation : public Noncopyable { -public: - CompositeAnimation(AnimationController* animationController); - ~CompositeAnimation(); - - PassRefPtr<RenderStyle> animate(RenderObject*, RenderStyle* currentStyle, RenderStyle* targetStyle); - bool isAnimating() const; - - void setWaitingForStyleAvailable(bool); - void resetTransitions(RenderObject*); - - void suspendAnimations(); - void resumeAnimations(); - bool isSuspended() const; - - void styleAvailable(); - void setAnimating(bool); - bool isAnimatingProperty(int property, bool isRunningNow) const; - - void setAnimationStartTime(double t); - void setTransitionStartTime(int property, double t); - - void overrideImplicitAnimations(int property); - void resumeOverriddenImplicitAnimations(int property); - -private: - CompositeAnimationPrivate* m_data; -}; - -} // namespace WebCore - -#endif // CompositeAnimation_h diff --git a/WebCore/page/animation/ImplicitAnimation.cpp b/WebCore/page/animation/ImplicitAnimation.cpp deleted file mode 100644 index 4d470e4..0000000 --- a/WebCore/page/animation/ImplicitAnimation.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (C) 2007 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 "CSSPropertyNames.h" -#include "EventNames.h" -#include "ImplicitAnimation.h" -#include "RenderObject.h" - -namespace WebCore { - -ImplicitAnimation::ImplicitAnimation(const Animation* transition, int animatingProperty, RenderObject* renderer, CompositeAnimation* compAnim, RenderStyle* fromStyle) - : AnimationBase(transition, renderer, compAnim) - , m_transitionProperty(transition->property()) - , m_animatingProperty(animatingProperty) - , m_overridden(false) - , m_fromStyle(fromStyle) -{ - ASSERT(animatingProperty != cAnimateAll); -} - -ImplicitAnimation::~ImplicitAnimation() -{ - // Do the cleanup here instead of in the base class so the specialized methods get called - if (!postActive()) - updateStateMachine(AnimationStateInputEndAnimation, -1); -} - -bool ImplicitAnimation::shouldSendEventForListener(Document::ListenerType inListenerType) -{ - return m_object->document()->hasListenerType(inListenerType); -} - -void ImplicitAnimation::animate(CompositeAnimation* animation, RenderObject* renderer, RenderStyle* currentStyle, - RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle) -{ - if (paused()) - return; - - // If we get this far and the animation is done, it means we are cleaning up a just finished animation. - // So just return. Everything is already all cleaned up. - if (postActive()) - return; - - // Reset to start the transition if we are new - if (isNew()) - reset(targetStyle); - - // Run a cycle of animation. - // We know we will need a new render style, so make one if needed - if (!animatedStyle) - animatedStyle = RenderStyle::clone(targetStyle); - - if (blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0))) - setAnimating(); -} - -void ImplicitAnimation::onAnimationEnd(double elapsedTime) -{ - if (!sendTransitionEvent(eventNames().webkitTransitionEndEvent, elapsedTime)) { - // We didn't dispatch an event, which would call endAnimation(), so we'll just call it here. - endAnimation(true); - } -} - -bool ImplicitAnimation::sendTransitionEvent(const AtomicString& eventType, double elapsedTime) -{ - if (eventType == eventNames().webkitTransitionEndEvent) { - Document::ListenerType listenerType = Document::TRANSITIONEND_LISTENER; - - if (shouldSendEventForListener(listenerType)) { - String propertyName; - if (m_animatingProperty != cAnimateAll) - propertyName = getPropertyName(static_cast<CSSPropertyID>(m_animatingProperty)); - - // Dispatch the event - RefPtr<Element> element = 0; - if (m_object->node() && m_object->node()->isElementNode()) - element = static_cast<Element*>(m_object->node()); - - ASSERT(!element || element->document() && !element->document()->inPageCache()); - if (!element) - return false; - - // Keep a reference to this ImplicitAnimation so it doesn't go away in the handler - RefPtr<ImplicitAnimation> retainer(this); - - // Call the event handler - element->dispatchWebKitTransitionEvent(eventType, propertyName, elapsedTime); - - // Restore the original (unanimated) style - if (eventType == eventNames().webkitAnimationEndEvent && element->renderer()) - setChanged(element.get()); - - return true; // Did dispatch an event - } - } - - return false; // Didn't dispatch an event -} - -void ImplicitAnimation::reset(RenderStyle* to) -{ - ASSERT(to); - ASSERT(m_fromStyle); - - - m_toStyle = to; - - // Restart the transition - if (m_fromStyle && m_toStyle) - updateStateMachine(AnimationStateInputRestartAnimation, -1); - - // set the transform animation list - validateTransformFunctionList(); -} - -void ImplicitAnimation::setOverridden(bool b) -{ - if (b == m_overridden) - return; - - m_overridden = b; - updateStateMachine(m_overridden ? AnimationStateInputPauseOverride : AnimationStateInputResumeOverride, -1); -} - -bool ImplicitAnimation::affectsProperty(int property) const -{ - return (m_animatingProperty == property); -} - -bool ImplicitAnimation::isTargetPropertyEqual(int prop, const RenderStyle* targetStyle) -{ - return propertiesEqual(prop, m_toStyle.get(), targetStyle); -} - -void ImplicitAnimation::blendPropertyValueInStyle(int prop, RenderStyle* currentStyle) -{ - blendProperties(this, prop, currentStyle, m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0)); -} - -void ImplicitAnimation::validateTransformFunctionList() -{ - m_transformFunctionListValid = false; - - if (!m_fromStyle || !m_toStyle) - return; - - const TransformOperations* val = &m_fromStyle->transform(); - const TransformOperations* toVal = &m_toStyle->transform(); - - if (val->operations().isEmpty()) - val = toVal; - - if (val->operations().isEmpty()) - return; - - // See if the keyframes are valid - if (val != toVal) { - // A list of length 0 matches anything - if (!toVal->operations().isEmpty()) { - // If the sizes of the function lists don't match, the lists don't match - if (val->operations().size() != toVal->operations().size()) - return; - - // If the types of each function are not the same, the lists don't match - for (size_t j = 0; j < val->operations().size(); ++j) { - if (!val->operations()[j]->isSameType(*toVal->operations()[j])) - return; - } - } - } - - // Keyframes are valid - m_transformFunctionListValid = true; -} - -} // namespace WebCore diff --git a/WebCore/page/animation/ImplicitAnimation.h b/WebCore/page/animation/ImplicitAnimation.h deleted file mode 100644 index 7c9d50f..0000000 --- a/WebCore/page/animation/ImplicitAnimation.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2007 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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. - */ - -#ifndef ImplicitAnimation_h -#define ImplicitAnimation_h - -#include "AnimationBase.h" -#include "Document.h" - -namespace WebCore { - -// An ImplicitAnimation tracks the state of a transition of a specific CSS property -// for a single RenderObject. -class ImplicitAnimation : public AnimationBase { -public: - static PassRefPtr<ImplicitAnimation> create(const Animation* animation, int animatingProperty, RenderObject* renderer, CompositeAnimation* compositeAnimation, RenderStyle* fromStyle) - { - return adoptRef(new ImplicitAnimation(animation, animatingProperty, renderer, compositeAnimation, fromStyle)); - }; - - int transitionProperty() const { return m_transitionProperty; } - int animatingProperty() const { return m_animatingProperty; } - - virtual void onAnimationEnd(double elapsedTime); - - virtual void animate(CompositeAnimation*, RenderObject*, RenderStyle* currentStyle, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle); - virtual void reset(RenderStyle* to); - - void setOverridden(bool); - virtual bool overridden() const { return m_overridden; } - - virtual bool shouldFireEvents() const { return true; } - - virtual bool affectsProperty(int) const; - - bool hasStyle() const { return m_fromStyle && m_toStyle; } - - bool isTargetPropertyEqual(int, const RenderStyle* targetStyle); - - void blendPropertyValueInStyle(int, RenderStyle* currentStyle); - -protected: - bool shouldSendEventForListener(Document::ListenerType); - bool sendTransitionEvent(const AtomicString&, double elapsedTime); - - void validateTransformFunctionList(); - -private: - ImplicitAnimation(const Animation*, int animatingProperty, RenderObject*, CompositeAnimation*, RenderStyle* fromStyle); - virtual ~ImplicitAnimation(); - - int m_transitionProperty; // Transition property as specified in the RenderStyle. May be cAnimateAll - int m_animatingProperty; // Specific property for this ImplicitAnimation - bool m_overridden; // true when there is a keyframe animation that overrides the transitioning property - - // The two styles that we are blending. - RefPtr<RenderStyle> m_fromStyle; - RefPtr<RenderStyle> m_toStyle; -}; - -} // namespace WebCore - -#endif // ImplicitAnimation_h diff --git a/WebCore/page/animation/KeyframeAnimation.cpp b/WebCore/page/animation/KeyframeAnimation.cpp deleted file mode 100644 index 69fdd11..0000000 --- a/WebCore/page/animation/KeyframeAnimation.cpp +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright (C) 2007 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 "KeyframeAnimation.h" - -#include "CSSPropertyNames.h" -#include "CSSStyleSelector.h" -#include "CompositeAnimation.h" -#include "EventNames.h" -#include "RenderObject.h" -#include "SystemTime.h" - -namespace WebCore { - -KeyframeAnimation::KeyframeAnimation(const Animation* animation, RenderObject* renderer, int index, CompositeAnimation* compAnim, RenderStyle* unanimatedStyle) - : AnimationBase(animation, renderer, compAnim) - , m_keyframes(renderer, animation->name()) - , m_index(index) - , m_unanimatedStyle(unanimatedStyle) -{ - // Get the keyframe RenderStyles - if (m_object && m_object->element() && m_object->element()->isElementNode()) - m_object->document()->styleSelector()->keyframeStylesForAnimation(static_cast<Element*>(m_object->element()), unanimatedStyle, m_keyframes); - - // Update the m_transformFunctionListValid flag based on whether the function lists in the keyframes match. - validateTransformFunctionList(); -} - -KeyframeAnimation::~KeyframeAnimation() -{ - // Do the cleanup here instead of in the base class so the specialized methods get called - if (!postActive()) - updateStateMachine(AnimationStateInputEndAnimation, -1); -} - -void KeyframeAnimation::animate(CompositeAnimation* animation, RenderObject* renderer, const RenderStyle* currentStyle, - const RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle) -{ - // If we have not yet started, we will not have a valid start time, so just start the animation if needed. - if (isNew() && m_animation->playState() == AnimPlayStatePlaying) - updateStateMachine(AnimationStateInputStartAnimation, -1); - - // If we get this far and the animation is done, it means we are cleaning up a just finished animation. - // If so, we need to send back the targetStyle. - if (postActive()) { - if (!animatedStyle) - animatedStyle = const_cast<RenderStyle*>(targetStyle); - return; - } - - // If we are waiting for the start timer, we don't want to change the style yet. - // Special case - if the delay time is 0, then we do want to set the first frame of the - // animation right away. This avoids a flash when the animation starts. - if (waitingToStart() && m_animation->delay() > 0) - return; - - // FIXME: we need to be more efficient about determining which keyframes we are animating between. - // We should cache the last pair or something. - - // Find the first key - double elapsedTime = (m_startTime > 0) ? ((!paused() ? currentTime() : m_pauseTime) - m_startTime) : 0; - if (elapsedTime < 0) - elapsedTime = 0; - - double t = m_animation->duration() ? (elapsedTime / m_animation->duration()) : 1; - int i = static_cast<int>(t); - t -= i; - if (m_animation->direction() && (i & 1)) - t = 1 - t; - - const RenderStyle* fromStyle = 0; - const RenderStyle* toStyle = 0; - double scale = 1; - double offset = 0; - Vector<KeyframeValue>::const_iterator endKeyframes = m_keyframes.endKeyframes(); - for (Vector<KeyframeValue>::const_iterator it = m_keyframes.beginKeyframes(); it != endKeyframes; ++it) { - if (t < it->key()) { - // The first key should always be 0, so we should never succeed on the first key - if (!fromStyle) - break; - scale = 1.0 / (it->key() - offset); - toStyle = it->style(); - break; - } - - offset = it->key(); - fromStyle = it->style(); - } - - // If either style is 0 we have an invalid case, just stop the animation. - if (!fromStyle || !toStyle) { - updateStateMachine(AnimationStateInputEndAnimation, -1); - return; - } - - // Run a cycle of animation. - // We know we will need a new render style, so make one if needed. - if (!animatedStyle) - animatedStyle = RenderStyle::clone(targetStyle); - - const TimingFunction* timingFunction = 0; - if (fromStyle->animations() && fromStyle->animations()->size() > 0) - timingFunction = &(fromStyle->animations()->animation(0)->timingFunction()); - - double prog = progress(scale, offset, timingFunction); - - HashSet<int>::const_iterator endProperties = m_keyframes.endProperties(); - for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it) { - if (blendProperties(this, *it, animatedStyle.get(), fromStyle, toStyle, prog)) - setAnimating(); - } -} - -bool KeyframeAnimation::hasAnimationForProperty(int property) const -{ - HashSet<int>::const_iterator end = m_keyframes.endProperties(); - for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != end; ++it) { - if (*it == property) - return true; - } - - return false; -} - -void KeyframeAnimation::endAnimation(bool) -{ - // Restore the original (unanimated) style - if (m_object) - setChanged(m_object->element()); -} - -bool KeyframeAnimation::shouldSendEventForListener(Document::ListenerType listenerType) -{ - return m_object->document()->hasListenerType(listenerType); -} - -void KeyframeAnimation::onAnimationStart(double elapsedTime) -{ - sendAnimationEvent(eventNames().webkitAnimationStartEvent, elapsedTime); -} - -void KeyframeAnimation::onAnimationIteration(double elapsedTime) -{ - sendAnimationEvent(eventNames().webkitAnimationIterationEvent, elapsedTime); -} - -void KeyframeAnimation::onAnimationEnd(double elapsedTime) -{ - if (!sendAnimationEvent(eventNames().webkitAnimationEndEvent, elapsedTime)) { - // We didn't dispatch an event, which would call endAnimation(), so we'll just call it here. - endAnimation(true); - } -} - -bool KeyframeAnimation::sendAnimationEvent(const AtomicString& eventType, double elapsedTime) -{ - Document::ListenerType listenerType; - if (eventType == eventNames().webkitAnimationIterationEvent) - listenerType = Document::ANIMATIONITERATION_LISTENER; - else if (eventType == eventNames().webkitAnimationEndEvent) - listenerType = Document::ANIMATIONEND_LISTENER; - else { - ASSERT(eventType == eventNames().webkitAnimationStartEvent); - listenerType = Document::ANIMATIONSTART_LISTENER; - } - - if (shouldSendEventForListener(listenerType)) { - // Dispatch the event - RefPtr<Element> element; - if (m_object->node() && m_object->node()->isElementNode()) - element = static_cast<Element*>(m_object->node()); - - ASSERT(!element || element->document() && !element->document()->inPageCache()); - if (!element) - return false; - - // Keep a reference to this ImplicitAnimation so it doesn't go away in the handler - RefPtr<KeyframeAnimation> retainer(this); - - // Call the event handler - element->dispatchWebKitAnimationEvent(eventType, m_keyframes.animationName(), elapsedTime); - - // Restore the original (unanimated) style - if (eventType == eventNames().webkitAnimationEndEvent && element->renderer()) - setChanged(element.get()); - - return true; // Did dispatch an event - } - - return false; // Did not dispatch an event -} - -void KeyframeAnimation::overrideAnimations() -{ - // This will override implicit animations that match the properties in the keyframe animation - HashSet<int>::const_iterator end = m_keyframes.endProperties(); - for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != end; ++it) - compositeAnimation()->overrideImplicitAnimations(*it); -} - -void KeyframeAnimation::resumeOverriddenAnimations() -{ - // This will resume overridden implicit animations - HashSet<int>::const_iterator end = m_keyframes.endProperties(); - for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != end; ++it) - compositeAnimation()->resumeOverriddenImplicitAnimations(*it); -} - -bool KeyframeAnimation::affectsProperty(int property) const -{ - HashSet<int>::const_iterator end = m_keyframes.endProperties(); - for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != end; ++it) { - if (*it == property) - return true; - } - return false; -} - -void KeyframeAnimation::validateTransformFunctionList() -{ - m_transformFunctionListValid = false; - - if (m_keyframes.size() < 2 || !m_keyframes.containsProperty(CSSPropertyWebkitTransform)) - return; - - Vector<KeyframeValue>::const_iterator end = m_keyframes.endKeyframes(); - - // Empty transforms match anything, so find the first non-empty entry as the reference - size_t firstIndex = 0; - Vector<KeyframeValue>::const_iterator firstIt = end; - - for (Vector<KeyframeValue>::const_iterator it = m_keyframes.beginKeyframes(); it != end; ++it, ++firstIndex) { - if (it->style()->transform().operations().size() > 0) { - firstIt = it; - break; - } - } - - if (firstIt == end) - return; - - const TransformOperations* firstVal = &firstIt->style()->transform(); - - // See if the keyframes are valid - for (Vector<KeyframeValue>::const_iterator it = firstIt+1; it != end; ++it) { - const TransformOperations* val = &it->style()->transform(); - - // A null transform matches anything - if (val->operations().isEmpty()) - continue; - - // If the sizes of the function lists don't match, the lists don't match - if (firstVal->operations().size() != val->operations().size()) - return; - - // If the types of each function are not the same, the lists don't match - for (size_t j = 0; j < firstVal->operations().size(); ++j) { - if (!firstVal->operations()[j]->isSameType(*val->operations()[j])) - return; - } - } - - // Keyframes are valid - m_transformFunctionListValid = true; -} - -} // namespace WebCore diff --git a/WebCore/page/animation/KeyframeAnimation.h b/WebCore/page/animation/KeyframeAnimation.h deleted file mode 100644 index 55b429a..0000000 --- a/WebCore/page/animation/KeyframeAnimation.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2007 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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. - */ - -#ifndef KeyframeAnimation_h -#define KeyframeAnimation_h - -#include "AnimationBase.h" -#include "Document.h" -#include "KeyframeList.h" -#include "RenderStyle.h" - -namespace WebCore { - -// A KeyframeAnimation tracks the state of an explicit animation -// for a single RenderObject. -class KeyframeAnimation : public AnimationBase { -public: - static PassRefPtr<KeyframeAnimation> create(const Animation* animation, RenderObject* renderer, int index, CompositeAnimation* compositeAnimation, RenderStyle* unanimatedStyle) - { - return adoptRef(new KeyframeAnimation(animation, renderer, index, compositeAnimation, unanimatedStyle)); - }; - - virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* currentStyle, const RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle); - - const AtomicString& name() const { return m_keyframes.animationName(); } - int index() const { return m_index; } - void setIndex(int i) { m_index = i; } - - virtual bool shouldFireEvents() const { return true; } - - bool hasAnimationForProperty(int property) const; - - RenderStyle* unanimatedStyle() const { return m_unanimatedStyle.get(); } - -protected: - virtual void onAnimationStart(double elapsedTime); - virtual void onAnimationIteration(double elapsedTime); - virtual void onAnimationEnd(double elapsedTime); - virtual void endAnimation(bool reset); - - virtual void overrideAnimations(); - virtual void resumeOverriddenAnimations(); - - bool shouldSendEventForListener(Document::ListenerType inListenerType); - bool sendAnimationEvent(const AtomicString&, double elapsedTime); - - virtual bool affectsProperty(int) const; - - void validateTransformFunctionList(); - -private: - KeyframeAnimation(const Animation* animation, RenderObject*, int index, CompositeAnimation*, RenderStyle* unanimatedStyle); - virtual ~KeyframeAnimation(); - - // The keyframes that we are blending. - KeyframeList m_keyframes; - - // The order in which this animation appears in the animation-name style. - int m_index; - - // The style just before we started animation - RefPtr<RenderStyle> m_unanimatedStyle; -}; - -} // namespace WebCore - -#endif // KeyframeAnimation_h |