Bug 1180125 part 7 - Queue transition events from CSSTransition::Tick; r=dbaron

This patch moves the logic for queueing events out of the logic for flushing
transitions making it a separate step. It still doesn't delay the dispatch of
those events into a separate step, however. That is done in a subsequent patch.

This patch also makes sure to clear any queued events when the nsPresShell that
owns the transition manager is destroyed. We don't expect CSSTransition::Tick to
be called anywhere except nsTransitionManger::FlushTransitions so there
shouldn't be any orphaned events but for completeness it seems best to add this
now. (Later, when we tick transitions from their timeline we will need this.)

This patch introduces a separate flag to CSSTransition for tracking if a
transition is newly-finished so we can correctly dispatch the transitionend
event. Although, this may seem to be redundant with the "IsFinishedTransition"
we also track, that state will soon be removed in bug 1181392 and hence this
flag will be needed then.

Note that Animation already has flags mIsPreviousStateFinished and
mFinishedAtLastComposeStyle which would appear to be similar however,

- mIsPreviousStateFinished will be removed in bug 1178665 and is updated more
  often than we queue events so it is not useful here.
- mFinishedAtLastComposeStyle is used to determine if we can throttle a style
  update and is also updated more frequently than we queue events and hence
  can't be used here.

Once we guarantee one call to Tick() per frame we may be able to simplify this
by tracking "state on last tick" but for now we need this additional flag on
CSSTransition. CSSAnimation has a similar flag for this
(mPreviousPhaseOrIteration) which we may be able to unify at the same point.
This commit is contained in:
Brian Birtles 2015-07-29 10:57:40 +09:00
parent f38ef9d3a1
commit d23c414f8c
3 changed files with 52 additions and 8 deletions

View File

@ -1252,6 +1252,7 @@ PresShell::Destroy()
if (mPresContext) {
mPresContext->AnimationManager()->ClearEventQueue();
mPresContext->TransitionManager()->ClearEventQueue();
}
// Revoke any pending events. We need to do this and cancel pending reflows

View File

@ -117,6 +117,42 @@ CSSTransition::GetAnimationManager() const
return context->TransitionManager();
}
void
CSSTransition::QueueEvents()
{
AnimationPlayState playState = PlayState();
bool newlyFinished = !mWasFinishedOnLastTick &&
playState == AnimationPlayState::Finished;
mWasFinishedOnLastTick = playState == AnimationPlayState::Finished;
if (!newlyFinished || !mEffect || !mOwningElement.IsSet()) {
return;
}
dom::Element* owningElement;
nsCSSPseudoElements::Type owningPseudoType;
mOwningElement.GetElement(owningElement, owningPseudoType);
MOZ_ASSERT(owningElement, "Owning element should be set");
nsPresContext* presContext = mOwningElement.GetRenderedPresContext();
if (!presContext) {
return;
}
nsTransitionManager* manager = presContext->TransitionManager();
manager->QueueEvent(
TransitionEventInfo(owningElement, TransitionProperty(),
mEffect->Timing().mIterationDuration,
owningPseudoType));
}
void
CSSTransition::Tick()
{
Animation::Tick();
QueueEvents();
}
nsCSSProperty
CSSTransition::TransitionProperty() const
{
@ -917,14 +953,6 @@ nsTransitionManager::FlushTransitions(FlushFlags aFlags)
ComputedTiming computedTiming =
anim->GetEffect()->GetComputedTiming();
if (computedTiming.mPhase == ComputedTiming::AnimationPhase_After) {
nsCSSProperty prop =
anim->GetEffect()->AsTransition()->TransitionProperty();
TimeDuration duration =
anim->GetEffect()->Timing().mIterationDuration;
mEventDispatcher.QueueEvent(
TransitionEventInfo(collection->mElement, prop,
duration, collection->PseudoElementType()));
// Leave this transition in the list for one more refresh
// cycle, since we haven't yet processed its style change, and
// if we also have (already, or will have from processing

View File

@ -84,6 +84,7 @@ class CSSTransition final : public Animation
public:
explicit CSSTransition(nsIGlobalObject* aGlobal)
: dom::Animation(aGlobal)
, mWasFinishedOnLastTick(false)
{
}
@ -117,6 +118,8 @@ public:
MOZ_ASSERT(mSequenceNum == kUnsequenced);
}
void Tick() override;
nsCSSProperty TransitionProperty() const;
bool HasLowerCompositeOrderThan(const Animation& aOther) const override;
@ -166,9 +169,13 @@ protected:
virtual CommonAnimationManager* GetAnimationManager() const override;
void QueueEvents();
// The (pseudo-)element whose computed transition-property refers to this
// transition (if any).
OwningElementRef mOwningElement;
bool mWasFinishedOnLastTick;
};
} // namespace dom
@ -272,6 +279,14 @@ public:
void FlushTransitions(FlushFlags aFlags);
void QueueEvent(mozilla::TransitionEventInfo&& aEventInfo)
{
mEventDispatcher.QueueEvent(
mozilla::Forward<mozilla::TransitionEventInfo>(aEventInfo));
}
void ClearEventQueue() { mEventDispatcher.ClearEventQueue(); }
protected:
virtual ~nsTransitionManager() {}