mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1078122 part 9 - Move queuing of CSS animation events to CSSAnimationPlayer; r=dholbert
This patch moves the code for queuing CSS animation events from nsAnimationManager to CSSAnimationPlayer. In doing so, it also moves the mLastNotification member and associated enum values.
This commit is contained in:
parent
ce354c28fb
commit
f71c3c8dee
@ -143,7 +143,6 @@ public:
|
||||
, mTiming(aTiming)
|
||||
, mName(aName)
|
||||
, mIsFinishedTransition(false)
|
||||
, mLastNotification(LAST_NOTIFICATION_NONE)
|
||||
, mPseudoType(aPseudoType)
|
||||
{
|
||||
MOZ_ASSERT(aTarget, "null animation target is not yet supported");
|
||||
@ -254,15 +253,6 @@ public:
|
||||
bool IsCurrent() const;
|
||||
bool IsInEffect() const;
|
||||
|
||||
enum {
|
||||
LAST_NOTIFICATION_NONE = uint64_t(-1),
|
||||
LAST_NOTIFICATION_END = uint64_t(-2)
|
||||
};
|
||||
uint64_t LastNotification() const { return mLastNotification; }
|
||||
void SetLastNotification(uint64_t aLastNotification) {
|
||||
mLastNotification = aLastNotification;
|
||||
}
|
||||
|
||||
bool HasAnimationOfProperty(nsCSSProperty aProperty) const;
|
||||
const InfallibleTArray<AnimationProperty>& Properties() const {
|
||||
return mProperties;
|
||||
@ -292,9 +282,6 @@ protected:
|
||||
// A flag to mark transitions that have finished and are due to
|
||||
// be removed on the next throttle-able cycle.
|
||||
bool mIsFinishedTransition;
|
||||
// One of the LAST_NOTIFICATION_* constants, or an integer for the iteration
|
||||
// whose start we last notified on.
|
||||
uint64_t mLastNotification;
|
||||
nsCSSPseudoElements::Type mPseudoType;
|
||||
|
||||
InfallibleTArray<AnimationProperty> mProperties;
|
||||
|
@ -62,6 +62,91 @@ CSSAnimationPlayer::PauseFromStyle()
|
||||
AnimationPlayer::Pause(eNoUpdate);
|
||||
}
|
||||
|
||||
void
|
||||
CSSAnimationPlayer::QueueEvents(EventArray& aEventsToDispatch)
|
||||
{
|
||||
if (!mSource) {
|
||||
return;
|
||||
}
|
||||
|
||||
ComputedTiming computedTiming = mSource->GetComputedTiming();
|
||||
|
||||
dom::Element* target;
|
||||
nsCSSPseudoElements::Type targetPseudoType;
|
||||
mSource->GetTarget(target, targetPseudoType);
|
||||
|
||||
switch (computedTiming.mPhase) {
|
||||
case ComputedTiming::AnimationPhase_Null:
|
||||
case ComputedTiming::AnimationPhase_Before:
|
||||
// Do nothing
|
||||
break;
|
||||
|
||||
case ComputedTiming::AnimationPhase_Active:
|
||||
// Dispatch 'animationstart' or 'animationiteration' when needed.
|
||||
if (computedTiming.mCurrentIteration != mLastNotification) {
|
||||
// Notify 'animationstart' even if a negative delay puts us
|
||||
// past the first iteration.
|
||||
// Note that when somebody changes the animation-duration
|
||||
// dynamically, this will fire an extra iteration event
|
||||
// immediately in many cases. It's not clear to me if that's the
|
||||
// right thing to do.
|
||||
uint32_t message = mLastNotification == LAST_NOTIFICATION_NONE
|
||||
? NS_ANIMATION_START
|
||||
: NS_ANIMATION_ITERATION;
|
||||
mLastNotification = computedTiming.mCurrentIteration;
|
||||
TimeDuration iterationStart =
|
||||
mSource->Timing().mIterationDuration *
|
||||
computedTiming.mCurrentIteration;
|
||||
TimeDuration elapsedTime =
|
||||
std::max(iterationStart, mSource->InitialAdvance());
|
||||
AnimationEventInfo ei(target, Name(), message,
|
||||
StickyTimeDuration(elapsedTime),
|
||||
PseudoTypeAsString(targetPseudoType));
|
||||
aEventsToDispatch.AppendElement(ei);
|
||||
}
|
||||
break;
|
||||
|
||||
case ComputedTiming::AnimationPhase_After:
|
||||
// If we skipped the animation interval entirely, dispatch
|
||||
// 'animationstart' first
|
||||
if (mLastNotification == LAST_NOTIFICATION_NONE) {
|
||||
// Notifying for start of 0th iteration.
|
||||
// (This is overwritten below but we set it here to maintain
|
||||
// internal consistency.)
|
||||
mLastNotification = 0;
|
||||
StickyTimeDuration elapsedTime =
|
||||
std::min(StickyTimeDuration(mSource->InitialAdvance()),
|
||||
computedTiming.mActiveDuration);
|
||||
AnimationEventInfo ei(target, Name(), NS_ANIMATION_START,
|
||||
elapsedTime,
|
||||
PseudoTypeAsString(targetPseudoType));
|
||||
aEventsToDispatch.AppendElement(ei);
|
||||
}
|
||||
// Dispatch 'animationend' when needed.
|
||||
if (mLastNotification != LAST_NOTIFICATION_END) {
|
||||
mLastNotification = LAST_NOTIFICATION_END;
|
||||
AnimationEventInfo ei(target, Name(), NS_ANIMATION_END,
|
||||
computedTiming.mActiveDuration,
|
||||
PseudoTypeAsString(targetPseudoType));
|
||||
aEventsToDispatch.AppendElement(ei);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ nsString
|
||||
CSSAnimationPlayer::PseudoTypeAsString(nsCSSPseudoElements::Type aPseudoType)
|
||||
{
|
||||
switch (aPseudoType) {
|
||||
case nsCSSPseudoElements::ePseudo_before:
|
||||
return NS_LITERAL_STRING("::before");
|
||||
case nsCSSPseudoElements::ePseudo_after:
|
||||
return NS_LITERAL_STRING("::after");
|
||||
default:
|
||||
return EmptyString();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsAnimationManager::UpdateStyleAndEvents(AnimationPlayerCollection*
|
||||
aCollection,
|
||||
@ -69,83 +154,19 @@ nsAnimationManager::UpdateStyleAndEvents(AnimationPlayerCollection*
|
||||
EnsureStyleRuleFlags aFlags)
|
||||
{
|
||||
aCollection->EnsureStyleRuleFor(aRefreshTime, aFlags);
|
||||
GetEventsForCurrentTime(aCollection, mPendingEvents);
|
||||
QueueEvents(aCollection, mPendingEvents);
|
||||
CheckNeedsRefresh();
|
||||
}
|
||||
|
||||
void
|
||||
nsAnimationManager::GetEventsForCurrentTime(AnimationPlayerCollection*
|
||||
aCollection,
|
||||
EventArray& aEventsToDispatch)
|
||||
nsAnimationManager::QueueEvents(AnimationPlayerCollection* aCollection,
|
||||
EventArray& aEventsToDispatch)
|
||||
{
|
||||
for (size_t playerIdx = aCollection->mPlayers.Length(); playerIdx-- != 0; ) {
|
||||
AnimationPlayer* player = aCollection->mPlayers[playerIdx];
|
||||
Animation* anim = player->GetSource();
|
||||
if (!anim) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ComputedTiming computedTiming = anim->GetComputedTiming();
|
||||
|
||||
switch (computedTiming.mPhase) {
|
||||
case ComputedTiming::AnimationPhase_Null:
|
||||
case ComputedTiming::AnimationPhase_Before:
|
||||
// Do nothing
|
||||
break;
|
||||
|
||||
case ComputedTiming::AnimationPhase_Active:
|
||||
// Dispatch 'animationstart' or 'animationiteration' when needed.
|
||||
if (computedTiming.mCurrentIteration != anim->LastNotification()) {
|
||||
// Notify 'animationstart' even if a negative delay puts us
|
||||
// past the first iteration.
|
||||
// Note that when somebody changes the animation-duration
|
||||
// dynamically, this will fire an extra iteration event
|
||||
// immediately in many cases. It's not clear to me if that's the
|
||||
// right thing to do.
|
||||
uint32_t message =
|
||||
anim->LastNotification() == Animation::LAST_NOTIFICATION_NONE
|
||||
? NS_ANIMATION_START
|
||||
: NS_ANIMATION_ITERATION;
|
||||
anim->SetLastNotification(computedTiming.mCurrentIteration);
|
||||
TimeDuration iterationStart =
|
||||
anim->Timing().mIterationDuration *
|
||||
computedTiming.mCurrentIteration;
|
||||
TimeDuration elapsedTime =
|
||||
std::max(iterationStart, anim->InitialAdvance());
|
||||
AnimationEventInfo ei(aCollection->mElement, player->Name(), message,
|
||||
StickyTimeDuration(elapsedTime),
|
||||
aCollection->PseudoElement());
|
||||
aEventsToDispatch.AppendElement(ei);
|
||||
}
|
||||
break;
|
||||
|
||||
case ComputedTiming::AnimationPhase_After:
|
||||
// If we skipped the animation interval entirely, dispatch
|
||||
// 'animationstart' first
|
||||
if (anim->LastNotification() == Animation::LAST_NOTIFICATION_NONE) {
|
||||
// Notifying for start of 0th iteration.
|
||||
// (This is overwritten below but we set it here to maintain
|
||||
// internal consistency.)
|
||||
anim->SetLastNotification(0);
|
||||
StickyTimeDuration elapsedTime =
|
||||
std::min(StickyTimeDuration(anim->InitialAdvance()),
|
||||
computedTiming.mActiveDuration);
|
||||
AnimationEventInfo ei(aCollection->mElement,
|
||||
player->Name(), NS_ANIMATION_START,
|
||||
elapsedTime, aCollection->PseudoElement());
|
||||
aEventsToDispatch.AppendElement(ei);
|
||||
}
|
||||
// Dispatch 'animationend' when needed.
|
||||
if (anim->LastNotification() != Animation::LAST_NOTIFICATION_END) {
|
||||
anim->SetLastNotification(Animation::LAST_NOTIFICATION_END);
|
||||
AnimationEventInfo ei(aCollection->mElement,
|
||||
player->Name(), NS_ANIMATION_END,
|
||||
computedTiming.mActiveDuration,
|
||||
aCollection->PseudoElement());
|
||||
aEventsToDispatch.AppendElement(ei);
|
||||
}
|
||||
break;
|
||||
}
|
||||
CSSAnimationPlayer* player =
|
||||
aCollection->mPlayers[playerIdx]->AsCSSAnimationPlayer();
|
||||
MOZ_ASSERT(player, "Expected a collection of CSS Animation players");
|
||||
player->QueueEvents(aEventsToDispatch);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,7 @@ public:
|
||||
: dom::AnimationPlayer(aTimeline)
|
||||
, mIsStylePaused(false)
|
||||
, mPauseShouldStick(false)
|
||||
, mLastNotification(LAST_NOTIFICATION_NONE)
|
||||
{
|
||||
}
|
||||
|
||||
@ -70,9 +71,13 @@ public:
|
||||
|
||||
bool IsStylePaused() const { return mIsStylePaused; }
|
||||
|
||||
void QueueEvents(EventArray& aEventsToDispatch);
|
||||
|
||||
protected:
|
||||
virtual ~CSSAnimationPlayer() { }
|
||||
|
||||
static nsString PseudoTypeAsString(nsCSSPseudoElements::Type aPseudoType);
|
||||
|
||||
// When combining animation-play-state with play() / pause() the following
|
||||
// behavior applies:
|
||||
// 1. pause() is sticky and always overrides the underlying
|
||||
@ -124,6 +129,14 @@ protected:
|
||||
// they don't represent valid states.)
|
||||
bool mIsStylePaused;
|
||||
bool mPauseShouldStick;
|
||||
|
||||
enum {
|
||||
LAST_NOTIFICATION_NONE = uint64_t(-1),
|
||||
LAST_NOTIFICATION_END = uint64_t(-2)
|
||||
};
|
||||
// One of the LAST_NOTIFICATION_* constants, or an integer for the iteration
|
||||
// whose start we last notified on.
|
||||
uint64_t mLastNotification;
|
||||
};
|
||||
|
||||
} /* namespace mozilla */
|
||||
@ -159,8 +172,8 @@ public:
|
||||
void UpdateStyleAndEvents(mozilla::AnimationPlayerCollection* aEA,
|
||||
mozilla::TimeStamp aRefreshTime,
|
||||
mozilla::EnsureStyleRuleFlags aFlags);
|
||||
void GetEventsForCurrentTime(mozilla::AnimationPlayerCollection* aEA,
|
||||
mozilla::EventArray &aEventsToDispatch);
|
||||
void QueueEvents(mozilla::AnimationPlayerCollection* aEA,
|
||||
mozilla::EventArray &aEventsToDispatch);
|
||||
|
||||
// nsIStyleRuleProcessor (parts)
|
||||
virtual void RulesMatching(ElementRuleProcessorData* aData) MOZ_OVERRIDE;
|
||||
|
Loading…
Reference in New Issue
Block a user