Bug 1150810 part 5 - Handle Timeline() returning null; r=jwatt

--HG--
extra : commitid : K6pABHL7QRC
extra : rebase_source : ba96781d897d28db1d2db83f73ce8c31b89638cd
This commit is contained in:
Brian Birtles 2015-04-28 12:49:12 +09:00
parent 6d3dd1a595
commit 4159c4a595
3 changed files with 32 additions and 14 deletions

View File

@ -58,13 +58,7 @@ Animation::SetEffect(KeyframeEffectReadOnly* aEffect)
void
Animation::SetStartTime(const Nullable<TimeDuration>& aNewStartTime)
{
#if 1
// Bug 1096776: once we support inactive/missing timelines we'll want to take
// the disabled branch.
MOZ_ASSERT(mTimeline && !mTimeline->GetCurrentTime().IsNull(),
"We don't support inactive/missing timelines yet");
#else
Nullable<TimeDuration> timelineTime = mTimeline->GetCurrentTime();
Nullable<TimeDuration> timelineTime;
if (mTimeline) {
// The spec says to check if the timeline is active (has a resolved time)
// before using it here, but we don't need to since it's harmless to set
@ -74,7 +68,7 @@ Animation::SetStartTime(const Nullable<TimeDuration>& aNewStartTime)
if (timelineTime.IsNull() && !aNewStartTime.IsNull()) {
mHoldTime.SetNull();
}
#endif
Nullable<TimeDuration> previousCurrentTime = GetCurrentTime();
mStartTime = aNewStartTime;
if (!aNewStartTime.IsNull()) {
@ -106,7 +100,7 @@ Animation::GetCurrentTime() const
return result;
}
if (!mStartTime.IsNull()) {
if (mTimeline && !mStartTime.IsNull()) {
Nullable<TimeDuration> timelineTime = mTimeline->GetCurrentTime();
if (!timelineTime.IsNull()) {
result.SetValue((timelineTime.Value() - mStartTime.Value())
@ -315,6 +309,8 @@ Animation::Tick()
// resuming.
if (mPendingState != PendingState::NotPending &&
!mPendingReadyTime.IsNull() &&
mTimeline &&
!mTimeline->GetCurrentTime().IsNull() &&
mPendingReadyTime.Value() <= mTimeline->GetCurrentTime().Value()) {
FinishPendingAt(mPendingReadyTime.Value());
mPendingReadyTime.SetNull();
@ -355,8 +351,15 @@ Animation::TriggerNow()
if (PlayState() != AnimationPlayState::Pending) {
return;
}
MOZ_ASSERT(mTimeline && !mTimeline->GetCurrentTime().IsNull(),
"Expected an active timeline");
// If we don't have an active timeline we can't trigger the animation.
// However, this is a test-only method that we don't expect to be used in
// conjunction with animations without an active timeline so generate
// a warning if we do find ourselves in that situation.
if (!mTimeline || mTimeline->GetCurrentTime().IsNull()) {
NS_WARNING("Failed to trigger an animation with an active timeline");
return;
}
FinishPendingAt(mTimeline->GetCurrentTime().Value());
}
@ -797,10 +800,12 @@ Animation::UpdateFinishedState(SeekFlag aSeekFlag)
mHoldTime.SetValue(0);
}
} else if (mPlaybackRate != 0.0 &&
!currentTime.IsNull()) {
!currentTime.IsNull() &&
mTimeline &&
!mTimeline->GetCurrentTime().IsNull()) {
if (aSeekFlag == SeekFlag::DidSeek && !mHoldTime.IsNull()) {
mStartTime.SetValue(mTimeline->GetCurrentTime().Value() -
(mHoldTime.Value().MultDouble(1 / mPlaybackRate)));
(mHoldTime.Value().MultDouble(1 / mPlaybackRate)));
}
mHoldTime.SetNull();
}

View File

@ -55,6 +55,13 @@ TriggerAnimationAtTime(nsRefPtrHashKey<dom::Animation>* aKey,
dom::Animation* animation = aKey->GetKey();
dom::AnimationTimeline* timeline = animation->Timeline();
// If the animation does not have a timeline, just drop it from the map.
// The animation will detect that it is not being tracked and will trigger
// itself on the next tick where it has a timeline.
if (!timeline) {
return PL_DHASH_REMOVE;
}
// When the timeline's refresh driver is under test control, its values
// have no correspondance to wallclock times so we shouldn't try to convert
// aReadyTime (which is a wallclock time) to a timeline value. Instead, the

View File

@ -364,6 +364,11 @@ AddAnimationForProperty(nsIFrame* aFrame, const AnimationProperty& aProperty,
MOZ_ASSERT(aLayer->AsContainerLayer(), "Should only animate ContainerLayer");
MOZ_ASSERT(aAnimation->GetEffect(),
"Should not be adding an animation without an effect");
MOZ_ASSERT(!aAnimation->GetCurrentOrPendingStartTime().IsNull() ||
(aAnimation->Timeline() &&
aAnimation->Timeline()->TracksWallclockTime()),
"Animation should either have a resolved start time or "
"a timeline that tracks wallclock time");
nsStyleContext* styleContext = aFrame->StyleContext();
nsPresContext* presContext = aFrame->PresContext();
TransformReferenceBox refBox(aFrame);
@ -462,7 +467,8 @@ AddAnimationsForProperty(nsIFrame* aFrame, nsCSSProperty aProperty,
// driver under test control. In this case, the next time the refresh
// driver is advanced it will trigger any pending animations.
if (anim->PlayState() == AnimationPlayState::Pending &&
!anim->Timeline()->TracksWallclockTime()) {
(!anim->Timeline() ||
!anim->Timeline()->TracksWallclockTime())) {
continue;
}