diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index 268143514298..7b1403b492c5 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -46,7 +46,7 @@ use std::mem; use std::sync::Arc; use style::computed_values::{background_attachment, background_clip, background_origin}; use style::computed_values::{background_repeat, background_size, border_style}; -use style::computed_values::{cursor, image_rendering, overflow_x, border_image_slice}; +use style::computed_values::{cursor, image_rendering, overflow_x}; use style::computed_values::{pointer_events, position, transform_style, visibility}; use style::computed_values::_servo_overflow_clip_box as overflow_clip_box; use style::computed_values::filter::Filter; @@ -58,6 +58,7 @@ use style::properties::style_structs; use style::servo::restyle_damage::REPAINT; use style::values::{RGBA, computed}; use style::values::computed::{AngleOrCorner, Gradient, GradientKind, LengthOrPercentage, LengthOrPercentageOrAuto}; +use style::values::computed::NumberOrPercentage; use style::values::specified::{HorizontalDirection, VerticalDirection}; use style_traits::CSSPixel; use style_traits::cursor::Cursor; @@ -68,13 +69,13 @@ trait ResolvePercentage { fn resolve(&self, length: u32) -> u32; } -impl ResolvePercentage for border_image_slice::PercentageOrNumber { +impl ResolvePercentage for NumberOrPercentage { fn resolve(&self, length: u32) -> u32 { match *self { - border_image_slice::PercentageOrNumber::Percentage(p) => { + NumberOrPercentage::Percentage(p) => { (p.0 * length as f32).round() as u32 } - border_image_slice::PercentageOrNumber::Number(n) => { + NumberOrPercentage::Number(n) => { n.round() as u32 } } diff --git a/components/style/gecko/values.rs b/components/style/gecko/values.rs index cccb5ca697f3..64bef9d86be9 100644 --- a/components/style/gecko/values.rs +++ b/components/style/gecko/values.rs @@ -12,10 +12,11 @@ use gecko_bindings::structs::{nsStyleCoord, StyleGridTrackBreadth, StyleShapeRad use gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue}; use std::cmp::max; use values::{Auto, Either, ExtremumLength, None_, Normal}; -use values::computed::{Angle, LengthOrPercentageOrNone, Number}; -use values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto}; +use values::computed::{Angle, LengthOrPercentage, LengthOrPercentageOrAuto}; +use values::computed::{LengthOrPercentageOrNone, Number, NumberOrPercentage}; use values::computed::{MaxLength, MinLength}; use values::computed::basic_shape::ShapeRadius; +use values::specified::Percentage; use values::specified::grid::{TrackBreadth, TrackKeyword}; /// A trait that defines an interface to convert from and to `nsStyleCoord`s. @@ -62,6 +63,38 @@ impl GeckoStyleCoordConvertible for Number { } } +impl GeckoStyleCoordConvertible for Percentage { + fn to_gecko_style_coord(&self, coord: &mut T) { + coord.set_value(CoordDataValue::Percent(self.0)); + } + + fn from_gecko_style_coord(coord: &T) -> Option { + match coord.as_value() { + CoordDataValue::Percent(p) => Some(Percentage(p)), + _ => None, + } + } +} + +impl GeckoStyleCoordConvertible for NumberOrPercentage { + fn to_gecko_style_coord(&self, coord: &mut T) { + match *self { + NumberOrPercentage::Number(ref n) => n.to_gecko_style_coord(coord), + NumberOrPercentage::Percentage(ref p) => p.to_gecko_style_coord(coord), + } + } + + fn from_gecko_style_coord(coord: &T) -> Option { + match coord.as_value() { + CoordDataValue::Factor(f) => Some(NumberOrPercentage::Number(f)), + CoordDataValue::Percent(p) => { + Some(NumberOrPercentage::Percentage(Percentage(p))) + }, + _ => None, + } + } +} + impl GeckoStyleCoordConvertible for LengthOrPercentage { fn to_gecko_style_coord(&self, coord: &mut T) { let value = match *self { diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 3bd5e6b31207..cc890e4764a9 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -898,17 +898,9 @@ fn static_assert() { pub fn set_border_image_slice(&mut self, v: longhands::border_image_slice::computed_value::T) { use gecko_bindings::structs::{NS_STYLE_BORDER_IMAGE_SLICE_NOFILL, NS_STYLE_BORDER_IMAGE_SLICE_FILL}; - use properties::longhands::border_image_slice::computed_value::PercentageOrNumber; for (i, corner) in v.corners.iter().enumerate() { - match *corner { - PercentageOrNumber::Percentage(p) => { - self.gecko.mBorderImageSlice.data_at_mut(i).set_value(CoordDataValue::Percent(p.0)) - }, - PercentageOrNumber::Number(n) => { - self.gecko.mBorderImageSlice.data_at_mut(i).set_value(CoordDataValue::Factor(n)) - }, - } + corner.to_gecko_style_coord(&mut self.gecko.mBorderImageSlice.data_at_mut(i)); } let fill = if v.fill { diff --git a/components/style/properties/longhand/border.mako.rs b/components/style/properties/longhand/border.mako.rs index ab6abd844d14..79f2bfc246be 100644 --- a/components/style/properties/longhand/border.mako.rs +++ b/components/style/properties/longhand/border.mako.rs @@ -562,32 +562,25 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box", use std::fmt; use style_traits::ToCss; use values::HasViewportPercentage; - use values::specified::{Number, Percentage}; + use values::computed::NumberOrPercentage as ComputedNumberOrPercentage; + use values::specified::{NumberOrPercentage, Percentage}; no_viewport_percentage!(SpecifiedValue); pub mod computed_value { - use values::computed::Number; - use values::specified::Percentage; + use values::computed::NumberOrPercentage; #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct T { - pub corners: Vec, + pub corners: Vec, pub fill: bool, } - - #[derive(Debug, Clone, PartialEq)] - #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub enum PercentageOrNumber { - Percentage(Percentage), - Number(Number), - } } #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue { - pub corners: Vec, + pub corners: Vec, pub fill: bool, } @@ -622,60 +615,13 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box", } } - #[derive(Debug, Clone, PartialEq)] - #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub enum PercentageOrNumber { - Percentage(Percentage), - Number(Number), - } - - impl ToCss for computed_value::PercentageOrNumber { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - computed_value::PercentageOrNumber::Percentage(percentage) => percentage.to_css(dest), - computed_value::PercentageOrNumber::Number(number) => number.to_css(dest), - } - } - } - impl ToCss for PercentageOrNumber { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - PercentageOrNumber::Percentage(percentage) => percentage.to_css(dest), - PercentageOrNumber::Number(number) => number.to_css(dest), - } - } - } - - impl ToComputedValue for PercentageOrNumber { - type ComputedValue = computed_value::PercentageOrNumber; - - #[inline] - fn to_computed_value(&self, context: &Context) -> computed_value::PercentageOrNumber { - match *self { - PercentageOrNumber::Percentage(percentage) => - computed_value::PercentageOrNumber::Percentage(percentage), - PercentageOrNumber::Number(number) => - computed_value::PercentageOrNumber::Number(number.to_computed_value(context)), - } - } - #[inline] - fn from_computed_value(computed: &computed_value::PercentageOrNumber) -> Self { - match *computed { - computed_value::PercentageOrNumber::Percentage(percentage) => - PercentageOrNumber::Percentage(percentage), - computed_value::PercentageOrNumber::Number(number) => - PercentageOrNumber::Number(ToComputedValue::from_computed_value(&number)), - } - } - } - #[inline] pub fn get_initial_value() -> computed_value::T { computed_value::T { - corners: vec![computed_value::PercentageOrNumber::Percentage(Percentage(1.0)), - computed_value::PercentageOrNumber::Percentage(Percentage(1.0)), - computed_value::PercentageOrNumber::Percentage(Percentage(1.0)), - computed_value::PercentageOrNumber::Percentage(Percentage(1.0))], + corners: vec![ComputedNumberOrPercentage::Percentage(Percentage(1.0)), + ComputedNumberOrPercentage::Percentage(Percentage(1.0)), + ComputedNumberOrPercentage::Percentage(Percentage(1.0)), + ComputedNumberOrPercentage::Percentage(Percentage(1.0))], fill: false, } } @@ -683,7 +629,7 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box", #[inline] pub fn get_initial_specified_value() -> SpecifiedValue { SpecifiedValue { - corners: vec![PercentageOrNumber::Percentage(Percentage(1.0))], + corners: vec![NumberOrPercentage::Percentage(Percentage(1.0))], fill: false, } } @@ -730,23 +676,12 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box", } } - impl Parse for PercentageOrNumber { - fn parse(context: &ParserContext, input: &mut Parser) -> Result { - if let Ok(per) = input.try(|input| Percentage::parse(context, input)) { - return Ok(PercentageOrNumber::Percentage(per)); - } - - let num = try!(Number::parse_non_negative(input)); - Ok(PercentageOrNumber::Number(num)) - } - } - pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { let mut fill = input.try(|input| input.expect_ident_matching("fill")).is_ok(); let mut values = vec![]; for _ in 0..4 { - let value = input.try(|input| PercentageOrNumber::parse(context, input)); + let value = input.try(|input| NumberOrPercentage::parse(context, input)); match value { Ok(val) => values.push(val), Err(_) => break, diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 6a3caa4acaae..87eb9e972cc8 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -20,7 +20,7 @@ pub use self::image::{LengthOrKeyword, LengthOrPercentageOrKeyword}; pub use super::{Auto, Either, None_}; #[cfg(feature = "gecko")] pub use super::specified::{AlignItems, AlignJustifyContent, AlignJustifySelf, JustifyItems}; -pub use super::specified::{Angle, BorderStyle, GridLine, Time, UrlOrNone}; +pub use super::specified::{Angle, BorderStyle, GridLine, Percentage, Time, UrlOrNone}; pub use super::specified::url::SpecifiedUrl; pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto}; pub use self::length::{LengthOrPercentageOrAutoOrContent, LengthOrPercentageOrNone, LengthOrNone}; @@ -264,6 +264,46 @@ pub struct Shadow { /// A `` value. pub type Number = CSSFloat; +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] +pub enum NumberOrPercentage { + Percentage(Percentage), + Number(Number), +} + +impl ToComputedValue for specified::NumberOrPercentage { + type ComputedValue = NumberOrPercentage; + + #[inline] + fn to_computed_value(&self, context: &Context) -> NumberOrPercentage { + match *self { + specified::NumberOrPercentage::Percentage(percentage) => + NumberOrPercentage::Percentage(percentage.to_computed_value(context)), + specified::NumberOrPercentage::Number(number) => + NumberOrPercentage::Number(number.to_computed_value(context)), + } + } + #[inline] + fn from_computed_value(computed: &NumberOrPercentage) -> Self { + match *computed { + NumberOrPercentage::Percentage(percentage) => + specified::NumberOrPercentage::Percentage(ToComputedValue::from_computed_value(&percentage)), + NumberOrPercentage::Number(number) => + specified::NumberOrPercentage::Number(ToComputedValue::from_computed_value(&number)), + } + } +} + +impl ToCss for NumberOrPercentage { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + NumberOrPercentage::Percentage(percentage) => percentage.to_css(dest), + NumberOrPercentage::Number(number) => number.to_css(dest), + } + } +} + /// A type used for opacity. pub type Opacity = CSSFloat; diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index 7a16ce41d8fe..5aa839874b43 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -19,7 +19,7 @@ use style_traits::values::specified::AllowedNumericType; use super::{Angle, Number, SimplifiedValueNode, SimplifiedSumNode, Time}; use values::{Auto, CSSFloat, Either, FONT_MEDIUM_PX, HasViewportPercentage, None_, Normal}; use values::ExtremumLength; -use values::computed::Context; +use values::computed::{ComputedValueAsSpecified, Context}; pub use super::image::{AngleOrCorner, ColorStop, EndingShape as GradientEndingShape, Gradient}; pub use super::image::{GradientKind, HorizontalDirection, Image, LengthOrKeyword, LengthOrPercentageOrKeyword}; @@ -921,6 +921,8 @@ impl Parse for Percentage { } } +impl ComputedValueAsSpecified for Percentage {} + /// A length or a percentage value. /// /// TODO(emilio): Does this make any sense vs. CalcLengthOrPercentage? diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 46924f878204..a7c07de2bad6 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -572,6 +572,38 @@ impl ToCss for Number { } } +/// +/// Accepts only non-negative numbers. +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] +pub enum NumberOrPercentage { + Percentage(Percentage), + Number(Number), +} + +no_viewport_percentage!(NumberOrPercentage); + +impl Parse for NumberOrPercentage { + fn parse(context: &ParserContext, input: &mut Parser) -> Result { + if let Ok(per) = input.try(|input| Percentage::parse(context, input)) { + return Ok(NumberOrPercentage::Percentage(per)); + } + + let num = try!(Number::parse_non_negative(input)); + Ok(NumberOrPercentage::Number(num)) + } +} + +impl ToCss for NumberOrPercentage { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + NumberOrPercentage::Percentage(percentage) => percentage.to_css(dest), + NumberOrPercentage::Number(number) => number.to_css(dest), + } + } +} + #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)]