void InspectorAnimationAgent::resolveAnimation( ErrorString* errorString, const String& animationId, std::unique_ptr<v8_inspector::protocol::Runtime::API::RemoteObject>* result) { blink::Animation* animation = assertAnimation(errorString, animationId); if (!animation) return; if (m_idToAnimationClone.get(animationId)) animation = m_idToAnimationClone.get(animationId); const Element* element = toKeyframeEffect(animation->effect())->target(); Document* document = element->ownerDocument(); LocalFrame* frame = document ? document->frame() : nullptr; ScriptState* scriptState = frame ? ScriptState::forMainWorld(frame) : nullptr; if (!scriptState) { *errorString = "Element not associated with a document."; return; } ScriptState::Scope scope(scriptState); static const char kAnimationObjectGroup[] = "animation"; m_v8Session->releaseObjectGroup( toV8InspectorStringView(kAnimationObjectGroup)); *result = m_v8Session->wrapObject( scriptState->context(), toV8(animation, scriptState->context()->Global(), scriptState->isolate()), toV8InspectorStringView(kAnimationObjectGroup)); if (!*result) *errorString = "Element not associated with a document."; }
void InspectorAnimationAgent::setPaused( ErrorString* errorString, std::unique_ptr<protocol::Array<String>> animationIds, bool paused) { for (size_t i = 0; i < animationIds->length(); ++i) { String animationId = animationIds->get(i); blink::Animation* animation = assertAnimation(errorString, animationId); if (!animation) return; blink::Animation* clone = animationClone(animation); if (!clone) { *errorString = "Failed to clone detached animation"; return; } if (paused && !clone->paused()) { // Ensure we restore a current time if the animation is limited. double currentTime = clone->timeline()->currentTime() - clone->startTime(); clone->pause(); clone->setCurrentTime(currentTime); } else if (!paused && clone->paused()) { clone->unpause(); } } }
void InspectorAnimationAgent::resolveAnimation(ErrorString* errorString, const String& animationId, RefPtr<TypeBuilder::Runtime::RemoteObject>& result) { Animation* animation = assertAnimation(errorString, animationId); if (!animation) return; if (m_idToAnimationClone.get(animationId)) animation = m_idToAnimationClone.get(animationId); const Element* element = toKeyframeEffect(animation->effect())->target(); Document* document = element->ownerDocument(); LocalFrame* frame = document ? document->frame() : nullptr; if (!frame) { *errorString = "Element not associated with a document."; return; } ScriptState* scriptState = ScriptState::forMainWorld(frame); InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(scriptState); if (injectedScript.isEmpty()) return; ScriptState::Scope scope(scriptState); v8::Isolate* isolate = scriptState->isolate(); ScriptValue scriptValue = ScriptValue(scriptState, toV8(animation, scriptState->context()->Global(), isolate)); injectedScript.releaseObjectGroup("animation"); result = injectedScript.wrapObject(scriptValue, "animation"); }
void InspectorAnimationAgent::setTiming(ErrorString* errorString, const String& animationId, double duration, double delay) { Animation* animation = assertAnimation(errorString, animationId); if (!animation) return; AnimationType type = m_idToAnimationType.get(animationId); if (type == AnimationType::CSSTransition) { KeyframeEffect* effect = toKeyframeEffect(animation->effect()); KeyframeEffectModelBase* model = toKeyframeEffectModelBase(effect->model()); const AnimatableValueKeyframeEffectModel* oldModel = toAnimatableValueKeyframeEffectModel(model); // Refer to CSSAnimations::calculateTransitionUpdateForProperty() for the structure of transitions. const KeyframeVector& frames = oldModel->getFrames(); ASSERT(frames.size() == 3); KeyframeVector newFrames; for (int i = 0; i < 3; i++) newFrames.append(toAnimatableValueKeyframe(frames[i]->clone().get())); // Update delay, represented by the distance between the first two keyframes. newFrames[1]->setOffset(delay / (delay + duration)); model->setFrames(newFrames); AnimationEffectTiming* timing = animation->effect()->timing(); UnrestrictedDoubleOrString unrestrictedDuration; unrestrictedDuration.setUnrestrictedDouble(duration + delay); timing->setDuration(unrestrictedDuration); } else if (type == AnimationType::WebAnimation) { AnimationEffectTiming* timing = animation->effect()->timing(); UnrestrictedDoubleOrString unrestrictedDuration; unrestrictedDuration.setUnrestrictedDouble(duration); timing->setDuration(unrestrictedDuration); timing->setDelay(delay); } }
void InspectorAnimationAgent::getCurrentTime(ErrorString* errorString, const String& id, double* currentTime) { Animation* animation = assertAnimation(errorString, id); if (m_idToAnimationClone.get(id)) animation = m_idToAnimationClone.get(id); *currentTime = animation->timeline()->currentTime() - animation->startTime(); }
void InspectorAnimationAgent::getCurrentTime(ErrorString* errorString, const String& id, double* currentTime) { blink::Animation* animation = assertAnimation(errorString, id); if (!animation) return; if (m_idToAnimationClone.get(id)) animation = m_idToAnimationClone.get(id); if (animation->paused()) { *currentTime = animation->currentTime(); } else { // Use startTime where possible since currentTime is limited. *currentTime = animation->timeline()->currentTime() - animation->startTime(); } }
void InspectorAnimationAgent::seekAnimations(ErrorString* errorString, const RefPtr<JSONArray>& animationIds, double currentTime) { for (const auto& id : *animationIds) { String animationId; if (!(id->asString(&animationId))) { *errorString = "Invalid argument type"; return; } Animation* animation = assertAnimation(errorString, animationId); if (!animation) return; m_isCloning = true; Animation* clone = animationClone(animation); m_isCloning = false; clone->play(); clone->setCurrentTime(currentTime); } }
void InspectorAnimationAgent::seekAnimations( ErrorString* errorString, std::unique_ptr<protocol::Array<String>> animationIds, double currentTime) { for (size_t i = 0; i < animationIds->length(); ++i) { String animationId = animationIds->get(i); blink::Animation* animation = assertAnimation(errorString, animationId); if (!animation) return; blink::Animation* clone = animationClone(animation); if (!clone) { *errorString = "Failed to clone a detached animation."; return; } if (!clone->paused()) clone->play(); clone->setCurrentTime(currentTime); } }