Bug 1037321 - Implement playState on AnimationPlayer; r=birtles, r=bz

This commit is contained in:
David Zbarsky 2014-10-20 13:55:45 +09:00
parent 6ab3c04168
commit 5f09ff6dc7
6 changed files with 110 additions and 3 deletions

View File

@ -34,6 +34,25 @@ AnimationPlayer::GetCurrentTime() const
return AnimationUtils::TimeDurationToDouble(GetCurrentTimeDuration());
}
AnimationPlayState
AnimationPlayer::PlayState() const
{
Nullable<TimeDuration> currentTime = GetCurrentTimeDuration();
if (currentTime.IsNull()) {
return AnimationPlayState::Idle;
}
if (mIsPaused) {
return AnimationPlayState::Paused;
}
if (currentTime.Value() >= SourceContentEnd()) {
return AnimationPlayState::Finished;
}
return AnimationPlayState::Running;
}
void
AnimationPlayer::Play(UpdateFlags aFlags)
{
@ -81,6 +100,17 @@ AnimationPlayer::Pause(UpdateFlags aFlags)
}
}
AnimationPlayState
AnimationPlayer::PlayStateFromJS() const
{
// FIXME: Once we introduce CSSTransitionPlayer, this should move to an
// override of PlayStateFromJS in CSSAnimationPlayer and CSSTransitionPlayer
// and we should skip it in the general case.
FlushStyle();
return PlayState();
}
void
AnimationPlayer::PlayFromJS()
{
@ -174,6 +204,17 @@ AnimationPlayer::MaybePostRestyle() const
nsChangeHint_AllReflowHints);
}
StickyTimeDuration
AnimationPlayer::SourceContentEnd() const
{
if (!mSource) {
return StickyTimeDuration(0);
}
return mSource->Timing().mDelay
+ mSource->GetComputedTiming().mActiveDuration;
}
} // namespace dom
void

View File

@ -11,6 +11,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/TimeStamp.h" // for TimeStamp, TimeDuration
#include "mozilla/dom/Animation.h" // for Animation
#include "mozilla/dom/AnimationPlayerBinding.h" // for AnimationPlayState
#include "mozilla/dom/AnimationTimeline.h" // for AnimationTimeline
#include "nsCSSProperty.h" // for nsCSSProperty
@ -60,12 +61,14 @@ public:
AnimationTimeline* Timeline() const { return mTimeline; }
Nullable<double> GetStartTime() const;
Nullable<double> GetCurrentTime() const;
AnimationPlayState PlayState() const;
virtual void Play(UpdateFlags aUpdateFlags);
virtual void Pause(UpdateFlags aUpdateFlags);
bool IsRunningOnCompositor() const { return mIsRunningOnCompositor; }
// Wrapper functions for performing extra steps such as flushing
// style when calling from JS.
AnimationPlayState PlayStateFromJS() const;
void PlayFromJS();
void PauseFromJS();
@ -101,6 +104,7 @@ public:
protected:
void FlushStyle() const;
void MaybePostRestyle() const;
StickyTimeDuration SourceContentEnd() const;
Nullable<TimeDuration> mHoldTime; // Player timescale
bool mIsPaused;

View File

@ -0,0 +1,57 @@
<!doctype html>
<meta charset=utf-8>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<style>
@keyframes anim { }
</style>
<script>
'use strict';
function addDiv() {
var div = document.createElement('div');
document.body.appendChild(div);
return div;
}
test(function() {
var div = addDiv();
var cs = window.getComputedStyle(div);
div.style.animation = 'anim 1000s';
var player = div.getAnimationPlayers()[0];
assert_equals(player.playState, 'running');
}, 'Player returns correct playState when running');
test(function() {
var div = addDiv();
var cs = window.getComputedStyle(div);
div.style.animation = 'anim 1000s paused';
var player = div.getAnimationPlayers()[0];
assert_equals(player.playState, 'paused');
}, 'Player returns correct playState when paused');
test(function() {
var div = addDiv();
var cs = window.getComputedStyle(div);
div.style.animation = 'anim 1000s';
var player = div.getAnimationPlayers()[0];
player.pause();
assert_equals(player.playState, 'paused');
}, 'Player.playState updates when paused by script');
test(function() {
var div = addDiv();
var cs = window.getComputedStyle(div);
div.style.animation = 'anim 1000s paused';
var player = div.getAnimationPlayers()[0];
div.style.animationPlayState = 'running';
// This test also checks that calling playState flushes style
assert_equals(player.playState, 'running');
}, 'Player.playState updates when resumed by setting style');
</script>

View File

@ -323,8 +323,8 @@ test(function() {
// Update pause state (an AnimationPlayer change)
div.style.animationPlayState = 'paused';
var pausedPlayer = div.getAnimationPlayers()[0];
// FIXME: Check pausedPlayer.playState has changed once the API is available
// (bug 1037321)
assert_equals(pausedPlayer.playState, 'paused',
'player\'s paused state is updated');
assert_equals(originalPlayer, pausedPlayer,
'getAnimationPlayers returns the same objects even when their'
+ ' play state changes');

View File

@ -5,4 +5,5 @@ skip-if = buildapp == 'mulet'
[css-integration/test_animations-dynamic-changes.html]
[css-integration/test_animation-effect-name.html]
[css-integration/test_animation-pausing.html]
[css-integration/test_animation-player-playstate.html]
[css-integration/test_animation-target.html]

View File

@ -10,6 +10,8 @@
* liability, trademark and document use rules apply.
*/
enum AnimationPlayState { "idle", "pending", "running", "paused", "finished" };
[Pref="dom.animations-api.core.enabled"]
interface AnimationPlayer {
// Bug 1049975
@ -22,8 +24,10 @@ interface AnimationPlayer {
readonly attribute double? currentTime;
/* Not yet implemented
attribute double playbackRate;
attribute double playbackRate; */
[BinaryName="playStateFromJS"]
readonly attribute AnimationPlayState playState;
/*
readonly attribute Promise ready;
readonly attribute Promise finished;
void cancel ();