Bug 1260976 - Make nsTransitionManager use Keyframe objects to set up transitions; r?heycam
MozReview-Commit-ID: KHqoMELYyzQ
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -58,23 +58,20 @@ ElementPropertyTransition::CurrentValueP
// case, we override the fill mode to 'both' to ensure the progress
// is never null.
TimingParams timingToUse = SpecifiedTiming();
timingToUse.mFill = dom::FillMode::Both;
ComputedTiming computedTiming = GetComputedTiming(&timingToUse);
MOZ_ASSERT(!computedTiming.mProgress.IsNull(),
"Got a null progress for a fill mode of 'both'");
- MOZ_ASSERT(mProperties.Length() == 1,
- "Should have one animation property for a transition");
- MOZ_ASSERT(mProperties[0].mSegments.Length() == 1,
- "Animation property should have one segment for a transition");
- return ComputedTimingFunction::GetPortion(
- mProperties[0].mSegments[0].mTimingFunction,
- computedTiming.mProgress.Value());
+ MOZ_ASSERT(mFrames.Length() == 2,
+ "Should have two animation frames for a transition");
+ return ComputedTimingFunction::GetPortion(mFrames[0].mTimingFunction,
+ computedTiming.mProgress.Value());
}
////////////////////////// CSSTransition ////////////////////////////
JSObject*
CSSTransition::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return dom::CSSTransitionBinding::Wrap(aCx, this, aGivenProto);
@@ -662,29 +659,19 @@ nsTransitionManager::ConsiderStartingTra
timing.mDirection = dom::PlaybackDirection::Normal;
timing.mFill = dom::FillMode::Backwards;
RefPtr<ElementPropertyTransition> pt =
new ElementPropertyTransition(aElement->OwnerDoc(), aElement,
aNewStyleContext->GetPseudoType(), timing,
startForReversingTest, reversePortion);
- AnimationProperty& prop = *pt->Properties().AppendElement();
- prop.mProperty = aProperty;
-
- AnimationPropertySegment& segment = *prop.mSegments.AppendElement();
- segment.mFromValue = startValue;
- segment.mToValue = endValue;
- segment.mFromKey = 0;
- segment.mToKey = 1;
- if (tf.mType != nsTimingFunction::Type::Linear) {
- ComputedTimingFunction computedTimingFunction;
- computedTimingFunction.Init(tf);
- segment.mTimingFunction = Some(computedTimingFunction);
- }
+ pt->SetFrames(GetTransitionKeyframes(aNewStyleContext, aProperty,
+ Move(startValue), Move(endValue), tf),
+ aNewStyleContext);
MOZ_ASSERT(mPresContext->RestyleManager()->IsGecko(),
"ServoRestyleManager should not use nsTransitionManager "
"for transitions");
RefPtr<CSSTransition> animation =
new CSSTransition(mPresContext->Document()->GetScopeObject());
animation->SetOwningElement(
@@ -742,16 +729,57 @@ nsTransitionManager::ConsiderStartingTra
if (effectSet) {
effectSet->UpdateAnimationGeneration(mPresContext);
}
*aStartedAny = true;
aWhichStarted->AddProperty(aProperty);
}
+nsTArray<Keyframe>
+nsTransitionManager::GetTransitionKeyframes(
+ nsStyleContext* aStyleContext,
+ nsCSSProperty aProperty,
+ StyleAnimationValue&& aStartValue,
+ StyleAnimationValue&& aEndValue,
+ const nsTimingFunction& aTimingFunction)
+{
+ nsTArray<Keyframe> keyframes(2);
+
+ {
+ Keyframe& fromFrame = *keyframes.AppendElement();
+ fromFrame.mOffset.emplace(0.0);
+ PropertyValuePair& pv = *fromFrame.mPropertyValues.AppendElement();
+ pv.mProperty = aProperty;
+ DebugOnly<bool> uncomputeResult =
+ StyleAnimationValue::UncomputeValue(aProperty, Move(aStartValue),
+ pv.mValue);
+ MOZ_ASSERT(uncomputeResult,
+ "Unable to get specified value from computed from value");
+ if (aTimingFunction.mType != nsTimingFunction::Type::Linear) {
+ fromFrame.mTimingFunction.emplace();
+ fromFrame.mTimingFunction->Init(aTimingFunction);
+ }
+ }
+
+ {
+ Keyframe& toFrame = *keyframes.AppendElement();
+ toFrame.mOffset.emplace(1.0);
+ PropertyValuePair& pv = *toFrame.mPropertyValues.AppendElement();
+ pv.mProperty = aProperty;
+ DebugOnly<bool> uncomputeResult =
+ StyleAnimationValue::UncomputeValue(aProperty, Move(aEndValue),
+ pv.mValue);
+ MOZ_ASSERT(uncomputeResult,
+ "Unable to get specified value from computed to value");
+ }
+
+ return keyframes;
+}
+
void
nsTransitionManager::PruneCompletedTransitions(mozilla::dom::Element* aElement,
CSSPseudoElementType aPseudoType,
nsStyleContext* aNewStyleContext)
{
CSSTransitionCollection* collection =
CSSTransitionCollection::GetAnimationCollection(aElement, aPseudoType);
if (!collection) {
--- a/layout/style/nsTransitionManager.h
+++ b/layout/style/nsTransitionManager.h
@@ -18,16 +18,17 @@
class nsIGlobalObject;
class nsStyleContext;
class nsPresContext;
class nsCSSPropertySet;
namespace mozilla {
enum class CSSPseudoElementType : uint8_t;
+struct Keyframe;
struct StyleTransition;
} // namespace mozilla
/*****************************************************************************
* Per-Element data *
*****************************************************************************/
namespace mozilla {
@@ -350,15 +351,22 @@ protected:
const mozilla::StyleTransition& aTransition,
mozilla::dom::Element* aElement,
CSSTransitionCollection*& aElementTransitions,
nsStyleContext* aOldStyleContext,
nsStyleContext* aNewStyleContext,
bool* aStartedAny,
nsCSSPropertySet* aWhichStarted);
+ nsTArray<mozilla::Keyframe> GetTransitionKeyframes(
+ nsStyleContext* aStyleContext,
+ nsCSSProperty aProperty,
+ mozilla::StyleAnimationValue&& aStartValue,
+ mozilla::StyleAnimationValue&& aEndValue,
+ const nsTimingFunction& aTimingFunction);
+
bool mInAnimationOnlyStyleUpdate;
mozilla::DelayedEventDispatcher<mozilla::TransitionEventInfo>
mEventDispatcher;
};
#endif /* !defined(nsTransitionManager_h_) */