зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1202333 part 2 - Update the CSSTransition::QueueEvents to specification. r=birtles
MozReview-Commit-ID: BxkZ359g7JR --HG-- extra : rebase_source : b832f1e85ae022291bf3999cd3d49dfe2ba6a6a0
This commit is contained in:
Родитель
90c5d3d372
Коммит
70e5e7e4ef
|
@ -33,11 +33,15 @@ using mozilla::dom::AnimationPlayState;
|
|||
using mozilla::dom::KeyframeEffectReadOnly;
|
||||
using mozilla::dom::CSSAnimation;
|
||||
|
||||
typedef mozilla::ComputedTiming::AnimationPhase AnimationPhase;
|
||||
|
||||
namespace {
|
||||
|
||||
// Pair of an event message and elapsed time used when determining the set of
|
||||
// events to queue.
|
||||
typedef Pair<EventMessage, StickyTimeDuration> EventPair;
|
||||
struct AnimationEventParams {
|
||||
EventMessage mMessage;
|
||||
StickyTimeDuration mElapsedTime;
|
||||
TimeStamp mTimeStamp;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
@ -193,69 +197,94 @@ CSSAnimation::QueueEvents()
|
|||
return;
|
||||
}
|
||||
nsAnimationManager* manager = presContext->AnimationManager();
|
||||
|
||||
ComputedTiming computedTiming = mEffect->GetComputedTiming();
|
||||
|
||||
if (computedTiming.mPhase == ComputedTiming::AnimationPhase::Null) {
|
||||
return; // do nothing
|
||||
ComputedTiming::AnimationPhase currentPhase = computedTiming.mPhase;
|
||||
uint64_t currentIteration = computedTiming.mCurrentIteration;
|
||||
if (currentPhase == mPreviousPhase &&
|
||||
currentIteration == mPreviousIteration) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Note that script can change the start time, so we have to handle moving
|
||||
// backwards through the animation as well as forwards. An 'animationstart'
|
||||
// is dispatched if we enter the active phase (regardless if that is from
|
||||
// before or after the animation's active phase). An 'animationend' is
|
||||
// dispatched if we leave the active phase (regardless if that is to before
|
||||
// or after the animation's active phase).
|
||||
const StickyTimeDuration zeroDuration;
|
||||
StickyTimeDuration intervalStartTime =
|
||||
std::max(std::min(StickyTimeDuration(-mEffect->SpecifiedTiming().mDelay),
|
||||
computedTiming.mActiveDuration),
|
||||
zeroDuration);
|
||||
StickyTimeDuration intervalEndTime =
|
||||
std::max(std::min((EffectEnd() - mEffect->SpecifiedTiming().mDelay),
|
||||
computedTiming.mActiveDuration),
|
||||
zeroDuration);
|
||||
|
||||
bool wasActive = mPreviousPhaseOrIteration != PREVIOUS_PHASE_BEFORE &&
|
||||
mPreviousPhaseOrIteration != PREVIOUS_PHASE_AFTER;
|
||||
bool isActive =
|
||||
computedTiming.mPhase == ComputedTiming::AnimationPhase::Active;
|
||||
bool isSameIteration =
|
||||
computedTiming.mCurrentIteration == mPreviousPhaseOrIteration;
|
||||
bool skippedActivePhase =
|
||||
(mPreviousPhaseOrIteration == PREVIOUS_PHASE_BEFORE &&
|
||||
computedTiming.mPhase == ComputedTiming::AnimationPhase::After) ||
|
||||
(mPreviousPhaseOrIteration == PREVIOUS_PHASE_AFTER &&
|
||||
computedTiming.mPhase == ComputedTiming::AnimationPhase::Before);
|
||||
uint64_t iterationBoundary = mPreviousIteration > currentIteration
|
||||
? currentIteration + 1
|
||||
: currentIteration;
|
||||
StickyTimeDuration iterationStartTime =
|
||||
computedTiming.mDuration.MultDouble(
|
||||
(iterationBoundary - computedTiming.mIterationStart));
|
||||
|
||||
MOZ_ASSERT(!skippedActivePhase || (!isActive && !wasActive),
|
||||
"skippedActivePhase only makes sense if we were & are inactive");
|
||||
TimeStamp startTimeStamp = ElapsedTimeToTimeStamp(intervalStartTime);
|
||||
TimeStamp endTimeStamp = ElapsedTimeToTimeStamp(intervalEndTime);
|
||||
TimeStamp iterationTimeStamp = ElapsedTimeToTimeStamp(iterationStartTime);
|
||||
|
||||
if (computedTiming.mPhase == ComputedTiming::AnimationPhase::Before) {
|
||||
mPreviousPhaseOrIteration = PREVIOUS_PHASE_BEFORE;
|
||||
} else if (computedTiming.mPhase == ComputedTiming::AnimationPhase::Active) {
|
||||
mPreviousPhaseOrIteration = computedTiming.mCurrentIteration;
|
||||
} else if (computedTiming.mPhase == ComputedTiming::AnimationPhase::After) {
|
||||
mPreviousPhaseOrIteration = PREVIOUS_PHASE_AFTER;
|
||||
AutoTArray<AnimationEventParams, 2> events;
|
||||
switch (mPreviousPhase) {
|
||||
case AnimationPhase::Null:
|
||||
case AnimationPhase::Before:
|
||||
if (currentPhase == AnimationPhase::Active) {
|
||||
events.AppendElement(AnimationEventParams{ eAnimationStart,
|
||||
intervalStartTime,
|
||||
startTimeStamp });
|
||||
} else if (currentPhase == AnimationPhase::After) {
|
||||
events.AppendElement(AnimationEventParams{ eAnimationStart,
|
||||
intervalStartTime,
|
||||
startTimeStamp });
|
||||
events.AppendElement(AnimationEventParams{ eAnimationEnd,
|
||||
intervalEndTime,
|
||||
endTimeStamp });
|
||||
}
|
||||
break;
|
||||
case AnimationPhase::Active:
|
||||
if (currentPhase == AnimationPhase::Before) {
|
||||
events.AppendElement(AnimationEventParams{ eAnimationEnd,
|
||||
intervalStartTime,
|
||||
startTimeStamp });
|
||||
} else if (currentPhase == AnimationPhase::Active) {
|
||||
// The currentIteration must have changed or element we would have
|
||||
// returned early above.
|
||||
MOZ_ASSERT(currentIteration != mPreviousIteration);
|
||||
events.AppendElement(AnimationEventParams{ eAnimationIteration,
|
||||
iterationStartTime,
|
||||
iterationTimeStamp });
|
||||
} else if (currentPhase == AnimationPhase::After) {
|
||||
events.AppendElement(AnimationEventParams{ eAnimationEnd,
|
||||
intervalEndTime,
|
||||
endTimeStamp });
|
||||
}
|
||||
break;
|
||||
case AnimationPhase::After:
|
||||
if (currentPhase == AnimationPhase::Before) {
|
||||
events.AppendElement(AnimationEventParams{ eAnimationStart,
|
||||
intervalEndTime,
|
||||
startTimeStamp});
|
||||
events.AppendElement(AnimationEventParams{ eAnimationEnd,
|
||||
intervalStartTime,
|
||||
endTimeStamp });
|
||||
} else if (currentPhase == AnimationPhase::Active) {
|
||||
events.AppendElement(AnimationEventParams{ eAnimationStart,
|
||||
intervalEndTime,
|
||||
endTimeStamp });
|
||||
}
|
||||
break;
|
||||
}
|
||||
mPreviousPhase = currentPhase;
|
||||
mPreviousIteration = currentIteration;
|
||||
|
||||
AutoTArray<EventPair, 2> events;
|
||||
StickyTimeDuration initialAdvance = StickyTimeDuration(InitialAdvance());
|
||||
StickyTimeDuration iterationStart = computedTiming.mDuration *
|
||||
computedTiming.mCurrentIteration;
|
||||
const StickyTimeDuration& activeDuration = computedTiming.mActiveDuration;
|
||||
|
||||
if (!wasActive && isActive) {
|
||||
events.AppendElement(EventPair(eAnimationStart, initialAdvance));
|
||||
} else if (wasActive && !isActive) {
|
||||
events.AppendElement(EventPair(eAnimationEnd, activeDuration));
|
||||
} else if (wasActive && isActive && !isSameIteration) {
|
||||
events.AppendElement(EventPair(eAnimationIteration, iterationStart));
|
||||
} else if (skippedActivePhase) {
|
||||
events.AppendElement(EventPair(eAnimationStart,
|
||||
std::min(initialAdvance, activeDuration)));
|
||||
events.AppendElement(EventPair(eAnimationEnd, activeDuration));
|
||||
} else {
|
||||
return; // No events need to be sent
|
||||
}
|
||||
|
||||
for (const EventPair& pair : events){
|
||||
for (const AnimationEventParams& event : events){
|
||||
manager->QueueEvent(
|
||||
AnimationEventInfo(owningElement, owningPseudoType,
|
||||
pair.first(), mAnimationName,
|
||||
pair.second(),
|
||||
ElapsedTimeToTimeStamp(pair.second()),
|
||||
event.mMessage, mAnimationName,
|
||||
event.mElapsedTime, event.mTimeStamp,
|
||||
this));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,7 +76,8 @@ public:
|
|||
, mIsStylePaused(false)
|
||||
, mPauseShouldStick(false)
|
||||
, mNeedsNewAnimationIndexWhenRun(false)
|
||||
, mPreviousPhaseOrIteration(PREVIOUS_PHASE_BEFORE)
|
||||
, mPreviousPhase(ComputedTiming::AnimationPhase::Null)
|
||||
, mPreviousIteration(0)
|
||||
{
|
||||
// We might need to drop this assertion once we add a script-accessible
|
||||
// constructor but for animations generated from CSS markup the
|
||||
|
@ -257,13 +258,10 @@ protected:
|
|||
// its animation index should be updated.
|
||||
bool mNeedsNewAnimationIndexWhenRun;
|
||||
|
||||
enum {
|
||||
PREVIOUS_PHASE_BEFORE = uint64_t(-1),
|
||||
PREVIOUS_PHASE_AFTER = uint64_t(-2)
|
||||
};
|
||||
// One of the PREVIOUS_PHASE_* constants, or an integer for the iteration
|
||||
// whose start we last notified on.
|
||||
uint64_t mPreviousPhaseOrIteration;
|
||||
// Phase and current iteration from the previous time we queued events.
|
||||
// This is used to determine what new events to dispatch.
|
||||
ComputedTiming::AnimationPhase mPreviousPhase;
|
||||
uint64_t mPreviousIteration;
|
||||
};
|
||||
|
||||
} /* namespace dom */
|
||||
|
|
Загрузка…
Ссылка в новой задаче