Bug 1343753 - Part 7: Use template for UpdateTransitions and ConsiderInitiatingTransition. draft
authorBoris Chiou <boris.chiou@gmail.com>
Thu, 09 Mar 2017 15:37:17 +0800
changeset 561129 b84f9d1e1e511d9a2ea04f01cb1dc75e6916af39
parent 561128 7fe78acbe55c3b10204d1ffb5a9ff8c0244bc59e
child 561130 c15a8eea0d3619bef0b63a16811c6b7552e7deed
push id53643
push userbmo:boris.chiou@gmail.com
push dateWed, 12 Apr 2017 08:51:47 +0000
bugs1343753
milestone55.0a1
Bug 1343753 - Part 7: Use template for UpdateTransitions and ConsiderInitiatingTransition. We use the template to replace the type, nsStyleContext and ServoComputedValuesWithParent. MozReview-Commit-ID: JFPdODZAwX8
layout/style/nsTransitionManager.cpp
layout/style/nsTransitionManager.h
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -580,18 +580,22 @@ nsTransitionManager::StyleContextChanged
   }
 
   nsAutoAnimationMutationBatch mb(aElement->OwnerDoc());
 
   DebugOnly<bool> startedAny = false;
   // We don't have to update transitions if display:none, although we will
   // cancel them after restyling.
   if (!afterChangeStyle->IsInDisplayNoneSubtree()) {
-    startedAny = UpdateTransitions(disp, aElement, collection,
-                                   aOldStyleContext, afterChangeStyle);
+    startedAny = UpdateTransitions(disp,
+                                   aElement,
+                                   afterChangeStyle->GetPseudoType(),
+                                   collection,
+                                   aOldStyleContext,
+                                   afterChangeStyle.get());
   }
 
   MOZ_ASSERT(!startedAny || collection,
              "must have element transitions if we started any transitions");
 
   EffectCompositor::CascadeLevel cascadeLevel =
     EffectCompositor::CascadeLevel::Transitions;
 
@@ -611,23 +615,25 @@ nsTransitionManager::StyleContextChanged
     // manager's GetAnimationGeneration() will ensure that we don't go
     // through the rest of this function again when we do.
     mPresContext->EffectCompositor()->PostRestyleForAnimation(aElement,
                                                               pseudoType,
                                                               cascadeLevel);
   }
 }
 
+template<typename StyleType>
 bool
 nsTransitionManager::UpdateTransitions(
   const nsStyleDisplay* aDisp,
   dom::Element* aElement,
+  CSSPseudoElementType aPseudoType,
   CSSTransitionCollection*& aElementTransitions,
-  nsStyleContext* aOldStyleContext,
-  nsStyleContext* aNewStyleContext)
+  StyleType aOldStyle,
+  StyleType aNewStyle)
 {
   MOZ_ASSERT(aDisp, "Null nsStyleDisplay");
   MOZ_ASSERT(!aElementTransitions ||
              aElementTransitions->mElement == aElement, "Element mismatch");
 
   // Per http://lists.w3.org/Archives/Public/www-style/2009Aug/0109.html
   // I'll consider only the transitions from the number of items in
   // 'transition-property' on down, and later ones will override earlier
@@ -648,32 +654,34 @@ nsTransitionManager::UpdateTransitions(
       if (property == eCSSPropertyExtra_no_properties ||
           property == eCSSPropertyExtra_variable ||
           property == eCSSProperty_UNKNOWN) {
         // Nothing to do, but need to exclude this from cases below.
       } else if (property == eCSSPropertyExtra_all_properties) {
         for (nsCSSPropertyID p = nsCSSPropertyID(0);
              p < eCSSProperty_COUNT_no_shorthands;
              p = nsCSSPropertyID(p + 1)) {
-          ConsiderInitiatingTransition(p, t, aElement, aElementTransitions,
-                                       aOldStyleContext, aNewStyleContext,
+          ConsiderInitiatingTransition(p, t, aElement, aPseudoType,
+                                       aElementTransitions,
+                                       aOldStyle, aNewStyle,
                                        &startedAny, &whichStarted);
         }
       } else if (nsCSSProps::IsShorthand(property)) {
         CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(subprop, property,
                                              CSSEnabledState::eForAllContent)
         {
-          ConsiderInitiatingTransition(*subprop, t, aElement,
+          ConsiderInitiatingTransition(*subprop, t, aElement, aPseudoType,
                                        aElementTransitions,
-                                       aOldStyleContext, aNewStyleContext,
+                                       aOldStyle, aNewStyle,
                                        &startedAny, &whichStarted);
         }
       } else {
-        ConsiderInitiatingTransition(property, t, aElement, aElementTransitions,
-                                     aOldStyleContext, aNewStyleContext,
+        ConsiderInitiatingTransition(property, t, aElement, aPseudoType,
+                                     aElementTransitions,
+                                     aOldStyle, aNewStyle,
                                      &startedAny, &whichStarted);
       }
     }
   }
 
   // Stop any transitions for properties that are no longer in
   // 'transition-property', including finished transitions.
   // Also stop any transitions (and remove any finished transitions)
@@ -725,23 +733,22 @@ nsTransitionManager::UpdateTransitions(
       if ((checkProperties &&
            !allTransitionProperties.HasProperty(anim->TransitionProperty())) ||
           // properties whose computed values changed but for which we
           // did not start a new transition (because delay and
           // duration are both zero, or because the new value is not
           // interpolable); a new transition would have anim->ToValue()
           // matching currentValue
           !ExtractNonDiscreteComputedValue(anim->TransitionProperty(),
-                                           aNewStyleContext, currentValue) ||
+                                           aNewStyle, currentValue) ||
           currentValue != anim->ToValue()) {
         // stop the transition
         if (anim->HasCurrentEffect()) {
           EffectSet* effectSet =
-            EffectSet::GetEffectSet(aElement,
-                                    aNewStyleContext->GetPseudoType());
+            EffectSet::GetEffectSet(aElement, aPseudoType);
           if (effectSet) {
             effectSet->UpdateAnimationGeneration(mPresContext);
           }
         }
         anim->CancelFromStyle();
         animations.RemoveElementAt(i);
       }
     } while (i != 0);
@@ -794,24 +801,26 @@ GetTransitionKeyframes(nsCSSPropertyID a
     fromFrame.mTimingFunction->Init(aTimingFunction);
   }
 
   AppendKeyframe(1.0, aProperty, Move(aEndValue), keyframes);
 
   return keyframes;
 }
 
+template<typename StyleType>
 void
 nsTransitionManager::ConsiderInitiatingTransition(
   nsCSSPropertyID aProperty,
   const StyleTransition& aTransition,
   dom::Element* aElement,
+  CSSPseudoElementType aPseudoType,
   CSSTransitionCollection*& aElementTransitions,
-  nsStyleContext* aOldStyleContext,
-  nsStyleContext* aNewStyleContext,
+  StyleType aOldStyle,
+  StyleType aNewStyle,
   bool* aStartedAny,
   nsCSSPropertyIDSet* aWhichStarted)
 {
   // IsShorthand itself will assert if aProperty is not a property.
   MOZ_ASSERT(!nsCSSProps::IsShorthand(aProperty),
              "property out of range");
   NS_ASSERTION(!aElementTransitions ||
                aElementTransitions->mElement == aElement, "Element mismatch");
@@ -834,18 +843,18 @@ nsTransitionManager::ConsiderInitiatingT
   if (nsCSSProps::kAnimTypeTable[aProperty] == eStyleAnimType_None) {
     return;
   }
 
   dom::DocumentTimeline* timeline = aElement->OwnerDoc()->Timeline();
 
   AnimationValue startValue, endValue;
   bool haveValues =
-    ExtractNonDiscreteComputedValue(aProperty, aOldStyleContext, startValue) &&
-    ExtractNonDiscreteComputedValue(aProperty, aNewStyleContext, endValue);
+    ExtractNonDiscreteComputedValue(aProperty, aOldStyle, startValue) &&
+    ExtractNonDiscreteComputedValue(aProperty, aNewStyle, endValue);
 
   bool haveChange = startValue != endValue;
 
   bool shouldAnimate =
     haveValues &&
     haveChange &&
     startValue.IsInterpolableWith(aProperty, endValue);
 
@@ -894,18 +903,17 @@ nsTransitionManager::ConsiderInitiatingT
       // in-progress value (which is particularly easy to cause when we're
       // currently in the 'transition-delay').  It also might happen because we
       // just got a style change to a value that can't be interpolated.
       OwningCSSTransitionPtrArray& animations =
         aElementTransitions->mAnimations;
       animations[currentIndex]->CancelFromStyle();
       oldPT = nullptr; // Clear pointer so it doesn't dangle
       animations.RemoveElementAt(currentIndex);
-      EffectSet* effectSet =
-        EffectSet::GetEffectSet(aElement, aNewStyleContext->GetPseudoType());
+      EffectSet* effectSet = EffectSet::GetEffectSet(aElement, aPseudoType);
       if (effectSet) {
         effectSet->UpdateAnimationGeneration(mPresContext);
       }
 
       if (animations.IsEmpty()) {
         aElementTransitions->Destroy();
         // |aElementTransitions| is now a dangling pointer!
         aElementTransitions = nullptr;
@@ -972,46 +980,41 @@ nsTransitionManager::ConsiderInitiatingT
   TimingParams timing =
     TimingParamsFromCSSParams(duration, delay,
                               1.0 /* iteration count */,
                               dom::PlaybackDirection::Normal,
                               dom::FillMode::Backwards);
 
   // aElement is non-null here, so we emplace it directly.
   Maybe<OwningAnimationTarget> target;
-  target.emplace(aElement, aNewStyleContext->GetPseudoType());
+  target.emplace(aElement, aPseudoType);
   KeyframeEffectParams effectOptions;
   RefPtr<ElementPropertyTransition> pt =
     new ElementPropertyTransition(aElement->OwnerDoc(), target, timing,
                                   startForReversingTest, reversePortion,
                                   effectOptions);
 
   pt->SetKeyframes(GetTransitionKeyframes(aProperty,
                                           Move(startValue), Move(endValue), tf),
-                   aNewStyleContext);
-
-  MOZ_ASSERT(mPresContext->RestyleManager()->IsGecko(),
-             "ServoRestyleManager should not use nsTransitionManager "
-             "for transitions");
+                   aNewStyle);
 
   RefPtr<CSSTransition> animation =
     new CSSTransition(mPresContext->Document()->GetScopeObject());
-  animation->SetOwningElement(
-    OwningElementRef(*aElement, aNewStyleContext->GetPseudoType()));
+  animation->SetOwningElement(OwningElementRef(*aElement, aPseudoType));
   animation->SetTimelineNoUpdate(timeline);
   animation->SetCreationSequence(
     mPresContext->RestyleManager()->GetAnimationGeneration());
   animation->SetEffectFromStyle(pt);
   animation->PlayFromStyle();
 
   if (!aElementTransitions) {
     bool createdCollection = false;
     aElementTransitions =
       CSSTransitionCollection::GetOrCreateAnimationCollection(
-        aElement, aNewStyleContext->GetPseudoType(), &createdCollection);
+        aElement, aPseudoType, &createdCollection);
     if (!aElementTransitions) {
       MOZ_ASSERT(!createdCollection, "outparam should agree with return value");
       NS_WARNING("allocating collection failed");
       return;
     }
 
     if (createdCollection) {
       AddElementCollection(aElementTransitions);
@@ -1056,18 +1059,17 @@ nsTransitionManager::ConsiderInitiatingT
     animations[currentIndex] = animation;
   } else {
     if (!animations.AppendElement(animation)) {
       NS_WARNING("out of memory");
       return;
     }
   }
 
-  EffectSet* effectSet =
-    EffectSet::GetEffectSet(aElement, aNewStyleContext->GetPseudoType());
+  EffectSet* effectSet = EffectSet::GetEffectSet(aElement, aPseudoType);
   if (effectSet) {
     effectSet->UpdateAnimationGeneration(mPresContext);
   }
 
   *aStartedAny = true;
   aWhichStarted->AddProperty(aProperty);
 }
 
--- a/layout/style/nsTransitionManager.h
+++ b/layout/style/nsTransitionManager.h
@@ -410,30 +410,32 @@ protected:
 
   typedef nsTArray<RefPtr<mozilla::dom::CSSTransition>>
     OwningCSSTransitionPtrArray;
 
   // Update the transitions. It'd start new, replace, or stop current
   // transitions if need. aDisp and aElement shouldn't be nullptr.
   // aElementTransitions is the collection of current transitions, and it
   // could be a nullptr if we don't have any transitions.
-  bool
+  template<typename StyleType> bool
   UpdateTransitions(const nsStyleDisplay* aDisp,
                     mozilla::dom::Element* aElement,
+                    mozilla::CSSPseudoElementType aPseudoType,
                     CSSTransitionCollection*& aElementTransitions,
-                    nsStyleContext* aOldStyleContext,
-                    nsStyleContext* aNewStyleContext);
+                    StyleType aOldStyle,
+                    StyleType aNewStyle);
 
-  void
+  template<typename StyleType> void
   ConsiderInitiatingTransition(nsCSSPropertyID aProperty,
                                const mozilla::StyleTransition& aTransition,
                                mozilla::dom::Element* aElement,
+                               mozilla::CSSPseudoElementType aPseudoType,
                                CSSTransitionCollection*& aElementTransitions,
-                               nsStyleContext* aOldStyleContext,
-                               nsStyleContext* aNewStyleContext,
+                               StyleType aOldStyle,
+                               StyleType aNewStyle,
                                bool* aStartedAny,
                                nsCSSPropertyIDSet* aWhichStarted);
 
   bool mInAnimationOnlyStyleUpdate;
 
   mozilla::DelayedEventDispatcher<mozilla::TransitionEventInfo>
       mEventDispatcher;
 };