Bug 1293490 - Part 1: Implement CSS animation-composition longhand in style system. r=emilio

This patch introduces animation-composition longhand but we don't
accept it in @keyframe rule for now. I will support this for @keyframe
in the patch series.

Besides, the shorthand of animation doesn't include animation-composition.
The spec issue is: https://github.com/w3c/csswg-drafts/issues/6946.
We could fix the shorthand once this spec issue gets updated.

Differential Revision: https://phabricator.services.mozilla.com/D150299
This commit is contained in:
Boris Chiou 2022-07-12 19:02:03 +00:00
parent c50b2c34fa
commit 41a30d913e
14 changed files with 69 additions and 23 deletions

View File

@ -185,6 +185,7 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [
[
"none",
new Set([
"animation-composition",
"animation-delay",
"animation-direction",
"animation-duration",

View File

@ -3233,6 +3233,7 @@ exports.CSS_PROPERTIES = {
"animation-direction",
"animation-play-state",
"animation-fill-mode",
"animation-composition",
"animation-delay",
"animation-timeline",
"scroll-timeline-name",
@ -11803,6 +11804,10 @@ exports.PREFERENCES = [
"align-tracks",
"layout.css.grid-template-masonry-value.enabled"
],
[
"animation-composition",
"layout.css.animation-composition.enabled"
],
[
"animation-timeline",
"layout.css.scroll-linked-animations.enabled"

View File

@ -30,7 +30,8 @@
#include "imgIContainer.h"
#include "CounterStyleManager.h"
#include "mozilla/dom/AnimationEffectBinding.h" // for PlaybackDirection
#include "mozilla/dom/AnimationEffectBinding.h" // for PlaybackDirection
#include "mozilla/dom/BaseKeyframeTypesBinding.h" // for CompositeOperation
#include "mozilla/dom/DocGroup.h"
#include "mozilla/dom/ImageTracker.h"
#include "mozilla/CORSMode.h"
@ -2169,6 +2170,7 @@ void StyleAnimation::SetInitialValues() {
mFillMode = dom::FillMode::None;
mPlayState = StyleAnimationPlayState::Running;
mIterationCount = 1.0f;
mComposition = dom::CompositeOperation::Replace;
mTimeline = StyleAnimationTimeline::Auto();
}
@ -2178,7 +2180,7 @@ bool StyleAnimation::operator==(const StyleAnimation& aOther) const {
mName == aOther.mName && mDirection == aOther.mDirection &&
mFillMode == aOther.mFillMode && mPlayState == aOther.mPlayState &&
mIterationCount == aOther.mIterationCount &&
mTimeline == aOther.mTimeline;
mComposition == aOther.mComposition && mTimeline == aOther.mTimeline;
}
// --------------------
@ -3188,6 +3190,7 @@ nsStyleUIReset::nsStyleUIReset(const Document& aDocument)
mAnimationFillModeCount(1),
mAnimationPlayStateCount(1),
mAnimationIterationCountCount(1),
mAnimationCompositionCount(1),
mAnimationTimelineCount(1),
mScrollTimelineAxis(StyleScrollAxis::Block) {
MOZ_COUNT_CTOR(nsStyleUIReset);
@ -3220,6 +3223,7 @@ nsStyleUIReset::nsStyleUIReset(const nsStyleUIReset& aSource)
mAnimationFillModeCount(aSource.mAnimationFillModeCount),
mAnimationPlayStateCount(aSource.mAnimationPlayStateCount),
mAnimationIterationCountCount(aSource.mAnimationIterationCountCount),
mAnimationCompositionCount(aSource.mAnimationCompositionCount),
mAnimationTimelineCount(aSource.mAnimationTimelineCount),
mScrollTimelineName(aSource.mScrollTimelineName),
mScrollTimelineAxis(aSource.mScrollTimelineAxis) {
@ -3273,6 +3277,7 @@ nsChangeHint nsStyleUIReset::CalcDifference(
mAnimationPlayStateCount != aNewData.mAnimationPlayStateCount ||
mAnimationIterationCountCount !=
aNewData.mAnimationIterationCountCount ||
mAnimationCompositionCount != aNewData.mAnimationCompositionCount ||
mAnimationTimelineCount != aNewData.mAnimationTimelineCount ||
mIMEMode != aNewData.mIMEMode ||
mWindowOpacity != aNewData.mWindowOpacity ||

View File

@ -44,6 +44,10 @@ struct IntrinsicSize;
} // namespace mozilla
namespace mozilla::dom {
enum class CompositeOperation : uint8_t;
} // namespace mozilla::dom
namespace mozilla {
using Position = StylePosition;
@ -1185,6 +1189,7 @@ struct StyleAnimation {
dom::FillMode GetFillMode() const { return mFillMode; }
StyleAnimationPlayState GetPlayState() const { return mPlayState; }
float GetIterationCount() const { return mIterationCount; }
dom::CompositeOperation GetComposition() const { return mComposition; }
const StyleAnimationTimeline& GetTimeline() const { return mTimeline; }
void SetName(already_AddRefed<nsAtom> aName) { mName = aName; }
@ -1204,6 +1209,7 @@ struct StyleAnimation {
dom::FillMode mFillMode;
StyleAnimationPlayState mPlayState;
float mIterationCount; // mozilla::PositiveInfinity<float>() means infinite
dom::CompositeOperation mComposition;
StyleAnimationTimeline mTimeline;
};
@ -1821,6 +1827,10 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUIReset {
return mAnimations[aIndex % mAnimationTimingFunctionCount]
.GetTimingFunction();
}
mozilla::dom::CompositeOperation GetAnimationComposition(
uint32_t aIndex) const {
return mAnimations[aIndex % mAnimationCompositionCount].GetComposition();
}
const mozilla::StyleAnimationTimeline& GetTimeline(uint32_t aIndex) const {
return mAnimations[aIndex % mAnimationTimelineCount].GetTimeline();
}
@ -1853,6 +1863,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUIReset {
uint32_t mAnimationFillModeCount;
uint32_t mAnimationPlayStateCount;
uint32_t mAnimationIterationCountCount;
uint32_t mAnimationCompositionCount;
uint32_t mAnimationTimelineCount;
mozilla::StyleScrollTimelineName mScrollTimelineName;

View File

@ -22,6 +22,7 @@ prefs =
layout.css.scroll-linked-animations.enabled=true
layout.css.scrollbar-gutter.enabled=true
layout.css.linear-easing-function.enabled=true
layout.css.animation-composition.enabled=true
support-files =
animation_utils.js
bug1729861.js

View File

@ -13583,6 +13583,24 @@ if (IsCSSPropertyPrefEnabled("layout.css.color-scheme.enabled")) {
};
}
if (IsCSSPropertyPrefEnabled("layout.css.animation-composition.enabled")) {
gCSSProperties["animation-composition"] = {
domProp: "animationComposition",
inherited: false,
type: CSS_TYPE_LONGHAND,
applies_to_marker: true,
initial_values: ["replace"],
other_values: [
"add",
"accumulate",
"replace, add",
"add, accumulate",
"replace, add, accumulate",
],
invalid_values: ["all", "none"],
};
}
if (IsCSSPropertyPrefEnabled("layout.css.scroll-linked-animations.enabled")) {
// Basically, web-platform-tests should cover most cases, so here we only
// put some basic test cases.

View File

@ -7589,6 +7589,11 @@
value: 6.0
mirror: always
# Whether the `animation-composition` in css-animations-2 is enabled.
- name: layout.css.animation-composition.enabled
type: bool
value: false
mirror: always
# Whether the `aspect-ratio` in css-sizing-4 is enabled.
- name: layout.css.aspect-ratio.enabled

View File

@ -1731,7 +1731,7 @@ mask-mode mask-repeat mask-clip mask-origin mask-composite mask-position-x mask-
<% skip_ui_longhands = """animation-name animation-delay animation-duration
animation-direction animation-fill-mode
animation-play-state animation-iteration-count
animation-timeline animation-timing-function
animation-timing-function animation-composition animation-timeline
transition-duration transition-delay
transition-timing-function transition-property""" %>
@ -1863,6 +1863,8 @@ mask-mode mask-repeat mask-clip mask-origin mask-composite mask-position-x mask-
&& self.gecko.mAnimationIterationCountCount == other.gecko.mAnimationIterationCountCount
&& self.gecko.mAnimationPlayStateCount == other.gecko.mAnimationPlayStateCount
&& self.gecko.mAnimationTimingFunctionCount == other.gecko.mAnimationTimingFunctionCount
&& self.gecko.mAnimationCompositionCount == other.gecko.mAnimationCompositionCount
&& self.gecko.mAnimationTimelineCount == other.gecko.mAnimationTimelineCount
&& unsafe { bindings::Gecko_StyleAnimationsEquals(&self.gecko.mAnimations, &other.gecko.mAnimations) }
}
@ -1907,6 +1909,8 @@ mask-mode mask-repeat mask-clip mask-origin mask-composite mask-position-x mask-
data.longhands_by_name["animation-fill-mode"].keyword)}
${impl_animation_keyword('play_state', 'PlayState',
data.longhands_by_name["animation-play-state"].keyword)}
${impl_animation_keyword('composition', 'Composition',
data.longhands_by_name["animation-composition"].keyword)}
pub fn set_animation_iteration_count<I>(&mut self, v: I)
where

View File

@ -276,6 +276,20 @@ ${helpers.single_keyword(
rule_types_allowed=DEFAULT_RULES_EXCEPT_KEYFRAME,
)}
${helpers.single_keyword(
"animation-composition",
"replace add accumulate",
engines="gecko",
need_index=True,
animation_value_type="none",
vector=True,
gecko_enum_prefix="CompositeOperation",
gecko_inexhaustive=True,
gecko_pref="layout.css.animation-composition.enabled",
spec="https://drafts.csswg.org/css-animations-2/#animation-composition",
rule_types_allowed=DEFAULT_RULES_EXCEPT_KEYFRAME,
)}
${helpers.predefined_type(
"animation-delay",
"Time",

View File

@ -1 +1 @@
prefs: [dom.animations-api.compositing.enabled:true, dom.animations-api.core.enabled:true, dom.animations-api.getAnimations.enabled:true, dom.animations-api.implicit-keyframes.enabled:true, dom.animations-api.timelines.enabled:true, layout.css.step-position-jump.enabled:true, layout.css.marker.restricted:false]
prefs: [dom.animations-api.compositing.enabled:true, dom.animations-api.core.enabled:true, dom.animations-api.getAnimations.enabled:true, dom.animations-api.implicit-keyframes.enabled:true, dom.animations-api.timelines.enabled:true, layout.css.step-position-jump.enabled:true, layout.css.marker.restricted:false, layout.css.animation-composition.enabled:true]

View File

@ -1,3 +0,0 @@
[animation-composition-computed.tentative.html]
[Property animation-composition value 'replace, add, accumulate']
expected: FAIL

View File

@ -1,12 +0,0 @@
[animation-composition-valid.tentative.html]
[e.style['animation-composition'\] = "replace" should set the property value]
expected: FAIL
[e.style['animation-composition'\] = "add" should set the property value]
expected: FAIL
[e.style['animation-composition'\] = "accumulate" should set the property value]
expected: FAIL
[e.style['animation-composition'\] = "replace, add, accumulate" should set the property value]
expected: FAIL

View File

@ -1,2 +1,2 @@
prefs: [dom.css_pseudo_element.enabled:true]
prefs: [dom.css_pseudo_element.enabled:true, layout.css.animation-composition.enabled:true]
leak-threshold: [tab:51200]

View File

@ -49,6 +49,3 @@
[Property text-emphasis-style value 'dot' in ::marker]
expected: FAIL
[Property animation-composition value 'add' in ::marker]
expected: FAIL