From 29f6db4d16b1d862d3348b4679eea5a515133c92 Mon Sep 17 00:00:00 2001 From: Boris Chiou Date: Tue, 6 Aug 2019 18:32:16 +0000 Subject: [PATCH] style: Support multiple track sizes for grid-auto-{columns|rows}. Support `+` on the implicit track sizing properties, grid-auto-columns and grid-auto-rows. Differential Revision: https://phabricator.services.mozilla.com/D38408 --- .../properties/longhands/position.mako.rs | 5 +- .../properties/shorthands/position.mako.rs | 18 +++---- components/style/values/computed/mod.rs | 4 ++ components/style/values/generics/grid.rs | 48 ++++++++++++++++--- components/style/values/specified/grid.rs | 19 +++++++- components/style/values/specified/mod.rs | 4 ++ 6 files changed, 76 insertions(+), 22 deletions(-) diff --git a/components/style/properties/longhands/position.mako.rs b/components/style/properties/longhands/position.mako.rs index b2e8acaf60b..a63f7637db4 100644 --- a/components/style/properties/longhands/position.mako.rs +++ b/components/style/properties/longhands/position.mako.rs @@ -357,16 +357,13 @@ ${helpers.predefined_type( )} % endfor - // NOTE: According to the spec, this should handle multiple values of ``, - // but gecko supports only a single value ${helpers.predefined_type( "grid-auto-%ss" % kind, - "TrackSize", + "ImplicitGridTracks", "Default::default()", engines="gecko", animation_value_type="discrete", spec="https://drafts.csswg.org/css-grid/#propdef-grid-auto-%ss" % kind, - boxed=True, )} ${helpers.predefined_type( diff --git a/components/style/properties/shorthands/position.mako.rs b/components/style/properties/shorthands/position.mako.rs index 4b7397719b1..81a54dbfa57 100644 --- a/components/style/properties/shorthands/position.mako.rs +++ b/components/style/properties/shorthands/position.mako.rs @@ -496,7 +496,7 @@ use crate::parser::Parse; use crate::properties::longhands::{grid_auto_columns, grid_auto_rows, grid_auto_flow}; use crate::values::generics::grid::GridTemplateComponent; - use crate::values::specified::{GenericGridTemplateComponent, TrackSize}; + use crate::values::specified::{GenericGridTemplateComponent, ImplicitGridTracks}; use crate::values::specified::position::{AutoFlow, GridAutoFlow, GridTemplateAreas}; pub fn parse_value<'i, 't>( @@ -506,8 +506,8 @@ let mut temp_rows = GridTemplateComponent::None; let mut temp_cols = GridTemplateComponent::None; let mut temp_areas = GridTemplateAreas::None; - let mut auto_rows = TrackSize::default(); - let mut auto_cols = TrackSize::default(); + let mut auto_rows = ImplicitGridTracks::default(); + let mut auto_cols = ImplicitGridTracks::default(); let mut flow = grid_auto_flow::get_initial_value(); fn parse_auto_flow<'i, 't>( @@ -568,8 +568,8 @@ /// Returns true if other sub properties except template-{rows,columns} are initial. fn is_grid_template(&self) -> bool { *self.grid_template_areas == GridTemplateAreas::None && - *self.grid_auto_rows == TrackSize::default() && - *self.grid_auto_columns == TrackSize::default() && + self.grid_auto_rows.is_initial() && + self.grid_auto_columns.is_initial() && *self.grid_auto_flow == grid_auto_flow::get_initial_value() } } @@ -587,7 +587,7 @@ if self.grid_auto_flow.autoflow == AutoFlow::Column { // It should fail to serialize if other branch of the if condition's values are set. - if *self.grid_auto_rows != TrackSize::default() || + if !self.grid_auto_rows.is_initial() || *self.grid_template_columns != GridTemplateComponent::None { return Ok(()); } @@ -605,13 +605,13 @@ dest.write_str(" dense")?; } - if !self.grid_auto_columns.is_default() { + if !self.grid_auto_columns.is_initial() { dest.write_str(" ")?; self.grid_auto_columns.to_css(dest)?; } } else { // It should fail to serialize if other branch of the if condition's values are set. - if *self.grid_auto_columns != TrackSize::default() || + if !self.grid_auto_columns.is_initial() || *self.grid_template_rows != GridTemplateComponent::None { return Ok(()); } @@ -628,7 +628,7 @@ dest.write_str(" dense")?; } - if !self.grid_auto_rows.is_default() { + if !self.grid_auto_rows.is_initial() { dest.write_str(" ")?; self.grid_auto_rows.to_css(dest)?; } diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index b017f195bd9..5decee9654e 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -7,6 +7,7 @@ use self::transform::DirectionVector; use super::animated::ToAnimatedValue; use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent; +use super::generics::grid::ImplicitGridTracks as GenericImplicitGridTracks; use super::generics::grid::{GenericGridLine, GenericTrackBreadth}; use super::generics::grid::{GenericTrackSize, TrackList as GenericTrackList}; use super::generics::transform::IsParallelTo; @@ -696,6 +697,9 @@ pub type TrackBreadth = GenericTrackBreadth; /// The computed value of a grid `` pub type TrackSize = GenericTrackSize; +/// The computed value of a grid `+` +pub type ImplicitGridTracks = GenericImplicitGridTracks; + /// The computed value of a grid `` /// (could also be `` or ``) pub type TrackList = GenericTrackList; diff --git a/components/style/values/generics/grid.rs b/components/style/values/generics/grid.rs index 7da6f54d147..876186696a2 100644 --- a/components/style/values/generics/grid.rs +++ b/components/style/values/generics/grid.rs @@ -290,16 +290,17 @@ impl TrackSize { } } -impl Default for TrackSize { - fn default() -> Self { - TrackSize::Breadth(TrackBreadth::Auto) +impl TrackSize { + /// Return true if it is `auto`. + #[inline] + pub fn is_auto(&self) -> bool { + *self == TrackSize::Breadth(TrackBreadth::Auto) } } -impl TrackSize { - /// Returns true if current TrackSize is same as default. - pub fn is_default(&self) -> bool { - *self == TrackSize::default() +impl Default for TrackSize { + fn default() -> Self { + TrackSize::Breadth(TrackBreadth::Auto) } } @@ -334,6 +335,39 @@ impl ToCss for TrackSize { } } +/// A `+`. +/// We use the empty slice as `auto`, and always parse `auto` as an empty slice. +/// This means it's impossible to have a slice containing only one auto item. +#[derive( + Clone, + Debug, + Default, + MallocSizeOf, + PartialEq, + SpecifiedValueInfo, + ToComputedValue, + ToCss, + ToResolvedValue, + ToShmem, +)] +#[repr(transparent)] +pub struct GenericImplicitGridTracks( + #[css(if_empty = "auto", iterable)] pub crate::OwnedSlice, +); + +pub use self::GenericImplicitGridTracks as ImplicitGridTracks; + +impl ImplicitGridTracks { + /// Returns true if current value is same as its initial value (i.e. auto). + pub fn is_initial(&self) -> bool { + debug_assert_ne!( + *self, + ImplicitGridTracks(crate::OwnedSlice::from(vec![Default::default()])) + ); + self.0.is_empty() + } +} + /// Helper function for serializing identifiers with a prefix and suffix, used /// for serializing (in grid). pub fn concat_serialize_idents( diff --git a/components/style/values/specified/grid.rs b/components/style/values/specified/grid.rs index 29629a6c0c6..2bbfd9164fd 100644 --- a/components/style/values/specified/grid.rs +++ b/components/style/values/specified/grid.rs @@ -6,8 +6,8 @@ //! [grids](https://drafts.csswg.org/css-grid/) use crate::parser::{Parse, ParserContext}; -use crate::values::generics::grid::{GridTemplateComponent, RepeatCount, TrackBreadth}; -use crate::values::generics::grid::{LineNameList, TrackRepeat, TrackSize}; +use crate::values::generics::grid::{GridTemplateComponent, ImplicitGridTracks, RepeatCount}; +use crate::values::generics::grid::{LineNameList, TrackBreadth, TrackRepeat, TrackSize}; use crate::values::generics::grid::{TrackList, TrackListValue}; use crate::values::specified::{Integer, LengthPercentage}; use crate::values::{CSSFloat, CustomIdent}; @@ -95,6 +95,21 @@ impl Parse for TrackSize { } } +impl Parse for ImplicitGridTracks> { + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { + use style_traits::{Separator, Space}; + let track_sizes = Space::parse(input, |i| TrackSize::parse(context, i))?; + if track_sizes.len() == 1 && track_sizes[0].is_auto() { + //`auto`, which is the initial value, is always represented by an empty slice. + return Ok(Default::default()); + } + return Ok(ImplicitGridTracks(track_sizes.into())); + } +} + /// Parse the grid line names into a vector of owned strings. /// /// diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 98f8116d5c0..21dd4f0d9b0 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -8,6 +8,7 @@ use super::computed::transform::DirectionVector; use super::computed::{Context, ToComputedValue}; +use super::generics::grid::ImplicitGridTracks as GenericImplicitGridTracks; use super::generics::grid::{GridLine as GenericGridLine, TrackBreadth as GenericTrackBreadth}; use super::generics::grid::{TrackList as GenericTrackList, TrackSize as GenericTrackSize}; use super::generics::transform::IsParallelTo; @@ -626,6 +627,9 @@ pub type TrackBreadth = GenericTrackBreadth; /// The specified value of a grid `` pub type TrackSize = GenericTrackSize; +/// The specified value of a grid `+` +pub type ImplicitGridTracks = GenericImplicitGridTracks; + /// The specified value of a grid `` /// (could also be `` or ``) pub type TrackList = GenericTrackList;