diff --git a/components/style/properties/shorthand/position.mako.rs b/components/style/properties/shorthand/position.mako.rs index 1d4586552c2..9acc385b0aa 100644 --- a/components/style/properties/shorthand/position.mako.rs +++ b/components/style/properties/shorthand/position.mako.rs @@ -372,14 +372,41 @@ template_columns.to_css(dest) }, Either::First(ref areas) => { + // The length of template-area and template-rows values should be equal. + if areas.strings.len() != template_rows.track_list_len() { + return Ok(()); + } + let track_list = match *template_rows { - GenericGridTemplateComponent::TrackList(ref list) => list, + GenericGridTemplateComponent::TrackList(ref list) => { + // We should fail if there is a `repeat` function. `grid` and + // `grid-template` shorthands doesn't accept that. Only longhand accepts. + if list.auto_repeat.is_some() { + return Ok(()); + } + list + }, // Others template components shouldn't exist with normal shorthand values. // But if we need to serialize a group of longhand sub-properties for // the shorthand, we should be able to return empty string instead of crashing. _ => return Ok(()), }; + // We need to check some values that longhand accepts but shorthands don't. + match *template_columns { + // We should fail if there is a `repeat` function. `grid` and + // `grid-template` shorthands doesn't accept that. Only longhand accepts that. + GenericGridTemplateComponent::TrackList(ref list) if list.auto_repeat.is_some() => { + return Ok(()); + }, + // Also the shorthands don't accept subgrids unlike longhand. + // We should fail without an error here. + GenericGridTemplateComponent::Subgrid(_) => { + return Ok(()); + }, + _ => {}, + } + let mut names_iter = track_list.line_names.iter(); for (((i, string), names), size) in areas.strings.iter().enumerate() .zip(&mut names_iter) @@ -431,8 +458,8 @@ use properties::longhands::{grid_auto_columns, grid_auto_rows, grid_auto_flow}; use properties::longhands::grid_auto_flow::computed_value::{AutoFlow, T as SpecifiedAutoFlow}; use values::{Either, None_}; - use values::generics::grid::GridTemplateComponent; - use values::specified::{LengthOrPercentage, TrackSize}; + use values::generics::grid::{GridTemplateComponent, TrackListType}; + use values::specified::{GenericGridTemplateComponent, LengthOrPercentage, TrackSize}; pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { @@ -510,6 +537,14 @@ impl<'a> ToCss for LonghandsToSerialize<'a> { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + // `grid` shorthand resets these properties. If they are not zero, that means they + // are changed by longhands and in that case we should fail serializing `grid`. + if *self.grid_row_gap != LengthOrPercentage::zero() || + *self.grid_column_gap != LengthOrPercentage::zero() { + return Ok(()); + } + + if *self.grid_template_areas != Either::Second(None_) || (*self.grid_template_rows != GridTemplateComponent::None && *self.grid_template_columns != GridTemplateComponent::None) || @@ -520,6 +555,19 @@ } 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() || + *self.grid_template_columns != GridTemplateComponent::None { + return Ok(()); + } + + // It should fail to serialize if template-rows value is not Explicit. + if let GenericGridTemplateComponent::TrackList(ref list) = *self.grid_template_rows { + if list.list_type != TrackListType::Explicit { + return Ok(()); + } + } + self.grid_template_rows.to_css(dest)?; dest.write_str(" / auto-flow")?; if self.grid_auto_flow.dense { @@ -531,6 +579,19 @@ 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() || + *self.grid_template_rows != GridTemplateComponent::None { + return Ok(()); + } + + // It should fail to serialize if template-column value is not Explicit. + if let GenericGridTemplateComponent::TrackList(ref list) = *self.grid_template_columns { + if list.list_type != TrackListType::Explicit { + return Ok(()); + } + } + dest.write_str("auto-flow")?; if self.grid_auto_flow.dense { dest.write_str(" dense")?; diff --git a/components/style/values/generics/grid.rs b/components/style/values/generics/grid.rs index fbbc6a4d532..83b96199a84 100644 --- a/components/style/values/generics/grid.rs +++ b/components/style/values/generics/grid.rs @@ -701,3 +701,13 @@ pub enum GridTemplateComponent { /// A `subgrid ?` Subgrid(LineNameList), } + +impl GridTemplateComponent { + /// Returns length of the s + pub fn track_list_len(&self) -> usize { + match *self { + GridTemplateComponent::TrackList(ref tracklist) => tracklist.values.len(), + _ => 0, + } + } +}