1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #include "core/inspector/InspectorAnimationAgent.h"
9 #include "core/animation/Animation.h"
10 #include "core/animation/AnimationEffect.h"
11 #include "core/animation/AnimationNode.h"
12 #include "core/animation/AnimationPlayer.h"
13 #include "core/animation/ElementAnimation.h"
14 #include "core/animation/KeyframeEffectModel.h"
15 #include "core/animation/StringKeyframe.h"
16 #include "core/css/CSSKeyframeRule.h"
17 #include "core/css/CSSKeyframesRule.h"
18 #include "core/inspector/InspectorDOMAgent.h"
19 #include "core/inspector/InspectorStyleSheet.h"
20 #include "platform/Decimal.h"
24 InspectorAnimationAgent::InspectorAnimationAgent(InspectorDOMAgent* domAgent)
25 : InspectorBaseAgent<InspectorAnimationAgent>("Animation")
26 , m_domAgent(domAgent)
31 void InspectorAnimationAgent::setFrontend(InspectorFrontend* frontend)
33 m_frontend = frontend->animation();
36 void InspectorAnimationAgent::clearFrontend()
42 void InspectorAnimationAgent::reset()
44 m_idToAnimationPlayer.clear();
47 static PassRefPtr<TypeBuilder::Animation::AnimationNode> buildObjectForAnimationNode(AnimationNode* animationNode)
49 RefPtr<TypeBuilder::Animation::AnimationNode> animationObject = TypeBuilder::Animation::AnimationNode::create()
50 .setStartDelay(animationNode->specifiedTiming().startDelay)
51 .setPlaybackRate(animationNode->specifiedTiming().playbackRate)
52 .setIterationStart(animationNode->specifiedTiming().iterationStart)
53 .setIterationCount(animationNode->specifiedTiming().iterationCount)
54 .setDuration(animationNode->duration())
55 .setDirection(animationNode->specifiedTiming().direction)
56 .setFillMode(animationNode->specifiedTiming().fillMode)
57 .setTimeFraction(animationNode->timeFraction())
58 .setName(animationNode->name());
59 return animationObject.release();
62 static String playerId(AnimationPlayer& player)
64 return String::number(player.sequenceNumber());
67 static PassRefPtr<TypeBuilder::Animation::AnimationPlayer> buildObjectForAnimationPlayer(AnimationPlayer& animationPlayer, PassRefPtr<TypeBuilder::Animation::KeyframesRule> keyframeRule = nullptr)
69 RefPtr<TypeBuilder::Animation::AnimationNode> animationObject = buildObjectForAnimationNode(animationPlayer.source());
71 animationObject->setKeyframesRule(keyframeRule);
73 RefPtr<TypeBuilder::Animation::AnimationPlayer> playerObject = TypeBuilder::Animation::AnimationPlayer::create()
74 .setId(playerId(animationPlayer))
75 .setPausedState(animationPlayer.paused())
76 .setPlayState(animationPlayer.playState())
77 .setPlaybackRate(animationPlayer.playbackRate())
78 .setStartTime(animationPlayer.startTime())
79 .setCurrentTime(animationPlayer.currentTime())
80 .setSource(animationObject.release());
81 return playerObject.release();
84 static PassRefPtr<TypeBuilder::Animation::KeyframeStyle> buildObjectForStyleKeyframe(StyleKeyframe* keyframe)
86 RefPtrWillBeRawPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), keyframe->mutableProperties().ensureCSSStyleDeclaration(), 0);
87 RefPtr<TypeBuilder::Animation::KeyframeStyle> keyframeObject = TypeBuilder::Animation::KeyframeStyle::create()
88 .setOffset(keyframe->keyText())
89 .setStyle(inspectorStyle->buildObjectForStyle());
90 return keyframeObject.release();
93 static PassRefPtr<TypeBuilder::Animation::KeyframeStyle> buildObjectForStringKeyframe(const StringKeyframe* keyframe)
95 RefPtrWillBeRawPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), keyframe->propertySetForInspector().get()->ensureCSSStyleDeclaration(), 0);
96 Decimal decimal = Decimal::fromDouble(keyframe->offset() * 100);
97 String offset = decimal.toString();
100 RefPtr<TypeBuilder::Animation::KeyframeStyle> keyframeObject = TypeBuilder::Animation::KeyframeStyle::create()
102 .setStyle(inspectorStyle->buildObjectForStyle());
103 return keyframeObject.release();
106 static PassRefPtr<TypeBuilder::Animation::KeyframesRule> buildObjectForStyleRuleKeyframes(const StyleRuleKeyframes* keyframesRule)
108 RefPtr<TypeBuilder::Array<TypeBuilder::Animation::KeyframeStyle> > keyframes = TypeBuilder::Array<TypeBuilder::Animation::KeyframeStyle>::create();
109 const WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> >& styleKeyframes = keyframesRule->keyframes();
110 for (const auto& styleKeyframe : styleKeyframes)
111 keyframes->addItem(buildObjectForStyleKeyframe(styleKeyframe.get()));
113 RefPtr<TypeBuilder::Animation::KeyframesRule> keyframesObject = TypeBuilder::Animation::KeyframesRule::create()
114 .setKeyframes(keyframes);
115 keyframesObject->setName(keyframesRule->name());
116 return keyframesObject.release();
119 static PassRefPtr<TypeBuilder::Animation::KeyframesRule> buildObjectForAnimationKeyframes(const Animation* animation)
121 if (!animation->effect()->isKeyframeEffectModel())
123 const KeyframeEffectModelBase* effect = toKeyframeEffectModelBase(animation->effect());
124 WillBeHeapVector<RefPtrWillBeMember<Keyframe> > normalizedKeyframes = KeyframeEffectModelBase::normalizedKeyframesForInspector(effect->getFrames());
125 RefPtr<TypeBuilder::Array<TypeBuilder::Animation::KeyframeStyle> > keyframes = TypeBuilder::Array<TypeBuilder::Animation::KeyframeStyle>::create();
127 for (const auto& keyframe : normalizedKeyframes) {
128 // Ignore CSS Transitions
129 if (!keyframe.get()->isStringKeyframe())
131 const StringKeyframe* stringKeyframe = toStringKeyframe(keyframe.get());
132 keyframes->addItem(buildObjectForStringKeyframe(stringKeyframe));
134 RefPtr<TypeBuilder::Animation::KeyframesRule> keyframesObject = TypeBuilder::Animation::KeyframesRule::create()
135 .setKeyframes(keyframes);
136 return keyframesObject.release();
139 static PassRefPtr<TypeBuilder::Animation::KeyframesRule> buildObjectForKeyframesRule(const Element& element, const AnimationPlayer& player)
141 StyleResolver& styleResolver = element.ownerDocument()->ensureStyleResolver();
142 CSSAnimations& cssAnimations = element.activeAnimations()->cssAnimations();
143 const AtomicString animationName = cssAnimations.getAnimationNameForInspector(player);
144 RefPtr<TypeBuilder::Animation::KeyframesRule> keyframeRule;
146 if (!animationName.isNull()) {
148 const StyleRuleKeyframes* keyframes = cssAnimations.matchScopedKeyframesRule(&styleResolver, &element, animationName.impl());
149 keyframeRule = buildObjectForStyleRuleKeyframes(keyframes);
152 keyframeRule = buildObjectForAnimationKeyframes(toAnimation(player.source()));
158 void InspectorAnimationAgent::getAnimationPlayersForNode(ErrorString* errorString, int nodeId, RefPtr<TypeBuilder::Array<TypeBuilder::Animation::AnimationPlayer> >& animationPlayersArray)
160 animationPlayersArray = TypeBuilder::Array<TypeBuilder::Animation::AnimationPlayer>::create();
161 Element* element = m_domAgent->assertElement(errorString, nodeId);
164 m_idToAnimationPlayer.clear();
165 WillBeHeapVector<RefPtrWillBeMember<AnimationPlayer> > players = ElementAnimation::getAnimationPlayers(*element);
166 for (WillBeHeapVector<RefPtrWillBeMember<AnimationPlayer> >::iterator it = players.begin(); it != players.end(); ++it) {
167 AnimationPlayer& player = *(it->get());
168 m_idToAnimationPlayer.set(playerId(player), &player);
169 RefPtr<TypeBuilder::Animation::KeyframesRule> keyframeRule = buildObjectForKeyframesRule(*element, player);
170 animationPlayersArray->addItem(buildObjectForAnimationPlayer(player, keyframeRule));
174 void InspectorAnimationAgent::pauseAnimationPlayer(ErrorString* errorString, const String& id, RefPtr<TypeBuilder::Animation::AnimationPlayer>& animationPlayer)
176 AnimationPlayer* player = assertAnimationPlayer(errorString, id);
180 animationPlayer = buildObjectForAnimationPlayer(*player);
183 void InspectorAnimationAgent::playAnimationPlayer(ErrorString* errorString, const String& id, RefPtr<TypeBuilder::Animation::AnimationPlayer>& animationPlayer)
185 AnimationPlayer* player = assertAnimationPlayer(errorString, id);
189 animationPlayer = buildObjectForAnimationPlayer(*player);
192 void InspectorAnimationAgent::setAnimationPlayerCurrentTime(ErrorString* errorString, const String& id, double currentTime, RefPtr<TypeBuilder::Animation::AnimationPlayer>& animationPlayer)
194 AnimationPlayer* player = assertAnimationPlayer(errorString, id);
197 player->setCurrentTime(currentTime);
198 animationPlayer = buildObjectForAnimationPlayer(*player);
201 void InspectorAnimationAgent::getAnimationPlayerState(ErrorString* errorString, const String& id, double* currentTime, bool* isRunning)
203 AnimationPlayer* player = assertAnimationPlayer(errorString, id);
206 *currentTime = player->currentTime();
207 *isRunning = player->playing();
210 AnimationPlayer* InspectorAnimationAgent::assertAnimationPlayer(ErrorString* errorString, const String& id)
212 AnimationPlayer* player = m_idToAnimationPlayer.get(id);
214 *errorString = "Could not find animation player with given id";
220 void InspectorAnimationAgent::trace(Visitor* visitor)
223 visitor->trace(m_idToAnimationPlayer);
224 visitor->trace(m_domAgent);
226 InspectorBaseAgent::trace(visitor);