mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1171817 part 2 - Add CSSAnimation::GetOwningElement; r=dbaron
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 commit is contained in:
parent
8bc8dcf737
commit
0aad11786e
@ -127,11 +127,10 @@ public:
|
||||
* CSSAnimation::PauseFromJS so we leave it for now.
|
||||
*/
|
||||
void PauseFromJS(ErrorResult& aRv) { Pause(aRv); }
|
||||
|
||||
// Wrapper functions for Animation DOM methods when called from style.
|
||||
//
|
||||
// Typically these DOM methods also notify style of changes but when
|
||||
// we are calling from style we don't need to do this.
|
||||
void CancelFromStyle() { DoCancel(); }
|
||||
|
||||
virtual void CancelFromStyle() { DoCancel(); }
|
||||
|
||||
void Tick();
|
||||
|
||||
|
@ -552,6 +552,7 @@ nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext,
|
||||
}
|
||||
|
||||
nsRefPtr<CSSAnimation> dest = new CSSAnimation(aTimeline, src.GetName());
|
||||
dest->SetOwningElement(*aTarget, aStyleContext->GetPseudoType());
|
||||
aAnimations.AppendElement(dest);
|
||||
|
||||
AnimationTiming timing;
|
||||
|
@ -56,10 +56,12 @@ namespace dom {
|
||||
class CSSAnimation final : public Animation
|
||||
{
|
||||
public:
|
||||
explicit CSSAnimation(DocumentTimeline* aTimeline,
|
||||
explicit CSSAnimation(dom::DocumentTimeline* aTimeline,
|
||||
const nsSubstring& aAnimationName)
|
||||
: Animation(aTimeline)
|
||||
: dom::Animation(aTimeline)
|
||||
, mAnimationName(aAnimationName)
|
||||
, mOwningElement(nullptr)
|
||||
, mOwningPseudoType(nsCSSPseudoElements::ePseudo_NotPseudoElement)
|
||||
, mIsStylePaused(false)
|
||||
, mPauseShouldStick(false)
|
||||
, mPreviousPhaseOrIteration(PREVIOUS_PHASE_BEFORE)
|
||||
@ -92,11 +94,57 @@ public:
|
||||
|
||||
void PlayFromStyle();
|
||||
void PauseFromStyle();
|
||||
void CancelFromStyle() override
|
||||
{
|
||||
mOwningElement = nullptr;
|
||||
mOwningPseudoType = nsCSSPseudoElements::ePseudo_NotPseudoElement;
|
||||
|
||||
Animation::CancelFromStyle();
|
||||
}
|
||||
|
||||
bool IsStylePaused() const { return mIsStylePaused; }
|
||||
|
||||
void QueueEvents(EventArray& aEventsToDispatch);
|
||||
|
||||
// Returns the element or pseudo-element whose animation-name property
|
||||
// this CSSAnimation corresponds to (if any). This is used for determining
|
||||
// the relative composite order of animations generated from CSS markup.
|
||||
//
|
||||
// Typically this will be the same as the target element of the keyframe
|
||||
// effect associated with this animation. However, it can differ in the
|
||||
// following circumstances:
|
||||
//
|
||||
// a) If script removes or replaces the effect of this animation,
|
||||
// b) If this animation is cancelled (e.g. by updating the
|
||||
// animation-name property or removing the owning element from the
|
||||
// document),
|
||||
// c) If this object is generated from script using the CSSAnimation
|
||||
// constructor.
|
||||
//
|
||||
// For (b) and (c) the returned owning element will by nullptr and the
|
||||
// pseudo-type will be nsCSSPseudoElements::ePseudo_NotPseudoElement.
|
||||
void GetOwningElement(dom::Element*& aElement,
|
||||
nsCSSPseudoElements::Type& aPseudoType) const {
|
||||
MOZ_ASSERT(mOwningElement != nullptr ||
|
||||
mOwningPseudoType ==
|
||||
nsCSSPseudoElements::ePseudo_NotPseudoElement,
|
||||
"When there is no owning element there should be no "
|
||||
"pseudo-type");
|
||||
aElement = mOwningElement;
|
||||
aPseudoType = mOwningPseudoType;
|
||||
}
|
||||
|
||||
// Sets the owning element and pseudo-type which is used for determining
|
||||
// the composite order of CSSAnimation objects generated from CSS markup.
|
||||
//
|
||||
// @see GetOwningElement.
|
||||
void SetOwningElement(dom::Element& aElement,
|
||||
nsCSSPseudoElements::Type aPseudoType)
|
||||
{
|
||||
mOwningElement = &aElement;
|
||||
mOwningPseudoType = aPseudoType;
|
||||
}
|
||||
|
||||
// Is this animation currently in effect for the purposes of computing
|
||||
// mWinsInCascade. (In general, this can be computed from the timing
|
||||
// function. This boolean remembers the state as of the last time we
|
||||
@ -105,13 +153,25 @@ public:
|
||||
bool mInEffectForCascadeResults;
|
||||
|
||||
protected:
|
||||
virtual ~CSSAnimation() { }
|
||||
virtual ~CSSAnimation()
|
||||
{
|
||||
MOZ_ASSERT(!mOwningElement, "Owning element should be cleared before a "
|
||||
"CSS animation is destroyed");
|
||||
}
|
||||
virtual css::CommonAnimationManager* GetAnimationManager() const override;
|
||||
|
||||
static nsString PseudoTypeAsString(nsCSSPseudoElements::Type aPseudoType);
|
||||
|
||||
nsString mAnimationName;
|
||||
|
||||
// The (pseudo-)element whose computed animation-name refers to this
|
||||
// animation (if any).
|
||||
//
|
||||
// Raw pointer because this is only ever set when this object is part
|
||||
// of mOwningElement's AnimationCollection.
|
||||
dom::Element* MOZ_NON_OWNING_REF mOwningElement;
|
||||
nsCSSPseudoElements::Type mOwningPseudoType;
|
||||
|
||||
// When combining animation-play-state with play() / pause() the following
|
||||
// behavior applies:
|
||||
// 1. pause() is sticky and always overrides the underlying
|
||||
|
Loading…
Reference in New Issue
Block a user