Bug 1340322 - Part 1: Split CSSAnimationBuilder::Build off as a static function. r?birtles draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Mon, 06 Mar 2017 09:46:40 +0900
changeset 493772 c44ea1d2ebe64b40c8d7f46952916e39624c10c0
parent 493721 8d026c60151005ad942e3d4389318fe28a0c8c54
child 493773 846dbf9f284cd19f1e43119a0b8dd5825c391801
push id47837
push userhikezoe@mozilla.com
push dateMon, 06 Mar 2017 01:11:14 +0000
reviewersbirtles
bugs1340322
milestone54.0a1
Bug 1340322 - Part 1: Split CSSAnimationBuilder::Build off as a static function. r?birtles The static function will be a template function that can be used with servo's computed values as well. MozReview-Commit-ID: DgLTQ8ihPod
layout/style/nsAnimationManager.cpp
--- a/layout/style/nsAnimationManager.cpp
+++ b/layout/style/nsAnimationManager.cpp
@@ -528,38 +528,28 @@ ResolvedStyleCache::Get(nsPresContext *a
     result = resultStrong;
   }
   return result;
 }
 
 class MOZ_STACK_CLASS CSSAnimationBuilder final {
 public:
   CSSAnimationBuilder(nsStyleContext* aStyleContext,
-                      dom::Element* aTarget,
-                      nsAnimationManager::CSSAnimationCollection* aCollection)
+                      dom::Element* aTarget)
     : mStyleContext(aStyleContext)
     , mTarget(aTarget)
-    , mCollection(aCollection)
   {
     MOZ_ASSERT(aStyleContext);
     MOZ_ASSERT(aTarget);
-    mTimeline = mTarget->OwnerDoc()->Timeline();
   }
 
-  // Returns a new animation set up with given StyleAnimation.
-  // Or returns an existing animation matching StyleAnimation's name updated
-  // with the new StyleAnimation.
-  already_AddRefed<CSSAnimation>
-  Build(nsPresContext* aPresContext,
-        const StyleAnimation& aSrc);
-
-private:
   nsTArray<Keyframe> BuildAnimationFrames(nsPresContext* aPresContext,
                                           const StyleAnimation& aSrc,
                                           const nsCSSKeyframesRule* aRule);
+private:
   Maybe<ComputedTimingFunction> GetKeyframeTimingFunction(
     nsPresContext* aPresContext,
     nsCSSKeyframeRule* aKeyframeRule,
     const Maybe<ComputedTimingFunction>& aInheritedTimingFunction);
   nsTArray<PropertyValuePair> GetKeyframePropertyValues(
     nsPresContext* aPresContext,
     nsCSSKeyframeRule* aKeyframeRule,
     nsCSSPropertyIDSet& aAnimatedProperties);
@@ -571,111 +561,110 @@ private:
     const Maybe<ComputedTimingFunction>& aInheritedTimingFunction,
     nsTArray<Keyframe>& aKeyframes);
   void AppendProperty(nsPresContext* aPresContext,
                       nsCSSPropertyID aProperty,
                       nsTArray<PropertyValuePair>& aPropertyValues);
   nsCSSValue GetComputedValue(nsPresContext* aPresContext,
                               nsCSSPropertyID aProperty);
 
-  static TimingParams TimingParamsFrom(const StyleAnimation& aStyleAnimation)
-  {
-    return TimingParamsFromCSSParams(aStyleAnimation.GetDuration(),
-                                     aStyleAnimation.GetDelay(),
-                                     aStyleAnimation.GetIterationCount(),
-                                     aStyleAnimation.GetDirection(),
-                                     aStyleAnimation.GetFillMode());
-  }
-
   RefPtr<nsStyleContext> mStyleContext;
   RefPtr<dom::Element> mTarget;
-  RefPtr<dom::DocumentTimeline> mTimeline;
 
   ResolvedStyleCache mResolvedStyles;
   RefPtr<nsStyleContext> mStyleWithoutAnimation;
-  // Existing collection, nullptr if the target element has no animations.
-  nsAnimationManager::CSSAnimationCollection* mCollection;
 };
 
 static Maybe<ComputedTimingFunction>
 ConvertTimingFunction(const nsTimingFunction& aTimingFunction);
 
-already_AddRefed<CSSAnimation>
-CSSAnimationBuilder::Build(nsPresContext* aPresContext,
-                           const StyleAnimation& aSrc)
+// Returns a new animation set up with given StyleAnimation.
+// Or returns an existing animation matching StyleAnimation's name updated
+// with the new StyleAnimation.
+static already_AddRefed<CSSAnimation>
+BuildAnimation(nsPresContext* aPresContext,
+               nsStyleContext* aStyleContext,
+               dom::Element* aTarget,
+               const StyleAnimation& aSrc,
+               CSSAnimationBuilder& aBuilder,
+               nsAnimationManager::CSSAnimationCollection* aCollection)
 {
   MOZ_ASSERT(aPresContext);
 
   nsTArray<Keyframe> keyframes;
   if (aPresContext->StyleSet()->IsServo()) {
     ServoStyleSet* styleSet = aPresContext->StyleSet()->AsServo();
     MOZ_ASSERT(styleSet);
     const ServoComputedValues* computedValues =
-      mStyleContext->StyleSource().AsServoComputedValues();
+      aStyleContext->StyleSource().AsServoComputedValues();
     const nsTimingFunction& timingFunction = aSrc.GetTimingFunction();
     if (!styleSet->FillKeyframesForName(aSrc.GetName(),
                                         timingFunction,
                                         computedValues,
                                         keyframes)) {
       return nullptr;
     }
   } else {
     nsCSSKeyframesRule* rule =
       aPresContext->StyleSet()->AsGecko()->KeyframesRuleForName(aSrc.GetName());
     if (!rule) {
       return nullptr;
     }
 
-    keyframes = BuildAnimationFrames(aPresContext, aSrc, rule);
+    keyframes = aBuilder.BuildAnimationFrames(aPresContext, aSrc, rule);
   }
 
-  TimingParams timing = TimingParamsFrom(aSrc);
+  TimingParams timing = TimingParamsFromCSSParams(aSrc.GetDuration(),
+                                                  aSrc.GetDelay(),
+                                                  aSrc.GetIterationCount(),
+                                                  aSrc.GetDirection(),
+                                                  aSrc.GetFillMode());
 
   bool isStylePaused =
     aSrc.GetPlayState() == NS_STYLE_ANIMATION_PLAY_STATE_PAUSED;
 
   // Find the matching animation with animation name in the old list
   // of animations and remove the matched animation from the list.
   RefPtr<CSSAnimation> oldAnim =
-    PopExistingAnimation(aSrc.GetName(), mCollection);
+    PopExistingAnimation(aSrc.GetName(), aCollection);
 
   if (oldAnim) {
     // Copy over the start times and (if still paused) pause starts
     // for each animation (matching on name only) that was also in the
     // old list of animations.
     // This means that we honor dynamic changes, which isn't what the
     // spec says to do, but WebKit seems to honor at least some of
     // them.  See
     // http://lists.w3.org/Archives/Public/www-style/2011Apr/0079.html
     // In order to honor what the spec said, we'd copy more data over.
     UpdateOldAnimationPropertiesWithNew(*oldAnim,
                                         timing,
                                         Move(keyframes),
                                         isStylePaused,
-                                        mStyleContext);
+                                        aStyleContext);
     return oldAnim.forget();
   }
 
   // mTarget is non-null here, so we emplace it directly.
   Maybe<OwningAnimationTarget> target;
-  target.emplace(mTarget, mStyleContext->GetPseudoType());
+  target.emplace(aTarget, aStyleContext->GetPseudoType());
   KeyframeEffectParams effectOptions;
   RefPtr<KeyframeEffectReadOnly> effect =
     new KeyframeEffectReadOnly(aPresContext->Document(), target, timing,
                                effectOptions);
 
-  effect->SetKeyframes(Move(keyframes), mStyleContext);
+  effect->SetKeyframes(Move(keyframes), aStyleContext);
 
   RefPtr<CSSAnimation> animation =
     new CSSAnimation(aPresContext->Document()->GetScopeObject(),
                      aSrc.GetName());
   animation->SetOwningElement(
-    OwningElementRef(*mTarget, mStyleContext->GetPseudoType()));
+    OwningElementRef(*aTarget, aStyleContext->GetPseudoType()));
 
-  animation->SetTimelineNoUpdate(mTimeline);
+  animation->SetTimelineNoUpdate(aTarget->OwnerDoc()->Timeline());
   animation->SetEffectNoUpdate(effect);
 
   if (isStylePaused) {
     animation->PauseFromStyle();
   } else {
     animation->PlayFromStyle();
   }
 
@@ -1087,32 +1076,36 @@ nsAnimationManager::BuildAnimations(nsSt
                                     dom::Element* aTarget,
                                     CSSAnimationCollection* aCollection,
                                     OwningCSSAnimationPtrArray& aAnimations)
 {
   MOZ_ASSERT(aAnimations.IsEmpty(), "expect empty array");
 
   const nsStyleDisplay *disp = aStyleContext->StyleDisplay();
 
-  CSSAnimationBuilder builder(aStyleContext, aTarget, aCollection);
+  CSSAnimationBuilder builder(aStyleContext, aTarget);
 
   for (size_t animIdx = disp->mAnimationNameCount; animIdx-- != 0;) {
     const StyleAnimation& src = disp->mAnimations[animIdx];
 
     // CSS Animations whose animation-name does not match a @keyframes rule do
     // not generate animation events. This includes when the animation-name is
     // "none" which is represented by an empty name in the StyleAnimation.
     // Since such animations neither affect style nor dispatch events, we do
     // not generate a corresponding CSSAnimation for them.
     if (src.GetName().IsEmpty()) {
       continue;
     }
 
-    RefPtr<CSSAnimation> dest =
-      builder.Build(mPresContext, src);
+    RefPtr<CSSAnimation> dest = BuildAnimation(mPresContext,
+                                               aStyleContext,
+                                               aTarget,
+                                               src,
+                                               builder,
+                                               aCollection);
     if (!dest) {
       continue;
     }
 
     dest->SetAnimationIndex(static_cast<uint64_t>(animIdx));
     aAnimations.AppendElement(dest);
   }
 }