Bug 1299695 - Rework animation phase and fill mode handling r=hiro

This reflects the following updates to the spec:

  9369384f6c

MozReview-Commit-ID: JYUOZcnPEJQ

--HG--
extra : rebase_source : 88e012f19b875d8e718770772189737e2c17ddaa
This commit is contained in:
Brian Birtles 2016-09-01 10:57:55 +09:00
parent dd0c4e65ac
commit dbdadee2fc
7 changed files with 32 additions and 25 deletions

View File

@ -143,10 +143,14 @@ AnimationEffectReadOnly::GetComputedTimingAt(
StickyTimeDuration activeTime;
StickyTimeDuration beforeActiveBoundary =
std::min(StickyTimeDuration(aTiming.mDelay), result.mEndTime);
std::max(std::min(StickyTimeDuration(aTiming.mDelay), result.mEndTime),
zeroDuration);
StickyTimeDuration activeAfterBoundary =
std::min(StickyTimeDuration(aTiming.mDelay + result.mActiveDuration),
result.mEndTime);
std::max(std::min(StickyTimeDuration(aTiming.mDelay +
result.mActiveDuration),
result.mEndTime),
zeroDuration);
if (localTime > activeAfterBoundary ||
(aPlaybackRate >= 0 && localTime == activeAfterBoundary)) {
@ -155,9 +159,10 @@ AnimationEffectReadOnly::GetComputedTimingAt(
// The animation isn't active or filling at this time.
return result;
}
activeTime = std::max(std::min(result.mActiveDuration,
result.mActiveDuration + aTiming.mEndDelay),
zeroDuration);
activeTime =
std::max(std::min(StickyTimeDuration(localTime - aTiming.mDelay),
result.mActiveDuration),
zeroDuration);
} else if (localTime < beforeActiveBoundary ||
(aPlaybackRate < 0 && localTime == beforeActiveBoundary)) {
result.mPhase = ComputedTiming::AnimationPhase::Before;
@ -165,7 +170,8 @@ AnimationEffectReadOnly::GetComputedTimingAt(
// The animation isn't active or filling at this time.
return result;
}
// activeTime is zero
activeTime = std::max(StickyTimeDuration(localTime - aTiming.mDelay),
zeroDuration);
} else {
MOZ_ASSERT(result.mActiveDuration != zeroDuration,
"How can we be in the middle of a zero-duration interval?");

View File

@ -114,7 +114,8 @@ struct TimingParams
StickyTimeDuration EndTime() const
{
return mDelay + ActiveDuration() + mEndDelay;
return std::max(mDelay + ActiveDuration() + mEndDelay,
StickyTimeDuration());
}
bool operator==(const TimingParams& aOther) const;

View File

@ -192,7 +192,7 @@ test(function(t) {
// undefined value.
var div = addDiv(t, {style: 'animation: moveAnimation 10s -100s forwards'});
var effect = div.getAnimations()[0].effect;
assert_equals(effect.getComputedTiming().endTime, -90 * MS_PER_SEC,
assert_equals(effect.getComputedTiming().endTime, 0,
'Initial value of endTime');
}, 'endTime of an animation that finishes before its startTime');

View File

@ -107,12 +107,8 @@ test(function(t) {
assert_equals(getComputedStyle(div).opacity, '0.5',
'set currentTime same as endTime');
anim.currentTime = 9999;
assert_equals(getComputedStyle(div).opacity, '0.5',
'set currentTime during duration');
anim.currentTime = 10000;
assert_equals(getComputedStyle(div).opacity, '0.5',
assert_equals(getComputedStyle(div).opacity, '0',
'set currentTime after endTime');
}, 'change currentTime when fill forwards and endDelay is negative');

View File

@ -189,10 +189,10 @@ var gEndTimeTests = [
{ desc: "an non-zero duration and negative delay greater than active " +
"duration",
input: { duration: 1000, iterations: 2, delay: -3000 },
expected: -1000 },
expected: 0 },
{ desc: "a zero duration and negative delay",
input: { duration: 0, iterations: 2, delay: -1000 },
expected: -1000 }
expected: 0 }
];
gEndTimeTests.forEach(function(stest) {

View File

@ -100,7 +100,7 @@ test(function(t) {
var anim = createDiv(t).animate(null, { duration: 1000,
iterations: 2.3,
delay: 500,
endDelay: -3000,
endDelay: -2500,
fill: 'forwards' });
anim.finish();
assert_equals(anim.effect.getComputedTiming().currentIteration, 0);

View File

@ -73,7 +73,7 @@ test(function(t) {
var animation = createDiv(t).animate(null, { duration: 1, delay: -1 });
[ { currentTime: -2, phase: 'before' },
{ currentTime: -1, phase: 'active' },
{ currentTime: -1, phase: 'before' },
{ currentTime: 0, phase: 'after' } ]
.forEach(function(test) {
assert_phase_at_time(animation, test.phase, test.currentTime);
@ -121,7 +121,8 @@ test(function(t) {
var animation = createDiv(t).animate(null, { duration: 1, endDelay: -2 });
[ { currentTime: -2, phase: 'before' },
{ currentTime: -1, phase: 'after' } ]
{ currentTime: -1, phase: 'before' },
{ currentTime: 0, phase: 'after' } ]
.forEach(function(test) {
assert_phase_at_time(animation, test.phase, test.currentTime);
});
@ -133,8 +134,8 @@ test(function(t) {
delay: 1,
endDelay: -1 });
[ { currentTime: 0, phase: 'before' },
{ currentTime: 1, phase: 'active' },
[ { currentTime: 0, phase: 'before' },
{ currentTime: 1, phase: 'active' },
{ currentTime: 2, phase: 'after' } ]
.forEach(function(test) {
assert_phase_at_time(animation, test.phase, test.currentTime);
@ -147,8 +148,9 @@ test(function(t) {
delay: -1,
endDelay: -1 });
[ { currentTime: -2, phase: 'before' },
{ currentTime: -1, phase: 'after' } ]
[ { currentTime: -2, phase: 'before' },
{ currentTime: -1, phase: 'before' },
{ currentTime: 0, phase: 'after' } ]
.forEach(function(test) {
assert_phase_at_time(animation, test.phase, test.currentTime);
});
@ -160,8 +162,10 @@ test(function(t) {
delay: -1,
endDelay: -2 });
[ { currentTime: -3, phase: 'before' },
{ currentTime: -2, phase: 'after' } ]
[ { currentTime: -3, phase: 'before' },
{ currentTime: -2, phase: 'before' },
{ currentTime: -1, phase: 'before' },
{ currentTime: 0, phase: 'after' } ]
.forEach(function(test) {
assert_phase_at_time(animation, test.phase, test.currentTime);
});