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

Cleaning up CalcLengthOrPercentage #15063

Merged
merged 2 commits into from
Jan 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 11 additions & 4 deletions components/style/values/computed/length.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use std::fmt;
use style_traits::ToCss;
use super::{Number, ToComputedValue, Context};
use values::{Auto, CSSFloat, Either, None_, Normal, specified};
use values::specified::length::{FontRelativeLength, ViewportPercentageLength};

pub use cssparser::Color as CSSColor;
pub use super::image::{EndingShape as GradientShape, Gradient, GradientKind, Image};
Expand Down Expand Up @@ -105,29 +106,35 @@ impl ToComputedValue for specified::CalcLengthOrPercentage {
length += absolute;
}

for val in &[self.vw, self.vh, self.vmin, self.vmax] {
for val in &[self.vw.map(ViewportPercentageLength::Vw),
self.vh.map(ViewportPercentageLength::Vh),
self.vmin.map(ViewportPercentageLength::Vmin),
self.vmax.map(ViewportPercentageLength::Vmax)] {
if let Some(val) = *val {
length += val.to_computed_value(context.viewport_size());
}
}

for val in &[self.ch, self.em, self.ex, self.rem] {
for val in &[self.ch.map(FontRelativeLength::Ch),
self.em.map(FontRelativeLength::Em),
self.ex.map(FontRelativeLength::Ex),
self.rem.map(FontRelativeLength::Rem)] {
if let Some(val) = *val {
length += val.to_computed_value(context, /* use inherited */ false);
}
}

CalcLengthOrPercentage {
length: length,
percentage: self.percentage.map(|p| p.0),
percentage: self.percentage,
}
}

#[inline]
fn from_computed_value(computed: &CalcLengthOrPercentage) -> Self {
specified::CalcLengthOrPercentage {
absolute: Some(computed.length),
percentage: computed.percentage.map(specified::Percentage),
percentage: computed.percentage,
..Default::default()
}
}
Expand Down
79 changes: 47 additions & 32 deletions components/style/values/specified/length.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,15 +440,15 @@ pub enum CalcUnit {
#[allow(missing_docs)]
pub struct CalcLengthOrPercentage {
pub absolute: Option<Au>,
pub vw: Option<ViewportPercentageLength>,
pub vh: Option<ViewportPercentageLength>,
pub vmin: Option<ViewportPercentageLength>,
pub vmax: Option<ViewportPercentageLength>,
pub em: Option<FontRelativeLength>,
pub ex: Option<FontRelativeLength>,
pub ch: Option<FontRelativeLength>,
pub rem: Option<FontRelativeLength>,
pub percentage: Option<Percentage>,
pub vw: Option<CSSFloat>,
pub vh: Option<CSSFloat>,
pub vmin: Option<CSSFloat>,
pub vmax: Option<CSSFloat>,
pub em: Option<CSSFloat>,
pub ex: Option<CSSFloat>,
pub ch: Option<CSSFloat>,
pub rem: Option<CSSFloat>,
pub percentage: Option<CSSFloat>,
}

impl CalcLengthOrPercentage {
Expand Down Expand Up @@ -671,15 +671,15 @@ impl CalcLengthOrPercentage {

Ok(CalcLengthOrPercentage {
absolute: absolute.map(Au),
vw: vw.map(ViewportPercentageLength::Vw),
vh: vh.map(ViewportPercentageLength::Vh),
vmax: vmax.map(ViewportPercentageLength::Vmax),
vmin: vmin.map(ViewportPercentageLength::Vmin),
em: em.map(FontRelativeLength::Em),
ex: ex.map(FontRelativeLength::Ex),
ch: ch.map(FontRelativeLength::Ch),
rem: rem.map(FontRelativeLength::Rem),
percentage: percentage.map(Percentage),
vw: vw,
vh: vh,
vmax: vmax,
vmin: vmin,
em: em,
ex: ex,
ch: ch,
rem: rem,
percentage: percentage,
})
}

Expand Down Expand Up @@ -767,21 +767,26 @@ impl ToCss for CalcLengthOrPercentage {
};
}

let mut first_value = true;
macro_rules! first_value_check {
() => {
if !first_value {
try!(dest.write_str(" + "));
} else {
first_value = false;
}
};
}

macro_rules! serialize {
( $( $val:ident ),* ) => {
{
let mut first_value = true;
$(
if let Some(val) = self.$val {
if !first_value {
try!(write!(dest, " + "));
} else {
first_value = false;
}
try!(val.to_css(dest));
}
)*
}
$(
if let Some(val) = self.$val {
first_value_check!();
try!(val.to_css(dest));
try!(dest.write_str(stringify!($val)));
}
)*
};
}

Expand All @@ -792,11 +797,21 @@ impl ToCss for CalcLengthOrPercentage {
try!(write!(dest, "calc("));
}

serialize!(ch, em, ex, absolute, rem, vh, vmax, vmin, vw, percentage);
serialize!(ch, em, ex, rem, vh, vmax, vmin, vw);
if let Some(val) = self.absolute {
first_value_check!();
try!(val.to_css(dest));
}

if let Some(val) = self.percentage {
first_value_check!();
try!(write!(dest, "{}%", val * 100.));
}

if count > 1 {
try!(write!(dest, ")"));
}

Ok(())
}
}
Expand Down
4 changes: 2 additions & 2 deletions tests/wpt/mozilla/tests/mozilla/calc.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@

// Alphabetical order
['calc(0ch + 0px + 0pt + 0pc + 0in + 0cm + 0mm + 0rem + 0em + 0ex + 0% + 0vw + 0vh + 0vmin + 0vmax)',
'calc(0ch + 0em + 0ex + 0px + 0rem + 0vh + 0vmax + 0vmin + 0vw + 0%)',
'calc(0ch + 0em + 0ex + 0rem + 0vh + 0vmax + 0vmin + 0vw + 0px + 0%)',
'0px'],

// Simplification
['calc((2 - 1) * 10px)', '10px', '10px'],
['calc(((3 - 1) * (8 + 4)) * 10px)', '240px', '240px'],
['calc(5 * (20px / 2 + 7 * (3em + 12px/4 + (8 - 2) * 2rem)))', 'calc(105em + 155px + 420rem)', '8555px'],
['calc(5 * (20px / 2 + 7 * (3em + 12px/4 + (8 - 2) * 2rem)))', 'calc(105em + 420rem + 155px)', '8555px'],

];

Expand Down