Bug 1349004 part 2 - Call UpdateProperties with ServoComputedValuesWithParent. r?hiro draft
authorMantaroh Yoshinaga <mantaroh@gmail.com>
Thu, 11 May 2017 15:36:58 +0900
changeset 576011 fafbcc81641a098a76ddc4f73eb0ff43703f6fa6
parent 576010 f7c8ddb2882726867f254c94d6a2e4651e0d57e6
child 576012 db125c7883d2cf97456ed219ab812fd93017bbdb
push id58237
push usermantaroh@gmail.com
push dateThu, 11 May 2017 06:37:20 +0000
reviewershiro
bugs1349004
milestone55.0a1
Bug 1349004 part 2 - Call UpdateProperties with ServoComputedValuesWithParent. r?hiro MozReview-Commit-ID: 33L8omLOAar
dom/animation/KeyframeEffect.cpp
dom/animation/KeyframeEffect.h
dom/animation/KeyframeEffectReadOnly.cpp
dom/animation/KeyframeEffectReadOnly.h
--- a/dom/animation/KeyframeEffect.cpp
+++ b/dom/animation/KeyframeEffect.cpp
@@ -6,16 +6,17 @@
 
 #include "mozilla/dom/KeyframeEffect.h"
 
 #include "mozilla/dom/KeyframeAnimationOptionsBinding.h"
   // For UnrestrictedDoubleOrKeyframeAnimationOptions
 #include "mozilla/dom/AnimationEffectTiming.h"
 #include "mozilla/dom/KeyframeEffectBinding.h"
 #include "mozilla/KeyframeUtils.h"
+#include "mozilla/ServoComputedValuesWithParent.h"
 #include "nsDOMMutationObserver.h" // For nsAutoAnimationMutationBatch
 #include "nsIScriptError.h"
 
 namespace mozilla {
 namespace dom {
 
 KeyframeEffect::KeyframeEffect(nsIDocument* aDocument,
                                const Maybe<OwningAnimationTarget>& aTarget,
@@ -105,22 +106,17 @@ KeyframeEffect::SetTarget(const Nullable
       nsNodeUtils::AnimationRemoved(mAnimation);
     }
   }
 
   mTarget = newTarget;
 
   if (mTarget) {
     UpdateTargetRegistration();
-    RefPtr<nsStyleContext> styleContext = GetTargetStyleContext();
-    if (styleContext) {
-      UpdateProperties(styleContext);
-    } else if (mEffectOptions.mSpacingMode == SpacingMode::paced) {
-      KeyframeUtils::ApplyDistributeSpacing(mKeyframes);
-    }
+    UpdatePropertiesFromCurrentStyle();
 
     MaybeUpdateFrameForCompositor();
 
     RequestRestyle(EffectCompositor::RestyleType::Layer);
 
     nsAutoAnimationMutationBatch mb(mTarget->mElement->OwnerDoc());
     if (mAnimation) {
       nsNodeUtils::AnimationAdded(mAnimation);
@@ -168,20 +164,17 @@ KeyframeEffect::SetComposite(const Compo
 
   mEffectOptions.mComposite = aComposite;
 
   if (mAnimation && mAnimation->IsRelevant()) {
     nsNodeUtils::AnimationChanged(mAnimation);
   }
 
   if (mTarget) {
-    RefPtr<nsStyleContext> styleContext = GetTargetStyleContext();
-    if (styleContext) {
-      UpdateProperties(styleContext);
-    }
+    UpdatePropertiesFromCurrentStyle();
   }
 }
 
 void
 KeyframeEffect::SetSpacing(JSContext* aCx,
                            const nsAString& aSpacing,
                            CallerType aCallerType,
                            ErrorResult& aRv)
@@ -224,16 +217,42 @@ KeyframeEffect::SetSpacing(JSContext* aC
     KeyframeUtils::ApplyDistributeSpacing(mKeyframes);
   }
 
   if (mAnimation && mAnimation->IsRelevant()) {
     nsNodeUtils::AnimationChanged(mAnimation);
   }
 
   if (mTarget) {
+    UpdatePropertiesFromCurrentStyle();
+  }
+}
+
+void
+KeyframeEffect::UpdatePropertiesFromCurrentStyle()
+{
+  MOZ_ASSERT(mTarget);
+
+  if (mDocument->IsStyledByServo()) {
+    nsPresContext* presContext =
+      nsContentUtils::GetContextForContent(mTarget->mElement);
+    if (!presContext) {
+      // If we don't have presContext(e.g. The target element don't belong with
+      // any document), we will not need to call UpdateProperties.
+      return;
+    }
+
+    RefPtr<ServoComputedValues> currentValue =
+      GetCurrentServoComputedValues(presContext);
+    RefPtr<ServoComputedValues> parentValue =
+      GetParentServoComputedValues(presContext);
+
+    const ServoComputedValuesWithParent value = { currentValue, parentValue };
+    UpdateProperties(value);
+  } else {
     RefPtr<nsStyleContext> styleContext = GetTargetStyleContext();
     if (styleContext) {
       UpdateProperties(styleContext);
     }
   }
 }
 
 } // namespace dom
--- a/dom/animation/KeyframeEffect.h
+++ b/dom/animation/KeyframeEffect.h
@@ -81,14 +81,17 @@ public:
   IterationCompositeOperation IterationComposite(CallerType aCallerType)
   {
     return KeyframeEffectReadOnly::IterationComposite();
   }
   void SetIterationComposite(
     const IterationCompositeOperation& aIterationComposite,
     CallerType aCallerType);
   void SetComposite(const CompositeOperation& aComposite);
+
+private:
+  void UpdatePropertiesFromCurrentStyle();
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_KeyframeEffect_h
--- a/dom/animation/KeyframeEffectReadOnly.cpp
+++ b/dom/animation/KeyframeEffectReadOnly.cpp
@@ -5,16 +5,18 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/KeyframeEffectReadOnly.h"
 
 #include "gfxPrefs.h"
 #include "mozilla/dom/KeyframeAnimationOptionsBinding.h"
   // For UnrestrictedDoubleOrKeyframeAnimationOptions;
 #include "mozilla/dom/CSSPseudoElement.h"
+#include "mozilla/dom/ElementInlines.h"
+  //For GetFlattenedTreeParentElementForStyle
 #include "mozilla/dom/KeyframeEffectBinding.h"
 #include "mozilla/AnimValuesStyleRule.h"
 #include "mozilla/AnimationUtils.h"
 #include "mozilla/AutoRestore.h"
 #include "mozilla/EffectSet.h"
 #include "mozilla/FloatingPoint.h" // For IsFinite
 #include "mozilla/LookAndFeel.h" // For LookAndFeel::GetInt
 #include "mozilla/KeyframeUtils.h"
@@ -180,19 +182,41 @@ KeyframeEffectReadOnly::SetKeyframes(JSC
                                      ErrorResult& aRv)
 {
   nsTArray<Keyframe> keyframes =
     KeyframeUtils::GetKeyframesFromObject(aContext, mDocument, aKeyframes, aRv);
   if (aRv.Failed()) {
     return;
   }
 
-  RefPtr<nsStyleContext> styleContext = GetTargetStyleContext();
-  nsStyleContext* rawStyleContext = styleContext.get();
-  SetKeyframes(Move(keyframes), rawStyleContext);
+  if (mDocument->IsStyledByServo()) {
+    nsPresContext* presContext =
+    nsContentUtils::GetContextForContent(mTarget->mElement);
+    if (!presContext) {
+      // If we don't have presContext(e.g. The target element don't belong with
+      // any document), we will not need to call UpdateProperties, only setting
+      // the keyframes.
+      nsStyleContext* value = nullptr;
+      SetKeyframes(Move(keyframes), value);
+      return;
+    }
+
+    RefPtr<ServoComputedValues> currentValue =
+      GetCurrentServoComputedValues(presContext);
+    RefPtr<ServoComputedValues> parentValue =
+      GetParentServoComputedValues(presContext);
+
+    const ServoComputedValuesWithParent value = { currentValue, parentValue };
+    SetKeyframes(Move(keyframes), value);
+  } else {
+    RefPtr<nsStyleContext> styleContext = GetTargetStyleContext();
+    nsStyleContext* rawStyleContext = styleContext.get();
+
+    SetKeyframes(Move(keyframes), rawStyleContext);
+  }
 }
 
 template<typename StyleType>
 void
 KeyframeEffectReadOnly::SetKeyframes(nsTArray<Keyframe>&& aKeyframes,
                                      StyleType&& aStyle)
 {
   static_assert(IsSame<StyleType, nsStyleContext*&>::value ||
@@ -280,32 +304,19 @@ SpecifiedKeyframeArraysAreEqual(const ns
   return true;
 }
 #endif
 
 void
 KeyframeEffectReadOnly::UpdateProperties(nsStyleContext* aStyleContext)
 {
   MOZ_ASSERT(aStyleContext);
-
-  if (!mDocument->IsStyledByServo()) {
-    DoUpdateProperties(Move(aStyleContext));
-    return;
-  }
+  MOZ_ASSERT(mDocument->IsStyledByServo());
 
-  const ServoComputedValues* currentStyle =
-    aStyleContext->StyleSource().AsServoComputedValues();
-  // FIXME: Remove GetParentAllowServo() in Bug 1349004.
-  const ServoComputedValues* parentStyle =
-    aStyleContext->GetParentAllowServo()
-      ? aStyleContext->GetParentAllowServo()->StyleSource().AsServoComputedValues()
-      : nullptr;
-
-  const ServoComputedValuesWithParent servoValues = { currentStyle, parentStyle };
-  DoUpdateProperties(servoValues);
+  DoUpdateProperties(Move(aStyleContext));
 }
 
 void
 KeyframeEffectReadOnly::UpdateProperties(
   const ServoComputedValuesWithParent& aServoValues)
 {
   DoUpdateProperties(aServoValues);
 }
@@ -1044,16 +1055,52 @@ KeyframeEffectReadOnly::GetTargetStyleCo
 
   nsIAtom* pseudo = mTarget->mPseudoType < CSSPseudoElementType::Count
                     ? nsCSSPseudoElements::GetPseudoAtom(mTarget->mPseudoType)
                     : nullptr;
 
   return nsComputedDOMStyle::GetStyleContext(mTarget->mElement, pseudo, shell);
 }
 
+already_AddRefed<ServoComputedValues>
+KeyframeEffectReadOnly::GetCurrentServoComputedValues(
+  nsPresContext* presContext)
+{
+  MOZ_ASSERT(presContext);
+  ServoStyleSet* styleSet = presContext->StyleSet()->AsServo();
+  MOZ_ASSERT(styleSet);
+
+  nsIAtom* pseudo = mTarget->mPseudoType < CSSPseudoElementType::Count
+                    ? nsCSSPseudoElements::GetPseudoAtom(mTarget->mPseudoType)
+                    : nullptr;
+  return styleSet->ResolveTransientServoStyle(mTarget->mElement, pseudo);
+}
+
+already_AddRefed<ServoComputedValues>
+KeyframeEffectReadOnly::GetParentServoComputedValues(
+  nsPresContext* presContext)
+{
+  MOZ_ASSERT(presContext);
+  ServoStyleSet* styleSet = presContext->StyleSet()->AsServo();
+  MOZ_ASSERT(styleSet);
+
+  nsIAtom* pseudo = mTarget->mPseudoType < CSSPseudoElementType::Count
+                    ? nsCSSPseudoElements::GetPseudoAtom(mTarget->mPseudoType)
+                    : nullptr;
+
+  dom::Element* parent = pseudo
+                       ? mTarget->mElement.get()
+                       : mTarget->mElement->GetFlattenedTreeParentElementForStyle();
+  if (parent) {
+    return styleSet->ResolveTransientServoStyle(parent, nullptr);
+  }
+
+  return nullptr;
+}
+
 #ifdef DEBUG
 void
 DumpAnimationProperties(nsTArray<AnimationProperty>& aAnimationProperties)
 {
   for (auto& p : aAnimationProperties) {
     printf("%s\n", nsCSSProps::GetStringValue(p.mProperty).get());
     for (auto& s : p.mSegments) {
       nsString fromValue, toValue;
--- a/dom/animation/KeyframeEffectReadOnly.h
+++ b/dom/animation/KeyframeEffectReadOnly.h
@@ -334,16 +334,21 @@ protected:
 
   // Looks up the style context associated with the target element, if any.
   // We need to be careful to *not* call this when we are updating the style
   // context. That's because calling GetStyleContext when we are in the process
   // of building a style context may trigger various forms of infinite
   // recursion.
   already_AddRefed<nsStyleContext> GetTargetStyleContext();
 
+  already_AddRefed<ServoComputedValues> GetCurrentServoComputedValues(
+    nsPresContext* presContext);
+  already_AddRefed<ServoComputedValues> GetParentServoComputedValues(
+    nsPresContext* presContext);
+
   // A wrapper for marking cascade update according to the current
   // target and its effectSet.
   void MarkCascadeNeedsUpdate();
 
   // Composites |aValueToComposite| using |aCompositeOperation| onto the value
   // for |aProperty| in |aAnimationRule|, or, if there is no suitable value in
   // |aAnimationRule|, uses the base value for the property recorded on the
   // target element's EffectSet.