Bug 1325193 - Get underlying style value in the case where the last segment is missing keyframe for accumulation of iteration composite. r=birtles

Both of tests in this patch fail and cause lots of assertions without this fix.

MozReview-Commit-ID: CFrWSlM0Us5
This commit is contained in:
Hiroyuki Ikezoe 2017-01-12 10:28:46 +09:00
Родитель f16fdb17ae
Коммит 5e2100a627
5 изменённых файлов: 80 добавлений и 22 удалений

Просмотреть файл

@ -347,6 +347,34 @@ KeyframeEffectReadOnly::CompositeValue(
return StyleAnimationValue(); return StyleAnimationValue();
} }
StyleAnimationValue
KeyframeEffectReadOnly::GetUnderlyingStyle(
nsCSSPropertyID aProperty,
const RefPtr<AnimValuesStyleRule>& aAnimationRule)
{
StyleAnimationValue result;
if (aAnimationRule->HasValue(aProperty)) {
// If we have already composed style for the property, we use the style
// as the underlying style.
DebugOnly<bool> success = aAnimationRule->GetValue(aProperty, result);
MOZ_ASSERT(success, "AnimValuesStyleRule::GetValue should not fail");
} else {
// If we are composing with composite operation that is not 'replace'
// and we have not composed style for the property yet, we have to get
// the base style for the property.
RefPtr<nsStyleContext> styleContext = GetTargetStyleContext();
result = EffectCompositor::GetBaseStyle(aProperty,
styleContext,
*mTarget->mElement,
mTarget->mPseudoType);
MOZ_ASSERT(!result.IsNull(), "The base style should be set");
SetNeedsBaseStyle(aProperty);
}
return result;
}
StyleAnimationValue StyleAnimationValue
KeyframeEffectReadOnly::CompositeValue( KeyframeEffectReadOnly::CompositeValue(
nsCSSPropertyID aProperty, nsCSSPropertyID aProperty,
@ -374,23 +402,7 @@ KeyframeEffectReadOnly::CompositeValue(
aCompositeOperation == CompositeOperation::Add, aCompositeOperation == CompositeOperation::Add,
"InputValue should be null only if additive composite"); "InputValue should be null only if additive composite");
if (aAnimationRule->HasValue(aProperty)) { result = GetUnderlyingStyle(aProperty, aAnimationRule);
// If we have already composed style for the property, we use the style
// as the underlying style.
DebugOnly<bool> success = aAnimationRule->GetValue(aProperty, result);
MOZ_ASSERT(success, "AnimValuesStyleRule::GetValue should not fail");
} else {
// If we are composing with composite operation that is not 'replace'
// and we have not composed style for the property yet, we have to get
// the base style for the property.
RefPtr<nsStyleContext> styleContext = GetTargetStyleContext();
result = EffectCompositor::GetBaseStyle(aProperty,
styleContext,
*mTarget->mElement,
mTarget->mPseudoType);
MOZ_ASSERT(!result.IsNull(), "The base style should be set");
SetNeedsBaseStyle(aProperty);
}
return CompositeValue(aProperty, return CompositeValue(aProperty,
aValueToComposite, aValueToComposite,
@ -533,14 +545,17 @@ KeyframeEffectReadOnly::ComposeStyle(
prop.mSegments.LastElement(); prop.mSegments.LastElement();
// FIXME: Bug 1293492: Add a utility function to calculate both of // FIXME: Bug 1293492: Add a utility function to calculate both of
// below StyleAnimationValues. // below StyleAnimationValues.
StyleAnimationValue lastValue = lastSegment.mToValue.IsNull()
? GetUnderlyingStyle(prop.mProperty, aStyleRule)
: lastSegment.mToValue;
fromValue = fromValue =
StyleAnimationValue::Accumulate(prop.mProperty, StyleAnimationValue::Accumulate(prop.mProperty,
lastSegment.mToValue, lastValue,
Move(fromValue), Move(fromValue),
computedTiming.mCurrentIteration); computedTiming.mCurrentIteration);
toValue = toValue =
StyleAnimationValue::Accumulate(prop.mProperty, StyleAnimationValue::Accumulate(prop.mProperty,
lastSegment.mToValue, lastValue,
Move(toValue), Move(toValue),
computedTiming.mCurrentIteration); computedTiming.mCurrentIteration);
} }

Просмотреть файл

@ -423,6 +423,11 @@ protected:
const StyleAnimationValue& aValueToComposite, const StyleAnimationValue& aValueToComposite,
CompositeOperation aCompositeOperation); CompositeOperation aCompositeOperation);
// Returns underlying style animation value for |aProperty|.
StyleAnimationValue GetUnderlyingStyle(
nsCSSPropertyID aProperty,
const RefPtr<AnimValuesStyleRule>& aAnimationRule);
// Set a bit in mNeedsBaseStyleSet if |aProperty| can be run on the // Set a bit in mNeedsBaseStyleSet if |aProperty| can be run on the
// compositor. // compositor.
void SetNeedsBaseStyle(nsCSSPropertyID aProperty); void SetNeedsBaseStyle(nsCSSPropertyID aProperty);

Просмотреть файл

@ -490,6 +490,26 @@ promise_test(t => {
}, 'Transform value for animation with no keyframe at offset 0 and with ' + }, 'Transform value for animation with no keyframe at offset 0 and with ' +
'positive delay'); 'positive delay');
promise_test(t => {
useTestRefreshMode(t);
var div = addDiv(t, { style: 'transform: translateX(100px)' });
div.animate([{ offset: 0, transform: 'translateX(200px)'}],
{ duration: 100 * MS_PER_SEC,
iterationStart: 1,
iterationComposite: 'accumulate' });
return waitForPaintsFlushed().then(() => {
var transform =
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
assert_matrix_equals(transform, 'matrix(1, 0, 0, 1, 300, 0)',
'Transform value for animation with no keyframe at offset 1 and its ' +
'iterationComposite is accumulate');
});
}, 'Transform value for animation with no keyframe at offset 1 and its ' +
'iterationComposite is accumulate');
done(); done();
</script> </script>
</body> </body>

Просмотреть файл

@ -85,10 +85,24 @@ test(t => {
// (200px + 200px) * 0.5 // (200px + 200px) * 0.5
assert_equals(getComputedStyle(div).marginLeft, '200px', assert_equals(getComputedStyle(div).marginLeft, '200px',
'The margin-left value at 50% should be additive value of ' + 'The margin-left value at 50% should be additive value of ' +
'of the transition and animation'); 'the transition and animation');
}, 'margin-left value at 50% for an animation with no keyframe at offset 1 ' + }, 'margin-left value at 50% for an animation with no keyframe at offset 1 ' +
'is that of transition'); 'is that of transition');
test(t => {
var div = addDiv(t, { style: 'margin-left: 100px' });
var animation = div.animate([{ offset: 0, marginLeft: '200px' }],
{ duration: 100 * MS_PER_SEC,
iterationStart: 1,
iterationComposite: 'accumulate' });
assert_equals(getComputedStyle(div).marginLeft, '300px',
'The margin-left value should be additive value of the ' +
'accumulation of the initial value onto the base value ');
}, 'margin-left value for an animation with no keyframe at offset 1 and its ' +
'iterationComposite is accumulate');
done(); done();
</script> </script>
</body> </body>

Просмотреть файл

@ -613,12 +613,16 @@ SampleValue(float aPortion, const Animation& aAnimation,
// below StyleAnimationValues. // below StyleAnimationValues.
startValue = startValue =
StyleAnimationValue::Accumulate(aAnimation.property(), StyleAnimationValue::Accumulate(aAnimation.property(),
aLastValue, aLastValue.IsNull()
? aUnderlyingValue
: aLastValue,
Move(startValue), Move(startValue),
aCurrentIteration); aCurrentIteration);
endValue = endValue =
StyleAnimationValue::Accumulate(aAnimation.property(), StyleAnimationValue::Accumulate(aAnimation.property(),
aLastValue, aLastValue.IsNull()
? aUnderlyingValue
: aLastValue,
Move(endValue), Move(endValue),
aCurrentIteration); aCurrentIteration);
} }