diff --git a/components/style/gecko/values.rs b/components/style/gecko/values.rs index 5260adbb10f..39faa388040 100644 --- a/components/style/gecko/values.rs +++ b/components/style/gecko/values.rs @@ -10,8 +10,8 @@ use gecko_bindings::structs::{NS_RADIUS_CLOSEST_SIDE, NS_RADIUS_FARTHEST_SIDE}; use gecko_bindings::structs::nsStyleCoord; use gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue}; use std::cmp::max; -use values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone}; -use values::computed::Angle; +use values::computed::{LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto}; +use values::computed::{LengthOrPercentageOrNone, Angle}; use values::computed::basic_shape::ShapeRadius; pub trait StyleCoordHelpers { @@ -108,6 +108,24 @@ impl GeckoStyleCoordConvertible for LengthOrPercentageOrNone { } } +impl GeckoStyleCoordConvertible for LengthOrNumber { + fn to_gecko_style_coord(&self, coord: &mut T) { + let value = match *self { + LengthOrNumber::Length(au) => CoordDataValue::Coord(au.0), + LengthOrNumber::Number(number) => CoordDataValue::Factor(number), + }; + coord.set_value(value); + } + + fn from_gecko_style_coord(coord: &T) -> Option { + match coord.as_value() { + CoordDataValue::Coord(coord) => Some(LengthOrNumber::Length(Au(coord))), + CoordDataValue::Factor(f) => Some(LengthOrNumber::Number(f)), + _ => None, + } + } +} + impl GeckoStyleCoordConvertible for ShapeRadius { fn to_gecko_style_coord(&self, coord: &mut T) { match *self { diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index b291246a8f3..cead90fc571 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -683,14 +683,9 @@ fn static_assert() { } pub fn set_border_image_outset(&mut self, v: longhands::border_image_outset::computed_value::T) { - use properties::longhands::border_image_outset::computed_value::LengthOrNumber; % for side in SIDES: - match v.${side.index} { - LengthOrNumber::Length(l) => - l.to_gecko_style_coord(&mut self.gecko.mBorderImageOutset.data_at_mut(${side.index})), - LengthOrNumber::Number(n) => - self.gecko.mBorderImageOutset.data_at_mut(${side.index}).set_value(CoordDataValue::Factor(n)), - } + v.${side.index}.to_gecko_style_coord(&mut self.gecko.mBorderImageOutset + .data_at_mut(${side.index})); % endfor } diff --git a/components/style/properties/longhand/border.mako.rs b/components/style/properties/longhand/border.mako.rs index 0d98a0c1600..73795afd844 100644 --- a/components/style/properties/longhand/border.mako.rs +++ b/components/style/properties/longhand/border.mako.rs @@ -141,25 +141,27 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box", <%helpers:longhand name="border-image-outset" products="gecko" animatable="False"> use cssparser::ToCss; use std::fmt; + use values::HasViewportPercentage; use values::LocalToCss; - use values::NoViewportPercentage; - use values::specified::{Length, Number}; + use values::specified::LengthOrNumber; - impl NoViewportPercentage for SpecifiedValue {} + impl HasViewportPercentage for SpecifiedValue { + fn has_viewport_percentage(&self) -> bool { + let mut viewport_percentage = false; + for value in self.0.iter() { + let vp = value.has_viewport_percentage(); + viewport_percentage = vp || viewport_percentage; + } + viewport_percentage + } + } pub mod computed_value { - use values::computed::{Length, Number}; + use values::computed::LengthOrNumber; #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct T(pub LengthOrNumber, pub LengthOrNumber, pub LengthOrNumber, pub LengthOrNumber); - - #[derive(Debug, Clone, PartialEq)] - #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub enum LengthOrNumber { - Length(Length), - Number(Number), - } } #[derive(Debug, Clone, PartialEq)] @@ -188,59 +190,12 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box", } } - #[derive(Debug, Clone, PartialEq)] - #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub enum LengthOrNumber { - Length(Length), - Number(Number), - } - - impl ToCss for computed_value::LengthOrNumber { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - computed_value::LengthOrNumber::Length(len) => len.to_css(dest), - computed_value::LengthOrNumber::Number(number) => number.to_css(dest), - } - } - } - impl ToCss for LengthOrNumber { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - LengthOrNumber::Length(len) => len.to_css(dest), - LengthOrNumber::Number(number) => number.to_css(dest), - } - } - } - - impl ToComputedValue for LengthOrNumber { - type ComputedValue = computed_value::LengthOrNumber; - - #[inline] - fn to_computed_value(&self, context: &Context) -> computed_value::LengthOrNumber { - match *self { - LengthOrNumber::Length(len) => - computed_value::LengthOrNumber::Length(len.to_computed_value(context)), - LengthOrNumber::Number(number) => - computed_value::LengthOrNumber::Number(number.to_computed_value(context)), - } - } - #[inline] - fn from_computed_value(computed: &computed_value::LengthOrNumber) -> Self { - match *computed { - computed_value::LengthOrNumber::Length(len) => - LengthOrNumber::Length(ToComputedValue::from_computed_value(&len)), - computed_value::LengthOrNumber::Number(number) => - LengthOrNumber::Number(ToComputedValue::from_computed_value(&number)), - } - } - } - #[inline] pub fn get_initial_value() -> computed_value::T { - computed_value::T(computed_value::LengthOrNumber::Number(0.0), - computed_value::LengthOrNumber::Number(0.0), - computed_value::LengthOrNumber::Number(0.0), - computed_value::LengthOrNumber::Number(0.0)) + computed_value::T(computed::LengthOrNumber::Number(0.0), + computed::LengthOrNumber::Number(0.0), + computed::LengthOrNumber::Number(0.0), + computed::LengthOrNumber::Number(0.0)) } impl ToComputedValue for SpecifiedValue { @@ -278,18 +233,6 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box", } } - impl Parse for LengthOrNumber { - fn parse(input: &mut Parser) -> Result { - let length = input.try(|input| Length::parse(input)); - if let Ok(len) = length { - return Ok(LengthOrNumber::Length(len)); - } - - let num = try!(Number::parse_non_negative(input)); - Ok(LengthOrNumber::Number(num)) - } - } - pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { let mut values = vec![]; for _ in 0..4 { diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index 72056f0bbdd..204c6071ce8 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -5,7 +5,7 @@ use app_units::Au; use ordered_float::NotNaN; use std::fmt; -use super::{ToComputedValue, Context}; +use super::{Number, ToComputedValue, Context}; use values::{CSSFloat, LocalToCss, specified}; pub use cssparser::Color as CSSColor; @@ -506,3 +506,53 @@ impl ::cssparser::ToCss for LengthOrNone { } } } + +#[derive(Clone, PartialEq)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +pub enum LengthOrNumber { + Length(Length), + Number(Number), +} + +impl fmt::Debug for LengthOrNumber { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + LengthOrNumber::Length(length) => write!(f, "{:?}", length), + LengthOrNumber::Number(number) => write!(f, "{:?}", number), + } + } +} + +impl ToComputedValue for specified::LengthOrNumber { + type ComputedValue = LengthOrNumber; + + #[inline] + fn to_computed_value(&self, context: &Context) -> LengthOrNumber { + match *self { + specified::LengthOrNumber::Length(len) => + LengthOrNumber::Length(len.to_computed_value(context)), + specified::LengthOrNumber::Number(number) => + LengthOrNumber::Number(number.to_computed_value(context)), + } + } + #[inline] + fn from_computed_value(computed: &LengthOrNumber) -> Self { + match *computed { + LengthOrNumber::Length(len) => + specified::LengthOrNumber::Length(ToComputedValue::from_computed_value(&len)), + LengthOrNumber::Number(number) => + specified::LengthOrNumber::Number(ToComputedValue::from_computed_value(&number)), + } + } +} + +impl ::cssparser::ToCss for LengthOrNumber { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + LengthOrNumber::Length(len) => len.to_css(dest), + LengthOrNumber::Number(number) => number.to_css(dest), + } + } +} + +pub type Length = Au; diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index de5dfa76844..6307c8b06a5 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -12,7 +12,7 @@ pub use cssparser::Color as CSSColor; pub use self::image::{EndingShape as GradientShape, Gradient, GradientKind, Image}; pub use self::image::{LengthOrKeyword, LengthOrPercentageOrKeyword}; pub use super::specified::{Angle, BorderStyle, Time, UrlExtraData, UrlOrNone}; -pub use self::length::{CalcLengthOrPercentage, LengthOrPercentage, LengthOrPercentageOrAuto}; +pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto}; pub use self::length::{LengthOrPercentageOrAutoOrContent, LengthOrPercentageOrNone, LengthOrNone}; pub mod basic_shape; @@ -147,7 +147,5 @@ impl ::cssparser::ToCss for BorderRadiusSize { } } - -pub type Length = Au; pub type Number = CSSFloat; pub type Opacity = CSSFloat; diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index 3ce892fdcad..bcd320da425 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -11,7 +11,7 @@ use std::cmp; use std::fmt; use std::ops::Mul; use style_traits::values::specified::AllowedNumericType; -use super::{Angle, SimplifiedValueNode, SimplifiedSumNode, Time}; +use super::{Angle, Number, SimplifiedValueNode, SimplifiedSumNode, Time}; use values::{CSSFloat, FONT_MEDIUM_PX, HasViewportPercentage, LocalToCss, computed}; pub use super::image::{AngleOrCorner, ColorStop, EndingShape as GradientEndingShape, Gradient}; @@ -1014,3 +1014,40 @@ impl LengthOrPercentageOrAutoOrContent { } } +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +pub enum LengthOrNumber { + Length(Length), + Number(Number), +} + +impl HasViewportPercentage for LengthOrNumber { + fn has_viewport_percentage(&self) -> bool { + match *self { + LengthOrNumber::Length(length) => length.has_viewport_percentage(), + _ => false + } + } +} + +impl ToCss for LengthOrNumber { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + LengthOrNumber::Length(len) => len.to_css(dest), + LengthOrNumber::Number(number) => number.to_css(dest), + } + } +} + +impl Parse for LengthOrNumber { + fn parse(input: &mut Parser) -> Result { + let length = input.try(Length::parse); + if let Ok(len) = length { + return Ok(LengthOrNumber::Length(len)); + } + + let num = try!(Number::parse_non_negative(input)); + Ok(LengthOrNumber::Number(num)) + } +} + diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 30ca7266185..84ad99c6112 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -22,8 +22,8 @@ pub use self::image::{AngleOrCorner, ColorStop, EndingShape as GradientEndingSha pub use self::image::{GradientKind, HorizontalDirection, Image, LengthOrKeyword, LengthOrPercentageOrKeyword}; pub use self::image::{SizeKeyword, VerticalDirection}; pub use self::length::{FontRelativeLength, ViewportPercentageLength, CharacterWidth, Length, CalcLengthOrPercentage}; -pub use self::length::{Percentage, LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone}; -pub use self::length::{LengthOrNone, LengthOrPercentageOrAutoOrContent, CalcUnit}; +pub use self::length::{Percentage, LengthOrNone, LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto}; +pub use self::length::{LengthOrPercentageOrNone, LengthOrPercentageOrAutoOrContent, CalcUnit}; pub mod basic_shape; pub mod image;