This is in anticipation of adding Animation::SetTimeline(). Once we set the
timeline out of band, there's a chance that getting it could return null so
this patch makes the WebIDL and method name reflect that.
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.
Add a virtual method we can use to determine when an animation is having its
sequence number set by some other mechanism than the general logic
defined for animations.
This allows CSS animations and transitions to re-use the sequence number for
their own purposes. Typically what will happen is something like this:
1. A CSSAnimation is created corresponding to an item in the animation-name
property.
At this point CSSAnimation::IsUsingCustomCompositeOrder() will return true
and nsAnimationManager will set the sequence number based on the position of
the animation in animation-name.
2. If at a later point the animation is removed from the animation-name but kept
alive by script, CSSAnimation::CancelFromStyle will be called which will
clear the custom sequence number (i.e. set it to kUnsequenced) and also
update the CSSAnimation's state such as
CSSAnimation::IsUsingCustomCompositeOrder() returns false.
3. Then, then the CSSAnimation next transitions out of the idle state it will
have its sequence number set just like any other Animation and be ordered
like any other Animation (since we can no longer use animation-name to
determine its composite order).
This behavior is added in subsequent patches in this series (and likewise for
CSS transitions too).
This patch introduces a method that will be used for sorting animations based on
their composite order. The method is based on the API for Comparator objects (as
used by nsTArray and co.) which have a LessThan method. (For the
Comparator::Equals method we can used pointer equality since no two independent
objects should have equal composite order.)
Web Animations defines Animations as having a globally unique sequence number
for the purpose of prioritization:
http://w3c.github.io/web-animations/#animation-sequence-number
As of the writing of this patch, the spec says the sequence number is updated
when the Animation is created. This is problematic and I have proposed that
actually this should be updated from each transition from idle:
https://lists.w3.org/Archives/Public/public-fx/2015AprJun/0054.html
This doesn't seem to have met any opposition so I will update the spec to
reflect this soon.
This patch implements the behavior of updating the sequence number on each
transition from idle.
To make sure we perform this on each change to timing this patch removes
a couple of instances of early returns to ensure that UpdateTiming is called.
The current maximum sequence number is simply a class static and we make no
attempt to deal with wraparound. This is because we only update this number when
an animation transitions from idle which only happens when an animation is
created or script calls cancel() followed by play() on the animation. Supposing
that across all content this happenned an unlikely 1 billion times a second we
still wouldn't exhaust the range of the unsigned 64-bit int for about 585 years.
We'd like to make kUnsequenced be zero and make the static represent the
current maximum. This would probably be easier to understand and recognize in
a debugger. However, later in this patch series we will make CSS animations and
CSS transitions override this sequencing behavior. If we define kUnsequenced
to be zero and they accidentally assign zero as an actual sequence number then
they'll run into trouble. To avoid that we set kUnsequenced to UINT64_MAX.
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 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.
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.
Most of this is fairly obvious. However, the addition of 'override' to
ElementPropertyTransition::Name() is not strictly necessary. It was simply added
because while making these changes I accidentally dropped the 'virtual' keyword
from the method in the superclass and the compiler didn't complain. Adding this
will hopefully make it harder to create the same bug in the future.
This is a bit awkward. We lazily set mName to the transition property and then
return it. The reasons for this approach are:
* We don't really want to eagerly fill in mName for all transitions since in
99% of cases we'll never use it and this will lead to wasted allocations.
* The signature of Name() returns a const nsString reference. This is because
Name() is used when building CSS Animations (to compare different copies of
the same animation when updating). For that case we don't really want to
generate unnecessary copies of nsString objects so we return a reference.
However, that means for transitions as well we need to return a reference so
we can't just generate a temporary string on-demand.
As a result we also have to const-cast ourselves so we can update the mName
member. We could make mName mutable but seeing as it's only set once, the
const_cast seems more appropriate.
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.
This patch adds a method for testing if an animation is "in play" which is
a term defined in the Web Animations spec. This is in preparation for removing
some slightly redundant code in IsRunning and aligning better with the spec.
In preparation for introducing IsInPlay (where "in play" is a term in the Web
Animations spec), this patch aligns the existing IsCurrent with the definition
in the spec that says an animation effect is only current if it is attached
to an animation (player in our current naming) that is not finished. In order
to ensure that we need to pass the animation/player into the method.
This actually changes the behavior of IsCurrent since now we will return false
for animations that are finished. As far as I can tell, all the call sites that
are requesting current animations should only be concerned with animations that
are actually running. If not, they need to be adjusted to look for animations
that are either current or in effect.