Commit 855446c8 authored by Fredrik Söderquist's avatar Fredrik Söderquist Committed by Commit Bot

Simplify the animation-policy "once" implementation in SMILTimeContainer

Using the "max presentation time" concept we can greatly simplify the
"once" animation-policy by essentially letting it define a limited
window of the timeline in which the animation will be active. This
allows us to drop the associated timer and other doodads, leaving just a
fairly simple method that is called whenever the container's
presentation time is reset.

There is a small change in behavior in that the container is no longer
explicitly paused, but rather just halted after 3 seconds.

Replace the layout test with a set of unittests.

Bug: 998526
Change-Id: I2aaa927198bc7918b5767381753a5334ebcd115d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2030969Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#738699}
parent e55564d5
...@@ -1446,6 +1446,7 @@ jumbo_source_set("unit_tests") { ...@@ -1446,6 +1446,7 @@ jumbo_source_set("unit_tests") {
"style/style_variables_test.cc", "style/style_variables_test.cc",
"style/svg_computed_style_test.cc", "style/svg_computed_style_test.cc",
"svg/animation/priority_queue_test.cc", "svg/animation/priority_queue_test.cc",
"svg/animation/smil_time_container_test.cc",
"svg/graphics/svg_image_test.cc", "svg/graphics/svg_image_test.cc",
"svg/svg_foreign_object_element_test.cc", "svg/svg_foreign_object_element_test.cc",
"svg/svg_path_parser_test.cc", "svg/svg_path_parser_test.cc",
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <ostream> #include <ostream>
#include "base/time/time.h" #include "base/time/time.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/hash_traits.h" #include "third_party/blink/renderer/platform/wtf/hash_traits.h"
...@@ -136,7 +137,7 @@ class SMILTime { ...@@ -136,7 +137,7 @@ class SMILTime {
base::TimeDelta time_; base::TimeDelta time_;
}; };
std::ostream& operator<<(std::ostream& os, SMILTime time); CORE_EXPORT std::ostream& operator<<(std::ostream& os, SMILTime time);
// What generated a SMILTime. // What generated a SMILTime.
enum class SMILTimeOrigin { enum class SMILTimeOrigin {
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include "third_party/blink/renderer/core/svg/animation/smil_time_container.h" #include "third_party/blink/renderer/core/svg/animation/smil_time_container.h"
#include <algorithm> #include <algorithm>
#include "third_party/blink/renderer/core/animation/animation_clock.h"
#include "third_party/blink/renderer/core/animation/document_timeline.h" #include "third_party/blink/renderer/core/animation/document_timeline.h"
#include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h" #include "third_party/blink/renderer/core/dom/element_traversal.h"
...@@ -149,14 +148,8 @@ void SMILTimeContainer::TimingUpdate::HandleEvents( ...@@ -149,14 +148,8 @@ void SMILTimeContainer::TimingUpdate::HandleEvents(
updated_elements_.insert(element, SMILInterval::Unresolved()); updated_elements_.insert(element, SMILInterval::Unresolved());
} }
static constexpr base::TimeDelta kAnimationPolicyOnceDuration =
base::TimeDelta::FromSeconds(3);
SMILTimeContainer::SMILTimeContainer(SVGSVGElement& owner) SMILTimeContainer::SMILTimeContainer(SVGSVGElement& owner)
// We can't seek beyond this time, because at Latest() any additions will : frame_scheduling_state_(kIdle),
// yield the same value.
: max_presentation_time_(SMILTime::Latest() - SMILTime::Epsilon()),
frame_scheduling_state_(kIdle),
started_(false), started_(false),
paused_(false), paused_(false),
should_dispatch_events_(!SVGImage::IsInSVGImage(&owner)), should_dispatch_events_(!SVGImage::IsInSVGImage(&owner)),
...@@ -166,15 +159,13 @@ SMILTimeContainer::SMILTimeContainer(SVGSVGElement& owner) ...@@ -166,15 +159,13 @@ SMILTimeContainer::SMILTimeContainer(SVGSVGElement& owner)
owner.GetDocument().GetTaskRunner(TaskType::kInternalDefault), owner.GetDocument().GetTaskRunner(TaskType::kInternalDefault),
this, this,
&SMILTimeContainer::WakeupTimerFired), &SMILTimeContainer::WakeupTimerFired),
animation_policy_once_timer_( owner_svg_element_(&owner) {
owner.GetDocument().GetTaskRunner(TaskType::kInternalDefault), // Update the max presentation time based on the animation policy in effect.
this, SetPresentationTime(presentation_time_);
&SMILTimeContainer::AnimationPolicyTimerFired), }
owner_svg_element_(&owner) {}
SMILTimeContainer::~SMILTimeContainer() { SMILTimeContainer::~SMILTimeContainer() {
CancelAnimationFrame(); CancelAnimationFrame();
CancelAnimationPolicyTimer();
DCHECK(!wakeup_timer_.IsActive()); DCHECK(!wakeup_timer_.IsActive());
DCHECK(AnimationTargetsMutationsAllowed()); DCHECK(AnimationTargetsMutationsAllowed());
} }
...@@ -275,7 +266,7 @@ void SMILTimeContainer::SynchronizeToDocumentTimeline() { ...@@ -275,7 +266,7 @@ void SMILTimeContainer::SynchronizeToDocumentTimeline() {
bool SMILTimeContainer::IsPaused() const { bool SMILTimeContainer::IsPaused() const {
// If animation policy is "none", the timeline is always paused. // If animation policy is "none", the timeline is always paused.
return paused_ || AnimationPolicy() == kImageAnimationPolicyNoAnimation; return paused_ || AnimationsDisabled();
} }
bool SMILTimeContainer::IsStarted() const { bool SMILTimeContainer::IsStarted() const {
...@@ -289,10 +280,7 @@ bool SMILTimeContainer::IsTimelineRunning() const { ...@@ -289,10 +280,7 @@ bool SMILTimeContainer::IsTimelineRunning() const {
void SMILTimeContainer::Start() { void SMILTimeContainer::Start() {
CHECK(!IsStarted()); CHECK(!IsStarted());
if (!GetDocument().IsActive()) if (AnimationsDisabled())
return;
if (!HandleAnimationPolicy(kRestartOnceTimerIfNotPaused))
return; return;
// Sample the document timeline to get a time reference for the "presentation // Sample the document timeline to get a time reference for the "presentation
...@@ -305,20 +293,21 @@ void SMILTimeContainer::Start() { ...@@ -305,20 +293,21 @@ void SMILTimeContainer::Start() {
} }
void SMILTimeContainer::Pause() { void SMILTimeContainer::Pause() {
if (!HandleAnimationPolicy(kCancelOnceTimer)) if (AnimationsDisabled())
return; return;
DCHECK(!IsPaused()); DCHECK(!IsPaused());
if (IsStarted()) { if (IsStarted()) {
presentation_time_ = Elapsed(); SetPresentationTime(Elapsed());
CancelAnimationFrame(); CancelAnimationFrame();
} }
// Update the flag after sampling elapsed(). // Update the flag after sampling elapsed().
paused_ = true; paused_ = true;
} }
void SMILTimeContainer::Unpause() { void SMILTimeContainer::Unpause() {
if (!HandleAnimationPolicy(kRestartOnceTimer)) if (AnimationsDisabled())
return; return;
DCHECK(IsPaused()); DCHECK(IsPaused());
...@@ -331,15 +320,31 @@ void SMILTimeContainer::Unpause() { ...@@ -331,15 +320,31 @@ void SMILTimeContainer::Unpause() {
ScheduleWakeUp(base::TimeDelta(), kSynchronizeAnimations); ScheduleWakeUp(base::TimeDelta(), kSynchronizeAnimations);
} }
void SMILTimeContainer::SetPresentationTime(SMILTime new_presentation_time) {
// Start by resetting the max presentation time, because if the
// animation-policy is "once" we'll set a new limit below regardless, and for
// the other cases it's the right thing to do.
//
// We can't seek beyond this time, because at Latest() any additions will
// yield the same value.
max_presentation_time_ = SMILTime::Latest() - SMILTime::Epsilon();
presentation_time_ = ClampPresentationTime(new_presentation_time);
if (AnimationPolicy() != kImageAnimationPolicyAnimateOnce)
return;
const SMILTime kAnimationPolicyOnceDuration = SMILTime::FromSecondsD(3);
max_presentation_time_ =
ClampPresentationTime(presentation_time_ + kAnimationPolicyOnceDuration);
}
SMILTime SMILTimeContainer::ClampPresentationTime( SMILTime SMILTimeContainer::ClampPresentationTime(
SMILTime presentation_time) const { SMILTime presentation_time) const {
return std::min(presentation_time, max_presentation_time_); return std::min(presentation_time, max_presentation_time_);
} }
void SMILTimeContainer::SetElapsed(SMILTime elapsed) { void SMILTimeContainer::SetElapsed(SMILTime elapsed) {
presentation_time_ = ClampPresentationTime(elapsed); SetPresentationTime(elapsed);
if (!GetDocument().IsActive()) if (AnimationsDisabled())
return; return;
// If the document hasn't finished loading, |presentation_time_| will be // If the document hasn't finished loading, |presentation_time_| will be
...@@ -347,9 +352,6 @@ void SMILTimeContainer::SetElapsed(SMILTime elapsed) { ...@@ -347,9 +352,6 @@ void SMILTimeContainer::SetElapsed(SMILTime elapsed) {
if (!IsStarted()) if (!IsStarted())
return; return;
if (!HandleAnimationPolicy(kRestartOnceTimerIfNotPaused))
return;
CancelAnimationFrame(); CancelAnimationFrame();
if (!IsPaused()) if (!IsPaused())
...@@ -407,58 +409,15 @@ void SMILTimeContainer::WakeupTimerFired(TimerBase*) { ...@@ -407,58 +409,15 @@ void SMILTimeContainer::WakeupTimerFired(TimerBase*) {
} }
} }
void SMILTimeContainer::ScheduleAnimationPolicyTimer() {
animation_policy_once_timer_.StartOneShot(kAnimationPolicyOnceDuration,
FROM_HERE);
}
void SMILTimeContainer::CancelAnimationPolicyTimer() {
animation_policy_once_timer_.Stop();
}
void SMILTimeContainer::AnimationPolicyTimerFired(TimerBase*) {
Pause();
}
ImageAnimationPolicy SMILTimeContainer::AnimationPolicy() const { ImageAnimationPolicy SMILTimeContainer::AnimationPolicy() const {
Settings* settings = GetDocument().GetSettings(); const Settings* settings = GetDocument().GetSettings();
if (!settings) return settings ? settings->GetImageAnimationPolicy()
return kImageAnimationPolicyAllowed; : kImageAnimationPolicyAllowed;
return settings->GetImageAnimationPolicy();
} }
bool SMILTimeContainer::HandleAnimationPolicy( bool SMILTimeContainer::AnimationsDisabled() const {
AnimationPolicyOnceAction once_action) { return !GetDocument().IsActive() ||
ImageAnimationPolicy policy = AnimationPolicy(); AnimationPolicy() == kImageAnimationPolicyNoAnimation;
// If the animation policy is "none", control is not allowed.
// returns false to exit flow.
if (policy == kImageAnimationPolicyNoAnimation)
return false;
// If the animation policy is "once",
if (policy == kImageAnimationPolicyAnimateOnce) {
switch (once_action) {
case kRestartOnceTimerIfNotPaused:
if (IsPaused())
break;
FALLTHROUGH;
case kRestartOnceTimer:
ScheduleAnimationPolicyTimer();
break;
case kCancelOnceTimer:
CancelAnimationPolicyTimer();
break;
}
}
if (policy == kImageAnimationPolicyAllowed) {
// When the SVG owner element becomes detached from its document,
// the policy defaults to ImageAnimationPolicyAllowed; there's
// no way back. If the policy had been "once" prior to that,
// ensure cancellation of its timer.
if (once_action == kCancelOnceTimer)
CancelAnimationPolicyTimer();
}
return true;
} }
void SMILTimeContainer::UpdateDocumentOrderIndexes() { void SMILTimeContainer::UpdateDocumentOrderIndexes() {
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_ANIMATION_SMIL_TIME_CONTAINER_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_ANIMATION_SMIL_TIME_CONTAINER_H_
#include "base/time/time.h" #include "base/time/time.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/svg/animation/priority_queue.h" #include "third_party/blink/renderer/core/svg/animation/priority_queue.h"
#include "third_party/blink/renderer/core/svg/animation/smil_time.h" #include "third_party/blink/renderer/core/svg/animation/smil_time.h"
#include "third_party/blink/renderer/platform/graphics/image_animation_policy.h" #include "third_party/blink/renderer/platform/graphics/image_animation_policy.h"
...@@ -41,7 +42,8 @@ class SVGElement; ...@@ -41,7 +42,8 @@ class SVGElement;
class SVGSMILElement; class SVGSMILElement;
class SVGSVGElement; class SVGSVGElement;
class SMILTimeContainer final : public GarbageCollected<SMILTimeContainer> { class CORE_EXPORT SMILTimeContainer final
: public GarbageCollected<SMILTimeContainer> {
public: public:
explicit SMILTimeContainer(SVGSVGElement& owner); explicit SMILTimeContainer(SVGSVGElement& owner);
~SMILTimeContainer(); ~SMILTimeContainer();
...@@ -88,25 +90,13 @@ class SMILTimeContainer final : public GarbageCollected<SMILTimeContainer> { ...@@ -88,25 +90,13 @@ class SMILTimeContainer final : public GarbageCollected<SMILTimeContainer> {
kAnimationFrame kAnimationFrame
}; };
enum AnimationPolicyOnceAction {
// Restart OnceTimer if the timeline is not paused.
kRestartOnceTimerIfNotPaused,
// Restart OnceTimer.
kRestartOnceTimer,
// Cancel OnceTimer.
kCancelOnceTimer
};
bool IsTimelineRunning() const; bool IsTimelineRunning() const;
void SynchronizeToDocumentTimeline(); void SynchronizeToDocumentTimeline();
void ScheduleAnimationFrame(base::TimeDelta delay_time); void ScheduleAnimationFrame(base::TimeDelta delay_time);
void CancelAnimationFrame(); void CancelAnimationFrame();
void WakeupTimerFired(TimerBase*); void WakeupTimerFired(TimerBase*);
void ScheduleAnimationPolicyTimer();
void CancelAnimationPolicyTimer();
void AnimationPolicyTimerFired(TimerBase*);
ImageAnimationPolicy AnimationPolicy() const; ImageAnimationPolicy AnimationPolicy() const;
bool HandleAnimationPolicy(AnimationPolicyOnceAction); bool AnimationsDisabled() const;
class TimingUpdate; class TimingUpdate;
void UpdateAnimationsAndScheduleFrameIfNeeded(TimingUpdate&); void UpdateAnimationsAndScheduleFrameIfNeeded(TimingUpdate&);
void PrepareSeek(TimingUpdate&); void PrepareSeek(TimingUpdate&);
...@@ -118,6 +108,7 @@ class SMILTimeContainer final : public GarbageCollected<SMILTimeContainer> { ...@@ -118,6 +108,7 @@ class SMILTimeContainer final : public GarbageCollected<SMILTimeContainer> {
void ServiceOnNextFrame(); void ServiceOnNextFrame();
void ScheduleWakeUp(base::TimeDelta delay_time, FrameSchedulingState); void ScheduleWakeUp(base::TimeDelta delay_time, FrameSchedulingState);
bool HasPendingSynchronization() const; bool HasPendingSynchronization() const;
void SetPresentationTime(SMILTime new_presentation_time);
SMILTime ClampPresentationTime(SMILTime presentation_time) const; SMILTime ClampPresentationTime(SMILTime presentation_time) const;
void UpdateDocumentOrderIndexes(); void UpdateDocumentOrderIndexes();
...@@ -145,7 +136,6 @@ class SMILTimeContainer final : public GarbageCollected<SMILTimeContainer> { ...@@ -145,7 +136,6 @@ class SMILTimeContainer final : public GarbageCollected<SMILTimeContainer> {
bool is_updating_intervals_; bool is_updating_intervals_;
TaskRunnerTimer<SMILTimeContainer> wakeup_timer_; TaskRunnerTimer<SMILTimeContainer> wakeup_timer_;
TaskRunnerTimer<SMILTimeContainer> animation_policy_once_timer_;
using AnimatedTargets = HeapHashCountedSet<WeakMember<SVGElement>>; using AnimatedTargets = HeapHashCountedSet<WeakMember<SVGElement>>;
AnimatedTargets animated_targets_; AnimatedTargets animated_targets_;
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_DOCUMENT_EXTENSIONS_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_DOCUMENT_EXTENSIONS_H_
#include "base/macros.h" #include "base/macros.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/svg/svg_resources_cache.h" #include "third_party/blink/renderer/core/layout/svg/svg_resources_cache.h"
#include "third_party/blink/renderer/platform/geometry/float_point.h" #include "third_party/blink/renderer/platform/geometry/float_point.h"
#include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/handle.h"
...@@ -48,7 +49,7 @@ class SVGDocumentExtensions final ...@@ -48,7 +49,7 @@ class SVGDocumentExtensions final
// needs applying. // needs applying.
void AddWebAnimationsPendingSVGElement(SVGElement&); void AddWebAnimationsPendingSVGElement(SVGElement&);
static void ServiceOnAnimationFrame(Document&); CORE_EXPORT static void ServiceOnAnimationFrame(Document&);
void StartAnimations(); void StartAnimations();
void PauseAnimations(); void PauseAnimations();
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_LENGTH_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_LENGTH_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_LENGTH_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_LENGTH_H_
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_numeric_literal_value.h"
#include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h"
#include "third_party/blink/renderer/core/svg/properties/svg_property.h" #include "third_party/blink/renderer/core/svg/properties/svg_property.h"
...@@ -35,7 +36,7 @@ class QualifiedName; ...@@ -35,7 +36,7 @@ class QualifiedName;
class SVGLengthTearOff; class SVGLengthTearOff;
class SVGLength final : public SVGPropertyBase { class CORE_EXPORT SVGLength final : public SVGPropertyBase {
public: public:
typedef SVGLengthTearOff TearOffType; typedef SVGLengthTearOff TearOffType;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_LENGTH_CONTEXT_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_LENGTH_CONTEXT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_LENGTH_CONTEXT_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_LENGTH_CONTEXT_H_
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h"
#include "third_party/blink/renderer/core/svg/svg_unit_types.h" #include "third_party/blink/renderer/core/svg/svg_unit_types.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h"
...@@ -34,7 +35,7 @@ class UnzoomedLength; ...@@ -34,7 +35,7 @@ class UnzoomedLength;
enum class SVGLengthMode { kWidth, kHeight, kOther }; enum class SVGLengthMode { kWidth, kHeight, kOther };
class SVGLengthContext { class CORE_EXPORT SVGLengthContext {
STACK_ALLOCATED(); STACK_ALLOCATED();
public: public:
......
SVG with animation policy, once
This tests svg animation with animation policy once
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS rootSVGElement.animationsPaused() is false
PASS rootSVGElement.animationsPaused() is false
PASS rootSVGElement.getCurrentTime() is 2.5
PASS rect.y.animVal.value is 100
PASS rootSVGElement.animationsPaused() is true
PASS rootSVGElement.animationsPaused() is false
PASS rootSVGElement.getCurrentTime() is 5.0
PASS rect.y.animVal.value is 100
PASS rootSVGElement.animationsPaused() is false
PASS rootSVGElement.animationsPaused() is true
PASS rootSVGElement.animationsPaused() is true
PASS rootSVGElement.animationsPaused() is false
PASS rootSVGElement.getCurrentTime() is 5.0
PASS rect.y.animVal.value is 100
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE html>
<script src="../../resources/js-test.js"></script>
<script>
if (window.internals)
internals.settings.setImageAnimationPolicy("once");
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.waitUntilDone();
}
window.jsTestIsAsync = true;
var rootSVGElement;
function iframeLoaded() {
rootSVGElement = document.getElementById("iframe").contentDocument.documentElement;
}
function timerFired()
{
// True because animation is frozen by animation policy.
shouldBeTrue("rootSVGElement.animationsPaused()");
// pauseAnimations after animation is frozen.
rootSVGElement.pauseAnimations();
shouldBeTrue("rootSVGElement.animationsPaused()");
// unpauseAnimations after animation is frozen.
rootSVGElement.unpauseAnimations();
shouldBeFalse("rootSVGElement.animationsPaused()");
// setCurrentTime after animation is frozen.
rootSVGElement.setCurrentTime(5.0);
shouldBe("rootSVGElement.getCurrentTime()", "5.0");
shouldBe("rect.y.animVal.value", "100");
finishJSTest();
}
function runTest() {
// SVG is not suspended.
// Check setCurrentTime before animation is frozen.
shouldBeFalse("rootSVGElement.animationsPaused()");
rootSVGElement.setCurrentTime(2.5);
shouldBe("rootSVGElement.getCurrentTime()", "2.5");
shouldBe("rect.y.animVal.value", "100");
// Check pauseAnimations before animation is frozen.
rootSVGElement.pauseAnimations();
shouldBeTrue("rootSVGElement.animationsPaused()");
// Check unpauseAnimations before animation is frozen.
rootSVGElement.unpauseAnimations();
shouldBeFalse("rootSVGElement.animationsPaused()");
// Check setCurrentTime over duration before animation is frozen.
rootSVGElement.setCurrentTime(5.0);
shouldBe("rootSVGElement.getCurrentTime()", "5.0");
shouldBe("rect.y.animVal.value", "100");
shouldBeFalse("rootSVGElement.animationsPaused()");
// It will be fired after animation is frozen.
// It's to check working after animation policy timer is fired.
// animation policy timer is 3 secs.
setTimeout(timerFired, 3000);
}
function prepareTest() {
rect = rootSVGElement.ownerDocument.getElementsByTagName("rect")[0];
description("This tests svg animation with animation policy once");
// Check SVG is not paused.
shouldBeFalse("rootSVGElement.animationsPaused()");
setTimeout(runTest, 0);
}
</script>
<body onload="prepareTest()">
<h1>SVG with animation policy, once</h1>
<iframe id="iframe" src="resources/animation-policy.svg" style="width: 300px; height: 300px;" onload="iframeLoaded()"></iframe>
<p id="description"></p>
<div id="console"></div>
</body>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment