aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Gilbertson <james.gilbertson@luniv.ca>2015-03-05 07:04:27 -0700
committerJames Gilbertson <james.gilbertson@luniv.ca>2015-03-05 07:11:34 -0700
commitbc1c44bbc2245d84e1b948506a1024ab1308ab8d (patch)
tree1d173aaf3c0f0caf6bfed55531ce9cf2fbd1a57b
parent16a80473435f5a441e5f4d2266e6a8a18e687bbb (diff)
downloadservo-bc1c44bbc2245d84e1b948506a1024ab1308ab8d.tar.gz
servo-bc1c44bbc2245d84e1b948506a1024ab1308ab8d.zip
Implement viewport percentage length units ('vw', 'vh', 'vmin', 'vmax')
-rw-r--r--components/style/media_queries.rs2
-rw-r--r--components/style/properties.mako.rs2
-rw-r--r--components/style/values.rs60
3 files changed, 64 insertions, 0 deletions
diff --git a/components/style/media_queries.rs b/components/style/media_queries.rs
index f856db6a21e..97f75104c40 100644
--- a/components/style/media_queries.rs
+++ b/components/style/media_queries.rs
@@ -34,6 +34,8 @@ impl Range<specified::Length> {
let initial_font_size = longhands::font_size::get_initial_value();
value.to_computed_value(initial_font_size, initial_font_size)
}
+ &specified::Length::ViewportPercentage(value) =>
+ value.to_computed_value(viewport_size),
_ => unreachable!()
}
};
diff --git a/components/style/properties.mako.rs b/components/style/properties.mako.rs
index 2975f33dbd7..f0215854a16 100644
--- a/components/style/properties.mako.rs
+++ b/components/style/properties.mako.rs
@@ -19,6 +19,7 @@ use cssparser::{Parser, Color, RGBA, AtRuleParser, DeclarationParser,
DeclarationListParser, parse_important, ToCss};
use geom::num::Zero;
use geom::SideOffsets2D;
+use geom::size::Size2D;
use values::specified::BorderStyle;
use values::computed::{self, ToComputedValue};
@@ -3732,6 +3733,7 @@ pub fn cascade(viewport_size: Size2D<Au>,
let inherited_font_style = inherited_style.get_font();
computed::Context {
is_root_element: is_root_element,
+ viewport_size: viewport_size,
inherited_font_weight: inherited_font_style.font_weight,
inherited_font_size: inherited_font_style.font_size,
inherited_height: inherited_style.get_box().height,
diff --git a/components/style/values.rs b/components/style/values.rs
index c53f2ec86c0..5195f806563 100644
--- a/components/style/values.rs
+++ b/components/style/values.rs
@@ -52,11 +52,14 @@ pub type CSSFloat = f64;
pub mod specified {
use std::ascii::AsciiExt;
+ use std::cmp;
use std::f64::consts::PI;
use std::fmt;
use std::fmt::{Formatter, Debug};
+ use std::num::{NumCast, ToPrimitive};
use url::Url;
use cssparser::{self, Token, Parser, ToCss, CssStringWriter};
+ use geom::size::Size2D;
use parser::ParserContext;
use text_writer::{self, TextWriter};
use util::geometry::Au;
@@ -155,6 +158,51 @@ pub mod specified {
}
#[derive(Clone, PartialEq, Copy)]
+ pub enum ViewportPercentageLength {
+ Vw(CSSFloat),
+ Vh(CSSFloat),
+ Vmin(CSSFloat),
+ Vmax(CSSFloat)
+ }
+
+ impl fmt::Debug for ViewportPercentageLength {
+ #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_to_css(f) }
+ }
+
+ impl ToCss for ViewportPercentageLength {
+ fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
+ match self {
+ &ViewportPercentageLength::Vw(length) => write!(dest, "{}vw", length),
+ &ViewportPercentageLength::Vh(length) => write!(dest, "{}vh", length),
+ &ViewportPercentageLength::Vmin(length) => write!(dest, "{}vmin", length),
+ &ViewportPercentageLength::Vmax(length) => write!(dest, "{}vmax", length)
+ }
+ }
+ }
+
+ impl ViewportPercentageLength {
+ pub fn to_computed_value(&self, viewport_size: Size2D<Au>) -> Au {
+ macro_rules! to_unit {
+ ($viewport_dimension:expr) => {
+ $viewport_dimension.to_f64().unwrap() / 100.0
+ }
+ }
+
+ let value = match self {
+ &ViewportPercentageLength::Vw(length) =>
+ length * to_unit!(viewport_size.width),
+ &ViewportPercentageLength::Vh(length) =>
+ length * to_unit!(viewport_size.height),
+ &ViewportPercentageLength::Vmin(length) =>
+ length * to_unit!(cmp::min(viewport_size.width, viewport_size.height)),
+ &ViewportPercentageLength::Vmax(length) =>
+ length * to_unit!(cmp::max(viewport_size.width, viewport_size.height)),
+ };
+ NumCast::from(value).unwrap()
+ }
+ }
+
+ #[derive(Clone, PartialEq, Copy)]
pub struct CharacterWidth(pub i32);
impl CharacterWidth {
@@ -173,6 +221,8 @@ pub mod specified {
pub enum Length {
Absolute(Au), // application units
FontRelative(FontRelativeLength),
+ ViewportPercentage(ViewportPercentageLength),
+
/// HTML5 "character width", as defined in HTML5 § 14.5.4.
///
/// This cannot be specified by the user directly and is only generated by
@@ -189,6 +239,7 @@ pub mod specified {
match self {
&Length::Absolute(length) => write!(dest, "{}px", length.to_subpx()),
&Length::FontRelative(length) => length.to_css(dest),
+ &Length::ViewportPercentage(length) => length.to_css(dest),
&Length::ServoCharacterWidth(_)
=> panic!("internal CSS values should never be serialized"),
}
@@ -232,6 +283,11 @@ pub mod specified {
"ex" => Ok(Length::FontRelative(FontRelativeLength::Ex(value))),
"ch" => Err(()),
"rem" => Ok(Length::FontRelative(FontRelativeLength::Rem(value))),
+ // viewport percentages
+ "vw" => Ok(Length::ViewportPercentage(ViewportPercentageLength::Vw(value))),
+ "vh" => Ok(Length::ViewportPercentage(ViewportPercentageLength::Vh(value))),
+ "vmin" => Ok(Length::ViewportPercentage(ViewportPercentageLength::Vmin(value))),
+ "vmax" => Ok(Length::ViewportPercentage(ViewportPercentageLength::Vmax(value)))
_ => Err(())
}
}
@@ -701,6 +757,7 @@ pub mod computed {
use super::specified::{AngleOrCorner};
use super::{specified, CSSFloat};
pub use cssparser::Color as CSSColor;
+ use geom::size::Size2D;
use properties::longhands;
use std::fmt;
use url::Url;
@@ -727,6 +784,7 @@ pub mod computed {
pub border_bottom_present: bool,
pub border_left_present: bool,
pub is_root_element: bool,
+ pub viewport_size: Size2D<Au>
// TODO, as needed: viewport size, etc.
}
@@ -768,6 +826,8 @@ pub mod computed {
&specified::Length::Absolute(length) => length,
&specified::Length::FontRelative(length) =>
length.to_computed_value(context.font_size, context.root_font_size),
+ &specified::Length::ViewportPercentage(length) =>
+ length.to_computed_value(context.viewport_size),
&specified::Length::ServoCharacterWidth(length) =>
length.to_computed_value(context.font_size)
}