From 6fec9d6f8c0837c79ef96ae4c2489bab444a1782 Mon Sep 17 00:00:00 2001 From: Ziran Sun Date: Wed, 6 Jul 2022 11:47:51 +0000 Subject: [PATCH] style: Add support for parsing the `contain-intrinsic-size` property from the CSS-sizing specification Differential Revision: https://phabricator.services.mozilla.com/D151001 --- .../properties/longhands/position.mako.rs | 15 +++++++ .../properties/shorthands/position.mako.rs | 9 ++++ components/style/values/computed/box.rs | 4 ++ components/style/values/computed/mod.rs | 2 +- components/style/values/generics/box.rs | 45 +++++++++++++++++++ components/style/values/specified/box.rs | 27 ++++++++++- components/style/values/specified/mod.rs | 2 +- 7 files changed, 101 insertions(+), 3 deletions(-) diff --git a/components/style/properties/longhands/position.mako.rs b/components/style/properties/longhands/position.mako.rs index 3969b986793..88c5ee3a8b9 100644 --- a/components/style/properties/longhands/position.mako.rs +++ b/components/style/properties/longhands/position.mako.rs @@ -463,3 +463,18 @@ ${helpers.predefined_type( gecko_pref="layout.css.aspect-ratio.enabled", servo_restyle_damage="reflow", )} + +% for (size, logical) in ALL_SIZES: + // FIXME: Bug 1778296, "contain-intrinsic-*" properties should be animatable. + ${helpers.predefined_type( + "contain-intrinsic-" + size, + "ContainIntrinsicSize", + "computed::ContainIntrinsicSize::None", + engines="gecko", + logical_group="contain-intrinsic-size", + logical=logical, + gecko_pref="layout.css.contain-intrinsic-size.enabled", + spec="https://drafts.csswg.org/css-sizing-4/#intrinsic-size-override", + animation_value_type="none", +)} +% endfor diff --git a/components/style/properties/shorthands/position.mako.rs b/components/style/properties/shorthands/position.mako.rs index c715f3182ae..7e2255e7dd1 100644 --- a/components/style/properties/shorthands/position.mako.rs +++ b/components/style/properties/shorthands/position.mako.rs @@ -861,3 +861,12 @@ ${helpers.two_properties_shorthand( engines="gecko servo", spec="https://drafts.csswg.org/css-logical/#propdef-inset-inline" )} + +${helpers.two_properties_shorthand( + "contain-intrinsic-size", + "contain-intrinsic-width", + "contain-intrinsic-height", + engines="gecko", + gecko_pref="layout.css.contain-intrinsic-size.enabled", + spec="https://drafts.csswg.org/css-sizing-4/#intrinsic-size-override", +)} diff --git a/components/style/values/computed/box.rs b/components/style/values/computed/box.rs index 96071177a57..28d704b015c 100644 --- a/components/style/values/computed/box.rs +++ b/components/style/values/computed/box.rs @@ -9,6 +9,7 @@ use crate::values::computed::{Context, Number, ToComputedValue}; use crate::values::generics::box_::AnimationIterationCount as GenericAnimationIterationCount; use crate::values::generics::box_::Perspective as GenericPerspective; use crate::values::generics::box_::VerticalAlign as GenericVerticalAlign; +use crate::values::generics::box_::ContainIntrinsicSize as GenericContainIntrinsicSize; use crate::values::specified::box_ as specified; pub use crate::values::specified::box_::{ @@ -26,6 +27,9 @@ pub type VerticalAlign = GenericVerticalAlign; /// A computed value for the `animation-iteration-count` property. pub type AnimationIterationCount = GenericAnimationIterationCount; +/// A computed value for the `contain-intrinsic-size` property. +pub type ContainIntrinsicSize = GenericContainIntrinsicSize; + impl AnimationIterationCount { /// Returns the value `1.0`. #[inline] diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 729959ed71e..6449495cb0c 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -46,7 +46,7 @@ pub use self::border::{BorderCornerRadius, BorderRadius, BorderSpacing}; pub use self::border::{BorderImageRepeat, BorderImageSideWidth}; pub use self::border::{BorderImageSlice, BorderImageWidth}; pub use self::box_::{AnimationIterationCount, AnimationName, AnimationTimeline, Contain, ContainerName, ContainerType}; -pub use self::box_::{Appearance, BreakBetween, BreakWithin, Clear, ContentVisibility, Float}; +pub use self::box_::{Appearance, BreakBetween, BreakWithin, Clear, ContentVisibility, ContainIntrinsicSize, Float}; pub use self::box_::{Display, Overflow, OverflowAnchor, TransitionProperty}; pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective, Resize, ScrollbarGutter}; pub use self::box_::{ScrollAxis, ScrollSnapAlign, ScrollSnapAxis, ScrollSnapStop}; diff --git a/components/style/values/generics/box.rs b/components/style/values/generics/box.rs index 5d6e8e25031..218afd477fc 100644 --- a/components/style/values/generics/box.rs +++ b/components/style/values/generics/box.rs @@ -5,6 +5,8 @@ //! Generic types for box properties. use crate::values::animated::ToAnimatedZero; +use std::fmt::{self, Write}; +use style_traits::{CssWriter, ToCss}; #[derive( Animate, @@ -76,6 +78,49 @@ impl ToAnimatedZero for VerticalAlign { } } +/// https://drafts.csswg.org/css-sizing-4/#intrinsic-size-override +#[derive( + Animate, + Clone, + ComputeSquaredDistance, + Debug, + MallocSizeOf, + PartialEq, + SpecifiedValueInfo, + ToComputedValue, + ToResolvedValue, + ToShmem, +)] +#[value_info(other_values = "auto")] +#[repr(C, u8)] +pub enum GenericContainIntrinsicSize { + /// The keyword `none`. + None, + /// A non-negative length. + Length(L), + /// "auto " + AutoLength(L), +} + +pub use self::GenericContainIntrinsicSize as ContainIntrinsicSize; + +impl ToCss for ContainIntrinsicSize { + + fn to_css(&self, dest: &mut CssWriter) -> fmt::Result + where + W: Write, + { + match *self { + Self::None => dest.write_str("none"), + Self::Length(ref l) => l.to_css(dest), + Self::AutoLength(ref l) => { + dest.write_str("auto ")?; + l.to_css(dest) + } + } + } +} + /// https://drafts.csswg.org/css-animations/#animation-iteration-count #[derive( Clone, diff --git a/components/style/values/specified/box.rs b/components/style/values/specified/box.rs index 25f8ae12769..2e49b2c40af 100644 --- a/components/style/values/specified/box.rs +++ b/components/style/values/specified/box.rs @@ -10,7 +10,7 @@ use crate::properties::{LonghandId, PropertyDeclarationId}; use crate::properties::{PropertyId, ShorthandId}; use crate::values::generics::box_::AnimationIterationCount as GenericAnimationIterationCount; use crate::values::generics::box_::Perspective as GenericPerspective; -use crate::values::generics::box_::{GenericVerticalAlign, VerticalAlignKeyword}; +use crate::values::generics::box_::{GenericContainIntrinsicSize, GenericVerticalAlign, VerticalAlignKeyword}; use crate::values::specified::length::{LengthPercentage, NonNegativeLength}; use crate::values::specified::{AllowQuirks, Number}; use crate::values::{CustomIdent, KeyframesName, TimelineName}; @@ -621,6 +621,9 @@ impl Debug for Display { } } +/// A specified value for the `contain-intrinsic-size` property. +pub type ContainIntrinsicSize = GenericContainIntrinsicSize; + /// A specified value for the `vertical-align` property. pub type VerticalAlign = GenericVerticalAlign; @@ -1427,6 +1430,28 @@ bitflags! { } } +impl Parse for ContainIntrinsicSize { + /// none | | auto + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { + + if let Ok(l) = input.try_parse(|i| NonNegativeLength::parse(context, i)) + { + return Ok(Self::Length(l)); + } + + if input.try_parse(|i| i.expect_ident_matching("auto")).is_ok() { + let l = NonNegativeLength::parse(context, input)?; + return Ok(Self::AutoLength(l)); + } + + input.expect_ident_matching("none")?; + Ok(Self::None) + } +} + /// https://drafts.csswg.org/css-contain-2/#content-visibility #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] #[derive( diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index fd931761562..fbb0a42d94f 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -38,7 +38,7 @@ pub use self::border::{BorderImageRepeat, BorderImageSideWidth}; pub use self::border::{BorderRadius, BorderSideWidth, BorderSpacing, BorderStyle}; pub use self::box_::{AnimationIterationCount, AnimationName, AnimationTimeline, Contain, Display}; pub use self::box_::{Appearance, BreakBetween, BreakWithin, ContainerName, ContainerType}; -pub use self::box_::{Clear, ContentVisibility, Float, Overflow, OverflowAnchor}; +pub use self::box_::{Clear, ContentVisibility, ContainIntrinsicSize, Float, Overflow, OverflowAnchor}; pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective, Resize, ScrollbarGutter}; pub use self::box_::{ScrollAxis, ScrollSnapAlign, ScrollSnapAxis, ScrollSnapStop}; pub use self::box_::{ScrollSnapStrictness, ScrollSnapType, ScrollTimelineName};