Bug 1322382 - Add EffectCompositor::GetBaseStyle for nsIFrame. r?birtles draft
authorHiroyuki Ikezoe <hiikezoe@mozilla-japan.org>
Sat, 10 Dec 2016 09:16:33 +0900
changeset 448356 b16b03c683c31c971f28fbe4a455ca87710a575a
parent 447633 ad993783599ab2ede0cf931fdec02f4df40a7a6d
child 539279 3826deac02d7e5979d549e4262f03b4ad487c52e
push id38332
push userhiikezoe@mozilla-japan.org
push dateSat, 10 Dec 2016 00:20:39 +0000
reviewersbirtles
bugs1322382
milestone53.0a1
Bug 1322382 - Add EffectCompositor::GetBaseStyle for nsIFrame. r?birtles Currently this function is used when an nsIFrame is generated by reframing. In reframing, we call EffectCompositor::UpdateEffectProperties, as a result, we have to clear the base style that we resolved once. So, for such cases, we need to re-resolve the base style with the style context that is associated with the nsIFrame. MozReview-Commit-ID: F90OuF44SPI
dom/animation/EffectCompositor.cpp
dom/animation/EffectCompositor.h
dom/animation/EffectSet.h
dom/animation/test/crashtests/1322382-1.html
dom/animation/test/crashtests/crashtests.list
layout/base/nsLayoutUtils.cpp
layout/painting/nsDisplayList.cpp
--- a/dom/animation/EffectCompositor.cpp
+++ b/dom/animation/EffectCompositor.cpp
@@ -907,16 +907,35 @@ EffectCompositor::GetBaseStyle(nsCSSProp
   MOZ_ASSERT(success, "Should be able to extract computed animation value");
   MOZ_ASSERT(!result.IsNull(), "Should have a valid StyleAnimationValue");
 
   effectSet->PutBaseStyle(aProperty, result);
 
   return result;
 }
 
+/* static */ StyleAnimationValue
+EffectCompositor::GetBaseStyle(nsCSSPropertyID aProperty,
+                               const nsIFrame* aFrame)
+{
+  MOZ_ASSERT(aFrame->StyleContext(),
+             "The frame should have a valid style context");
+
+  Maybe<NonOwningAnimationTarget> pseudoElement =
+    EffectCompositor::GetAnimationElementAndPseudoForFrame(aFrame);
+
+  MOZ_ASSERT(pseudoElement && pseudoElement->mElement,
+             "The frame should have an associated element");
+
+  return EffectCompositor::GetBaseStyle(aProperty,
+                                        aFrame->StyleContext(),
+                                        *pseudoElement->mElement,
+                                        pseudoElement->mPseudoType);
+}
+
 /* static */ void
 EffectCompositor::ClearBaseStyles(dom::Element& aElement,
                                   CSSPseudoElementType aPseudoType)
 {
   EffectSet* effectSet =
     EffectSet::GetEffectSet(&aElement, aPseudoType);
   if (!effectSet) {
     return;
--- a/dom/animation/EffectCompositor.h
+++ b/dom/animation/EffectCompositor.h
@@ -221,16 +221,22 @@ public:
   // If there is no cached base style for the property, a new base style value
   // is resolved with |aStyleContext|. The new resolved base style is cached
   // until ClearBaseStyles is called.
   static StyleAnimationValue GetBaseStyle(nsCSSPropertyID aProperty,
                                           nsStyleContext* aStyleContext,
                                           dom::Element& aElement,
                                           CSSPseudoElementType aPseudoType);
 
+  // Returns the base style corresponding to |aFrame|.
+  // This function should be called only after restyle process has done, i.e.
+  // |aFrame| has a resolved style context.
+  static StyleAnimationValue GetBaseStyle(nsCSSPropertyID aProperty,
+                                          const nsIFrame* aFrame);
+
   // Clear cached base styles of (pseudo-)element.
   static void ClearBaseStyles(dom::Element& aElement,
                               CSSPseudoElementType aPseudoType);
 
 private:
   ~EffectCompositor() = default;
 
   // Rebuilds the animation rule corresponding to |aCascadeLevel| on the
--- a/dom/animation/EffectSet.h
+++ b/dom/animation/EffectSet.h
@@ -194,16 +194,18 @@ public:
   {
     return mPropertiesWithImportantRules;
   }
   nsCSSPropertyIDSet& PropertiesForAnimationsLevel()
   {
     return mPropertiesForAnimationsLevel;
   }
 
+  // This function is intended to be called by EffectCompositor::GetBaseStyle
+  // and should not be called directly.
   StyleAnimationValue GetBaseStyle(nsCSSPropertyID aProperty) const
   {
     StyleAnimationValue result;
     DebugOnly<bool> hasProperty = mBaseStyleValues.Get(aProperty, &result);
     MOZ_ASSERT(hasProperty || result.IsNull());
     return result;
   }
 
new file mode 100644
--- /dev/null
+++ b/dom/animation/test/crashtests/1322382-1.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<style>
+details {
+  background-color: blue;
+  width: 100px;
+  height: 100px;
+}
+</style>
+<html>
+<details id=o1><div></div></details>
+<script>
+window.onload = function(){
+  o1.animate([{'transform': 'none'}], 100);
+};
+</script>
+</html>
--- a/dom/animation/test/crashtests/crashtests.list
+++ b/dom/animation/test/crashtests/crashtests.list
@@ -7,8 +7,9 @@ pref(dom.animations-api.core.enabled,tru
 pref(dom.animations-api.core.enabled,true) load 1216842-5.html
 pref(dom.animations-api.core.enabled,true) load 1216842-6.html
 pref(dom.animations-api.core.enabled,true) load 1272475-1.html
 pref(dom.animations-api.core.enabled,true) load 1272475-2.html
 pref(dom.animations-api.core.enabled,true) load 1278485-1.html
 pref(dom.animations-api.core.enabled,true) load 1277272-1.html
 pref(dom.animations-api.core.enabled,true) load 1290535-1.html
 pref(dom.animations-api.core.enabled,true) load 1304886-1.html
+pref(dom.animations-api.core.enabled,true) load 1322382-1.html
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -549,19 +549,18 @@ GetMinAndMaxScaleForAnimationProperty(co
       const AnimationProperty& prop = effect->Properties()[propIdx];
       if (prop.mProperty != eCSSProperty_transform) {
         continue;
       }
 
       // We need to factor in the scale of the base style if the base style
       // will be used on the compositor.
       if (effect->NeedsBaseStyle(prop.mProperty)) {
-        EffectSet* effects = EffectSet::GetEffectSet(aFrame);
         StyleAnimationValue baseStyle =
-          effects->GetBaseStyle(prop.mProperty);
+          EffectCompositor::GetBaseStyle(prop.mProperty, aFrame);
         MOZ_ASSERT(!baseStyle.IsNull(), "The base value should be set");
         UpdateMinMaxScale(aFrame, baseStyle, aMinScale, aMaxScale);
       }
 
       for (const AnimationPropertySegment& segment : prop.mSegments) {
         // In case of add or accumulate composite, StyleAnimationValue does
         // not have a valid value.
         if (segment.mFromComposite == dom::CompositeOperation::Replace) {
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -423,18 +423,18 @@ SetAnimatable(nsCSSPropertyID aProperty,
 static void
 SetBaseAnimationStyle(nsCSSPropertyID aProperty,
                       nsIFrame* aFrame,
                       const TransformReferenceBox& aRefBox,
                       layers::BaseAnimationStyle& aBaseStyle)
 {
   MOZ_ASSERT(aFrame);
 
-  EffectSet* effects = EffectSet::GetEffectSet(aFrame);
-  StyleAnimationValue baseValue = effects->GetBaseStyle(aProperty);
+  StyleAnimationValue baseValue =
+    EffectCompositor::GetBaseStyle(aProperty, aFrame);
   MOZ_ASSERT(!baseValue.IsNull(),
              "The base value should be already there");
 
   layers::Animatable animatable;
   SetAnimatable(aProperty, baseValue, aFrame, aRefBox, animatable);
   aBaseStyle = animatable;
 }