diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index ce8861cc5a9..7e0373f9262 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -62,9 +62,8 @@ use std::mem::{forget, uninitialized, transmute, zeroed}; use std::{cmp, ops, ptr}; use stylesheets::{MallocSizeOfWithRepeats, SizeOfState}; use values::{self, Auto, CustomIdent, Either, KeyframesName}; -use values::computed::{NonNegativeAu, ToComputedValue}; +use values::computed::{NonNegativeAu, ToComputedValue, Percentage}; use values::computed::effects::{BoxShadow, Filter, SimpleShadow}; -use values::computed::length::Percentage; use computed_values::border_style; pub mod style_structs { diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index b3b7af805fd..ed4a38255d3 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -9,7 +9,7 @@ use ordered_float::NotNaN; use std::fmt; use style_traits::ToCss; use style_traits::values::specified::AllowedLengthType; -use super::{Number, ToComputedValue, Context}; +use super::{Number, ToComputedValue, Context, Percentage}; use values::{Auto, CSSFloat, Either, ExtremumLength, None_, Normal, specified}; use values::computed::{NonNegativeAu, NonNegativeNumber}; use values::generics::NonNegative; @@ -19,47 +19,6 @@ use values::specified::length::ViewportPercentageLength; pub use super::image::Image; pub use values::specified::{Angle, BorderStyle, Time, UrlOrNone}; -/// A computed `` value. -/// -/// FIXME(emilio): why is this in length.rs? -#[derive(Clone, Copy, Debug, Default, PartialEq, HasViewportPercentage)] -#[cfg_attr(feature = "servo", derive(Deserialize, HeapSizeOf, Serialize))] -pub struct Percentage(pub CSSFloat); - -impl Percentage { - /// 0% - #[inline] - pub fn zero() -> Self { - Percentage(0.) - } - - /// 100% - #[inline] - pub fn hundred() -> Self { - Percentage(1.) - } -} - -impl ToCss for Percentage { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - write!(dest, "{}%", self.0 * 100.) - } -} - -impl ToComputedValue for specified::Percentage { - type ComputedValue = Percentage; - - #[inline] - fn to_computed_value(&self, _: &Context) -> Percentage { - Percentage(self.get()) - } - - #[inline] - fn from_computed_value(computed: &Percentage) -> Self { - specified::Percentage::new(computed.0) - } -} - impl ToComputedValue for specified::NoCalcLength { type ComputedValue = Au; diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 8cbcbca7eea..a1206529f80 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -43,7 +43,7 @@ pub use super::specified::{BorderStyle, UrlOrNone}; pub use super::generics::grid::GridLine; pub use super::specified::url::SpecifiedUrl; pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNone, LengthOrNumber, LengthOrPercentage}; -pub use self::length::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone, MaxLength, MozLength, Percentage}; +pub use self::length::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone, MaxLength, MozLength}; pub use self::length::NonNegativeLengthOrPercentage; pub use self::position::Position; pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind, SVGStrokeDashArray, SVGWidth}; @@ -645,3 +645,42 @@ impl From for NonNegativeAu { NonNegative::(au) } } + +/// A computed `` value. +#[derive(Clone, Copy, Debug, Default, PartialEq, HasViewportPercentage)] +#[cfg_attr(feature = "servo", derive(Deserialize, HeapSizeOf, Serialize))] +pub struct Percentage(pub CSSFloat); + +impl Percentage { + /// 0% + #[inline] + pub fn zero() -> Self { + Percentage(0.) + } + + /// 100% + #[inline] + pub fn hundred() -> Self { + Percentage(1.) + } +} + +impl ToCss for Percentage { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + write!(dest, "{}%", self.0 * 100.) + } +} + +impl ToComputedValue for specified::Percentage { + type ComputedValue = Percentage; + + #[inline] + fn to_computed_value(&self, _: &Context) -> Percentage { + Percentage(self.get()) + } + + #[inline] + fn from_computed_value(computed: &Percentage) -> Self { + specified::Percentage::new(computed.0) + } +} diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index 8959743655e..943185fce12 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -15,9 +15,9 @@ use std::{cmp, fmt, mem}; use std::ascii::AsciiExt; use std::ops::Mul; use style_traits::{HasViewportPercentage, ToCss, ParseError, StyleParseError}; -use style_traits::values::specified::{AllowedLengthType, AllowedNumericType}; +use style_traits::values::specified::AllowedLengthType; use stylesheets::CssRuleType; -use super::{AllowQuirks, Number, ToComputedValue}; +use super::{AllowQuirks, Number, ToComputedValue, Percentage}; use values::{Auto, CSSFloat, Either, FONT_MEDIUM_PX, None_, Normal}; use values::ExtremumLength; use values::computed::{self, Context}; @@ -756,124 +756,6 @@ pub type NonNegativeLengthOrAuto = Either; /// Either a NonNegativeLength or a NonNegativeNumber value. pub type NonNegativeLengthOrNumber = Either; -/// A percentage value. -#[derive(Clone, Copy, Debug, Default, PartialEq)] -#[cfg_attr(feature = "servo", derive(HeapSizeOf))] -pub struct Percentage { - /// The percentage value as a float. - /// - /// [0 .. 100%] maps to [0.0 .. 1.0] - value: CSSFloat, - /// If this percentage came from a calc() expression, this tells how - /// clamping should be done on the value. - calc_clamping_mode: Option, -} - -no_viewport_percentage!(Percentage); - -impl ToCss for Percentage { - fn to_css(&self, dest: &mut W) -> fmt::Result - where W: fmt::Write, - { - if self.calc_clamping_mode.is_some() { - dest.write_str("calc(")?; - } - - write!(dest, "{}%", self.value * 100.)?; - - if self.calc_clamping_mode.is_some() { - dest.write_str(")")?; - } - Ok(()) - } -} - -impl Percentage { - /// Create a percentage from a numeric value. - pub fn new(value: CSSFloat) -> Self { - Self { - value, - calc_clamping_mode: None, - } - } - - /// Get the underlying value for this float. - pub fn get(&self) -> CSSFloat { - self.calc_clamping_mode.map_or(self.value, |mode| mode.clamp(self.value)) - } - - /// Reverse this percentage, preserving calc-ness. - /// - /// For example: If it was 20%, convert it into 80%. - pub fn reverse(&mut self) { - let new_value = 1. - self.value; - self.value = new_value; - } - - - /// Parse a specific kind of percentage. - pub fn parse_with_clamping_mode<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - num_context: AllowedNumericType, - ) -> Result> { - // FIXME: remove early returns when lifetimes are non-lexical - match *input.next()? { - Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => { - return Ok(Percentage::new(unit_value)) - } - Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {} - ref t => return Err(BasicParseError::UnexpectedToken(t.clone()).into()) - } - - let result = input.parse_nested_block(|i| { - CalcNode::parse_percentage(context, i) - })?; - - // TODO(emilio): -moz-image-rect is the only thing that uses - // the clamping mode... I guess we could disallow it... - Ok(Percentage { - value: result, - calc_clamping_mode: Some(num_context), - }) - } - - /// Parses a percentage token, but rejects it if it's negative. - pub fn parse_non_negative<'i, 't>(context: &ParserContext, - input: &mut Parser<'i, 't>) - -> Result> { - Self::parse_with_clamping_mode(context, input, AllowedNumericType::NonNegative) - } - - /// 0% - #[inline] - pub fn zero() -> Self { - Percentage { - value: 0., - calc_clamping_mode: None, - } - } - - /// 100% - #[inline] - pub fn hundred() -> Self { - Percentage { - value: 1., - calc_clamping_mode: None, - } - } -} - -impl Parse for Percentage { - #[inline] - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't> - ) -> Result> { - Self::parse_with_clamping_mode(context, input, AllowedNumericType::All) - } -} - /// A length or a percentage value. #[allow(missing_docs)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 9a2dd857efc..0c95e9a3693 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -41,7 +41,7 @@ pub use self::length::{AbsoluteLength, CalcLengthOrPercentage, CharacterWidth}; pub use self::length::{FontRelativeLength, Length, LengthOrNone, LengthOrNumber}; pub use self::length::{LengthOrPercentage, LengthOrPercentageOrAuto}; pub use self::length::{LengthOrPercentageOrNone, MaxLength, MozLength}; -pub use self::length::{NoCalcLength, Percentage, ViewportPercentageLength}; +pub use self::length::{NoCalcLength, ViewportPercentageLength}; pub use self::length::NonNegativeLengthOrPercentage; pub use self::rect::LengthOrNumberRect; pub use self::position::{Position, PositionComponent}; @@ -1046,3 +1046,121 @@ impl ToCss for Attr { } impl ComputedValueAsSpecified for Attr {} + +/// A percentage value. +#[derive(Clone, Copy, Debug, Default, PartialEq)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +pub struct Percentage { + /// The percentage value as a float. + /// + /// [0 .. 100%] maps to [0.0 .. 1.0] + value: CSSFloat, + /// If this percentage came from a calc() expression, this tells how + /// clamping should be done on the value. + calc_clamping_mode: Option, +} + +no_viewport_percentage!(Percentage); + +impl ToCss for Percentage { + fn to_css(&self, dest: &mut W) -> fmt::Result + where W: fmt::Write, + { + if self.calc_clamping_mode.is_some() { + dest.write_str("calc(")?; + } + + write!(dest, "{}%", self.value * 100.)?; + + if self.calc_clamping_mode.is_some() { + dest.write_str(")")?; + } + Ok(()) + } +} + +impl Percentage { + /// Create a percentage from a numeric value. + pub fn new(value: CSSFloat) -> Self { + Self { + value, + calc_clamping_mode: None, + } + } + + /// Get the underlying value for this float. + pub fn get(&self) -> CSSFloat { + self.calc_clamping_mode.map_or(self.value, |mode| mode.clamp(self.value)) + } + + /// Reverse this percentage, preserving calc-ness. + /// + /// For example: If it was 20%, convert it into 80%. + pub fn reverse(&mut self) { + let new_value = 1. - self.value; + self.value = new_value; + } + + + /// Parse a specific kind of percentage. + pub fn parse_with_clamping_mode<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + num_context: AllowedNumericType, + ) -> Result> { + // FIXME: remove early returns when lifetimes are non-lexical + match *input.next()? { + Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => { + return Ok(Percentage::new(unit_value)) + } + Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {} + ref t => return Err(BasicParseError::UnexpectedToken(t.clone()).into()) + } + + let result = input.parse_nested_block(|i| { + CalcNode::parse_percentage(context, i) + })?; + + // TODO(emilio): -moz-image-rect is the only thing that uses + // the clamping mode... I guess we could disallow it... + Ok(Percentage { + value: result, + calc_clamping_mode: Some(num_context), + }) + } + + /// Parses a percentage token, but rejects it if it's negative. + pub fn parse_non_negative<'i, 't>(context: &ParserContext, + input: &mut Parser<'i, 't>) + -> Result> { + Self::parse_with_clamping_mode(context, input, AllowedNumericType::NonNegative) + } + + /// 0% + #[inline] + pub fn zero() -> Self { + Percentage { + value: 0., + calc_clamping_mode: None, + } + } + + /// 100% + #[inline] + pub fn hundred() -> Self { + Percentage { + value: 1., + calc_clamping_mode: None, + } + } +} + +impl Parse for Percentage { + #[inline] + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't> + ) -> Result> { + Self::parse_with_clamping_mode(context, input, AllowedNumericType::All) + } +} diff --git a/tests/unit/style/animated_properties.rs b/tests/unit/style/animated_properties.rs index ba387422262..f68b89f12e5 100644 --- a/tests/unit/style/animated_properties.rs +++ b/tests/unit/style/animated_properties.rs @@ -8,7 +8,7 @@ use style::properties::animated_properties::Animatable; use style::properties::longhands::transform::computed_value::ComputedOperation as TransformOperation; use style::properties::longhands::transform::computed_value::T as TransformList; use style::values::animated::ToAnimatedValue; -use style::values::computed::length::Percentage; +use style::values::computed::Percentage; fn interpolate_rgba(from: RGBA, to: RGBA, progress: f64) -> RGBA { let from = from.to_animated_value(); diff --git a/tests/unit/style/attr.rs b/tests/unit/style/attr.rs index 5d0388b5358..8c04de5caa0 100644 --- a/tests/unit/style/attr.rs +++ b/tests/unit/style/attr.rs @@ -4,8 +4,7 @@ use app_units::Au; use style::attr::{AttrValue, LengthOrPercentageOrAuto, parse_length}; -use style::values::computed::CalcLengthOrPercentage; -use style::values::computed::length::Percentage; +use style::values::computed::{CalcLengthOrPercentage, Percentage}; #[test] fn test_length_calc() { diff --git a/tests/unit/style/properties/serialization.rs b/tests/unit/style/properties/serialization.rs index 3cf56a1dc7f..87e7551b41a 100644 --- a/tests/unit/style/properties/serialization.rs +++ b/tests/unit/style/properties/serialization.rs @@ -353,8 +353,7 @@ mod shorthand_serialization { assert_eq!(serialization, "border-style: solid dotted;"); } - use style::values::specified::BorderCornerRadius; - use style::values::specified::length::Percentage; + use style::values::specified::{BorderCornerRadius, Percentage}; #[test] fn border_radius_should_serialize_correctly() {