Convert TrackList's 'values' field to store only TrackSize.

It was storing both TrackSize and TrackRepeat before and TrackRepeat have to be
converted into sequence of TrackSize during serialization. Instead of doing this
in serialization process(which is hard and hacky), we converted to do this in
parsing process. We were doing this conversion in the ComputedValue conversion.
So we only had to move this process to parsing.
This commit is contained in:
Nazım Can Altınova 2017-07-14 15:41:26 -07:00
parent 8e14d93602
commit ade76f10b7
5 changed files with 92 additions and 130 deletions

View file

@ -10,7 +10,7 @@ use parser::{Parse, ParserContext};
use std::{fmt, mem, usize};
use style_traits::{ToCss, ParseError, StyleParseError};
use values::{CSSFloat, CustomIdent};
use values::computed::{self, ComputedValueAsSpecified, Context, ToComputedValue};
use values::computed::{ComputedValueAsSpecified, Context, ToComputedValue};
use values::specified::Integer;
use values::specified::grid::parse_line_names;
@ -411,13 +411,9 @@ impl<L: ToCss> ToCss for TrackRepeat<L> {
Ok(())
}
}
impl<L: ToComputedValue> ToComputedValue for TrackRepeat<L> {
type ComputedValue = TrackRepeat<L::ComputedValue>;
#[inline]
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
// If the repeat count is numeric, then expand the values and merge accordingly.
impl<L: Clone> TrackRepeat<L> {
/// If the repeat count is numeric, then expand the values and merge accordingly.
pub fn expand(&self) -> Self {
if let RepeatCount::Number(num) = self.count {
let mut line_names = vec![];
let mut track_sizes = vec![];
@ -428,7 +424,7 @@ impl<L: ToComputedValue> ToComputedValue for TrackRepeat<L> {
for (size, names) in self.track_sizes.iter().zip(&mut names_iter) {
prev_names.extend_from_slice(&names);
line_names.push(mem::replace(&mut prev_names, vec![]));
track_sizes.push(size.to_computed_value(context));
track_sizes.push(size.clone());
}
if let Some(names) = names_iter.next() {
@ -446,13 +442,25 @@ impl<L: ToComputedValue> ToComputedValue for TrackRepeat<L> {
} else { // if it's auto-fit/auto-fill, then it's left to the layout.
TrackRepeat {
count: self.count,
track_sizes: self.track_sizes.iter()
.map(|l| l.to_computed_value(context))
.collect(),
track_sizes: self.track_sizes.clone(),
line_names: self.line_names.clone(),
}
}
}
}
impl<L: ToComputedValue> ToComputedValue for TrackRepeat<L> {
type ComputedValue = TrackRepeat<L::ComputedValue>;
#[inline]
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
TrackRepeat {
count: self.count,
track_sizes: self.track_sizes.iter()
.map(|val| val.to_computed_value(context))
.collect(),
line_names: self.line_names.clone(),
}
}
#[inline]
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
@ -489,6 +497,8 @@ pub enum TrackListType {
Explicit,
}
impl ComputedValueAsSpecified for TrackListType {}
/// A grid `<track-list>` type.
///
/// https://drafts.csswg.org/css-grid/#typedef-track-list
@ -500,22 +510,16 @@ pub struct TrackList<T> {
/// In order to avoid parsing the same value multiple times, this does a single traversal
/// and arrives at the type of value it has parsed (or bails out gracefully with an error).
pub list_type: TrackListType,
/// A vector of `<track-size> | <track-repeat>` values. In its specified form, it may contain
/// any value, but once it's computed, it contains only `<track_size>` values.
///
/// Note that this may also contain `<auto-repeat>` at an index. If it exists, it's
/// given by the index in `TrackListType::Auto`
pub values: Vec<T>,
/// A vector of `<track-size>` values.
pub values: Vec<TrackSize<T>>,
/// `<line-names>` accompanying `<track-size> | <track-repeat>` values.
///
/// If there's no `<line-names>`, then it's represented by an empty vector.
/// For N values, there will be N+1 `<line-names>`, and so this vector's
/// length is always one value more than that of the `<track-size>`.
pub line_names: Vec<Vec<CustomIdent>>,
/// `<auto-repeat>` value after computation. This field is necessary, because
/// the `values` field (after computation) will only contain `<track-size>` values, and
/// we need something to represent this function.
pub auto_repeat: Option<TrackRepeat<computed::LengthOrPercentage>>,
/// `<auto-repeat>` value. There can only be one `<auto-repeat>` in a TrackList.
pub auto_repeat: Option<TrackRepeat<T>>,
}
impl<T: ToCss> ToCss for TrackList<T> {
@ -552,7 +556,8 @@ impl<T: ToCss> ToCss for TrackList<T> {
},
}
if values_iter.peek().is_some() || line_names_iter.peek().map_or(false, |v| !v.is_empty()) {
if values_iter.peek().is_some() || line_names_iter.peek().map_or(false, |v| !v.is_empty()) ||
(idx + 1 == auto_idx) {
dest.write_str(" ")?;
}
}