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
--- 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;
}