From 41a30d913e55b3f5f237cd4040d58bc22fd2b43d Mon Sep 17 00:00:00 2001 From: Boris Chiou Date: Tue, 12 Jul 2022 19:02:03 +0000 Subject: [PATCH] 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 --- .../server/actors/animation-type-longhand.js | 1 + devtools/shared/css/generated/properties-db.js | 5 +++++ layout/style/nsStyleStruct.cpp | 9 +++++++-- layout/style/nsStyleStruct.h | 11 +++++++++++ layout/style/test/mochitest.ini | 1 + layout/style/test/property_database.js | 18 ++++++++++++++++++ modules/libpref/init/StaticPrefList.yaml | 5 +++++ .../components/style/properties/gecko.mako.rs | 6 +++++- .../style/properties/longhands/ui.mako.rs | 14 ++++++++++++++ .../meta/css/css-animations/__dir__.ini | 2 +- ...ion-composition-computed.tentative.html.ini | 3 --- ...mation-composition-valid.tentative.html.ini | 12 ------------ .../meta/css/css-pseudo/__dir__.ini | 2 +- .../marker-supported-properties.html.ini | 3 --- 14 files changed, 69 insertions(+), 23 deletions(-) delete mode 100644 testing/web-platform/meta/css/css-animations/parsing/animation-composition-computed.tentative.html.ini delete mode 100644 testing/web-platform/meta/css/css-animations/parsing/animation-composition-valid.tentative.html.ini diff --git a/devtools/server/actors/animation-type-longhand.js b/devtools/server/actors/animation-type-longhand.js index 661d787a52128..85df5ac984273 100644 --- a/devtools/server/actors/animation-type-longhand.js +++ b/devtools/server/actors/animation-type-longhand.js @@ -185,6 +185,7 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [ [ "none", new Set([ + "animation-composition", "animation-delay", "animation-direction", "animation-duration", diff --git a/devtools/shared/css/generated/properties-db.js b/devtools/shared/css/generated/properties-db.js index f9ad60d24d41f..44384755c8ac9 100644 --- a/devtools/shared/css/generated/properties-db.js +++ b/devtools/shared/css/generated/properties-db.js @@ -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" diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 78eb75e4e7986..6825e3981a101 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -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 || diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index b89d66e065b84..a5b8173f87060 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -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 aName) { mName = aName; } @@ -1204,6 +1209,7 @@ struct StyleAnimation { dom::FillMode mFillMode; StyleAnimationPlayState mPlayState; float mIterationCount; // mozilla::PositiveInfinity() 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; diff --git a/layout/style/test/mochitest.ini b/layout/style/test/mochitest.ini index d15df3b7bd508..23692a7869931 100644 --- a/layout/style/test/mochitest.ini +++ b/layout/style/test/mochitest.ini @@ -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 diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index d27b9d3902f5f..09fc3bc343944 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -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. diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index ae95e1eb8fa35..b1381135998a9 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -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 diff --git a/servo/components/style/properties/gecko.mako.rs b/servo/components/style/properties/gecko.mako.rs index c3c7e4523da64..bd5740ecbbcf7 100644 --- a/servo/components/style/properties/gecko.mako.rs +++ b/servo/components/style/properties/gecko.mako.rs @@ -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(&mut self, v: I) where diff --git a/servo/components/style/properties/longhands/ui.mako.rs b/servo/components/style/properties/longhands/ui.mako.rs index 0410b4d384999..ddf05a4c8da79 100644 --- a/servo/components/style/properties/longhands/ui.mako.rs +++ b/servo/components/style/properties/longhands/ui.mako.rs @@ -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", diff --git a/testing/web-platform/meta/css/css-animations/__dir__.ini b/testing/web-platform/meta/css/css-animations/__dir__.ini index dd0148c56e1b3..7d04f97498f05 100644 --- a/testing/web-platform/meta/css/css-animations/__dir__.ini +++ b/testing/web-platform/meta/css/css-animations/__dir__.ini @@ -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] diff --git a/testing/web-platform/meta/css/css-animations/parsing/animation-composition-computed.tentative.html.ini b/testing/web-platform/meta/css/css-animations/parsing/animation-composition-computed.tentative.html.ini deleted file mode 100644 index 05eb67ba3c000..0000000000000 --- a/testing/web-platform/meta/css/css-animations/parsing/animation-composition-computed.tentative.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[animation-composition-computed.tentative.html] - [Property animation-composition value 'replace, add, accumulate'] - expected: FAIL diff --git a/testing/web-platform/meta/css/css-animations/parsing/animation-composition-valid.tentative.html.ini b/testing/web-platform/meta/css/css-animations/parsing/animation-composition-valid.tentative.html.ini deleted file mode 100644 index 749e6bae389b9..0000000000000 --- a/testing/web-platform/meta/css/css-animations/parsing/animation-composition-valid.tentative.html.ini +++ /dev/null @@ -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 diff --git a/testing/web-platform/meta/css/css-pseudo/__dir__.ini b/testing/web-platform/meta/css/css-pseudo/__dir__.ini index 55ed8c2e693b3..423e33ba28f58 100644 --- a/testing/web-platform/meta/css/css-pseudo/__dir__.ini +++ b/testing/web-platform/meta/css/css-pseudo/__dir__.ini @@ -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] diff --git a/testing/web-platform/meta/css/css-pseudo/parsing/marker-supported-properties.html.ini b/testing/web-platform/meta/css/css-pseudo/parsing/marker-supported-properties.html.ini index d41c359a4d782..e8d8d1fdbbeff 100644 --- a/testing/web-platform/meta/css/css-pseudo/parsing/marker-supported-properties.html.ini +++ b/testing/web-platform/meta/css/css-pseudo/parsing/marker-supported-properties.html.ini @@ -49,6 +49,3 @@ [Property text-emphasis-style value 'dot' in ::marker] expected: FAIL - - [Property animation-composition value 'add' in ::marker] - expected: FAIL