diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index 3cbc5a2a33d..59c9785292c 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -793,6 +793,58 @@ % endif +// A shorthand of kind ` ?` where both properties have +// the same type. +<%def name="two_properties_shorthand( + name, + first_property, + second_property, + parser_function, + needs_context=True, + **kwargs +)"> +<%call expr="self.shorthand(name, sub_properties=' '.join([first_property, second_property]), **kwargs)"> + #[allow(unused_imports)] + use crate::parser::Parse; + use crate::values::specified; + + pub fn parse_value<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { + let parse_one = |_c: &ParserContext, input: &mut Parser<'i, 't>| { + % if needs_context: + ${parser_function}(_c, input) + % else: + ${parser_function}(input) + % endif + }; + + let first = parse_one(context, input)?; + let second = + input.try(|input| parse_one(context, input)).unwrap_or_else(|_| first.clone()); + Ok(expanded! { + ${to_rust_ident(first_property)}: first, + ${to_rust_ident(second_property)}: second, + }) + } + + impl<'a> ToCss for LonghandsToSerialize<'a> { + fn to_css(&self, dest: &mut CssWriter) -> fmt::Result where W: fmt::Write { + let first = &self.${to_rust_ident(first_property)}; + let second = &self.${to_rust_ident(second_property)}; + + first.to_css(dest)?; + if first != second { + dest.write_str(" ")?; + second.to_css(dest)?; + } + Ok(()) + } + } + + + <%def name="four_sides_shorthand(name, sub_property_pattern, parser_function, needs_context=True, allow_quirks=False, **kwargs)"> <% sub_properties=' '.join(sub_property_pattern % side for side in PHYSICAL_SIDES) %> diff --git a/components/style/properties/shorthands/box.mako.rs b/components/style/properties/shorthands/box.mako.rs index 3469d3f3fbb..0acb72b6bb9 100644 --- a/components/style/properties/shorthands/box.mako.rs +++ b/components/style/properties/shorthands/box.mako.rs @@ -4,76 +4,28 @@ <%namespace name="helpers" file="/helpers.mako.rs" /> -<%helpers:shorthand - name="overflow" - flags="SHORTHAND_IN_GETCS" - sub_properties="overflow-x overflow-y" - spec="https://drafts.csswg.org/css-overflow/#propdef-overflow" -> - use crate::properties::longhands::overflow_x::parse as parse_overflow; +${helpers.two_properties_shorthand( + "overflow", + "overflow-x", + "overflow-y", + "specified::Overflow::parse", + flags="SHORTHAND_IN_GETCS", + needs_context=False, + spec="https://drafts.csswg.org/css-overflow/#propdef-overflow", +)} - pub fn parse_value<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result> { - let overflow_x = parse_overflow(context, input)?; - let overflow_y = - input.try(|i| parse_overflow(context, i)).unwrap_or(overflow_x); - Ok(expanded! { - overflow_x: overflow_x, - overflow_y: overflow_y, - }) - } - - impl<'a> ToCss for LonghandsToSerialize<'a> { - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result where W: fmt::Write { - self.overflow_x.to_css(dest)?; - if self.overflow_x != self.overflow_y { - dest.write_char(' ')?; - self.overflow_y.to_css(dest)?; - } - Ok(()) - } - } - - -<%helpers:shorthand - name="overflow-clip-box" - sub_properties="overflow-clip-box-block overflow-clip-box-inline" - enabled_in="ua" - gecko_pref="layout.css.overflow-clip-box.enabled" +${helpers.two_properties_shorthand( + "overflow-clip-box", + "overflow-clip-box-block", + "overflow-clip-box-inline", + "specified::OverflowClipBox::parse", + enabled_in="ua", + needs_context=False, + gecko_pref="layout.css.overflow-clip-box.enabled", spec="Internal, may be standardized in the future " - "(https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-clip-box)" - products="gecko" -> - use crate::values::specified::OverflowClipBox; - pub fn parse_value<'i, 't>( - _: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result> { - let block_value = OverflowClipBox::parse(input)?; - let inline_value = - input.try(|input| OverflowClipBox::parse(input)).unwrap_or(block_value); - - Ok(expanded! { - overflow_clip_box_block: block_value, - overflow_clip_box_inline: inline_value, - }) - } - - impl<'a> ToCss for LonghandsToSerialize<'a> { - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result where W: fmt::Write { - self.overflow_clip_box_block.to_css(dest)?; - - if self.overflow_clip_box_block != self.overflow_clip_box_inline { - dest.write_str(" ")?; - self.overflow_clip_box_inline.to_css(dest)?; - } - - Ok(()) - } - } - + "(https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-clip-box)", + products="gecko", +)} macro_rules! try_parse_one { ($context: expr, $input: expr, $var: ident, $prop_module: ident) => { @@ -381,36 +333,16 @@ macro_rules! try_parse_one { } -<%helpers:shorthand name="overscroll-behavior" products="gecko" - gecko_pref="layout.css.overscroll-behavior.enabled" - sub_properties="overscroll-behavior-x overscroll-behavior-y" - spec="https://wicg.github.io/overscroll-behavior/#overscroll-behavior-properties"> - pub fn parse_value<'i, 't>( - _: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result> { - use crate::values::specified::OverscrollBehavior; - let behavior_x = OverscrollBehavior::parse(input)?; - let behavior_y = input.try(OverscrollBehavior::parse).unwrap_or(behavior_x); - Ok(expanded! { - overscroll_behavior_x: behavior_x, - overscroll_behavior_y: behavior_y, - }) - } - - impl<'a> ToCss for LonghandsToSerialize<'a> { - // Serializes into the single keyword value if both overscroll-behavior-x and overscroll-behavior-y are same. - // Otherwise into two values separated by a space. - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result where W: fmt::Write { - self.overscroll_behavior_x.to_css(dest)?; - if self.overscroll_behavior_y != self.overscroll_behavior_x { - dest.write_str(" ")?; - self.overscroll_behavior_y.to_css(dest)?; - } - Ok(()) - } - } - +${helpers.two_properties_shorthand( + "overscroll-behavior", + "overscroll-behavior-x", + "overscroll-behavior-y", + "specified::OverscrollBehavior::parse", + needs_context=False, + products="gecko", + gecko_pref="layout.css.overscroll-behavior.enabled", + spec="https://wicg.github.io/overscroll-behavior/#overscroll-behavior-properties", +)} <%helpers:shorthand name="page-break-before" diff --git a/components/style/properties/shorthands/margin.mako.rs b/components/style/properties/shorthands/margin.mako.rs index 2eb920700e3..8ccd33ebf3b 100644 --- a/components/style/properties/shorthands/margin.mako.rs +++ b/components/style/properties/shorthands/margin.mako.rs @@ -4,51 +4,27 @@ <%namespace name="helpers" file="/helpers.mako.rs" /> -${helpers.four_sides_shorthand("margin", "margin-%s", "specified::LengthPercentageOrAuto::parse", - spec="https://drafts.csswg.org/css-box/#propdef-margin", - allowed_in_page_rule=True, - allow_quirks=True)} +${helpers.four_sides_shorthand( + "margin", + "margin-%s", + "specified::LengthPercentageOrAuto::parse", + spec="https://drafts.csswg.org/css-box/#propdef-margin", + allowed_in_page_rule=True, + allow_quirks=True, +)} -% for axis in ["block", "inline"]: - <% - spec = "https://drafts.csswg.org/css-logical/#propdef-margin-%s" % axis - %> - <%helpers:shorthand - name="margin-${axis}" - sub_properties="${' '.join( - 'margin-%s-%s' % (axis, side) - for side in ['start', 'end'] - )}" - spec="${spec}"> +${helpers.two_properties_shorthand( + "margin-block", + "margin-block-start", + "margin-block-end", + "specified::LengthPercentageOrAuto::parse", + spec="https://drafts.csswg.org/css-logical/#propdef-margin-block" +)} - use crate::parser::Parse; - use crate::values::specified::length::LengthPercentageOrAuto; - pub fn parse_value<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result> { - let start_value = LengthPercentageOrAuto::parse(context, input)?; - let end_value = - input.try(|input| LengthPercentageOrAuto::parse(context, input)) - .unwrap_or_else(|_| start_value.clone()); - - Ok(expanded! { - margin_${axis}_start: start_value, - margin_${axis}_end: end_value, - }) - } - - impl<'a> ToCss for LonghandsToSerialize<'a> { - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result where W: fmt::Write { - self.margin_${axis}_start.to_css(dest)?; - - if self.margin_${axis}_end != self.margin_${axis}_start { - dest.write_str(" ")?; - self.margin_${axis}_end.to_css(dest)?; - } - - Ok(()) - } - } - -% endfor +${helpers.two_properties_shorthand( + "margin-inline", + "margin-inline-start", + "margin-inline-end", + "specified::LengthPercentageOrAuto::parse", + spec="https://drafts.csswg.org/css-logical/#propdef-margin-inline" +)} diff --git a/components/style/properties/shorthands/padding.mako.rs b/components/style/properties/shorthands/padding.mako.rs index 5749029aa20..3efc0b4a153 100644 --- a/components/style/properties/shorthands/padding.mako.rs +++ b/components/style/properties/shorthands/padding.mako.rs @@ -4,50 +4,26 @@ <%namespace name="helpers" file="/helpers.mako.rs" /> -${helpers.four_sides_shorthand("padding", "padding-%s", "specified::NonNegativeLengthPercentage::parse", - spec="https://drafts.csswg.org/css-box-3/#propdef-padding", - allow_quirks=True)} +${helpers.four_sides_shorthand( + "padding", + "padding-%s", + "specified::NonNegativeLengthPercentage::parse", + spec="https://drafts.csswg.org/css-box-3/#propdef-padding", + allow_quirks=True, +)} -% for axis in ["block", "inline"]: - <% - spec = "https://drafts.csswg.org/css-logical/#propdef-padding-%s" % axis - %> - <%helpers:shorthand - name="padding-${axis}" - sub_properties="${' '.join( - 'padding-%s-%s' % (axis, side) - for side in ['start', 'end'] - )}" - spec="${spec}"> +${helpers.two_properties_shorthand( + "padding-block", + "padding-block-start", + "padding-block-end", + "specified::NonNegativeLengthPercentage::parse", + spec="https://drafts.csswg.org/css-logical/#propdef-padding-block" +)} - use crate::parser::Parse; - use crate::values::specified::length::NonNegativeLengthPercentage; - pub fn parse_value<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result> { - let start_value = NonNegativeLengthPercentage::parse(context, input)?; - let end_value = - input.try(|input| NonNegativeLengthPercentage::parse(context, input)) - .unwrap_or_else(|_| start_value.clone()); - - Ok(expanded! { - padding_${axis}_start: start_value, - padding_${axis}_end: end_value, - }) - } - - impl<'a> ToCss for LonghandsToSerialize<'a> { - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result where W: fmt::Write { - self.padding_${axis}_start.to_css(dest)?; - - if self.padding_${axis}_end != self.padding_${axis}_start { - dest.write_str(" ")?; - self.padding_${axis}_end.to_css(dest)?; - } - - Ok(()) - } - } - -% endfor +${helpers.two_properties_shorthand( + "padding-inline", + "padding-inline-start", + "padding-inline-end", + "specified::NonNegativeLengthPercentage::parse", + spec="https://drafts.csswg.org/css-logical/#propdef-padding-inline" +)} diff --git a/components/style/properties/shorthands/position.mako.rs b/components/style/properties/shorthands/position.mako.rs index ad00ba8eafd..aaf97a0674c 100644 --- a/components/style/properties/shorthands/position.mako.rs +++ b/components/style/properties/shorthands/position.mako.rs @@ -772,46 +772,18 @@ ${helpers.four_sides_shorthand( allow_quirks=False, )} -% for axis in ["block", "inline"]: - <% - spec = "https://drafts.csswg.org/css-logical/#propdef-inset-%s" % axis - %> - <%helpers:shorthand - name="inset-${axis}" - sub_properties="${' '.join( - 'inset-%s-%s' % (axis, side) - for side in ['start', 'end'] - )}" - spec="${spec}"> +${helpers.two_properties_shorthand( + "inset-block", + "inset-block-start", + "inset-block-end", + "specified::LengthPercentageOrAuto::parse", + spec="https://drafts.csswg.org/css-logical/#propdef-inset-block" +)} - use crate::parser::Parse; - use crate::values::specified::length::LengthPercentageOrAuto; - pub fn parse_value<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result> { - let start_value = LengthPercentageOrAuto::parse(context, input)?; - let end_value = - input.try(|input| LengthPercentageOrAuto::parse(context, input)) - .unwrap_or_else(|_| start_value.clone()); - - Ok(expanded! { - inset_${axis}_start: start_value, - inset_${axis}_end: end_value, - }) - } - - impl<'a> ToCss for LonghandsToSerialize<'a> { - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result where W: fmt::Write { - self.inset_${axis}_start.to_css(dest)?; - - if self.inset_${axis}_end != self.inset_${axis}_start { - dest.write_str(" ")?; - self.inset_${axis}_end.to_css(dest)?; - } - - Ok(()) - } - } - -% endfor +${helpers.two_properties_shorthand( + "inset-inline", + "inset-inline-start", + "inset-inline-end", + "specified::LengthPercentageOrAuto::parse", + spec="https://drafts.csswg.org/css-logical/#propdef-inset-inline" +)}