Prior to this patch, CSSAnimation defined a method for converting an
nsCSSPseudoElements::Type to a nsString (but only for the set of
pseudo-elements that can have animations). We would like to re-use this
when setting up transition events so this patch moves it to
AnimationCollection. Re-using this method more widely means we can make
a few further simplifications to the code.
This patch extracts a utility class for queueing up a series of EventInfo
objects (of templated type) and then dispatching them. This covers the event
queuing behavior in nsAnimationManager so that we can reuse it in
nsTransitionManager.
The long-term plan is to drop the mozilla::css namespace altogether. Before we
go to much further with refactoring code in AnimationCommon, we should drop
usage of the mozilla::css namespace. Specifically, this patch moves the
CommonAnimationManager and AnimValuesStyleRule classes to the mozilla namespace.
This patch prepares the way for script-generated events by making
event dispatch a separate process that happens after sampling animations.
This will allow us to sample animations from their associated timeline
(removing the need for a further manager to tracker script-generated
animations).
Furthermore, once we sample animations from timelines the order in which they
are sampled is likely to be more or less random so by making event dispatch at
separate step, we have an opportunity to sort the events and dispatch in
a consistent and sensible order. It also ensures that event callbacks will
not be run until all animations (including transitions) have been updated
ensuring they see a consistent view of timing properties.
This patch only affects event handling for CSS animations. Transitions will
be dealt with in a subsequent patch.
The connection between an Animation and an AnimationTimeline is optional. That
is, it is possible to have an Animation without an AnimationTimeline. Until now
we have often just assumed the timeline will be set but eventually we need to
support the possibility of the timeline being null. Indeed, later in this patch
series we will set the timeline out-of-band (i.e. not in the constructor) using
SetTimeline which opens up the possibility that timeline will be null for
a period of time.
This patch paves the way for having an optional timeline by storing the global
used for, e.g. creating promises, on the Animation object itself.
This patch also extends the tests for Element.getAnimations(). It doesn't
actually exercise the code added (it's not actually called yet since it doesn't
need to be for Element.getAnimations) but simply provides a useful regression
and interop test.
This patch re-uses Animation::mSequenceNum to store the index of CSS animations
within their corresponding animation-name property. When the animation is
removed from an animation-name property it reverts to using the default
animation composite order.
This patch also updates Animation::DoCancel to call UpdateTiming instead of
UpdateEffect. This is because UpdateTiming is responsible for updating the
sequence number (when custom composite order is not in effect). When we remove
an animation from animation-name it will be cancelled and at that point we
expect its sequence number to be cleared which will only happen if
UpdateTiming gets called.
In order to sort CSS animation objects correctly, we need to know which
element's animation-name property they appear in, if any. Normally that's
simply the target element of the animation's keyframe effect but it can differ
in the following cases:
1) When script modifies a CSSAnimation's effect to target a different element
(or simply removes the effect altogether). In this case we use the
*owning* element to determine the priority of the animation, not the target
element.
This scenario does not yet occur (bug 1049975).
2) When script creates a CSSAnimation object using the CSSAnimation constructor.
In this case, the owning element should be empty (null) and we should
determine the priority of the animation in the same way as any other
Animation object.
Again, this is not yet supported (or even specced) but will be eventually.
3) When script holds a reference to a CSSAnimation object but then updates the
animation-name property such that the animation object is cancelled. In this
case the owning element should be cleared (null) so we know to not to try and
sort this with regard to any animation-name property.
This is possible using code such as the following:
elem.style.animation = 'a 5s';
var a = elem.getAnimations()[0];
elem.style.animation = 'b 5s';
a.play(); // Bring a back to life
document.timeline.getAnimations();
// ^ At this point we need to know how to sort 'a' and 'b' which depends
// on recognizing that a is no longer part of an animation-name list.
Until we implement bug 1049975, we could support sorting animations without
adding the reference to the owning element by setting a flag on the CSSAnimation
object but (having tried this) it turns out to be cleaner to just introduce this
reference now, particularly since we know we will need it later.
Note that we will also need this information in future to dispatch events to the
correct element in circumstances such as (1) once we separate updating timing
information (including events) from applying animation values.
This isn't spec'ed anywhere (since the whole Web Animations API <-> CSS
interaction isn't spec'ed yet) but it seems that changing animation-play-state
should not restart an idle animation.
If an author calls Cancel() on an animation then that animation should continue
to be idle until they call Play()/Pause() from the API. Cancelling an animation
and hanging on to it is a purely API-only feature and hence it's reasonable that
restoring it from this state is also an API-only feature.
One can imagine use-cases such as polyfilling where script wants to remove any
CSS Animations/Transitions run by the browser and replace them with something
else entirely. In that case, the script can call Cancel() on the animation and
be sure that the animation is going to stay out of the way even if something
else tweaks the animation-play-state.
This patch makes Cancel() call PostUpdate which clobbers certain state in style
so that animated style is correctly flushed when an animation is cancelled.
The main difficulty with this is that we *don't* want to call this when we're
cancelling an animation as a result of a style update or else we'll trigger
needless work. The pattern elsewhere has been to define a *FromStyle() method
for this case (e.g. CSSAnimation::PlayFromStyle, PauseFromStyle). This isn't
ideal because there's always the danger we will forget to call the appropriate
*FromStyle method. It is, however, consistent. Hopefully in bug 1151731 we'll
find a better way of expressing this.
This patch is a fairly minimal rename of the AnimationPlayer interface. It
leaves a bunch of local variables and helper classes still using the word
"player". These will be addressed in subsequent patches that don't require DOM
peer review.
This patch also tightens up a one or two references to 'target effect' replacing
them with just 'effect'. This is because 'target effect' is longer and easily
confused with 'target element'. 'effect' should be sufficient. 'target element'
is a term from the Web Animations specification and in that context, simply
referring to the 'effect' would sound a little odd.
There are still some other references to "source" in AnimationPlayer such as
HasInPlayerSource and UpdateSourceContent. These are renamed in a subsequent
patch (that doesn't require DOM peer review).
We define KeyframeEffectReadonly in KeyframeEffect.cpp since Web Animations also
defines KeyframeEffect and when we come to implement that I expect we'll define
it in the same class, maybe even using the same object.
This patch also adds a few missing includes in places where
KeyframeEffectReadonly is used so that we're not just cargo-culting it in.
This avoids some extra work that was added in bug 1125455 now that we
have a mechanism for detecting when animations start and stop being in
effect (introduced in patch 7).
This is also needed to prevent infinite recursion in patch 9.
This is the main patch for the bug; it makes us use the mechanism added
in bug 1125455 to avoid sending animations that aren't currently
applying to the compositor.
Patch 7 is needed to make this code rerun in all the cases where we need
to rerun it, though.
IsPaused is used in nsAnimationManager to detect if a newly created animation
should be paused. It is also used inside AnimationPlayer::IsRunning which is
used to determine what animations to send to the compositor (we don't send
paused animations to the compositor). In all these cases we want to treat paused
animations and pause-pending animations alike.
This patch updates IsPaused to include also pause-pending animations. At the
same time it renames IsPaused to IsPausedOrPausing to reflect the change in
behavior.
This patch also adjusts a few nearby one-line functions to put the opening brace
on a new line since apparently this is what the coding style says to do.