The existing relationship between the particular versions of
AnimationPlayer::Play* (particularly in the CSSAnimationPlayer) subclass are
confusing because, for example, CSSAnimationPlayer::PlayFromStyle needs to be
careful to *not* call Play on CSSAnimationPlayer, but only on the parent
object (since otherwise we reset the sticky pause behavior).
This patch reworks this relationship by adding a protected DoPlay method that
performs the common pausing behavior. Play/PlayFromJS/PlayFromStyle then add
flushing, sticky pausing etc. as necessary.
This patch also removes the UpdateFlags enum and parameters previously used to
control whether we forced an update to style. This is no longer necessary since
we no longer call 'Play' from style. Instead we make Play always post restyles.
If we come across a case where we want to call Play and *not* post restyles, we
can re-add the flags then.
Roughly the same arrangement is true for Pause except that we don't currently
flush styles for CSS animations in PauseFromJS since it currently won't make any
observable difference.
In order for AnimationPlayer objects to be able to notify their
collection/manager, the can either store an extra pointer member, or they can
navigate to the collection as follows:
player->source(animation)->target(element)->document
->presShell->presContext->manager->collection
This patch adds a getter for the first part of this journey up to the document.
Previously AnimationPlayer::Play() and AnimationPlayer::PlayState() would flush
styles as part of their operation. This, however, is only needed when the player
corresponds to a CSS Animation or CSS Transition. Now that we have concrete
subclasses for each of these cases we can move style flushing to the subclasses
and remove it from the base class (which is expected to be shared with
animations that are not dependent on style).
AnimationPlayer::CanThrottle determines if an animation player has just finished
by inspecting the value of mLastNotification. This is problematic for two
reasons:
1. mLastNotification is intended to be used for events (as the XXX comment
notes)
2. mLastNotification is specific to CSS Animations and should be moved to
CSSAnimationPlayer.
To address this, this patch adds an extra member mIsPreviousStateFinished. The
Web Animations spec already defines animation players as having such a member:
http://w3c.github.io/web-animations/#previous-finished-state
We set it to true when we calculate the style for an animation that has
finished. This differs slightly from the code it is replacing as explained
below.
In the case of CSS Animations we perform the following sequence of steps on each
sample.
1. EnsureStyleRuleFor (calls CanThrottle, and maybe ComposeStyle)
2. GetEventsForCurrentTime
In the existing code, we update mLastNotification in (2) which happens on every
sample, even throttled samples.
In this patch, however, we update mIsPreviousStateFinished in (1) during the
ComposeStyle step which only happens for unthrottled samples. So, as of this
patch, in CanThrottle, we ask "have we newly entered the finished state since
the last *unthrottled* sample?", whereas previously we simply looked for
a change since the last sample, throttled or not. However, if the answer to the
question is "yes", then we'll run an unthrottled sample and update
mIsPreviousStateFinished so these should be functionally equivalent.
Another subtle difference is that this patch looks at the player's finished
state rather than the animation phase of its source content, and these will
produce different results in the case where the player is paused. However, since
paused animations are not run on the compositor, this should not matter.
In the case of CSS Transitions, AnimationPlayer::CanThrottle() is not currently
used and so mIsPreviousStateFinished is irrelevant.
Ultimately, both the existing and the new code is somewhat fragile but hopefully
this will be addressed by:
* Replacing mIsPreviousStateFinished with inspecting whether the finished
promise is settled (bug 1074630),
* Merging more of the code in nsAnimationManager and nsTransitionManager and
applying a unified approach to sampling that better accommodates these
considerations.
This patch takes the CSSAnimationPlayer object, currently defined in
dom/animation/AnimationPlayer.{cpp,h}, and moves it to
layout/style/nsAnimationManager.{cpp,h} where the rest of the CSS
Animations-specific code lives.
At the same time it extends the scope of the mozilla namespace block in
nsAnimationManager.h to also include the AnimationEventInfo and EventArray types
since these classes, which don't have an ns* prefix, probably should be in the
mozilla namespace anyway.
This patch extracts the logic for calculating animation styles from
AnimationPlayerCollection and puts the bulk of it into the Animation objects.
Some of the initial logic surrounding the animation player state (e.g. is it
paused or not, etc.) is put into AnimationPlayer.
In future we may shift this logic even further down to the AnimationEffect
objects but currently we don't create such objects unless necessary.
This patch moves code from AnimationPlayerCollection to AnimationPlayer.
However, there is one subtle change in logic involved. Previously, we would test
if the player had finished by getting the computed time of its source content
and checking if it was in the after phase or not. In this patch, however, we
simply check the play state to see if it is finished or not.
These two approaches differ in the case where an animation is paused after it
has finished. The animation phase approach will indicate the player has
finished, but the play state approach will indicate the player has paused (since
the "paused" state trumps the "finished" state). This, however, should not
produce any observable effect because when an animation is paused
mIsRunningOnCompositor will be false (we don't put paused animations on the
compositor).
For players running CSS animations and CSS transitions we should perform a style
flush before running play() so that we are operating on the most up-to-date
state of animation-play-state.
For transitions, which don't have a play-state property, we will still need to
run this style flush before running play() to get the right finishing behavior
if transition-duration has changed. We haven't implemented finishing yet (that's
bug 1074630) but I've kept the flush for both cases now since I'm afraid we'll
forget it later.
Also, since we don't have a subclass of AnimationPlayer for transitions yet I've
put the style flush in the base class. In future, when we add
CSSTransitionPlayer we can move the flush to only those players that need up to
date style information.
When an animation player is paused by script this overrides whatever
animation-play-state is set by style. The logic for producing the correct
override behavior will be added to nsAnimationManager but first we need
to record in the player where it was paused.
This patch introduces the basic implementation of play() and pause().
There are a lot of gaps still because we don't yet:
* Support the pending state (to be covered in bug 927349)
* Support finishing behavior (to be covered in bug 1074630)
* Have a good way of updating animation state outside of style resolution (bug
1073336)
Also, we don't call these methods from CSS yet because the interaction between
play()/pause() and animation-play-state requires storing some extra state which
we introduce in subsequent patches in this series.
This patch introduces, temporarily, an update flag to indicate whether
play()/pause() operations need to post a restyle event. When these methods are
triggered by processing restyles we don't want to post another (unnecessary)
restyle event. In bug 1073336 we will remove the need for this.
We only need to store if an animation is paused or not, hence a bool is
sufficient. Furthermore, the convenience of using the same type as the specified
style of animation-play-state will disappear once pausing behavior is wrapped up
behind Play() and Pause() methods.
It's not the player that's "current" (a Web Animations term for an animation
that hasn't yet finished), but its source content, if any. This patch renames
the method on AnimationPlayer accordingly.
At the same time this patch moves the method to the header file since it's
quite simple and could possibly benefit from inlining.
As the third step in dividing functionality between AnimationPlayer and
Animation this patch moves the mIsFinishedTransition member and related methods
from AnimationPlayer to Animation.
At the same time we rename SetFinishedTransition to SetIsFinishedTransition.
As the second step in dividing functionality between AnimationPlayer and
Animation, this patch moves the AnimationTiming member from AnimationPlayer to
Animation.
Most of this patch is simply moving code around. However, one significant
functional difference is that Animation::GetLocalTime() uses the mParentTime
member which is set when the Animation is updated by the player it is attached
to.
Other less significant differences are:
* AnimationPlayer::GetLocalTime is renamed to GetCurrentTimeDuration
In Web Animations, animation players have a (writeable) "current time" and
animations have a (read-only) "local time".
We would call the method simply "GetCurrentTime" (instead of
"GetCurrentTimeDuration") but GetCurrentTime is the name of the method used in
the content-facing API where it returns a double.
* "IsCurrent" is defined on both AnimationPlayer and Animation with the version
in AnimationPlayer serving mostly as a convenience shortcut to the version on
Animation.
* Animation::GetComputedTiming (previously on AnimationPlayer) now makes the
timing parameter optional since most of the time it is not needed.
As the first step in dividing the functionality currently contained in
AnimationPlayer between AnimationPlayer and Animation this patch moves the set
of keyframe properties to the Animation.
These properties are returned from the Animation by a couple of Properties()
methods that provide direct access to the member variable. In future it is
anticipated that the non-const version will be replaced with an appropriate
setter function. This will likely happen when we implement a separate
KeyframeEffect object as defined by the Web Animations API.
With regards to error checking, nsAnimationManager checks the result of
AnimationPlayer::GetSource() and handles the case where it is nullptr.
nsTransitionManager, however, simply asserts that GetSource() is never null much
like it also asserts that there is only one property with one segment in the
animation. Eventually this code should be made more generic which will probably
happen in bug 999927.
This patch makes AnimationPlayers pass their current time down to the Animation
they are playing.
Since all Animations need from their players is their time, this avoids adding
a pointer back to their AnimationPlayer.
This patch renames mozilla::ElementAnimations to mozilla::dom::AnimationPlayer
and moves the code from layout/style/AnimationCommon.cpp to
dom/animation/AnimationPlayer.cpp.
It also moves various helper classes needed by AnimationPlayer to
AnimationPlayer.cpp and moves them from the mozilla::css namespace to the
mozilla namespace.
Beyond that, there are no functional changes contained in this patch.
The renaming of various members and variables that used to refer to
ElementAnimation objects but now refer to AnimationPlayer objects--to give them
a more appropriate name--is performed in a subsequent patch.
--HG--
rename : layout/style/AnimationCommon.cpp => dom/animation/AnimationPlayer.cpp
rename : layout/style/AnimationCommon.h => dom/animation/AnimationPlayer.h