From 301da4fe63ab846425e946a02734ec9d1cc3b950 Mon Sep 17 00:00:00 2001 From: batu_hoang Date: Wed, 15 Jan 2025 17:59:41 +0800 Subject: [PATCH] Enable overflow:clip for Servo --- style/properties/data.py | 1 + style/properties/longhands/margin.mako.rs | 16 ++- style/values/computed/box.rs | 2 +- style/values/computed/mod.rs | 2 +- style/values/generics/box.rs | 29 +++++ style/values/specified/box.rs | 130 +++++++++++++++++++++- style/values/specified/mod.rs | 2 +- 7 files changed, 171 insertions(+), 11 deletions(-) diff --git a/style/properties/data.py b/style/properties/data.py index b83e1b16a..507a1a3f9 100644 --- a/style/properties/data.py +++ b/style/properties/data.py @@ -587,6 +587,7 @@ def specified_is_copy(self): "Overflow", "OverflowAnchor", "OverflowClipBox", + "OverflowClipMargin", "OverflowWrap", "OverscrollBehavior", "PageOrientation", diff --git a/style/properties/longhands/margin.mako.rs b/style/properties/longhands/margin.mako.rs index 1b733859d..e11892e8d 100644 --- a/style/properties/longhands/margin.mako.rs +++ b/style/properties/longhands/margin.mako.rs @@ -28,14 +28,22 @@ )} % endfor + +// "Length", +// "computed::Length::zero()", +// parse_method="parse_non_negative", + +// "OverflowClipMargin", +// "generics::box_::OverflowClipMargin::None", + ${helpers.predefined_type( "overflow-clip-margin", - "Length", - "computed::Length::zero()", - parse_method="parse_non_negative", - engines="gecko", + "OverflowClipMargin", + "generics::box_::OverflowClipMargin::None", + engines="gecko servo", spec="https://drafts.csswg.org/css-overflow/#propdef-overflow-clip-margin", affects="overflow", + animation_type="discrete", )} % for index, side in enumerate(ALL_SIDES): diff --git a/style/values/computed/box.rs b/style/values/computed/box.rs index fcfc8cd9d..a03708c70 100644 --- a/style/values/computed/box.rs +++ b/style/values/computed/box.rs @@ -18,7 +18,7 @@ use style_traits::{CssWriter, ToCss}; pub use crate::values::specified::box_::{ Appearance, BaselineSource, BreakBetween, BreakWithin, Clear, Contain, ContainerName, ContainerType, ContentVisibility, Display, Float, Overflow, - OverflowAnchor, OverflowClipBox, OverscrollBehavior, ScrollSnapAlign, ScrollSnapAxis, + OverflowAnchor, OverflowClipBox, OverflowClipMargin, OverscrollBehavior, ScrollSnapAlign, ScrollSnapAxis, ScrollSnapStop, ScrollSnapStrictness, ScrollSnapType, ScrollbarGutter, TouchAction, WillChange, }; diff --git a/style/values/computed/mod.rs b/style/values/computed/mod.rs index 439e586e5..ddbe73781 100644 --- a/style/values/computed/mod.rs +++ b/style/values/computed/mod.rs @@ -53,7 +53,7 @@ pub use self::border::{ pub use self::box_::{ Appearance, BaselineSource, BreakBetween, BreakWithin, Clear, Contain, ContainIntrinsicSize, ContainerName, ContainerType, ContentVisibility, Display, Float, LineClamp, Overflow, - OverflowAnchor, OverflowClipBox, OverscrollBehavior, Perspective, Resize, ScrollSnapAlign, + OverflowAnchor, OverflowClipBox, OverflowClipMargin, OverscrollBehavior, Perspective, Resize, ScrollSnapAlign, ScrollSnapAxis, ScrollSnapStop, ScrollSnapStrictness, ScrollSnapType, ScrollbarGutter, TouchAction, VerticalAlign, WillChange, Zoom, }; diff --git a/style/values/generics/box.rs b/style/values/generics/box.rs index 9f568fcae..254e58aa4 100644 --- a/style/values/generics/box.rs +++ b/style/values/generics/box.rs @@ -211,3 +211,32 @@ impl Perspective { Perspective::None } } + +#[derive( + Animate, + Clone, + Copy, + Debug, + MallocSizeOf, + PartialEq, + SpecifiedValueInfo, + ToAnimatedValue, + ToAnimatedZero, + ToComputedValue, + ToCss, + ToResolvedValue, + ToShmem, +)] +/// A generic value for the `overflow-clip-margin` property. +pub enum GenericOverflowClipMargin { + /// None + None, + /// A non-negative length. + Margin(NonNegativeLength), + /// A visual box. + VisualBox(VisualBox), + /// Both a visual box and a non-negative length. + VisualBoxAndMargin(VisualBox, NonNegativeLength), +} + +pub use self::GenericOverflowClipMargin as OverflowClipMargin; \ No newline at end of file diff --git a/style/values/specified/box.rs b/style/values/specified/box.rs index f227ad61d..7a06cc672 100644 --- a/style/values/specified/box.rs +++ b/style/values/specified/box.rs @@ -10,14 +10,22 @@ use crate::values::generics::box_::{ GenericContainIntrinsicSize, GenericLineClamp, GenericPerspective, GenericVerticalAlign, VerticalAlignKeyword, }; -use crate::values::specified::length::{LengthPercentage, NonNegativeLength}; +use crate::values::specified::length::{LengthPercentage, NonNegativeLength, Length as SpecifiedLength}; use crate::values::specified::{AllowQuirks, Integer, NonNegativeNumberOrPercentage}; +use crate::values::computed::Length; + use crate::values::CustomIdent; use cssparser::Parser; use num_traits::FromPrimitive; use std::fmt::{self, Debug, Write}; use style_traits::{CssWriter, KeywordsCollectFn, ParseError}; use style_traits::{SpecifiedValueInfo, StyleParseErrorKind, ToCss}; +use crate::values::generics::box_ as generic; + +use super::length; + +/// OverflowClipMargin +pub type OverflowClipMargin = generic::OverflowClipMargin; #[cfg(not(feature = "servo"))] fn flexbox_enabled() -> bool { @@ -1813,7 +1821,6 @@ pub enum Overflow { Hidden, Scroll, Auto, - #[cfg(feature = "gecko")] Clip, } @@ -1829,7 +1836,6 @@ impl Parse for Overflow { "hidden" => Self::Hidden, "scroll" => Self::Scroll, "auto" | "overlay" => Self::Auto, - #[cfg(feature = "gecko")] "clip" => Self::Clip, #[cfg(feature = "gecko")] "-moz-hidden-unscrollable" if static_prefs::pref!("layout.css.overflow-moz-hidden-unscrollable.enabled") => { @@ -1852,12 +1858,128 @@ impl Overflow { match *self { Self::Hidden | Self::Scroll | Self::Auto => *self, Self::Visible => Self::Auto, - #[cfg(feature = "gecko")] Self::Clip => Self::Hidden, } } } +#[allow(missing_docs)] +#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] +#[derive( + Clone, + Copy, + Debug, + Eq, + MallocSizeOf, + Parse, + PartialEq, + SpecifiedValueInfo, + ToAnimatedValue, + ToComputedValue, + ToCss, + ToResolvedValue, + ToShmem, +)] +#[repr(u8)] +pub enum VisualBox { + PaddingBox, + ContentBox, + BorderBox, +} + +// #[allow(missing_docs)] +// #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] +// #[derive( +// Clone, +// Copy, +// Debug, +// MallocSizeOf, +// PartialEq, +// ToAnimatedValue, +// // ToComputedValue, +// ToCss, +// ToResolvedValue, +// ToShmem, +// )] +// pub enum OverflowClipMargin { +// None, +// ClipMargin(Length), +// VisualBox(VisualBox), +// VisualBoxAndLength(VisualBox, Length), +// } + +// overflow-clip-margin: [padding-box | content-box | border-box] +impl Parse for OverflowClipMargin { + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { + let mut visual_box = None; + let mut margin_length = None; + let mut no_parse_error = true; + + loop { + if visual_box.is_none() { + visual_box = input.try_parse(|input| VisualBox::parse(input)).ok(); + + if visual_box.is_some() { + continue; + } + } + + if margin_length.is_none() { + margin_length = input.try_parse(|input| SpecifiedLength::parse_non_negative(context, input)).ok(); + + if margin_length.is_some() { + continue; + } + } + + no_parse_error = false; + break; + } + + if no_parse_error { + if visual_box == None { + visual_box = Some(VisualBox::PaddingBox); + } + if margin_length == None { + margin_length = Some(SpecifiedLength::from_px(0.0)); + } + } + + match (margin_length, visual_box) { + (Some(length), Some(visual_box)) => { + let px_length = length.to_computed_pixel_length_without_context(); + Ok(Self::VisualBoxAndMargin(visual_box, Length::new(px_length.unwrap()))) + }, + (Some(length), None) => { + let px_length = length.to_computed_pixel_length_without_context(); + Ok(Self::Margin(Length::new(px_length.unwrap()))) + }, + (None, Some(visual_box)) => Ok(Self::VisualBox(visual_box)), + (None, None) => Ok(Self::None), + } + } +} + +impl SpecifiedValueInfo for OverflowClipMargin { + fn collect_completion_keywords(f: KeywordsCollectFn) { + f(&[ + "padding-box", + "content-box", + "border-box", + ]); + } +} + +impl OverflowClipMargin { + /// Return default value of `overflow-clip-margin` as `0 padding-box` + pub fn zero() -> Self { + OverflowClipMargin::VisualBoxAndMargin(VisualBox::PaddingBox, Length::new(0.0)) + } +} + #[derive( Clone, Copy, diff --git a/style/values/specified/mod.rs b/style/values/specified/mod.rs index 14640c5e1..f654cb75b 100644 --- a/style/values/specified/mod.rs +++ b/style/values/specified/mod.rs @@ -42,7 +42,7 @@ pub use self::border::{ pub use self::box_::{ Appearance, BaselineSource, BreakBetween, BreakWithin, Clear, Contain, ContainIntrinsicSize, ContainerName, ContainerType, ContentVisibility, Display, Float, LineClamp, Overflow, - OverflowAnchor, OverflowClipBox, OverscrollBehavior, Perspective, Resize, ScrollSnapAlign, + OverflowAnchor, OverflowClipBox, OverflowClipMargin, OverscrollBehavior, Perspective, Resize, ScrollSnapAlign, ScrollSnapAxis, ScrollSnapStop, ScrollSnapStrictness, ScrollSnapType, ScrollbarGutter, TouchAction, VerticalAlign, WillChange, Zoom, };