diff --git a/devtools/server/actors/animation-type-longhand.js b/devtools/server/actors/animation-type-longhand.js index 858bf46cd0bf..28e501591f4b 100644 --- a/devtools/server/actors/animation-type-longhand.js +++ b/devtools/server/actors/animation-type-longhand.js @@ -254,6 +254,7 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [ "transition-property", "transition-timing-function", "view-timeline-axis", + "view-timeline-inset", "view-timeline-name", "-moz-window-shadow", ]), diff --git a/devtools/shared/css/generated/properties-db.js b/devtools/shared/css/generated/properties-db.js index 46147bdc70e8..347087ccde1e 100644 --- a/devtools/shared/css/generated/properties-db.js +++ b/devtools/shared/css/generated/properties-db.js @@ -3261,6 +3261,7 @@ exports.CSS_PROPERTIES = { "scroll-timeline-axis", "view-timeline-name", "view-timeline-axis", + "view-timeline-inset", "-moz-box-align", "-moz-box-direction", "-moz-box-flex", @@ -12115,6 +12116,10 @@ exports.PREFERENCES = [ "view-timeline-axis", "layout.css.scroll-driven-animations.enabled" ], + [ + "view-timeline-inset", + "layout.css.scroll-driven-animations.enabled" + ], [ "view-timeline-name", "layout.css.scroll-driven-animations.enabled" diff --git a/layout/style/ServoBindings.toml b/layout/style/ServoBindings.toml index 958499c18576..165071674299 100644 --- a/layout/style/ServoBindings.toml +++ b/layout/style/ServoBindings.toml @@ -466,6 +466,7 @@ cbindgen-types = [ { gecko = "StyleScrollSnapType", servo = "crate::values::computed::ScrollSnapType" }, { gecko = "StyleScrollTimelineName", servo = "crate::values::computed::ScrollTimelineName" }, { gecko = "StyleScrollAxis", servo = "crate::values::computed::ScrollAxis" }, + { gecko = "StyleViewTimelineInset", servo = "crate::values::computed::ViewTimelineInset" }, { gecko = "StyleResize", servo = "crate::values::computed::Resize" }, { gecko = "StyleOverflowClipBox", servo = "crate::values::computed::OverflowClipBox" }, { gecko = "StyleFloat", servo = "crate::values::computed::Float" }, diff --git a/layout/style/ServoStyleConstsInlines.h b/layout/style/ServoStyleConstsInlines.h index be8bef606910..441fc6764811 100644 --- a/layout/style/ServoStyleConstsInlines.h +++ b/layout/style/ServoStyleConstsInlines.h @@ -1105,6 +1105,17 @@ inline double StyleComputedTimingFunction::GetPortion( return aFn ? aFn->At(aPortion, aBeforeFlag) : aPortion; } +/* static */ +template <> +inline LengthPercentageOrAuto LengthPercentageOrAuto::Zero() { + return LengthPercentage(LengthPercentage::Zero()); +} + +template <> +inline StyleViewTimelineInset::StyleGenericViewTimelineInset() + : start(LengthPercentageOrAuto::Zero()), + end(LengthPercentageOrAuto::Zero()) {} + } // namespace mozilla #endif diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index aa24546a9ee8..05c8f9b3bb10 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -3253,7 +3253,8 @@ nsStyleUIReset::nsStyleUIReset(const Document& aDocument) mViewTimelines( nsStyleAutoArray::WITH_SINGLE_INITIAL_ELEMENT), mViewTimelineNameCount(1), - mViewTimelineAxisCount(1) { + mViewTimelineAxisCount(1), + mViewTimelineInsetCount(1) { MOZ_COUNT_CTOR(nsStyleUIReset); mTransitions[0].SetInitialValues(); mAnimations[0].SetInitialValues(); @@ -3291,7 +3292,8 @@ nsStyleUIReset::nsStyleUIReset(const nsStyleUIReset& aSource) mScrollTimelineAxis(aSource.mScrollTimelineAxis), mViewTimelines(aSource.mViewTimelines.Clone()), mViewTimelineNameCount(aSource.mViewTimelineNameCount), - mViewTimelineAxisCount(aSource.mViewTimelineAxisCount) { + mViewTimelineAxisCount(aSource.mViewTimelineAxisCount), + mViewTimelineInsetCount(aSource.mViewTimelineInsetCount) { MOZ_COUNT_CTOR(nsStyleUIReset); } @@ -3355,7 +3357,8 @@ nsChangeHint nsStyleUIReset::CalcDifference( mScrollTimelineAxis != aNewData.mScrollTimelineAxis || mViewTimelines != aNewData.mViewTimelines || mViewTimelineNameCount != aNewData.mViewTimelineNameCount || - mViewTimelineAxisCount != aNewData.mViewTimelineAxisCount)) { + mViewTimelineAxisCount != aNewData.mViewTimelineAxisCount || + mViewTimelineInsetCount != aNewData.mViewTimelineInsetCount)) { hint |= nsChangeHint_NeutralChange; } diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 8f3a85fa77bf..34bb587fa207 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -1278,7 +1278,8 @@ struct StyleViewTimeline { void SetInitialValues() {} bool operator==(const StyleViewTimeline& aOther) const { - return mName == aOther.mName && mAxis == aOther.mAxis; + return mName == aOther.mName && mAxis == aOther.mAxis && + mInset == aOther.mInset; } bool operator!=(const StyleViewTimeline& aOther) const { return !(*this == aOther); @@ -1287,6 +1288,7 @@ struct StyleViewTimeline { private: StyleScrollTimelineName mName; StyleScrollAxis mAxis = StyleScrollAxis::Block; + StyleViewTimelineInset mInset; }; } // namespace mozilla @@ -1911,6 +1913,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUIReset { nsStyleAutoArray mViewTimelines; uint32_t mViewTimelineNameCount; uint32_t mViewTimelineAxisCount; + uint32_t mViewTimelineInsetCount; }; struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUI { diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index 2089a70dce42..8844a9f89aaa 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -13732,6 +13732,15 @@ if (IsCSSPropertyPrefEnabled("layout.css.scroll-driven-animations.enabled")) { other_values: ["inline", "vertical", "horizontal", "inline, block"], invalid_values: ["auto", "none", "abc", "inline block"], }; + + gCSSProperties["view-timeline-inset"] = { + domProp: "viewTimelineInset", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: ["0px"], + other_values: ["auto", "1%", "1px 1%", "auto auto", "calc(0px) auto"], + invalid_values: ["none", "rgb(1, 2, 3)", "foo bar", "1px 2px 3px"], + }; } if (IsCSSPropertyPrefEnabled("layout.css.scrollbar-gutter.enabled")) { diff --git a/servo/components/style/properties/gecko.mako.rs b/servo/components/style/properties/gecko.mako.rs index 61501100c816..a40375abaa19 100644 --- a/servo/components/style/properties/gecko.mako.rs +++ b/servo/components/style/properties/gecko.mako.rs @@ -1721,7 +1721,7 @@ mask-mode mask-repeat mask-clip mask-origin mask-composite mask-position-x mask- animation-timing-function animation-composition animation-timeline transition-duration transition-delay transition-timing-function transition-property - view-timeline-name view-timeline-axis""" %> + view-timeline-name view-timeline-axis view-timeline-inset""" %> <%self:impl_trait style_struct_name="UI" skip_longhands="${skip_ui_longhands}"> ${impl_coordinated_property('transition', 'delay', 'Delay')} @@ -1907,6 +1907,7 @@ mask-mode mask-repeat mask-clip mask-origin mask-composite mask-position-x mask- ${impl_coordinated_property('view_timeline', 'name', 'Name')} ${impl_coordinated_property('view_timeline', 'axis', 'Axis')} + ${impl_coordinated_property('view_timeline', 'inset', 'Inset')} <%self:impl_trait style_struct_name="XUL"> diff --git a/servo/components/style/properties/longhands/ui.mako.rs b/servo/components/style/properties/longhands/ui.mako.rs index 726f3e73f9d3..b2be1e02e75c 100644 --- a/servo/components/style/properties/longhands/ui.mako.rs +++ b/servo/components/style/properties/longhands/ui.mako.rs @@ -376,3 +376,16 @@ ${helpers.predefined_type( spec="https://drafts.csswg.org/scroll-animations-1/#view-timeline-axis", rule_types_allowed=DEFAULT_RULES_EXCEPT_KEYFRAME, )} + +${helpers.predefined_type( + "view-timeline-inset", + "ViewTimelineInset", + "computed::ViewTimelineInset::zero()", + vector=True, + need_index=True, + engines="gecko", + animation_value_type="none", + gecko_pref="layout.css.scroll-driven-animations.enabled", + spec="https://drafts.csswg.org/scroll-animations-1/#view-timeline-axis", + rule_types_allowed=DEFAULT_RULES_EXCEPT_KEYFRAME, +)} diff --git a/servo/components/style/values/computed/mod.rs b/servo/components/style/values/computed/mod.rs index e196826dcb91..2a36232656ee 100644 --- a/servo/components/style/values/computed/mod.rs +++ b/servo/components/style/values/computed/mod.rs @@ -104,7 +104,7 @@ pub use self::transform::{Rotate, Scale, Transform, TransformOperation}; pub use self::transform::{TransformOrigin, TransformStyle, Translate}; #[cfg(feature = "gecko")] pub use self::ui::CursorImage; -pub use self::ui::{BoolInteger, Cursor, UserSelect}; +pub use self::ui::{BoolInteger, Cursor, UserSelect, ViewTimelineInset}; pub use super::specified::TextTransform; pub use super::specified::ViewportVariant; pub use super::specified::{BorderStyle, TextDecorationLine}; diff --git a/servo/components/style/values/computed/ui.rs b/servo/components/style/values/computed/ui.rs index 6fa5137adf04..ee0fcadf414e 100644 --- a/servo/components/style/values/computed/ui.rs +++ b/servo/components/style/values/computed/ui.rs @@ -6,7 +6,7 @@ use crate::values::computed::color::Color; use crate::values::computed::image::Image; -use crate::values::computed::Number; +use crate::values::computed::{LengthPercentage, Number}; use crate::values::generics::ui as generics; pub use crate::values::specified::ui::CursorKind; @@ -20,3 +20,19 @@ pub type CursorImage = generics::GenericCursorImage; /// A computed value for `scrollbar-color` property. pub type ScrollbarColor = generics::GenericScrollbarColor; + +/// A computed value for the `view-timeline-inset` property. +pub type ViewTimelineInset = generics::GenericViewTimelineInset; + +impl ViewTimelineInset { + /// Returns the initial value, `0`. + #[inline] + pub fn zero() -> Self { + use crate::Zero; + + Self { + start: Zero::zero(), + end: Zero::zero(), + } + } +} diff --git a/servo/components/style/values/generics/ui.rs b/servo/components/style/values/generics/ui.rs index 4d9515199ad3..3db04e6586a5 100644 --- a/servo/components/style/values/generics/ui.rs +++ b/servo/components/style/values/generics/ui.rs @@ -4,6 +4,7 @@ //! Generic values for UI properties. +use crate::values::generics::length::GenericLengthPercentageOrAuto; use crate::values::specified::ui::CursorKind; use std::fmt::{self, Write}; use style_traits::{CssWriter, ToCss}; @@ -127,3 +128,44 @@ impl Default for ScrollbarColor { ScrollbarColor::Auto } } + +/// A generic value for the `[ [ auto | ]{1,2} ]`. +/// +/// https://drafts.csswg.org/scroll-animations-1/#view-timeline-inset +#[derive( + Clone, + Copy, + Debug, + MallocSizeOf, + PartialEq, + SpecifiedValueInfo, + ToComputedValue, + ToResolvedValue, + ToShmem, +)] +#[repr(C)] +pub struct GenericViewTimelineInset { + /// The start inset in the relevant axis. + pub start: GenericLengthPercentageOrAuto, + /// The end inset. + pub end: GenericLengthPercentageOrAuto, +} + +pub use self::GenericViewTimelineInset as ViewTimelineInset; + +impl ToCss for ViewTimelineInset +where + LengthPercent: ToCss + PartialEq, +{ + fn to_css(&self, dest: &mut CssWriter) -> fmt::Result + where + W: Write, + { + self.start.to_css(dest)?; + if self.end != self.start { + dest.write_char(' ')?; + self.end.to_css(dest)?; + } + Ok(()) + } +} diff --git a/servo/components/style/values/specified/box.rs b/servo/components/style/values/specified/box.rs index ff1fd236d498..1b5662549eb1 100644 --- a/servo/components/style/values/specified/box.rs +++ b/servo/components/style/values/specified/box.rs @@ -762,9 +762,11 @@ impl Default for Scroller { } } -/// A value for the used in scroll(). +/// A value for the used in scroll(), or a value for {scroll|view}-timeline-axis. /// -/// https://drafts.csswg.org/scroll-animations-1/rewrite#typedef-axis +/// https://drafts.csswg.org/scroll-animations-1/#typedef-axis +/// https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-axis +/// https://drafts.csswg.org/scroll-animations-1/#view-timeline-axis #[derive( Clone, Debug, @@ -891,7 +893,7 @@ impl Parse for AnimationTimeline { /// Note: The spec doesn't mention `auto` for scroll-timeline-name. However, `auto` is a keyword in /// animation-timeline, so we reject `auto` for scroll-timeline-name now. /// -/// https://drafts.csswg.org/scroll-animations-1/rewrite#scroll-timeline-name +/// https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-name #[derive( Clone, Debug, diff --git a/servo/components/style/values/specified/mod.rs b/servo/components/style/values/specified/mod.rs index 3b97173d37c3..3daa61a366b9 100644 --- a/servo/components/style/values/specified/mod.rs +++ b/servo/components/style/values/specified/mod.rs @@ -100,7 +100,7 @@ pub use self::transform::{Rotate, Scale, Transform}; pub use self::transform::{TransformOrigin, TransformStyle, Translate}; #[cfg(feature = "gecko")] pub use self::ui::CursorImage; -pub use self::ui::{BoolInteger, Cursor, UserSelect}; +pub use self::ui::{BoolInteger, Cursor, UserSelect, ViewTimelineInset}; pub use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent; #[cfg(feature = "gecko")] diff --git a/servo/components/style/values/specified/ui.rs b/servo/components/style/values/specified/ui.rs index 0c656faab20d..c6af7353286a 100644 --- a/servo/components/style/values/specified/ui.rs +++ b/servo/components/style/values/specified/ui.rs @@ -8,7 +8,7 @@ use crate::parser::{Parse, ParserContext}; use crate::values::generics::ui as generics; use crate::values::specified::color::Color; use crate::values::specified::image::Image; -use crate::values::specified::Number; +use crate::values::specified::{LengthPercentage, Number}; use cssparser::Parser; use std::fmt::{self, Write}; use style_traits::{ @@ -230,3 +230,23 @@ pub enum CursorKind { ZoomOut, Auto, } + +/// A specified value for the `view-timeline-inset` property. +pub type ViewTimelineInset = generics::GenericViewTimelineInset; + +impl Parse for ViewTimelineInset { + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { + use crate::values::specified::LengthPercentageOrAuto; + + let start = LengthPercentageOrAuto::parse(context, input)?; + let end = match input.try_parse(|input| LengthPercentageOrAuto::parse(context, input)) { + Ok(end) => end, + Err(_) => start.clone(), + }; + + Ok(Self { start, end }) + } +} diff --git a/servo/ports/geckolib/cbindgen.toml b/servo/ports/geckolib/cbindgen.toml index fb3249df0215..0a223425c55e 100644 --- a/servo/ports/geckolib/cbindgen.toml +++ b/servo/ports/geckolib/cbindgen.toml @@ -120,6 +120,7 @@ include = [ "ScrollSnapStrictness", "ScrollSnapType", "ScrollTimelineName", + "ViewTimelineInset", "OverflowAnchor", "OverflowClipBox", "Resize", @@ -419,6 +420,8 @@ renaming_overrides_prefixing = true // Just some convenient aliases for LengthOrAuto, to avoid confusing naming. inline bool IsLength() const; inline const StyleLength& AsLength() const; + + static inline StyleGenericLengthPercentageOrAuto Zero(); """ "GenericSize" = """ @@ -951,6 +954,11 @@ renaming_overrides_prefixing = true StyleScrollTimelineName(): _0(RefPtr(nsGkAtoms::_empty).forget()) {} """ +"GenericViewTimelineInset" = """ + public: + inline StyleGenericViewTimelineInset(); +""" + "Time" = """ float ToSeconds() const { return seconds; } float ToMilliseconds() const { return seconds * 1000.0f; } diff --git a/testing/web-platform/meta/scroll-animations/css/view-timeline-inset-computed.html.ini b/testing/web-platform/meta/scroll-animations/css/view-timeline-inset-computed.html.ini deleted file mode 100644 index d0349ff8b668..000000000000 --- a/testing/web-platform/meta/scroll-animations/css/view-timeline-inset-computed.html.ini +++ /dev/null @@ -1,53 +0,0 @@ -[view-timeline-inset-computed.html] - expected: - if (os == "android") and fission: [OK, TIMEOUT] - [Property view-timeline-inset value 'initial'] - expected: FAIL - - [Property view-timeline-inset value 'inherit'] - expected: FAIL - - [Property view-timeline-inset value 'unset'] - expected: FAIL - - [Property view-timeline-inset value 'revert'] - expected: FAIL - - [Property view-timeline-inset value '1px'] - expected: FAIL - - [Property view-timeline-inset value '1%'] - expected: FAIL - - [Property view-timeline-inset value 'calc(1% + 1px)'] - expected: FAIL - - [Property view-timeline-inset value '1px 2px'] - expected: FAIL - - [Property view-timeline-inset value '1px 2em'] - expected: FAIL - - [Property view-timeline-inset value 'calc(1px + 1em) 2px'] - expected: FAIL - - [Property view-timeline-inset value '1px 2px, 3px 4px'] - expected: FAIL - - [Property view-timeline-inset value '1px auto, auto 4px'] - expected: FAIL - - [Property view-timeline-inset value '1px, 2px, 3px'] - expected: FAIL - - [Property view-timeline-inset value '1px 1px, 2px 3px'] - expected: FAIL - - [Property view-timeline-inset value 'auto auto, auto auto'] - expected: FAIL - - [The view-timeline-inset property shows up in CSSStyleDeclaration enumeration] - expected: FAIL - - [The view-timeline-inset property shows up in CSSStyleDeclaration.cssText] - expected: FAIL diff --git a/testing/web-platform/meta/scroll-animations/css/view-timeline-inset-parsing.html.ini b/testing/web-platform/meta/scroll-animations/css/view-timeline-inset-parsing.html.ini deleted file mode 100644 index faf29ecd9abb..000000000000 --- a/testing/web-platform/meta/scroll-animations/css/view-timeline-inset-parsing.html.ini +++ /dev/null @@ -1,41 +0,0 @@ -[view-timeline-inset-parsing.html] - expected: - if (os == "android") and fission: [OK, TIMEOUT] - [e.style['view-timeline-inset'\] = "initial" should set the property value] - expected: FAIL - - [e.style['view-timeline-inset'\] = "inherit" should set the property value] - expected: FAIL - - [e.style['view-timeline-inset'\] = "unset" should set the property value] - expected: FAIL - - [e.style['view-timeline-inset'\] = "revert" should set the property value] - expected: FAIL - - [e.style['view-timeline-inset'\] = "1px" should set the property value] - expected: FAIL - - [e.style['view-timeline-inset'\] = "1px 2px" should set the property value] - expected: FAIL - - [e.style['view-timeline-inset'\] = "1px 2em" should set the property value] - expected: FAIL - - [e.style['view-timeline-inset'\] = "calc(1em + 1px) 2px" should set the property value] - expected: FAIL - - [e.style['view-timeline-inset'\] = "1px 2px, 3px 4px" should set the property value] - expected: FAIL - - [e.style['view-timeline-inset'\] = "1px auto, auto 4px" should set the property value] - expected: FAIL - - [e.style['view-timeline-inset'\] = "1px, 2px, 3px" should set the property value] - expected: FAIL - - [e.style['view-timeline-inset'\] = "1px 1px, 2px 3px" should set the property value] - expected: FAIL - - [e.style['view-timeline-inset'\] = "auto auto, auto auto" should set the property value] - expected: FAIL