Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stylo: store specified value of grid layout repeat() function #18206

Merged
merged 1 commit into from Sep 11, 2017
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -20,7 +20,7 @@ use stylesheets::{Origin, RulesMutateError};
use values::computed::{Angle, CalcLengthOrPercentage, Gradient, Image};
use values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, Percentage};
use values::generics::box_::VerticalAlign;
use values::generics::grid::TrackSize;
use values::generics::grid::{TrackListValue, TrackSize};
use values::generics::image::{CompatMode, Image as GenericImage, GradientItem};
use values::generics::rect::Rect;
use values::specified::url::SpecifiedUrl;
@@ -896,6 +896,23 @@ impl TrackSize<LengthOrPercentage> {
}
}

impl TrackListValue<LengthOrPercentage> {
/// Return TrackSize from given two nsStyleCoord
pub fn from_gecko_style_coords<T: CoordData>(gecko_min: &T, gecko_max: &T) -> Self {
TrackListValue::TrackSize(TrackSize::from_gecko_style_coords(gecko_min, gecko_max))
}

/// Save TrackSize to given gecko fields.
pub fn to_gecko_style_coords<T: CoordDataMut>(&self, gecko_min: &mut T, gecko_max: &mut T) {
use values::generics::grid::TrackListValue;

match *self {
TrackListValue::TrackSize(ref size) => size.to_gecko_style_coords(gecko_min, gecko_max),
_ => unreachable!("Should only transform from track-size computed values"),
}
}
}

impl<T> Rect<T> where T: GeckoStyleCoordConvertible {
/// Convert this generic Rect to given Gecko fields.
pub fn to_gecko_rect(&self, sides: &mut ::gecko_bindings::structs::nsStyleSides) {
@@ -1897,7 +1897,7 @@ fn static_assert() {
use nsstring::nsStringRepr;
use values::CustomIdent;
use values::generics::grid::{GridTemplateComponent, LineNameList, RepeatCount};
use values::generics::grid::{TrackList, TrackListType, TrackRepeat, TrackSize};
use values::generics::grid::{TrackList, TrackListType, TrackListValue, TrackRepeat, TrackSize};

let value = match unsafe { ${self_grid}.mPtr.as_ref() } {
None => return GridTemplateComponent::None,
@@ -1967,7 +1967,7 @@ fn static_assert() {

auto_repeat = Some(TrackRepeat{count, line_names, track_sizes});
} else {
values.push(track_size);
values.push(TrackListValue::TrackSize(track_size));
}
}

@@ -243,7 +243,8 @@
use parser::Parse;
use properties::longhands::grid_template_areas::TemplateAreas;
use values::{Either, None_};
use values::generics::grid::{LineNameList, TrackSize, TrackList, TrackListType, concat_serialize_idents};
use values::generics::grid::{LineNameList, TrackSize, TrackList, TrackListType};
use values::generics::grid::{TrackListValue, concat_serialize_idents};
use values::specified::{GridTemplateComponent, GenericGridTemplateComponent};
use values::specified::grid::parse_line_names;

@@ -287,7 +288,7 @@
line_names.push(names.into_boxed_slice());
strings.push(string);
let size = input.try(|i| TrackSize::parse(context, i)).unwrap_or_default();
values.push(size);
values.push(TrackListValue::TrackSize(size));
names = input.try(parse_line_names).unwrap_or(vec![].into_boxed_slice()).into_vec();
if let Ok(v) = input.try(parse_line_names) {
names.extend(v.into_vec());
@@ -380,7 +381,11 @@
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() {
if list.auto_repeat.is_some() ||
list.values.iter().any(|v| match *v {
TrackListValue::TrackRepeat(_) => true,
_ => false,
}) {
return Ok(());
}
list
@@ -395,8 +400,14 @@
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(());
GenericGridTemplateComponent::TrackList(ref list) => {
if list.auto_repeat.is_some() ||
list.values.iter().any(|v| match *v {
TrackListValue::TrackRepeat(_) => true,
_ => false,
}) {
return Ok(());
}
},
// Also the shorthands don't accept subgrids unlike longhand.
// We should fail without an error here.
@@ -407,9 +418,9 @@
}

let mut names_iter = track_list.line_names.iter();
for (((i, string), names), size) in areas.strings.iter().enumerate()
.zip(&mut names_iter)
.zip(track_list.values.iter()) {
for (((i, string), names), value) in areas.strings.iter().enumerate()
.zip(&mut names_iter)
.zip(track_list.values.iter()) {
if i > 0 {
dest.write_str(" ")?;
}
@@ -420,7 +431,7 @@

string.to_css(dest)?;
dest.write_str(" ")?;
size.to_css(dest)?;
value.to_css(dest)?;
}

if let Some(names) = names_iter.next() {
@@ -394,45 +394,27 @@ pub struct TrackRepeat<L> {

impl<L: ToCss> ToCss for TrackRepeat<L> {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
// If repeat count is an integer instead of a keyword, it should'n serialized
// with `repeat` function. It should serialized with `N` repeated form.
let repeat_count = match self.count {
RepeatCount::Number(integer) => integer.value(),
_ => {
dest.write_str("repeat(")?;
self.count.to_css(dest)?;
dest.write_str(", ")?;
1
},
};

for i in 0..repeat_count {
if i != 0 {
dest.write_str("repeat(")?;
self.count.to_css(dest)?;
dest.write_str(", ")?;

let mut line_names_iter = self.line_names.iter();
for (i, (ref size, ref names)) in self.track_sizes.iter()
.zip(&mut line_names_iter).enumerate() {
if i > 0 {
dest.write_str(" ")?;
}

let mut line_names_iter = self.line_names.iter();
for (i, (ref size, ref names)) in self.track_sizes.iter()
.zip(&mut line_names_iter).enumerate() {
if i > 0 {
dest.write_str(" ")?;
}

concat_serialize_idents("[", "] ", names, " ", dest)?;
size.to_css(dest)?;
}

if let Some(line_names_last) = line_names_iter.next() {
concat_serialize_idents(" [", "]", line_names_last, " ", dest)?;
}
concat_serialize_idents("[", "] ", names, " ", dest)?;
size.to_css(dest)?;
}

match self.count {
RepeatCount::AutoFill | RepeatCount::AutoFit => {
dest.write_str(")")?;
},
_ => {},
if let Some(line_names_last) = line_names_iter.next() {
concat_serialize_idents(" [", "]", line_names_last, " ", dest)?;
}

dest.write_str(")")?;

Ok(())
}
}
@@ -475,6 +457,16 @@ impl<L: Clone> TrackRepeat<L> {
}
}

/// Track list values. Can be <track-size> or <track-repeat>
#[derive(Clone, Debug, PartialEq, ToComputedValue, ToCss)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum TrackListValue<T> {

This comment has been minimized.

@wafflespeanut

wafflespeanut Sep 5, 2017

Member

We could use Either here - not sure whether it's particularly useful, but that's what I did on 26540df 😄

This comment has been minimized.

@ferjm

ferjm Sep 6, 2017

Author Member

TBH I would prefer to keep the current enum if you don't mind. Either syntax feels less clear than an explicit enum, specially since we need to do things like https://github.com/servo/servo/pull/18206/files#diff-ea526b2e68fb17c4d9af5ce82d3cc64eR899

/// A <track-size> value.
TrackSize(TrackSize<T>),
/// A <track-repeat> value.
TrackRepeat(TrackRepeat<T>),
}

/// The type of a `<track-list>` as determined during parsing.
///
/// https://drafts.csswg.org/css-grid/#typedef-track-list
@@ -504,21 +496,20 @@ impl ComputedValueAsSpecified for TrackListType {}
///
/// https://drafts.csswg.org/css-grid/#typedef-track-list
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, Debug, PartialEq, ToComputedValue)]
#[derive(Clone, Debug, PartialEq)]
pub struct TrackList<T> {
/// The type of this `<track-list>` (auto, explicit or general).
///
/// 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>` values.
pub values: Vec<TrackSize<T>>,
/// A vector of `<track-size> | <track-repeat>` values.
pub values: Vec<TrackListValue<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>`.
#[compute(clone)]
pub line_names: Box<[Box<[CustomIdent]>]>,
/// `<auto-repeat>` value. There can only be one `<auto-repeat>` in a TrackList.
pub auto_repeat: Option<TrackRepeat<T>>,
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.