From cf20c627b5d5b5c51520991663fa071889c71abe Mon Sep 17 00:00:00 2001 From: Martin McNickle Date: Fri, 14 Feb 2020 15:48:01 +0000 Subject: [PATCH] style: Replace existing GridAutoFlow struct with a `bitflags!` backed one. Differential Revision: https://phabricator.services.mozilla.com/D62787 --- .../properties/longhands/position.mako.rs | 2 +- .../properties/shorthands/position.mako.rs | 32 ++-- components/style/values/specified/position.rs | 153 +++++++----------- 3 files changed, 75 insertions(+), 112 deletions(-) diff --git a/components/style/properties/longhands/position.mako.rs b/components/style/properties/longhands/position.mako.rs index 660da1a5a37..f43c2c56aa3 100644 --- a/components/style/properties/longhands/position.mako.rs +++ b/components/style/properties/longhands/position.mako.rs @@ -375,7 +375,7 @@ ${helpers.predefined_type( ${helpers.predefined_type( "grid-auto-flow", "GridAutoFlow", - "computed::GridAutoFlow::row()", + "computed::GridAutoFlow::ROW", engines="gecko", animation_value_type="discrete", spec="https://drafts.csswg.org/css-grid/#propdef-grid-auto-flow", diff --git a/components/style/properties/shorthands/position.mako.rs b/components/style/properties/shorthands/position.mako.rs index d9cb9da3342..48e56e6ef3c 100644 --- a/components/style/properties/shorthands/position.mako.rs +++ b/components/style/properties/shorthands/position.mako.rs @@ -549,7 +549,7 @@ use crate::properties::longhands::{grid_auto_columns, grid_auto_rows, grid_auto_flow}; use crate::values::generics::grid::GridTemplateComponent; use crate::values::specified::{GenericGridTemplateComponent, ImplicitGridTracks}; - use crate::values::specified::position::{AutoFlow, GridAutoFlow, GridTemplateAreas}; + use crate::values::specified::position::{GridAutoFlow, GridTemplateAreas}; pub fn parse_value<'i, 't>( context: &ParserContext, @@ -566,28 +566,28 @@ input: &mut Parser<'i, 't>, is_row: bool, ) -> Result> { - let mut auto_flow = None; - let mut dense = false; + let mut track = None; + let mut dense = GridAutoFlow::empty(); + for _ in 0..2 { if input.try(|i| i.expect_ident_matching("auto-flow")).is_ok() { - auto_flow = if is_row { - Some(AutoFlow::Row) + track = if is_row { + Some(GridAutoFlow::ROW) } else { - Some(AutoFlow::Column) + Some(GridAutoFlow::COLUMN) }; } else if input.try(|i| i.expect_ident_matching("dense")).is_ok() { - dense = true; + dense = GridAutoFlow::DENSE } else { break } } - auto_flow.map(|flow| { - GridAutoFlow { - autoflow: flow, - dense: dense, - } - }).ok_or(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) + if track.is_some() { + Ok(track.unwrap() | dense) + } else { + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) + } } if let Ok((rows, cols, areas)) = input.try(|i| super::grid_template::parse_grid_template(context, i)) { @@ -637,7 +637,7 @@ self.grid_template_areas, dest); } - if self.grid_auto_flow.autoflow == AutoFlow::Column { + if self.grid_auto_flow.contains(GridAutoFlow::COLUMN) { // It should fail to serialize if other branch of the if condition's values are set. if !self.grid_auto_rows.is_initial() || !self.grid_template_columns.is_initial() { @@ -653,7 +653,7 @@ self.grid_template_rows.to_css(dest)?; dest.write_str(" / auto-flow")?; - if self.grid_auto_flow.dense { + if self.grid_auto_flow.contains(GridAutoFlow::DENSE) { dest.write_str(" dense")?; } @@ -676,7 +676,7 @@ } dest.write_str("auto-flow")?; - if self.grid_auto_flow.dense { + if self.grid_auto_flow.contains(GridAutoFlow::DENSE) { dest.write_str(" dense")?; } diff --git a/components/style/values/specified/position.rs b/components/style/values/specified/position.rs index 3f01988e49d..ff8cfade968 100644 --- a/components/style/values/specified/position.rs +++ b/components/style/values/specified/position.rs @@ -7,6 +7,7 @@ //! //! [position]: https://drafts.csswg.org/css-backgrounds-3/#position +use crate::gecko_bindings::structs; use crate::parser::{Parse, ParserContext}; use crate::selector_map::PrecomputedHashMap; use crate::str::HTML_SPACE_CHARACTERS; @@ -350,66 +351,24 @@ impl Side for VerticalPositionKeyword { } } -#[derive( - Clone, - Copy, - Debug, - Eq, - MallocSizeOf, - PartialEq, - SpecifiedValueInfo, - ToComputedValue, - ToCss, - ToResolvedValue, - ToShmem, -)] -/// Auto-placement algorithm Option -pub enum AutoFlow { - /// The auto-placement algorithm places items by filling each row in turn, - /// adding new rows as necessary. - Row, - /// The auto-placement algorithm places items by filling each column in turn, - /// adding new columns as necessary. - Column, -} - -/// If `dense` is specified, `row` is implied. -fn is_row_dense(autoflow: &AutoFlow, dense: &bool) -> bool { - *autoflow == AutoFlow::Row && *dense -} - -#[derive( - Clone, - Copy, - Debug, - Eq, - MallocSizeOf, - PartialEq, - SpecifiedValueInfo, - ToComputedValue, - ToCss, - ToResolvedValue, - ToShmem, -)] -/// Controls how the auto-placement algorithm works -/// specifying exactly how auto-placed items get flowed into the grid -pub struct GridAutoFlow { - /// Specifiy how auto-placement algorithm fills each `row` or `column` in turn - #[css(contextual_skip_if = "is_row_dense")] - pub autoflow: AutoFlow, - /// Specify use `dense` packing algorithm or not - #[css(represents_keyword)] - pub dense: bool, -} - -impl GridAutoFlow { - #[inline] - /// Get default `grid-auto-flow` as `row` - pub fn row() -> GridAutoFlow { - GridAutoFlow { - autoflow: AutoFlow::Row, - dense: false, - } +bitflags! { + /// Controls how the auto-placement algorithm works + /// specifying exactly how auto-placed items get flowed into the grid + #[derive( + MallocSizeOf, + SpecifiedValueInfo, + ToComputedValue, + ToResolvedValue, + ToShmem + )] + #[value_info(other_values = "row,column,dense")] + pub struct GridAutoFlow: u8 { + /// 'row' - mutually exclusive with 'column' + const ROW = structs::NS_STYLE_GRID_AUTO_FLOW_ROW as u8; + /// 'column' - mutually exclusive with 'row' + const COLUMN = structs::NS_STYLE_GRID_AUTO_FLOW_COLUMN as u8; + /// 'dense' + const DENSE = structs::NS_STYLE_GRID_AUTO_FLOW_DENSE as u8; } } @@ -419,26 +378,26 @@ impl Parse for GridAutoFlow { _context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result> { - let mut value = None; - let mut dense = false; + let mut track = None; + let mut dense = GridAutoFlow::empty(); while !input.is_exhausted() { let location = input.current_source_location(); let ident = input.expect_ident()?; let success = match_ignore_ascii_case! { &ident, - "row" if value.is_none() => { - value = Some(AutoFlow::Row); + "row" if track.is_none() => { + track = Some(GridAutoFlow::ROW); true }, - "column" if value.is_none() => { - value = Some(AutoFlow::Column); + "column" if track.is_none() => { + track = Some(GridAutoFlow::COLUMN); true }, - "dense" if !dense => { - dense = true; + "dense" if dense.is_empty() => { + dense = GridAutoFlow::DENSE; true }, - _ => false + _ => false, }; if !success { return Err(location @@ -446,47 +405,51 @@ impl Parse for GridAutoFlow { } } - if value.is_some() || dense { - Ok(GridAutoFlow { - autoflow: value.unwrap_or(AutoFlow::Row), - dense: dense, - }) + if track.is_some() || !dense.is_empty() { + Ok(track.unwrap_or(GridAutoFlow::ROW) | dense) } else { Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } } +impl ToCss for GridAutoFlow { + fn to_css(&self, dest: &mut CssWriter) -> fmt::Result + where + W: Write, + { + if *self == GridAutoFlow::ROW { + return dest.write_str("row"); + } + + if *self == GridAutoFlow::COLUMN { + return dest.write_str("column"); + } + + if *self == GridAutoFlow::ROW | GridAutoFlow::DENSE { + return dest.write_str("dense"); + } + + if *self == GridAutoFlow::COLUMN | GridAutoFlow::DENSE { + return dest.write_str("column dense"); + } + + debug_assert!(false, "Unknown or invalid grid-autoflow value"); + Ok(()) + } +} + #[cfg(feature = "gecko")] impl From for GridAutoFlow { fn from(bits: u8) -> GridAutoFlow { - use crate::gecko_bindings::structs; - - GridAutoFlow { - autoflow: if bits & structs::NS_STYLE_GRID_AUTO_FLOW_ROW as u8 != 0 { - AutoFlow::Row - } else { - AutoFlow::Column - }, - dense: bits & structs::NS_STYLE_GRID_AUTO_FLOW_DENSE as u8 != 0, - } + GridAutoFlow::from_bits(bits).unwrap() } } #[cfg(feature = "gecko")] impl From for u8 { fn from(v: GridAutoFlow) -> u8 { - use crate::gecko_bindings::structs; - - let mut result: u8 = match v.autoflow { - AutoFlow::Row => structs::NS_STYLE_GRID_AUTO_FLOW_ROW as u8, - AutoFlow::Column => structs::NS_STYLE_GRID_AUTO_FLOW_COLUMN as u8, - }; - - if v.dense { - result |= structs::NS_STYLE_GRID_AUTO_FLOW_DENSE as u8; - } - result + v.bits } }