Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / animation / css / CSSAnimations.cpp
index b60f033..6b4179a 100644 (file)
@@ -38,6 +38,7 @@
 #include "core/animation/KeyframeEffectModel.h"
 #include "core/animation/css/CSSAnimatableValueFactory.h"
 #include "core/animation/css/CSSAnimationDataList.h"
+#include "core/animation/css/CSSPropertyAnimation.h"
 #include "core/css/CSSKeyframeRule.h"
 #include "core/css/resolver/StyleResolver.h"
 #include "core/dom/Element.h"
@@ -46,6 +47,7 @@
 #include "core/events/TransitionEvent.h"
 #include "core/events/WebKitAnimationEvent.h"
 #include "core/frame/UseCounter.h"
+#include "core/rendering/RenderLayer.h"
 #include "core/rendering/RenderObject.h"
 #include "core/rendering/style/KeyframeList.h"
 #include "platform/animation/TimingFunction.h"
@@ -94,7 +96,6 @@ static PassRefPtr<TimingFunction> generateTimingFunction(const KeyframeEffectMod
 static void resolveKeyframes(StyleResolver* resolver, Element* element, const Element& parentElement, const RenderStyle& style, RenderStyle* parentStyle, const AtomicString& name, TimingFunction* defaultTimingFunction,
     Vector<std::pair<KeyframeEffectModel::KeyframeVector, RefPtr<TimingFunction> > >& keyframesAndTimingFunctions)
 {
-    ASSERT(RuntimeEnabledFeatures::webAnimationsCSSEnabled());
     // When the element is null, use its parent for scoping purposes.
     const Element* elementForScoping = element ? element : &parentElement;
     const StyleRuleKeyframes* keyframesRule = CSSAnimations::matchScopedKeyframesRule(resolver, elementForScoping, name.impl());
@@ -267,10 +268,8 @@ const PassRefPtr<TimingFunction> timingFromAnimationData(const CSSAnimationData*
 {
     if (animationData->isDelaySet())
         timing.startDelay = animationData->delay();
-    if (animationData->isDurationSet()) {
+    if (animationData->isDurationSet())
         timing.iterationDuration = animationData->duration();
-        timing.hasIterationDuration = true;
-    }
     if (animationData->isIterationCountSet()) {
         if (animationData->iterationCount() == CSSAnimationData::IterationCountInfinite)
             timing.iterationCount = std::numeric_limits<double>::infinity();
@@ -321,7 +320,7 @@ const PassRefPtr<TimingFunction> timingFromAnimationData(const CSSAnimationData*
     timing.assertValid();
     ASSERT(!timing.iterationStart);
     ASSERT(timing.playbackRate == 1);
-    ASSERT(timing.iterationDuration >= 0 && std::isfinite(timing.iterationDuration));
+    ASSERT(!std::isinf(timing.iterationDuration));
 
     isPaused = animationData->isPlayStateSet() && animationData->playState() == AnimPlayStatePaused;
     return animationData->isTimingFunctionSet() ? animationData->timingFunction() : CSSAnimationData::initialAnimationTimingFunction();
@@ -348,7 +347,6 @@ const StyleRuleKeyframes* CSSAnimations::matchScopedKeyframesRule(StyleResolver*
 
 PassOwnPtr<CSSAnimationUpdate> CSSAnimations::calculateUpdate(Element* element, const Element& parentElement, const RenderStyle& style, RenderStyle* parentStyle, StyleResolver* resolver)
 {
-    ASSERT(RuntimeEnabledFeatures::webAnimationsCSSEnabled());
     OwnPtr<CSSAnimationUpdate> update = adoptPtr(new CSSAnimationUpdate());
     calculateAnimationUpdate(update.get(), element, parentElement, style, parentStyle, resolver);
     calculateAnimationCompositableValues(update.get(), element);
@@ -443,6 +441,11 @@ void CSSAnimations::maybeApplyPendingUpdate(Element* element)
 
     m_previousCompositableValuesForAnimations.swap(update->compositableValuesForAnimations());
 
+    // FIXME: cancelling, pausing, unpausing animations all query compositingState, which is not necessarily up to date here
+    // since we call this from recalc style.
+    // https://code.google.com/p/chromium/issues/detail?id=339847
+    DisableCompositingQueryAsserts disabler;
+
     for (Vector<AtomicString>::const_iterator iter = update->cancelledAnimationNames().begin(); iter != update->cancelledAnimationNames().end(); ++iter) {
         const HashSet<RefPtr<Player> >& players = m_animations.take(*iter);
         for (HashSet<RefPtr<Player> >::const_iterator iter = players.begin(); iter != players.end(); ++iter)
@@ -456,7 +459,10 @@ void CSSAnimations::maybeApplyPendingUpdate(Element* element)
         for (HashSet<RefPtr<Player> >::const_iterator iter = players.begin(); iter != players.end(); ++iter) {
             Player* player = iter->get();
             ASSERT(player->paused() == isFirstPlayerPaused);
-            player->setPaused(!isFirstPlayerPaused);
+            if (isFirstPlayerPaused)
+                player->unpause();
+            else
+                player->pause();
         }
     }
 
@@ -467,9 +473,10 @@ void CSSAnimations::maybeApplyPendingUpdate(Element* element)
             const InertAnimation* inertAnimation = animationsIter->get();
             // The event delegate is set on the the first animation only. We
             // rely on the behavior of OwnPtr::release() to achieve this.
-            RefPtr<Animation> animation = Animation::create(element, inertAnimation->effect(), inertAnimation->specified(), Animation::DefaultPriority, eventDelegate.release());
+            RefPtr<Animation> animation = Animation::create(element, inertAnimation->effect(), inertAnimation->specifiedTiming(), Animation::DefaultPriority, eventDelegate.release());
             Player* player = element->document().timeline()->createPlayer(animation.get());
-            player->setPaused(inertAnimation->paused());
+            if (inertAnimation->paused())
+                player->pause();
             element->document().cssPendingAnimations().add(player);
             player->update();
             players.add(player);
@@ -524,7 +531,7 @@ void CSSAnimations::maybeApplyPendingUpdate(Element* element)
             newFrames.append(frames[1]->clone());
             effect = KeyframeEffectModel::create(newFrames);
         }
-        RefPtr<Animation> transition = Animation::create(element, effect, inertAnimation->specified(), Animation::TransitionPriority, eventDelegate.release());
+        RefPtr<Animation> transition = Animation::create(element, effect, inertAnimation->specifiedTiming(), Animation::TransitionPriority, eventDelegate.release());
         RefPtr<Player> player = element->document().transitionTimeline()->createPlayer(transition.get());
         player->update();
         element->document().cssPendingAnimations().add(player.get());
@@ -549,12 +556,16 @@ void CSSAnimations::calculateTransitionUpdateForProperty(CSSPropertyID id, const
             ASSERT(!element->activeAnimations() || !element->activeAnimations()->isAnimationStyleChange());
         }
     }
+
+    if (anim->duration() + anim->delay() <= 0)
+        return;
+
+    if (CSSPropertyAnimation::propertiesEqual(id, &oldStyle, &style))
+        return;
     if (!to)
         to = CSSAnimatableValueFactory::create(id, style);
-    RefPtr<AnimatableValue> from = CSSAnimatableValueFactory::create(id, oldStyle);
-    if (to->equals(from.get()))
-        return;
 
+    RefPtr<AnimatableValue> from = CSSAnimatableValueFactory::create(id, oldStyle);
     // If we have multiple transitions on the same property, we will use the
     // last one since we iterate over them in order.
     if (AnimatableValue::usesDefaultInterpolation(to.get(), from.get()))
@@ -611,7 +622,7 @@ void CSSAnimations::calculateTransitionUpdate(CSSAnimationUpdate* update, const
         for (size_t i = 0; i < style.transitions()->size(); ++i) {
             const CSSAnimationData* anim = style.transitions()->animation(i);
             CSSAnimationData::AnimationMode mode = anim->animationMode();
-            if (anim->duration() + anim->delay() <= 0 || mode == CSSAnimationData::AnimateNone)
+            if (mode == CSSAnimationData::AnimateNone)
                 continue;
 
             bool animateAll = mode == CSSAnimationData::AnimateAll;
@@ -746,13 +757,13 @@ void CSSAnimations::AnimationEventDelegate::onEventCondition(const TimedItem* ti
         // between a single pair of samples. See http://crbug.com/275263. For
         // compatibility with the existing implementation, this event uses
         // the elapsedTime for the first iteration in question.
-        ASSERT(timedItem->specified().hasIterationDuration);
-        const double elapsedTime = timedItem->specified().iterationDuration * (previousIteration + 1);
+        ASSERT(!std::isnan(timedItem->specifiedTiming().iterationDuration));
+        const double elapsedTime = timedItem->specifiedTiming().iterationDuration * (previousIteration + 1);
         maybeDispatch(Document::ANIMATIONITERATION_LISTENER, EventTypeNames::animationiteration, elapsedTime);
         return;
     }
     if ((isFirstSample || previousPhase == TimedItem::PhaseBefore) && isLaterPhase(currentPhase, TimedItem::PhaseBefore)) {
-        ASSERT(timedItem->specified().startDelay > 0 || isFirstSample);
+        ASSERT(timedItem->specifiedTiming().startDelay > 0 || isFirstSample);
         // The spec states that the elapsed time should be
         // 'delay < 0 ? -delay : 0', but we always use 0 to match the existing
         // implementation. See crbug.com/279611
@@ -771,7 +782,7 @@ void CSSAnimations::TransitionEventDelegate::onEventCondition(const TimedItem* t
     const TimedItem::Phase currentPhase = timedItem->phase();
     if (currentPhase == TimedItem::PhaseAfter && (isFirstSample || previousPhase != currentPhase) && m_target->document().hasListenerType(Document::TRANSITIONEND_LISTENER)) {
         String propertyName = getPropertyNameString(m_property);
-        const Timing& timing = timedItem->specified();
+        const Timing& timing = timedItem->specifiedTiming();
         double elapsedTime = timing.iterationDuration;
         const AtomicString& eventType = EventTypeNames::transitionend;
         String pseudoElement = PseudoElement::pseudoElementNameForEvents(m_target->pseudoId());
@@ -893,11 +904,6 @@ bool CSSAnimations::isAnimatableProperty(CSSPropertyID property)
     case CSSPropertyZIndex:
     case CSSPropertyZoom:
         return true;
-    // FIXME: Shorthands should not be present in this list, but
-    // CSSPropertyAnimation implements animation of these shorthands
-    // directly and makes use of this method.
-    case CSSPropertyFlex:
-        return !RuntimeEnabledFeatures::webAnimationsCSSEnabled();
     default:
         return false;
     }