Auto merge of #17630 - canaltinova:grid-shorthand, r=wafflespeanut

stylo: Properly serialize grid shorthand

It was failing to serialize correctly when grid was `<'grid-template'>` or some different edge cases.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17630)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-07-06 22:06:36 -07:00 committed by GitHub
commit 9268540e67
2 changed files with 28 additions and 17 deletions

View file

@ -307,9 +307,7 @@ ${helpers.predefined_type("object-position",
#[derive(PartialEq, Clone, Eq, Copy, Debug)] #[derive(PartialEq, Clone, Eq, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct T { pub struct T {
// This needs to be an Option because we need an indicator to determine whether this property is pub autoflow: AutoFlow,
// parsed or not in `grid` shorthand. Otherwise we can't properly serialize it.
pub autoflow: Option<AutoFlow>,
pub dense: bool, pub dense: bool,
} }
} }
@ -319,7 +317,7 @@ ${helpers.predefined_type("object-position",
impl ToCss for computed_value::T { impl ToCss for computed_value::T {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
dest.write_str(match self.autoflow.unwrap_or(computed_value::AutoFlow::Row) { dest.write_str(match self.autoflow {
computed_value::AutoFlow::Column => "column", computed_value::AutoFlow::Column => "column",
computed_value::AutoFlow::Row => "row" computed_value::AutoFlow::Row => "row"
})?; })?;
@ -332,9 +330,8 @@ ${helpers.predefined_type("object-position",
#[inline] #[inline]
pub fn get_initial_value() -> computed_value::T { pub fn get_initial_value() -> computed_value::T {
computed_value::T { computed_value::T {
// None should resolve to `computed_value::AutoFlow::Row` in layout. autoflow: computed_value::AutoFlow::Row,
autoflow: None, dense: false,
dense: false
} }
} }
@ -370,7 +367,7 @@ ${helpers.predefined_type("object-position",
if value.is_some() || dense { if value.is_some() || dense {
Ok(computed_value::T { Ok(computed_value::T {
autoflow: value, autoflow: value.unwrap_or(AutoFlow::Row),
dense: dense, dense: dense,
}) })
} else { } else {
@ -385,12 +382,12 @@ ${helpers.predefined_type("object-position",
use self::computed_value::AutoFlow; use self::computed_value::AutoFlow;
SpecifiedValue { SpecifiedValue {
autoflow: Some( autoflow:
if bits & structs::NS_STYLE_GRID_AUTO_FLOW_ROW as u8 != 0 { if bits & structs::NS_STYLE_GRID_AUTO_FLOW_ROW as u8 != 0 {
AutoFlow::Row AutoFlow::Row
} else { } else {
AutoFlow::Column AutoFlow::Column
}), },
dense: dense:
bits & structs::NS_STYLE_GRID_AUTO_FLOW_DENSE as u8 != 0, bits & structs::NS_STYLE_GRID_AUTO_FLOW_DENSE as u8 != 0,
} }
@ -403,7 +400,7 @@ ${helpers.predefined_type("object-position",
use gecko_bindings::structs; use gecko_bindings::structs;
use self::computed_value::AutoFlow; use self::computed_value::AutoFlow;
let mut result: u8 = match v.autoflow.unwrap_or(AutoFlow::Row) { let mut result: u8 = match v.autoflow {
AutoFlow::Row => structs::NS_STYLE_GRID_AUTO_FLOW_ROW as u8, AutoFlow::Row => structs::NS_STYLE_GRID_AUTO_FLOW_ROW as u8,
AutoFlow::Column => structs::NS_STYLE_GRID_AUTO_FLOW_COLUMN as u8, AutoFlow::Column => structs::NS_STYLE_GRID_AUTO_FLOW_COLUMN as u8,
}; };

View file

@ -460,7 +460,7 @@
auto_flow.map(|flow| { auto_flow.map(|flow| {
SpecifiedAutoFlow { SpecifiedAutoFlow {
autoflow: Some(flow), autoflow: flow,
dense: dense, dense: dense,
} }
}).ok_or(StyleParseError::UnspecifiedError.into()) }).ok_or(StyleParseError::UnspecifiedError.into())
@ -473,10 +473,10 @@
} else if let Ok(rows) = input.try(|i| GridTemplateComponent::parse(context, i)) { } else if let Ok(rows) = input.try(|i| GridTemplateComponent::parse(context, i)) {
temp_rows = rows; temp_rows = rows;
input.expect_delim('/')?; input.expect_delim('/')?;
flow = parse_auto_flow(input, true)?; flow = parse_auto_flow(input, false)?;
auto_cols = grid_auto_columns::parse(context, input).unwrap_or_default(); auto_cols = grid_auto_columns::parse(context, input).unwrap_or_default();
} else { } else {
flow = parse_auto_flow(input, false)?; flow = parse_auto_flow(input, true)?;
auto_rows = input.try(|i| grid_auto_rows::parse(context, i)).unwrap_or_default(); auto_rows = input.try(|i| grid_auto_rows::parse(context, i)).unwrap_or_default();
input.expect_delim('/')?; input.expect_delim('/')?;
temp_cols = GridTemplateComponent::parse(context, input)?; temp_cols = GridTemplateComponent::parse(context, input)?;
@ -495,16 +495,30 @@
}) })
} }
/// Returns true if every sub property value of `grid` shorthand is initial.
impl<'a> LonghandsToSerialize<'a> {
fn is_initial(&self) -> bool {
*self.grid_template_rows == GridTemplateComponent::None &&
*self.grid_template_columns == GridTemplateComponent::None &&
*self.grid_template_areas == Either::Second(None_) &&
*self.grid_auto_rows == TrackSize::default() &&
*self.grid_auto_columns == TrackSize::default() &&
*self.grid_auto_flow == grid_auto_flow::get_initial_value()
}
}
impl<'a> ToCss for LonghandsToSerialize<'a> { impl<'a> ToCss for LonghandsToSerialize<'a> {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
if self.grid_auto_flow.autoflow.is_none() { if *self.grid_template_areas != Either::Second(None_) ||
(*self.grid_template_rows != GridTemplateComponent::None &&
*self.grid_template_columns != GridTemplateComponent::None) ||
self.is_initial() {
return super::grid_template::serialize_grid_template(self.grid_template_rows, return super::grid_template::serialize_grid_template(self.grid_template_rows,
self.grid_template_columns, self.grid_template_columns,
self.grid_template_areas, dest); self.grid_template_areas, dest);
} }
// This unwrap is safe because we checked the None part in previous if condition. if self.grid_auto_flow.autoflow == AutoFlow::Column {
if self.grid_auto_flow.autoflow.unwrap() == AutoFlow::Row {
self.grid_template_rows.to_css(dest)?; self.grid_template_rows.to_css(dest)?;
dest.write_str(" / auto-flow")?; dest.write_str(" / auto-flow")?;
if self.grid_auto_flow.dense { if self.grid_auto_flow.dense {