1f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)/*
2f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) * Copyright (C) 2013 Google Inc. All rights reserved.
3f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) *
4f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without
5f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) * modification, are permitted provided that the following conditions are
6f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) * met:
7f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) *
8f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) *     * Redistributions of source code must retain the above copyright
9f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) * notice, this list of conditions and the following disclaimer.
10f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) *     * Redistributions in binary form must reproduce the above
11f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer
12f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) * in the documentation and/or other materials provided with the
13f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) * distribution.
14f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) *     * Neither the name of Google Inc. nor the names of its
15f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) * contributors may be used to endorse or promote products derived from
16f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) * this software without specific prior written permission.
17f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) *
18f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) */
30f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
31f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "config.h"
32f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "core/animation/css/CSSAnimations.h"
33f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
345d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/StylePropertyShorthand.h"
35c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "core/animation/ActiveAnimations.h"
36d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "core/animation/AnimationTimeline.h"
3751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/animation/CompositorAnimations.h"
3809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/animation/KeyframeEffectModel.h"
39c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/animation/LegacyStyleInterpolation.h"
401e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/animation/css/CSSAnimatableValueFactory.h"
41d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/animation/css/CSSPropertyEquality.h"
42f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "core/css/CSSKeyframeRule.h"
43e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#include "core/css/CSSPropertyMetadata.h"
445d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/css/resolver/CSSToStyleMap.h"
45f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "core/css/resolver/StyleResolver.h"
46f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "core/dom/Element.h"
4751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/dom/PseudoElement.h"
48c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/dom/StyleEngine.h"
491e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/events/TransitionEvent.h"
5006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/events/WebKitAnimationEvent.h"
5151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/frame/UseCounter.h"
5209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/rendering/RenderLayer.h"
5351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/rendering/RenderObject.h"
5451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/rendering/style/KeyframeList.h"
5509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "platform/animation/TimingFunction.h"
5651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "public/platform/Platform.h"
57a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "wtf/BitArray.h"
58f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "wtf/HashSet.h"
59f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
60c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
61e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
621e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)namespace {
63e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
64aafa69cb17c9d6606c07663ade5f81388a2c5986Ben MurdochCSSPropertyID propertyForAnimation(CSSPropertyID property)
65aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch{
66aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    switch (property) {
67aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    case CSSPropertyWebkitPerspective:
68aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        return CSSPropertyPerspective;
69aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    case CSSPropertyWebkitTransform:
70aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        return CSSPropertyTransform;
71aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    case CSSPropertyWebkitPerspectiveOriginX:
72aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    case CSSPropertyWebkitPerspectiveOriginY:
737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    case CSSPropertyWebkitPerspectiveOrigin:
74c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return CSSPropertyPerspectiveOrigin;
75aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    case CSSPropertyWebkitTransformOriginX:
76aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    case CSSPropertyWebkitTransformOriginY:
77aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    case CSSPropertyWebkitTransformOriginZ:
78c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return CSSPropertyTransformOrigin;
79aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    default:
80aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        break;
81aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    }
82aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    return property;
83aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch}
84aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch
857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccistatic void resolveKeyframes(StyleResolver* resolver, const Element* animatingElement, Element& element, const RenderStyle& style, RenderStyle* parentStyle, const AtomicString& name, TimingFunction* defaultTimingFunction,
86a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    AnimatableValueKeyframeVector& keyframes)
8751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // When the animating element is null, use its parent for scoping purposes.
897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    const Element* elementForScoping = animatingElement ? animatingElement : &element;
9009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const StyleRuleKeyframes* keyframesRule = CSSAnimations::matchScopedKeyframesRule(resolver, elementForScoping, name.impl());
9151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (!keyframesRule)
9251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return;
9351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
9407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    const WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> >& styleKeyframes = keyframesRule->keyframes();
9551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (styleKeyframes.isEmpty())
9651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return;
9751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
9851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // Construct and populate the style for each keyframe
99aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    PropertySet specifiedPropertiesForUseCounter;
10051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    for (size_t i = 0; i < styleKeyframes.size(); ++i) {
10151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        const StyleKeyframe* styleKeyframe = styleKeyframes[i].get();
10209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        RefPtr<RenderStyle> keyframeStyle = resolver->styleForKeyframe(element, style, parentStyle, styleKeyframe, name);
103a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        RefPtrWillBeRawPtr<AnimatableValueKeyframe> keyframe = AnimatableValueKeyframe::create();
10451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        const Vector<double>& offsets = styleKeyframe->keys();
10551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ASSERT(!offsets.isEmpty());
10651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        keyframe->setOffset(offsets[0]);
107d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        keyframe->setEasing(defaultTimingFunction);
108d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        const StylePropertySet& properties = styleKeyframe->properties();
109d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        for (unsigned j = 0; j < properties.propertyCount(); j++) {
110aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch            specifiedPropertiesForUseCounter.add(properties.propertyAt(j).id());
111aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch            CSSPropertyID property = propertyForAnimation(properties.propertyAt(j).id());
112aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch            if (property == CSSPropertyWebkitAnimationTimingFunction || property == CSSPropertyAnimationTimingFunction) {
113d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                CSSValue* value = properties.propertyAt(j).value();
114d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                RefPtr<TimingFunction> timingFunction;
115d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                if (value->isInheritedValue() && parentStyle->animations())
116d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                    timingFunction = parentStyle->animations()->timingFunctionList()[0];
117d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                else if (value->isInheritedValue() || value->isInitialValue())
118d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                    timingFunction = CSSTimingData::initialTimingFunction();
119d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                else
120f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)                    timingFunction = CSSToStyleMap::mapAnimationTimingFunction(toCSSValueList(value)->item(0));
121d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                keyframe->setEasing(timingFunction.release());
122e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            } else if (CSSPropertyMetadata::isAnimatableProperty(property)) {
12351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                keyframe->setPropertyValue(property, CSSAnimatableValueFactory::create(property, *keyframeStyle).get());
124aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch            }
12551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
12651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        keyframes.append(keyframe);
12751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // The last keyframe specified at a given offset is used.
12851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        for (size_t j = 1; j < offsets.size(); ++j) {
129a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            keyframes.append(toAnimatableValueKeyframe(keyframe->cloneWithOffset(offsets[j]).get()));
13051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
13151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
13251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(!keyframes.isEmpty());
13351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
134aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    for (PropertySet::const_iterator iter = specifiedPropertiesForUseCounter.begin(); iter != specifiedPropertiesForUseCounter.end(); ++iter) {
13551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        const CSSPropertyID property = *iter;
13651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ASSERT(property != CSSPropertyInvalid);
13751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        blink::Platform::current()->histogramSparse("WebCore.Animation.CSSProperties", UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(property));
13851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
13951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
14051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // Remove duplicate keyframes. In CSS the last keyframe at a given offset takes priority.
14151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    std::stable_sort(keyframes.begin(), keyframes.end(), Keyframe::compareOffsets);
14251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    size_t targetIndex = 0;
14351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    for (size_t i = 1; i < keyframes.size(); i++) {
14451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (keyframes[i]->offset() != keyframes[targetIndex]->offset())
14551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            targetIndex++;
14651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (targetIndex != i)
14751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            keyframes[targetIndex] = keyframes[i];
14851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
14951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    keyframes.shrink(targetIndex + 1);
15051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
15151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // Add 0% and 100% keyframes if absent.
152a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    RefPtrWillBeRawPtr<AnimatableValueKeyframe> startKeyframe = keyframes[0];
15351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (startKeyframe->offset()) {
154a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        startKeyframe = AnimatableValueKeyframe::create();
15551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        startKeyframe->setOffset(0);
156323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        startKeyframe->setEasing(defaultTimingFunction);
15751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        keyframes.prepend(startKeyframe);
15851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
159a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    RefPtrWillBeRawPtr<AnimatableValueKeyframe> endKeyframe = keyframes[keyframes.size() - 1];
16051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (endKeyframe->offset() != 1) {
161a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        endKeyframe = AnimatableValueKeyframe::create();
16251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        endKeyframe->setOffset(1);
163323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        endKeyframe->setEasing(defaultTimingFunction);
16451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        keyframes.append(endKeyframe);
16551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
16651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(keyframes.size() >= 2);
16751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(!keyframes.first()->offset());
16851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(keyframes.last()->offset() == 1);
16951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
17051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // Snapshot current property values for 0% and 100% if missing.
17151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    PropertySet allProperties;
17251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    size_t numKeyframes = keyframes.size();
17351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    for (size_t i = 0; i < numKeyframes; i++) {
17451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        const PropertySet& keyframeProperties = keyframes[i]->properties();
17551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        for (PropertySet::const_iterator iter = keyframeProperties.begin(); iter != keyframeProperties.end(); ++iter)
17651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            allProperties.add(*iter);
17751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
17851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    const PropertySet& startKeyframeProperties = startKeyframe->properties();
17951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    const PropertySet& endKeyframeProperties = endKeyframe->properties();
18051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    bool missingStartValues = startKeyframeProperties.size() < allProperties.size();
18151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    bool missingEndValues = endKeyframeProperties.size() < allProperties.size();
18251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (missingStartValues || missingEndValues) {
18351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        for (PropertySet::const_iterator iter = allProperties.begin(); iter != allProperties.end(); ++iter) {
18451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            const CSSPropertyID property = *iter;
18551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            bool startNeedsValue = missingStartValues && !startKeyframeProperties.contains(property);
18651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            bool endNeedsValue = missingEndValues && !endKeyframeProperties.contains(property);
18751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (!startNeedsValue && !endNeedsValue)
18851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                continue;
18907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            RefPtrWillBeRawPtr<AnimatableValue> snapshotValue = CSSAnimatableValueFactory::create(property, style);
19051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (startNeedsValue)
19151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                startKeyframe->setPropertyValue(property, snapshotValue.get());
19251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (endNeedsValue)
19351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                endKeyframe->setPropertyValue(property, snapshotValue.get());
19451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
19551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
19651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(startKeyframe->properties().size() == allProperties.size());
19751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(endKeyframe->properties().size() == allProperties.size());
19851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
19951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
2001e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)} // namespace
2011e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
202a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)const StyleRuleKeyframes* CSSAnimations::matchScopedKeyframesRule(StyleResolver* resolver, const Element* element, const StringImpl* animationName)
20351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
204c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    // FIXME: This is all implementation detail of style resolver, CSSAnimations shouldn't be reaching into any of it.
205c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (resolver->document().styleEngine()->hasOnlyScopedResolverForDocument())
206c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return element->document().scopedStyleResolver()->keyframeStylesForAnimation(animationName);
20751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
208c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8> stack;
209a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    resolver->styleTreeResolveScopedKeyframesRules(element, stack);
21051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (stack.isEmpty())
21151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return 0;
21251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
21351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    for (size_t i = 0; i < stack.size(); ++i) {
21451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (const StyleRuleKeyframes* keyframesRule = stack.at(i)->keyframeStylesForAnimation(animationName))
21551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return keyframesRule;
21651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
21751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return 0;
21851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
21951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
220a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben MurdochCSSAnimations::CSSAnimations()
221a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch{
222a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch}
223a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
2247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciPassOwnPtrWillBeRawPtr<CSSAnimationUpdate> CSSAnimations::calculateUpdate(const Element* animatingElement, Element& element, const RenderStyle& style, RenderStyle* parentStyle, StyleResolver* resolver)
225f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles){
22607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    OwnPtrWillBeRawPtr<CSSAnimationUpdate> update = adoptPtrWillBeNoop(new CSSAnimationUpdate());
2277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    calculateAnimationUpdate(update.get(), animatingElement, element, style, parentStyle, resolver);
2287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    calculateAnimationActiveInterpolations(update.get(), animatingElement, element.document().timeline().currentTimeInternal());
2297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    calculateTransitionUpdate(update.get(), animatingElement, style);
2307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    calculateTransitionActiveInterpolations(update.get(), animatingElement, element.document().timeline().currentTimeInternal());
2311e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return update->isEmpty() ? nullptr : update.release();
232f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)}
233f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
2347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid CSSAnimations::calculateAnimationUpdate(CSSAnimationUpdate* update, const Element* animatingElement, Element& element, const RenderStyle& style, RenderStyle* parentStyle, StyleResolver* resolver)
235f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles){
2367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    const ActiveAnimations* activeAnimations = animatingElement ? animatingElement->activeAnimations() : 0;
23709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
238197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if !ENABLE(ASSERT)
23909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // If we're in an animation style change, no animations can have started, been cancelled or changed play state.
24009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // When ASSERT is enabled, we verify this optimization.
24109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (activeAnimations && activeAnimations->isAnimationStyleChange())
24209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return;
24309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#endif
24409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
245d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    const CSSAnimationData* animationData = style.animations();
24609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const CSSAnimations* cssAnimations = activeAnimations ? &activeAnimations->cssAnimations() : 0;
2471e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
248c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    HashSet<AtomicString> inactive;
249f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    if (cssAnimations)
250f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        for (AnimationMap::const_iterator iter = cssAnimations->m_animations.begin(); iter != cssAnimations->m_animations.end(); ++iter)
251f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)            inactive.add(iter->key);
252f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
25351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (style.display() != NONE) {
254d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        for (size_t i = 0; animationData && i < animationData->nameList().size(); ++i) {
255d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            AtomicString animationName(animationData->nameList()[i]);
256d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            if (animationName == CSSAnimationData::initialName())
2573c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch                continue;
258d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
259d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            bool isPaused = CSSTimingData::getRepeated(animationData->playStateList(), i) == AnimPlayStatePaused;
260f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
261f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            // Keyframes and animation properties are snapshotted when the
262f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            // animation starts, so we don't need to track changes to these,
263f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            // with the exception of play-state.
264f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)            if (cssAnimations) {
265c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)                AnimationMap::const_iterator existing(cssAnimations->m_animations.find(animationName));
266f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                if (existing != cssAnimations->m_animations.end()) {
267c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)                    inactive.remove(animationName);
26807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                    AnimationPlayer* player = existing->value.get();
269d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                    if (isPaused != player->paused()) {
27009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                        ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleChange());
271f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)                        update->toggleAnimationPaused(animationName);
27209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    }
273f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                    continue;
274f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                }
275f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)            }
276f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
277d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            Timing timing = animationData->convertToTiming(i);
278d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            RefPtr<TimingFunction> keyframeTimingFunction = timing.timingFunction;
279d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            timing.timingFunction = Timing::defaults().timingFunction;
280a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            AnimatableValueKeyframeVector resolvedKeyframes;
2817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            resolveKeyframes(resolver, animatingElement, element, style, parentStyle, animationName, keyframeTimingFunction.get(), resolvedKeyframes);
282d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if (!resolvedKeyframes.isEmpty()) {
28309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleChange());
284a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                update->startAnimation(animationName, InertAnimation::create(AnimatableValueKeyframeEffectModel::create(resolvedKeyframes), timing, isPaused));
285f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)            }
286f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        }
287f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    }
288f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
289a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    ASSERT(inactive.isEmpty() || cssAnimations);
29009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    for (HashSet<AtomicString>::const_iterator iter = inactive.begin(); iter != inactive.end(); ++iter) {
29109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleChange());
29207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        update->cancelAnimation(*iter, *cssAnimations->m_animations.get(*iter));
29309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
294f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)}
295f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
296c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)void CSSAnimations::maybeApplyPendingUpdate(Element* element)
297f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles){
29819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    if (!m_pendingUpdate) {
29943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        m_previousActiveInterpolationsForAnimations.clear();
300c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        return;
30119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    }
302f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
30307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    OwnPtrWillBeRawPtr<CSSAnimationUpdate> update = m_pendingUpdate.release();
304f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
30543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    m_previousActiveInterpolationsForAnimations.swap(update->activeInterpolationsForAnimations());
30619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
30709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // FIXME: cancelling, pausing, unpausing animations all query compositingState, which is not necessarily up to date here
30809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // since we call this from recalc style.
30909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // https://code.google.com/p/chromium/issues/detail?id=339847
31009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    DisableCompositingQueryAsserts disabler;
31109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
3121e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    for (Vector<AtomicString>::const_iterator iter = update->cancelledAnimationNames().begin(); iter != update->cancelledAnimationNames().end(); ++iter) {
3139e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        RefPtrWillBeRawPtr<AnimationPlayer> player = m_animations.take(*iter);
314323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        player->cancel();
315323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        player->update(TimingUpdateOnDemand);
3161e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
317c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
318f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    for (Vector<AtomicString>::const_iterator iter = update->animationsWithPauseToggled().begin(); iter != update->animationsWithPauseToggled().end(); ++iter) {
31907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        AnimationPlayer* player = m_animations.get(*iter);
32007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        if (player->paused())
32107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            player->unpause();
32207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        else
32307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            player->pause();
324323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        if (player->outdated())
325323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            player->update(TimingUpdateOnDemand);
326f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    }
327c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
328d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    for (WillBeHeapVector<CSSAnimationUpdate::NewAnimation>::const_iterator iter = update->newAnimations().begin(); iter != update->newAnimations().end(); ++iter) {
32907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        const InertAnimation* inertAnimation = iter->animation.get();
330c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        OwnPtrWillBeRawPtr<AnimationEventDelegate> eventDelegate = adoptPtrWillBeNoop(new AnimationEventDelegate(element, iter->name));
331d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        RefPtrWillBeRawPtr<Animation> animation = Animation::create(element, inertAnimation->effect(), inertAnimation->specifiedTiming(), Animation::DefaultPriority, eventDelegate.release());
3327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        animation->setName(inertAnimation->name());
333d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        RefPtrWillBeRawPtr<AnimationPlayer> player = element->document().timeline().createAnimationPlayer(animation.get());
33407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        if (inertAnimation->paused())
33507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            player->pause();
336323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        player->update(TimingUpdateOnDemand);
33707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        m_animations.set(iter->name, player.get());
3381e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
3391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
34051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // Transitions that are run on the compositor only update main-thread state
34151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // lazily. However, we need the new state to know what the from state shoud
34251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // be when transitions are retargeted. Instead of triggering complete style
34351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // recalculation, we find these cases by searching for new transitions that
34451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // have matching cancelled animation property IDs on the compositor.
345d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    WillBeHeapHashMap<CSSPropertyID, std::pair<RefPtrWillBeMember<Animation>, double> > retargetedCompositorTransitions;
3461e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    for (HashSet<CSSPropertyID>::iterator iter = update->cancelledTransitions().begin(); iter != update->cancelledTransitions().end(); ++iter) {
34751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CSSPropertyID id = *iter;
34851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ASSERT(m_transitions.contains(id));
3496f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
350d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        RefPtrWillBeRawPtr<AnimationPlayer> player = m_transitions.take(id).player;
351a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        Animation* animation = toAnimation(player->source());
352a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        if (animation->hasActiveAnimationsOnCompositor(id) && update->newTransitions().find(id) != update->newTransitions().end())
353d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            retargetedCompositorTransitions.add(id, std::pair<RefPtrWillBeMember<Animation>, double>(animation, player->startTimeInternal()));
35451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        player->cancel();
355323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        player->update(TimingUpdateOnDemand);
3561e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
3571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
358a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    for (CSSAnimationUpdate::NewTransitionMap::const_iterator iter = update->newTransitions().begin(); iter != update->newTransitions().end(); ++iter) {
359a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        const CSSAnimationUpdate::NewTransition& newTransition = iter->value;
3601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
3611e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        RunningTransition runningTransition;
3621e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        runningTransition.from = newTransition.from;
3631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        runningTransition.to = newTransition.to;
3641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
3651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        CSSPropertyID id = newTransition.id;
3661e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        InertAnimation* inertAnimation = newTransition.animation.get();
367c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        OwnPtrWillBeRawPtr<TransitionEventDelegate> eventDelegate = adoptPtrWillBeNoop(new TransitionEventDelegate(element, newTransition.eventId));
36851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
369d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        RefPtrWillBeRawPtr<AnimationEffect> effect = inertAnimation->effect();
37051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
37151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (retargetedCompositorTransitions.contains(id)) {
372d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            const std::pair<RefPtrWillBeMember<Animation>, double>& oldTransition = retargetedCompositorTransitions.get(id);
373d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            RefPtrWillBeRawPtr<Animation> oldAnimation = oldTransition.first;
37451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            double oldStartTime = oldTransition.second;
375d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            double inheritedTime = isNull(oldStartTime) ? 0 : element->document().timeline().currentTimeInternal() - oldStartTime;
376a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
377a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            AnimatableValueKeyframeEffectModel* oldEffect = toAnimatableValueKeyframeEffectModel(inertAnimation->effect());
378a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            const KeyframeVector& frames = oldEffect->getFrames();
379a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
380a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            AnimatableValueKeyframeVector newFrames;
381a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            newFrames.append(toAnimatableValueKeyframe(frames[0]->clone().get()));
382a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            newFrames.append(toAnimatableValueKeyframe(frames[1]->clone().get()));
383a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
38451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            newFrames[0]->clearPropertyValue(id);
385d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            RefPtrWillBeRawPtr<InertAnimation> inertAnimationForSampling = InertAnimation::create(oldAnimation->effect(), oldAnimation->specifiedTiming(), false);
386a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            OwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > sample = inertAnimationForSampling->sample(inheritedTime);
387a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            ASSERT(sample->size() == 1);
388a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            newFrames[0]->setPropertyValue(id, toLegacyStyleInterpolation(sample->at(0).get())->currentValue());
389a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
390a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            effect = AnimatableValueKeyframeEffectModel::create(newFrames);
39151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
392a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
393d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        RefPtrWillBeRawPtr<Animation> transition = Animation::create(element, effect, inertAnimation->specifiedTiming(), Animation::TransitionPriority, eventDelegate.release());
3947242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        transition->setName(inertAnimation->name());
395d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        RefPtrWillBeRawPtr<AnimationPlayer> player = element->document().timeline().createAnimationPlayer(transition.get());
396323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        player->update(TimingUpdateOnDemand);
3976f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        runningTransition.player = player;
3981e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        m_transitions.set(id, runningTransition);
39951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ASSERT(id != CSSPropertyInvalid);
40051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        blink::Platform::current()->histogramSparse("WebCore.Animation.CSSProperties", UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(id));
4011e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
4021e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
4031e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
404d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void CSSAnimations::calculateTransitionUpdateForProperty(CSSPropertyID id, CSSPropertyID eventId, const CSSTransitionData& transitionData, size_t transitionIndex, const RenderStyle& oldStyle, const RenderStyle& style, const TransitionMap* activeTransitions, CSSAnimationUpdate* update, const Element* element)
4051e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){
40607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    RefPtrWillBeRawPtr<AnimatableValue> to = nullptr;
407a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if (activeTransitions) {
408a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        TransitionMap::const_iterator activeTransitionIter = activeTransitions->find(id);
409a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        if (activeTransitionIter != activeTransitions->end()) {
41009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            to = CSSAnimatableValueFactory::create(id, style);
411a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            const AnimatableValue* activeTo = activeTransitionIter->value.to;
412a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            if (to->equals(activeTo))
4131e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                return;
4141e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            update->cancelTransition(id);
415a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            ASSERT(!element->activeAnimations() || !element->activeAnimations()->isAnimationStyleChange());
4161e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
4171e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
4181e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
419d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (CSSPropertyEquality::propertiesEqual(id, oldStyle, style))
42009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return;
42109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!to)
42209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        to = CSSAnimatableValueFactory::create(id, style);
42309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
42407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    RefPtrWillBeRawPtr<AnimatableValue> from = CSSAnimatableValueFactory::create(id, oldStyle);
425a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    // If we have multiple transitions on the same property, we will use the
426a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    // last one since we iterate over them in order.
42709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (AnimatableValue::usesDefaultInterpolation(to.get(), from.get()))
428a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return;
429a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
430d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    Timing timing = transitionData.convertToTiming(transitionIndex);
431d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (timing.startDelay + timing.iterationDuration <= 0)
432d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        return;
43307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
434a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    AnimatableValueKeyframeVector keyframes;
4351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
436a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    RefPtrWillBeRawPtr<AnimatableValueKeyframe> startKeyframe = AnimatableValueKeyframe::create();
437a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    startKeyframe->setPropertyValue(id, from.get());
4381e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    startKeyframe->setOffset(0);
439d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    startKeyframe->setEasing(timing.timingFunction.release());
440d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    timing.timingFunction = LinearTimingFunction::shared();
4411e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    keyframes.append(startKeyframe);
4421e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
443a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    RefPtrWillBeRawPtr<AnimatableValueKeyframe> endKeyframe = AnimatableValueKeyframe::create();
444a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    endKeyframe->setPropertyValue(id, to.get());
4451e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    endKeyframe->setOffset(1);
4461e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    keyframes.append(endKeyframe);
4471e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
448a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
449d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    update->startTransition(id, eventId, from.get(), to.get(), InertAnimation::create(effect, timing, false));
450a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    ASSERT(!element->activeAnimations() || !element->activeAnimations()->isAnimationStyleChange());
4511e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
4521e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
4537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid CSSAnimations::calculateTransitionUpdate(CSSAnimationUpdate* update, const Element* animatingElement, const RenderStyle& style)
4541e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){
4557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!animatingElement)
45609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return;
45709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
4587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ActiveAnimations* activeAnimations = animatingElement->activeAnimations();
459a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    const TransitionMap* activeTransitions = activeAnimations ? &activeAnimations->cssAnimations().m_transitions : 0;
460d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    const CSSTransitionData* transitionData = style.transitions();
461a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
462197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
463a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    // In debug builds we verify that it would have been safe to avoid populating and testing listedProperties if the style recalc is due to animation.
464a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    const bool animationStyleRecalc = false;
4655d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#else
4665d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    // In release builds we avoid the cost of checking for new and interrupted transitions if the style recalc is due to animation.
4675d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    const bool animationStyleRecalc = activeAnimations && activeAnimations->isAnimationStyleChange();
468a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#endif
469a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
470a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    BitArray<numCSSProperties> listedProperties;
471d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    bool anyTransitionHadTransitionAll = false;
4727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    const RenderObject* renderer = animatingElement->renderer();
473d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (!animationStyleRecalc && style.display() != NONE && renderer && renderer->style() && transitionData) {
474a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        const RenderStyle& oldStyle = *renderer->style();
475a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
476d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        for (size_t i = 0; i < transitionData->propertyList().size(); ++i) {
477d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            const CSSTransitionData::TransitionProperty& transitionProperty = transitionData->propertyList()[i];
478d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            CSSTransitionData::TransitionPropertyType mode = transitionProperty.propertyType;
479d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            CSSPropertyID property = transitionProperty.propertyId;
48076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)            if (mode == CSSTransitionData::TransitionNone || mode == CSSTransitionData::TransitionUnknown)
481a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                continue;
482a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
483d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            bool animateAll = mode == CSSTransitionData::TransitionAll;
484d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            ASSERT(animateAll || mode == CSSTransitionData::TransitionSingleProperty);
485a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            if (animateAll)
486d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                anyTransitionHadTransitionAll = true;
487d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            const StylePropertyShorthand& propertyList = animateAll ? CSSAnimations::animatableProperties() : shorthandForProperty(property);
488a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            // If not a shorthand we only execute one iteration of this loop, and refer to the property directly.
489a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            for (unsigned j = 0; !j || j < propertyList.length(); ++j) {
490d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                CSSPropertyID id = propertyList.length() ? propertyList.properties()[j] : property;
491d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                CSSPropertyID eventId = id;
492a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
493a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                if (!animateAll) {
494aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch                    id = propertyForAnimation(id);
495e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                    if (CSSPropertyMetadata::isAnimatableProperty(id))
496a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                        listedProperties.set(id);
497a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                    else
498a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                        continue;
499a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                }
500a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
501a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                // FIXME: We should transition if an !important property changes even when an animation is running,
502a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                // but this is a bit hard to do with the current applyMatchedProperties system.
50343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)                if (!update->activeInterpolationsForAnimations().contains(id)
50443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)                    && (!activeAnimations || !activeAnimations->cssAnimations().m_previousActiveInterpolationsForAnimations.contains(id))) {
5057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                    calculateTransitionUpdateForProperty(id, eventId, *transitionData, i, oldStyle, style, activeTransitions, update, animatingElement);
506a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                }
507a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            }
50819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        }
5091e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
5101e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
511a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if (activeTransitions) {
512a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        for (TransitionMap::const_iterator iter = activeTransitions->begin(); iter != activeTransitions->end(); ++iter) {
513323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            const AnimationPlayer& player = *iter->value.player;
5141e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            CSSPropertyID id = iter->key;
515d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            if (player.finishedInternal() || (!anyTransitionHadTransitionAll && !animationStyleRecalc && !listedProperties.get(id))) {
516f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu                // TODO: Figure out why this fails on Chrome OS login page. crbug.com/365507
517323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)                // ASSERT(player.finishedInternal() || !(activeAnimations && activeAnimations->isAnimationStyleChange()));
5181e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                update->cancelTransition(id);
519a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            }
5201e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
521c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    }
522f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)}
523f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
524f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)void CSSAnimations::cancel()
525f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles){
526323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    for (AnimationMap::iterator iter = m_animations.begin(); iter != m_animations.end(); ++iter) {
52707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        iter->value->cancel();
528323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        iter->value->update(TimingUpdateOnDemand);
529323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    }
5301e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
531323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    for (TransitionMap::iterator iter = m_transitions.begin(); iter != m_transitions.end(); ++iter) {
5326f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        iter->value.player->cancel();
533323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        iter->value.player->update(TimingUpdateOnDemand);
534323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    }
535f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
536f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    m_animations.clear();
5371e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    m_transitions.clear();
538c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    m_pendingUpdate = nullptr;
539f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)}
540f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
5417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid CSSAnimations::calculateAnimationActiveInterpolations(CSSAnimationUpdate* update, const Element* animatingElement, double timelineCurrentTime)
542f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){
5437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ActiveAnimations* activeAnimations = animatingElement ? animatingElement->activeAnimations() : 0;
544f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    AnimationStack* animationStack = activeAnimations ? &activeAnimations->defaultStack() : 0;
545f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
546d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (update->newAnimations().isEmpty() && update->cancelledAnimationAnimationPlayers().isEmpty()) {
54707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > activeInterpolationsForAnimations(AnimationStack::activeInterpolations(animationStack, 0, 0, Animation::DefaultPriority, timelineCurrentTime));
54843e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAnimations);
54951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return;
55019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    }
551f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
552d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    WillBeHeapVector<RawPtrWillBeMember<InertAnimation> > newAnimations;
553f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    for (size_t i = 0; i < update->newAnimations().size(); ++i) {
55407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        newAnimations.append(update->newAnimations()[i].animation.get());
555f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    }
55607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > activeInterpolationsForAnimations(AnimationStack::activeInterpolations(animationStack, &newAnimations, &update->cancelledAnimationAnimationPlayers(), Animation::DefaultPriority, timelineCurrentTime));
55743e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAnimations);
558f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)}
559f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
5607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid CSSAnimations::calculateTransitionActiveInterpolations(CSSAnimationUpdate* update, const Element* animatingElement, double timelineCurrentTime)
561f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){
5627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ActiveAnimations* activeAnimations = animatingElement ? animatingElement->activeAnimations() : 0;
563f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    AnimationStack* animationStack = activeAnimations ? &activeAnimations->defaultStack() : 0;
564f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
56507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > activeInterpolationsForTransitions;
56619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    if (update->newTransitions().isEmpty() && update->cancelledTransitions().isEmpty()) {
56707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        activeInterpolationsForTransitions = AnimationStack::activeInterpolations(animationStack, 0, 0, Animation::TransitionPriority, timelineCurrentTime);
56819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    } else {
569d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        WillBeHeapVector<RawPtrWillBeMember<InertAnimation> > newTransitions;
570a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        for (CSSAnimationUpdate::NewTransitionMap::const_iterator iter = update->newTransitions().begin(); iter != update->newTransitions().end(); ++iter)
571a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            newTransitions.append(iter->value.animation.get());
57219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
573d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        WillBeHeapHashSet<RawPtrWillBeMember<const AnimationPlayer> > cancelledAnimationPlayers;
57419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        if (!update->cancelledTransitions().isEmpty()) {
575a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            ASSERT(activeAnimations);
57619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            const TransitionMap& transitionMap = activeAnimations->cssAnimations().m_transitions;
57719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            for (HashSet<CSSPropertyID>::iterator iter = update->cancelledTransitions().begin(); iter != update->cancelledTransitions().end(); ++iter) {
57819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)                ASSERT(transitionMap.contains(*iter));
5796f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch                cancelledAnimationPlayers.add(transitionMap.get(*iter).player.get());
58019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            }
581f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        }
58219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
58307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        activeInterpolationsForTransitions = AnimationStack::activeInterpolations(animationStack, &newTransitions, &cancelledAnimationPlayers, Animation::TransitionPriority, timelineCurrentTime);
584f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    }
585f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
58619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    // Properties being animated by animations don't get values from transitions applied.
58743e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    if (!update->activeInterpolationsForAnimations().isEmpty() && !activeInterpolationsForTransitions.isEmpty()) {
58807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        for (WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >::const_iterator iter = update->activeInterpolationsForAnimations().begin(); iter != update->activeInterpolationsForAnimations().end(); ++iter)
58943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)            activeInterpolationsForTransitions.remove(iter->key);
59019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    }
59143e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    update->adoptActiveInterpolationsForTransitions(activeInterpolationsForTransitions);
592f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)}
593f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
5941e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)void CSSAnimations::AnimationEventDelegate::maybeDispatch(Document::ListenerType listenerType, const AtomicString& eventName, double elapsedTime)
5951fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch{
596d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (m_target->document().hasListenerType(listenerType)) {
597a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        RefPtrWillBeRawPtr<WebKitAnimationEvent> event = WebKitAnimationEvent::create(eventName, m_name, elapsedTime);
598d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        event->setTarget(m_target);
599d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_target->document().enqueueAnimationFrameEvent(event);
600d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
6011fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch}
6021fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch
603d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void CSSAnimations::AnimationEventDelegate::onEventCondition(const AnimationNode* animationNode)
6041fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch{
605d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    const AnimationNode::Phase currentPhase = animationNode->phase();
606d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    const double currentIteration = animationNode->currentIteration();
607c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
608323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (m_previousPhase != currentPhase
609d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        && (currentPhase == AnimationNode::PhaseActive || currentPhase == AnimationNode::PhaseAfter)
610d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        && (m_previousPhase == AnimationNode::PhaseNone || m_previousPhase == AnimationNode::PhaseBefore)) {
611323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        // The spec states that the elapsed time should be
612323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        // 'delay < 0 ? -delay : 0', but we always use 0 to match the existing
613323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        // implementation. See crbug.com/279611
614323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        maybeDispatch(Document::ANIMATIONSTART_LISTENER, EventTypeNames::animationstart, 0);
615323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    }
616323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
617d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (currentPhase == AnimationNode::PhaseActive && m_previousPhase == currentPhase && m_previousIteration != currentIteration) {
618c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        // We fire only a single event for all iterations thast terminate
619c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        // between a single pair of samples. See http://crbug.com/275263. For
620c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        // compatibility with the existing implementation, this event uses
621c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        // the elapsedTime for the first iteration in question.
622d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        ASSERT(!std::isnan(animationNode->specifiedTiming().iterationDuration));
623d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        const double elapsedTime = animationNode->specifiedTiming().iterationDuration * (m_previousIteration + 1);
6241e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        maybeDispatch(Document::ANIMATIONITERATION_LISTENER, EventTypeNames::animationiteration, elapsedTime);
6251fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    }
626323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
627d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (currentPhase == AnimationNode::PhaseAfter && m_previousPhase != AnimationNode::PhaseAfter)
628d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        maybeDispatch(Document::ANIMATIONEND_LISTENER, EventTypeNames::animationend, animationNode->activeDurationInternal());
629323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
630323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    m_previousPhase = currentPhase;
631323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    m_previousIteration = currentIteration;
6321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
6331e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
634c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void CSSAnimations::AnimationEventDelegate::trace(Visitor* visitor)
635c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
636c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    visitor->trace(m_target);
637c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    AnimationNode::EventDelegate::trace(visitor);
638c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
639c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
640d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void CSSAnimations::TransitionEventDelegate::onEventCondition(const AnimationNode* animationNode)
6411e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){
642d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    const AnimationNode::Phase currentPhase = animationNode->phase();
643d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (currentPhase == AnimationNode::PhaseAfter && currentPhase != m_previousPhase && m_target->document().hasListenerType(Document::TRANSITIONEND_LISTENER)) {
6441e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        String propertyName = getPropertyNameString(m_property);
645d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        const Timing& timing = animationNode->specifiedTiming();
6461e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        double elapsedTime = timing.iterationDuration;
6471e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        const AtomicString& eventType = EventTypeNames::transitionend;
6481e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        String pseudoElement = PseudoElement::pseudoElementNameForEvents(m_target->pseudoId());
649a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        RefPtrWillBeRawPtr<TransitionEvent> event = TransitionEvent::create(eventType, propertyName, elapsedTime, pseudoElement);
650d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        event->setTarget(m_target);
651d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_target->document().enqueueAnimationFrameEvent(event);
6521e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
653323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
654323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    m_previousPhase = currentPhase;
655c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)}
656c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
657c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void CSSAnimations::TransitionEventDelegate::trace(Visitor* visitor)
658c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
659c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    visitor->trace(m_target);
660c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    AnimationNode::EventDelegate::trace(visitor);
661c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
662c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
6631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)const StylePropertyShorthand& CSSAnimations::animatableProperties()
6641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){
6651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    DEFINE_STATIC_LOCAL(Vector<CSSPropertyID>, properties, ());
6661e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    DEFINE_STATIC_LOCAL(StylePropertyShorthand, propertyShorthand, ());
6671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (properties.isEmpty()) {
6681e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        for (int i = firstCSSProperty; i < lastCSSProperty; ++i) {
6691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            CSSPropertyID id = convertToCSSPropertyID(i);
670e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            if (CSSPropertyMetadata::isAnimatableProperty(id))
6711e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                properties.append(id);
6721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
6731e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        propertyShorthand = StylePropertyShorthand(CSSPropertyInvalid, properties.begin(), properties.size());
6741e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
6751e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return propertyShorthand;
6761e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
6771e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
678323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)// Animation properties are not allowed to be affected by Web Animations.
679323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)// http://dev.w3.org/fxtf/web-animations/#not-animatable
680323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)bool CSSAnimations::isAllowedAnimation(CSSPropertyID property)
681323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles){
682323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    switch (property) {
683323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyAnimation:
684323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyAnimationDelay:
685323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyAnimationDirection:
686323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyAnimationDuration:
687323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyAnimationFillMode:
688323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyAnimationIterationCount:
689323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyAnimationName:
690323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyAnimationPlayState:
691323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyAnimationTimingFunction:
692323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyDisplay:
693323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyTransition:
694323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyTransitionDelay:
695323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyTransitionDuration:
696323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyTransitionProperty:
697323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyTransitionTimingFunction:
698323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyWebkitAnimation:
699323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyWebkitAnimationDelay:
700323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyWebkitAnimationDirection:
701323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyWebkitAnimationDuration:
702323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyWebkitAnimationFillMode:
703323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyWebkitAnimationIterationCount:
704323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyWebkitAnimationName:
705323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyWebkitAnimationPlayState:
706323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyWebkitAnimationTimingFunction:
707323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyWebkitTransition:
708323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyWebkitTransitionDelay:
709323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyWebkitTransitionDuration:
710323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyWebkitTransitionProperty:
711323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    case CSSPropertyWebkitTransitionTimingFunction:
712323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        return false;
713323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    default:
714323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        return true;
715323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    }
716323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)}
717323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
71807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochvoid CSSAnimations::trace(Visitor* visitor)
71907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{
720c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#if ENABLE(OILPAN)
72107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    visitor->trace(m_transitions);
72207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    visitor->trace(m_pendingUpdate);
723d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    visitor->trace(m_animations);
72407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    visitor->trace(m_previousActiveInterpolationsForAnimations);
725c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#endif
72607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch}
72707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
72807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochvoid CSSAnimationUpdate::trace(Visitor* visitor)
72907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{
730197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(OILPAN)
73107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    visitor->trace(m_newTransitions);
73207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    visitor->trace(m_activeInterpolationsForAnimations);
73307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    visitor->trace(m_activeInterpolationsForTransitions);
734d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    visitor->trace(m_newAnimations);
735d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    visitor->trace(m_cancelledAnimationPlayers);
736197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#endif
73707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch}
73807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
739c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
740