From 7497720081698df7c6513eeac8d127a5eaa8c409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 24 Jan 2018 13:02:42 +0100 Subject: [PATCH] style: Make content distribution parsing know the axis it's parsed for. MozReview-Commit-ID: LMPXVtKU1mq --- .../properties/longhand/position.mako.rs | 8 +- .../properties/shorthand/position.mako.rs | 35 +++-- components/style/values/computed/align.rs | 2 +- components/style/values/computed/mod.rs | 2 +- components/style/values/specified/align.rs | 128 +++++++++++++----- components/style/values/specified/mod.rs | 2 +- 6 files changed, 125 insertions(+), 52 deletions(-) diff --git a/components/style/properties/longhand/position.mako.rs b/components/style/properties/longhand/position.mako.rs index 013b93b2640..b2d87302ad5 100644 --- a/components/style/properties/longhand/position.mako.rs +++ b/components/style/properties/longhand/position.mako.rs @@ -69,8 +69,8 @@ ${helpers.single_keyword("flex-wrap", "nowrap wrap wrap-reverse", animation_value_type="discrete")} % else: ${helpers.predefined_type(name="justify-content", - type="ContentDistribution", - initial_value="specified::ContentDistribution::normal()", + type="JustifyContent", + initial_value="specified::JustifyContent(specified::ContentDistribution::normal())", spec="https://drafts.csswg.org/css-align/#propdef-justify-content", extra_prefixes="webkit", animation_value_type="discrete")} @@ -90,8 +90,8 @@ ${helpers.single_keyword("flex-wrap", "nowrap wrap wrap-reverse", animation_value_type="discrete")} % else: ${helpers.predefined_type(name="align-content", - type="ContentDistribution", - initial_value="specified::ContentDistribution::normal()", + type="AlignContent", + initial_value="specified::AlignContent(specified::ContentDistribution::normal())", spec="https://drafts.csswg.org/css-align/#propdef-align-content", extra_prefixes="webkit", animation_value_type="discrete")} diff --git a/components/style/properties/shorthand/position.mako.rs b/components/style/properties/shorthand/position.mako.rs index 8775eed5c2c..06549a71891 100644 --- a/components/style/properties/shorthand/position.mako.rs +++ b/components/style/properties/shorthand/position.mako.rs @@ -615,33 +615,44 @@ <%helpers:shorthand name="place-content" sub_properties="align-content justify-content" spec="https://drafts.csswg.org/css-align/#propdef-place-content" products="gecko"> - use values::specified::align::{ContentDistribution, FallbackAllowed}; + use values::specified::align::{AlignContent, JustifyContent, ContentDistribution, FallbackAllowed, AxisDirection}; pub fn parse_value<'i, 't>( _: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result> { - let align = ContentDistribution::parse_with_fallback(input, FallbackAllowed::No)?; - if align.has_extra_flags() { - return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); - } - let justify = - input.try(|input| ContentDistribution::parse_with_fallback(input, FallbackAllowed::No)) - .unwrap_or(align); - if justify.has_extra_flags() { + let align_content = + ContentDistribution::parse( + input, + FallbackAllowed::No, + AxisDirection::Inline, + )?; + + let justify_content = input.try(|input| { + ContentDistribution::parse( + input, + FallbackAllowed::No, + AxisDirection::Block, + ) + }).unwrap_or(align_content); + + // NOTE(emilio): align-content parsing is more restrictive than + // justify-content parsing, so no need to do any extra check here for + // that. + if align_content.has_extra_flags() || justify_content.has_extra_flags() { return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } Ok(expanded! { - align_content: align, - justify_content: justify, + align_content: AlignContent(align_content), + justify_content: JustifyContent(justify_content), }) } impl<'a> ToCss for LonghandsToSerialize<'a> { fn to_css(&self, dest: &mut CssWriter) -> fmt::Result where W: fmt::Write { self.align_content.to_css(dest)?; - if self.align_content != self.justify_content { + if self.align_content.0 != self.justify_content.0 { dest.write_str(" ")?; self.justify_content.to_css(dest)?; } diff --git a/components/style/values/computed/align.rs b/components/style/values/computed/align.rs index c7bf6a30c6b..836ef93f857 100644 --- a/components/style/values/computed/align.rs +++ b/components/style/values/computed/align.rs @@ -11,7 +11,7 @@ use style_traits::{CssWriter, ToCss}; use values::computed::{Context, ToComputedValue}; use values::specified; -pub use super::specified::{AlignItems, ContentDistribution, SelfAlignment}; +pub use super::specified::{AlignContent, JustifyContent, AlignItems, SelfAlignment}; /// The computed value for the `justify-items` property. /// diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 7600d23a9d1..f2fef4f26a5 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -32,7 +32,7 @@ use super::specified; pub use app_units::Au; pub use properties::animated_properties::TransitionProperty; #[cfg(feature = "gecko")] -pub use self::align::{AlignItems, ContentDistribution, SelfAlignment, JustifyItems}; +pub use self::align::{AlignItems, AlignContent, JustifyContent, SelfAlignment, JustifyItems}; pub use self::angle::Angle; pub use self::background::{BackgroundSize, BackgroundRepeat}; pub use self::border::{BorderImageSlice, BorderImageWidth, BorderImageSideWidth}; diff --git a/components/style/values/specified/align.rs b/components/style/values/specified/align.rs index 460037925bd..e0faf23f864 100644 --- a/components/style/values/specified/align.rs +++ b/components/style/values/specified/align.rs @@ -110,14 +110,14 @@ const ALIGN_ALL_BITS: u16 = structs::NS_STYLE_ALIGN_ALL_BITS as u16; /// Number of bits to shift a fallback alignment. const ALIGN_ALL_SHIFT: u32 = structs::NS_STYLE_ALIGN_ALL_SHIFT; -/// Value of the `align-content` or `justify-content` property. -/// -/// -#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue)] -#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] -pub struct ContentDistribution { - primary: AlignFlags, - fallback: AlignFlags, +/// An axis direction, either inline (for the `justify` properties) or block, +/// (for the `align` properties). +#[derive(Clone, Copy, PartialEq)] +pub enum AxisDirection { + /// Block direction. + Block, + /// Inline direction. + Inline, } /// Whether fallback is allowed in align-content / justify-content parsing. @@ -134,6 +134,16 @@ pub enum FallbackAllowed { No, } +/// Shared value for the `align-content` and `justify-content` properties. +/// +/// +#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue)] +#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] +pub struct ContentDistribution { + primary: AlignFlags, + fallback: AlignFlags, +} + impl ContentDistribution { /// The initial value 'normal' #[inline] @@ -155,6 +165,19 @@ impl ContentDistribution { Self { primary, fallback } } + fn from_bits(bits: u16) -> Self { + let primary = + AlignFlags::from_bits_truncate((bits & ALIGN_ALL_BITS) as u8); + let fallback = + AlignFlags::from_bits_truncate((bits >> ALIGN_ALL_SHIFT) as u8); + Self::with_fallback(primary, fallback) + } + + fn as_bits(&self) -> u16 { + self.primary.bits() as u16 | + ((self.fallback.bits() as u16) << ALIGN_ALL_SHIFT) + } + /// The primary alignment #[inline] pub fn primary(self) -> AlignFlags { @@ -176,9 +199,10 @@ impl ContentDistribution { /// Parse a value for align-content / justify-content, optionally allowing /// fallback. - pub fn parse_with_fallback<'i, 't>( + pub fn parse<'i, 't>( input: &mut Parser<'i, 't>, fallback_allowed: FallbackAllowed, + _axis: AxisDirection, ) -> Result> { // normal | if let Ok(value) = input.try(|input| parse_normal_or_baseline(input)) { @@ -224,12 +248,69 @@ impl ToCss for ContentDistribution { } } +/// Value for the `align-content` property. +/// +/// +#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss)] +pub struct AlignContent(pub ContentDistribution); -impl Parse for ContentDistribution { - // normal | | - // [ || [ ? && ] ] - fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { - Self::parse_with_fallback(input, FallbackAllowed::Yes) +impl Parse for AlignContent { + fn parse<'i, 't>( + _: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { + Ok(AlignContent(ContentDistribution::parse( + input, + FallbackAllowed::Yes, + AxisDirection::Block, + )?)) + } +} + +#[cfg(feature = "gecko")] +impl From for AlignContent { + fn from(bits: u16) -> Self { + AlignContent(ContentDistribution::from_bits(bits)) + } +} + +#[cfg(feature = "gecko")] +impl From for u16 { + fn from(v: AlignContent) -> u16 { + v.0.as_bits() + } +} + +/// Value for the `justify-content` property. +/// +/// +#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss)] +pub struct JustifyContent(pub ContentDistribution); + +impl Parse for JustifyContent { + fn parse<'i, 't>( + _: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { + Ok(JustifyContent(ContentDistribution::parse( + input, + FallbackAllowed::Yes, + AxisDirection::Inline, + )?)) + } +} + +#[cfg(feature = "gecko")] +impl From for JustifyContent { + fn from(bits: u16) -> Self { + JustifyContent(ContentDistribution::from_bits(bits)) + } +} + +#[cfg(feature = "gecko")] +impl From for u16 { + fn from(v: JustifyContent) -> u16 { + v.0.as_bits() } } @@ -349,25 +430,6 @@ impl Parse for JustifyItems { } } -#[cfg(feature = "gecko")] -impl From for ContentDistribution { - fn from(bits: u16) -> ContentDistribution { - let primary = - AlignFlags::from_bits_truncate((bits & ALIGN_ALL_BITS) as u8); - let fallback = - AlignFlags::from_bits_truncate((bits >> ALIGN_ALL_SHIFT) as u8); - ContentDistribution::with_fallback(primary, fallback) - } -} - -#[cfg(feature = "gecko")] -impl From for u16 { - fn from(v: ContentDistribution) -> u16 { - v.primary().bits() as u16 | - ((v.fallback().bits() as u16) << ALIGN_ALL_SHIFT) - } -} - // auto | normal | stretch | fn parse_auto_normal_stretch_baseline<'i, 't>( input: &mut Parser<'i, 't>, diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 2a9e05f7e75..1eb206de418 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -26,7 +26,7 @@ use values::specified::calc::CalcNode; pub use properties::animated_properties::TransitionProperty; pub use self::angle::Angle; #[cfg(feature = "gecko")] -pub use self::align::{AlignItems, ContentDistribution, SelfAlignment, JustifyItems}; +pub use self::align::{AlignContent, JustifyContent, AlignItems, ContentDistribution, SelfAlignment, JustifyItems}; pub use self::background::{BackgroundRepeat, BackgroundSize}; pub use self::border::{BorderCornerRadius, BorderImageSlice, BorderImageWidth}; pub use self::border::{BorderImageSideWidth, BorderRadius, BorderSideWidth, BorderSpacing};