diff --git a/components/style/properties.mako.rs b/components/style/properties.mako.rs index fa9aa4e9617..1ec5b97bd2c 100644 --- a/components/style/properties.mako.rs +++ b/components/style/properties.mako.rs @@ -775,8 +775,7 @@ pub mod longhands { % endfor &T::Length(length) => write!(f, "{:?}", length), &T::Percentage(number) => write!(f, "{}%", number), - // XXX HACK WRONG - &T::Calc(calc) => write!(f, "{}%", 10.), + &T::Calc(calc) => write!(f, "{:?}", calc) } } } @@ -1914,9 +1913,9 @@ pub mod longhands { specified::LengthOrPercentage::Length(value) => value, specified::LengthOrPercentage::Percentage(value) => specified::Length::FontRelative(specified::FontRelativeLength::Em(value)), - // XXX WRONG HACK - specified::LengthOrPercentage::Calc(calc) => - specified::Length::FontRelative(specified::FontRelativeLength::Em(20.)), + // FIXME(dzbarsky) handle calc for font-size + specified::LengthOrPercentage::Calc(_) => + specified::Length::FontRelative(specified::FontRelativeLength::Em(1.)), }) .or_else(|()| { match_ignore_ascii_case! { try!(input.expect_ident()), diff --git a/components/style/values.rs b/components/style/values.rs index fb84901239a..92f61754df6 100644 --- a/components/style/values.rs +++ b/components/style/values.rs @@ -607,35 +607,61 @@ pub mod specified { impl ToCss for Calc { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - // XXX WRONG HACK - try!(write!(dest, "calc(")); - if let Some(FontRelativeLength::Em(em)) = self.em { - try!(write!(dest, "{}em", em)); - } - if let Some(FontRelativeLength::Ex(ex)) = self.ex { - try!(write!(dest, "{}ex", ex)); - } - if let Some(absolute) = self.absolute { - try!(write!(dest, "{}px", Au::to_px(absolute))); - } - if let Some(FontRelativeLength::Rem(rem)) = self.rem { - try!(write!(dest, "{}rem", rem)); - } - if let Some(ViewportPercentageLength::Vh(vh)) = self.vh { - try!(write!(dest, "{}vh", vh)); - } - if let Some(ViewportPercentageLength::Vmax(vmax)) = self.vmax { - try!(write!(dest, "{}vmax", vmax)); - } - if let Some(ViewportPercentageLength::Vmin(vmin)) = self.vmin { - try!(write!(dest, "{}vmin", vmin)); - } - if let Some(ViewportPercentageLength::Vw(vw)) = self.vw { - try!(write!(dest, "{}vw", vw)); + + macro_rules! count { + ( $( $val:ident ),* ) => { + { + let mut count = 0; + $( + if let Some(_) = self.$val { + count += 1; + } + )* + count + } + }; } + macro_rules! serialize { + ( $( [$val:ident; $name:expr] ),* ) => { + { + let mut first_value = true; + $( + if let Some(val) = self.$val { + if !first_value { + try!(write!(dest, " + ")); + } else { + first_value = false; + } + try!(write!(dest, "{:?}{}", val, $name)); + } + )* + } + }; + } - write!(dest, ")") + let count = count!(em, ex, absolute, rem, vh, vmax, vmin, vw, percentage); + assert!(count > 0); + + if count > 1 { + try!(write!(dest, "calc(")); + } + + serialize!( + [em; "em"], + [ex; "ex"], + [absolute; "px"], + [rem; "rem"], + [vh; "vh"], + [vmax; "vmax"], + [vmin; "vmin"], + [vw; "vw"], + [percentage; "%"]); + + if count > 1 { + try!(write!(dest, ")")); + } + Ok(()) } } @@ -1308,8 +1334,7 @@ pub mod computed { match self { &LengthOrPercentage::Length(length) => write!(f, "{:?}", length), &LengthOrPercentage::Percentage(percentage) => write!(f, "{}%", percentage * 100.), - // XXX HACK WRONG - &LengthOrPercentage::Calc(calc) => write!(f, "{}%", 100.), + &LengthOrPercentage::Calc(calc) => write!(f, "{:?}", calc), } } } @@ -1356,8 +1381,7 @@ pub mod computed { &LengthOrPercentageOrAuto::Length(length) => write!(f, "{:?}", length), &LengthOrPercentageOrAuto::Percentage(percentage) => write!(f, "{}%", percentage * 100.), &LengthOrPercentageOrAuto::Auto => write!(f, "auto"), - // XXX HACK WRONG - &LengthOrPercentageOrAuto::Calc(calc) => write!(f, "{}%", 100.), + &LengthOrPercentageOrAuto::Calc(calc) => write!(f, "{:?}", calc), } } } diff --git a/components/style/viewport.rs b/components/style/viewport.rs index bb38050f9b4..cc56030e226 100644 --- a/components/style/viewport.rs +++ b/components/style/viewport.rs @@ -9,7 +9,8 @@ use parser::{ParserContext, log_css_error}; use properties::longhands; use stylesheets::Origin; use util::geometry::{Au, PagePx, ViewportPx}; -use values::specified::{AllowedNumericType, Length, LengthOrPercentageOrAuto}; +use values::computed::{Context, ToComputedValue}; +use values::specified::{AllowedNumericType, LengthOrPercentageOrAuto}; use std::ascii::AsciiExt; use std::collections::hash_map::{Entry, HashMap}; @@ -420,25 +421,42 @@ impl ViewportConstraints { let initial_viewport = Size2D::new(Au::from_f32_px(initial_viewport.width.get()), Au::from_f32_px(initial_viewport.height.get())); + + let context = Context { + is_root_element: false, + viewport_size: initial_viewport, + inherited_font_weight: longhands::font_weight::get_initial_value(), + inherited_font_size: longhands::font_size::get_initial_value(), + inherited_text_decorations_in_effect: longhands::_servo_text_decorations_in_effect::get_initial_value(), + font_size: longhands::font_size::get_initial_value(), + root_font_size: longhands::font_size::get_initial_value(), + display: longhands::display::get_initial_value(), + color: longhands::color::get_initial_value(), + text_decoration: longhands::text_decoration::get_initial_value(), + overflow_x: longhands::overflow_x::get_initial_value(), + overflow_y: longhands::overflow_y::get_initial_value(), + positioned: false, + floated: false, + border_top_present: false, + border_right_present: false, + border_bottom_present: false, + border_left_present: false, + outline_style_present: false, + }; + macro_rules! to_pixel_length { ($value:ident, $dimension:ident) => { if let Some($value) = $value { match $value { - LengthOrPercentageOrAuto::Length(ref value) => Some(match value { - &Length::Absolute(length) => length, - &Length::FontRelative(length) => { - let initial_font_size = longhands::font_size::get_initial_value(); - length.to_computed_value(initial_font_size, initial_font_size) - } - &Length::ViewportPercentage(length) => - length.to_computed_value(initial_viewport), - _ => unreachable!() - }), + LengthOrPercentageOrAuto::Length(value) => + Some(value.to_computed_value(&context)), LengthOrPercentageOrAuto::Percentage(value) => Some(initial_viewport.$dimension.scale_by(value)), LengthOrPercentageOrAuto::Auto => None, - // XXX WRONG HACK - LengthOrPercentageOrAuto::Calc(calc) => None, + LengthOrPercentageOrAuto::Calc(calc) => { + let calc = calc.to_computed_value(&context); + Some(initial_viewport.$dimension.scale_by(calc.percentage()) + calc.length()) + } } } else { None