Backed out 8 changesets (bug 1873776) for causing vendor failures. CLOSED TREE
[gecko.git] / dom / animation / CSSTransition.h
blobb2a76d34164ccd0516025fb700b9ee88ac652d07
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_CSSTransition_h
8 #define mozilla_dom_CSSTransition_h
10 #include "mozilla/ComputedTiming.h"
11 #include "mozilla/dom/Animation.h"
12 #include "mozilla/AnimatedPropertyID.h"
13 #include "mozilla/StyleAnimationValue.h"
14 #include "AnimationCommon.h"
16 class nsIGlobalObject;
18 namespace mozilla {
19 namespace dom {
21 class CSSTransition final : public Animation {
22 public:
23 explicit CSSTransition(nsIGlobalObject* aGlobal,
24 const AnimatedPropertyID& aProperty)
25 : Animation(aGlobal),
26 mPreviousTransitionPhase(TransitionPhase::Idle),
27 mNeedsNewAnimationIndexWhenRun(false),
28 mTransitionProperty(aProperty) {}
30 JSObject* WrapObject(JSContext* aCx,
31 JS::Handle<JSObject*> aGivenProto) override;
33 CSSTransition* AsCSSTransition() override { return this; }
34 const CSSTransition* AsCSSTransition() const override { return this; }
36 // CSSTransition interface
37 void GetTransitionProperty(nsString& aRetVal) const;
39 // Animation interface overrides
40 AnimationPlayState PlayStateFromJS() const override;
41 bool PendingFromJS() const override;
42 void PlayFromJS(ErrorResult& aRv) override;
44 // A variant of Play() that avoids posting style updates since this method
45 // is expected to be called whilst already updating style.
46 void PlayFromStyle() {
47 ErrorResult rv;
48 PlayNoUpdate(rv, Animation::LimitBehavior::Continue);
49 // play() should not throw when LimitBehavior is Continue
50 MOZ_ASSERT(!rv.Failed(), "Unexpected exception playing transition");
53 void CancelFromStyle(PostRestyleMode aPostRestyle) {
54 // The animation index to use for compositing will be established when
55 // this transition next transitions out of the idle state but we still
56 // update it now so that the sort order of this transition remains
57 // defined until that moment.
59 // See longer explanation in CSSAnimation::CancelFromStyle.
60 mAnimationIndex = sNextAnimationIndex++;
61 mNeedsNewAnimationIndexWhenRun = true;
63 Animation::Cancel(aPostRestyle);
65 // It is important we do this *after* calling Cancel().
66 // This is because Cancel() will end up posting a restyle and
67 // that restyle should target the *transitions* level of the cascade.
68 // However, once we clear the owning element, CascadeLevel() will begin
69 // returning CascadeLevel::Animations.
70 mOwningElement = OwningElementRef();
73 void SetEffectFromStyle(KeyframeEffect*);
75 void Tick(TickState&) override;
77 const AnimatedPropertyID& TransitionProperty() const;
78 AnimationValue ToValue() const;
80 bool HasLowerCompositeOrderThan(const CSSTransition& aOther) const;
81 EffectCompositor::CascadeLevel CascadeLevel() const override {
82 return IsTiedToMarkup() ? EffectCompositor::CascadeLevel::Transitions
83 : EffectCompositor::CascadeLevel::Animations;
86 void SetCreationSequence(uint64_t aIndex) {
87 MOZ_ASSERT(IsTiedToMarkup());
88 mAnimationIndex = aIndex;
91 // Sets the owning element which is used for determining the composite
92 // oder of CSSTransition objects generated from CSS markup.
94 // @see mOwningElement
95 void SetOwningElement(const OwningElementRef& aElement) {
96 mOwningElement = aElement;
98 // True for transitions that are generated from CSS markup and continue to
99 // reflect changes to that markup.
100 bool IsTiedToMarkup() const { return mOwningElement.IsSet(); }
102 // Return the animation current time based on a given TimeStamp, a given
103 // start time and a given playbackRate on a given timeline. This is useful
104 // when we estimate the current animated value running on the compositor
105 // because the animation on the compositor may be running ahead while
106 // main-thread is busy.
107 static Nullable<TimeDuration> GetCurrentTimeAt(
108 const AnimationTimeline& aTimeline, const TimeStamp& aBaseTime,
109 const TimeDuration& aStartTime, double aPlaybackRate);
111 void MaybeQueueCancelEvent(const StickyTimeDuration& aActiveTime) override {
112 QueueEvents(aActiveTime);
115 // Compute the portion of the *value* space that we should be through
116 // at the current time. (The input to the transition timing function
117 // has time units, the output has value units.)
118 double CurrentValuePortion() const;
120 const AnimationValue& StartForReversingTest() const {
121 return mStartForReversingTest;
123 double ReversePortion() const { return mReversePortion; }
125 void SetReverseParameters(AnimationValue&& aStartForReversingTest,
126 double aReversePortion) {
127 mStartForReversingTest = std::move(aStartForReversingTest);
128 mReversePortion = aReversePortion;
131 struct ReplacedTransitionProperties {
132 TimeDuration mStartTime;
133 double mPlaybackRate;
134 TimingParams mTiming;
135 Maybe<StyleComputedTimingFunction> mTimingFunction;
136 AnimationValue mFromValue, mToValue;
138 void SetReplacedTransition(
139 ReplacedTransitionProperties&& aReplacedTransition) {
140 mReplacedTransition.emplace(std::move(aReplacedTransition));
143 // For a new transition interrupting an existing transition on the
144 // compositor, update the start value to match the value of the replaced
145 // transitions at the current time.
146 void UpdateStartValueFromReplacedTransition();
148 protected:
149 virtual ~CSSTransition() {
150 MOZ_ASSERT(!mOwningElement.IsSet(),
151 "Owning element should be cleared "
152 "before a CSS transition is destroyed");
155 // Animation overrides
156 void UpdateTiming(SeekFlag aSeekFlag,
157 SyncNotifyFlag aSyncNotifyFlag) override;
159 void QueueEvents(const StickyTimeDuration& activeTime = StickyTimeDuration());
161 enum class TransitionPhase;
163 // The (pseudo-)element whose computed transition-property refers to this
164 // transition (if any).
166 // This is used for determining the relative composite order of transitions
167 // generated from CSS markup.
169 // Typically this will be the same as the target element of the keyframe
170 // effect associated with this transition. However, it can differ in the
171 // following circumstances:
173 // a) If script removes or replaces the effect of this transition,
174 // b) If this transition is cancelled (e.g. by updating the
175 // transition-property or removing the owning element from the document),
176 // c) If this object is generated from script using the CSSTransition
177 // constructor.
179 // For (b) and (c) the owning element will return !IsSet().
180 OwningElementRef mOwningElement;
182 // The 'transition phase' used to determine which transition events need
183 // to be queued on this tick.
184 // See: https://drafts.csswg.org/css-transitions-2/#transition-phase
185 enum class TransitionPhase {
186 Idle = static_cast<int>(ComputedTiming::AnimationPhase::Idle),
187 Before = static_cast<int>(ComputedTiming::AnimationPhase::Before),
188 Active = static_cast<int>(ComputedTiming::AnimationPhase::Active),
189 After = static_cast<int>(ComputedTiming::AnimationPhase::After),
190 Pending
192 TransitionPhase mPreviousTransitionPhase;
194 // When true, indicates that when this transition next leaves the idle state,
195 // its animation index should be updated.
196 bool mNeedsNewAnimationIndexWhenRun;
198 // Store the transition property and to-value here since we need that
199 // information in order to determine if there is an existing transition
200 // for a given style change. We can't store that information on the
201 // effect however since it can be replaced using the Web Animations API.
202 AnimatedPropertyID mTransitionProperty;
203 AnimationValue mTransitionToValue;
205 // This is the start value to be used for a check for whether a
206 // transition is being reversed. Normally the same as
207 // mEffect->mProperties[0].mSegments[0].mFromValue, except when this
208 // transition started as the reversal of another in-progress transition
209 // or when the effect has been mutated using the Web Animations API.
211 // Needed so we can handle two reverses in a row.
212 AnimationValue mStartForReversingTest;
214 // Likewise, the portion (in value space) of the "full" reversed
215 // transition that we're actually covering. For example, if a :hover
216 // effect has a transition that moves the element 10px to the right
217 // (by changing 'left' from 0px to 10px), and the mouse moves in to
218 // the element (starting the transition) but then moves out after the
219 // transition has advanced 4px, the second transition (from 10px/4px
220 // to 0px) will have mReversePortion of 0.4. (If the mouse then moves
221 // in again when the transition is back to 2px, the mReversePortion
222 // for the third transition (from 0px/2px to 10px) will be 0.8.
223 double mReversePortion = 1.0;
225 Maybe<ReplacedTransitionProperties> mReplacedTransition;
228 } // namespace dom
230 } // namespace mozilla
232 #endif // mozilla_dom_CSSTransition_h