From 796a2b9632c2c2903ceb14cc6f3baff477aeb4c1 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Mon, 14 Aug 2017 02:37:32 +0200 Subject: [PATCH] Move specified and computed percentages to submodules --- .../helpers/animated_properties.mako.rs | 15 -- components/style/values/computed/mod.rs | 41 +---- .../style/values/computed/percentage.rs | 54 +++++++ components/style/values/specified/length.rs | 2 +- components/style/values/specified/mod.rs | 120 +------------- .../style/values/specified/percentage.rs | 152 ++++++++++++++++++ components/style/values/specified/rect.rs | 2 +- 7 files changed, 212 insertions(+), 174 deletions(-) create mode 100644 components/style/values/computed/percentage.rs create mode 100644 components/style/values/specified/percentage.rs diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index e3ee36399acc..1cc8140277dd 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -888,21 +888,6 @@ impl Animatable for Angle { } } -/// https://drafts.csswg.org/css-transitions/#animtype-percentage -impl Animatable for Percentage { - #[inline] - fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result { - Ok(Percentage((self.0 as f64 * self_portion + other.0 as f64 * other_portion) as f32)) - } -} - -impl ToAnimatedZero for Percentage { - #[inline] - fn to_animated_zero(&self) -> Result { - Ok(Percentage(0.)) - } -} - /// https://drafts.csswg.org/css-transitions/#animtype-visibility impl Animatable for Visibility { #[inline] diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index b963d37fab62..43076d1f5464 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -49,6 +49,7 @@ pub use super::generics::grid::GridLine; pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNone, LengthOrNumber, LengthOrPercentage}; pub use self::length::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone, MaxLength, MozLength}; pub use self::length::NonNegativeLengthOrPercentage; +pub use self::percentage::Percentage; pub use self::position::Position; pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind, SVGStrokeDashArray, SVGWidth}; pub use self::text::{InitialLetter, LetterSpacing, LineHeight, WordSpacing}; @@ -66,6 +67,7 @@ pub mod image; #[cfg(feature = "gecko")] pub mod gecko; pub mod length; +pub mod percentage; pub mod position; pub mod rect; pub mod svg; @@ -658,45 +660,6 @@ impl From for NonNegativeAu { } } -/// A computed `` value. -#[derive(Clone, ComputeSquaredDistance, Copy, Debug, Default, HasViewportPercentage, PartialEq)] -#[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) - } -} - /// The computed value of a CSS `url()`, resolved relative to the stylesheet URL. #[cfg(feature = "servo")] #[derive(Clone, Debug, HeapSizeOf, Serialize, Deserialize, PartialEq)] diff --git a/components/style/values/computed/percentage.rs b/components/style/values/computed/percentage.rs new file mode 100644 index 000000000000..bd19579bcc4f --- /dev/null +++ b/components/style/values/computed/percentage.rs @@ -0,0 +1,54 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//! Computed percentages. + +use properties::animated_properties::Animatable; +use std::fmt; +use style_traits::ToCss; +use values::CSSFloat; +use values::animated::ToAnimatedZero; + +/// A computed percentage. +#[derive(Clone, ComputeSquaredDistance, Copy, Debug, Default, HasViewportPercentage, PartialEq)] +#[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.) + } +} + +/// https://drafts.csswg.org/css-transitions/#animtype-percentage +impl Animatable for Percentage { + #[inline] + fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result { + Ok(Percentage((self.0 as f64 * self_portion + other.0 as f64 * other_portion) as f32)) + } +} + +impl ToAnimatedZero for Percentage { + #[inline] + fn to_animated_zero(&self) -> Result { + Ok(Percentage(0.)) + } +} + +impl ToCss for Percentage { + fn to_css(&self, dest: &mut W) -> fmt::Result + where + W: fmt::Write, + { + write!(dest, "{}%", self.0 * 100.) + } +} diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index 943185fce12b..dfef6fab0e85 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -785,7 +785,7 @@ impl From for LengthOrPercentage { impl From for LengthOrPercentage { #[inline] fn from(pc: Percentage) -> Self { - if pc.calc_clamping_mode.is_some() { + if pc.is_calc() { LengthOrPercentage::Calc(Box::new(CalcLengthOrPercentage { percentage: Some(computed::Percentage(pc.get())), .. Default::default() diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index e8bfad406ad8..95031e895f09 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -44,6 +44,7 @@ pub use self::length::{LengthOrPercentageOrNone, MaxLength, MozLength}; pub use self::length::{NoCalcLength, ViewportPercentageLength}; pub use self::length::NonNegativeLengthOrPercentage; pub use self::rect::LengthOrNumberRect; +pub use self::percentage::Percentage; pub use self::position::{Position, PositionComponent}; pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind, SVGStrokeDashArray, SVGWidth}; pub use self::text::{InitialLetter, LetterSpacing, LineHeight, WordSpacing}; @@ -65,6 +66,7 @@ pub mod gecko; pub mod grid; pub mod image; pub mod length; +pub mod percentage; pub mod position; pub mod rect; pub mod svg; @@ -1047,121 +1049,3 @@ 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/components/style/values/specified/percentage.rs b/components/style/values/specified/percentage.rs new file mode 100644 index 000000000000..104d60142c01 --- /dev/null +++ b/components/style/values/specified/percentage.rs @@ -0,0 +1,152 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//! Specified percentages. + +use cssparser::{BasicParseError, Parser, Token}; +use parser::{Parse, ParserContext}; +use std::ascii::AsciiExt; +use std::fmt; +use style_traits::{ParseError, ToCss}; +use style_traits::values::specified::AllowedNumericType; +use values::CSSFloat; +use values::computed::{Context, ToComputedValue}; +use values::computed::percentage::Percentage as ComputedPercentage; +use values::specified::calc::CalcNode; + +/// 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 { + /// Creates a percentage from a numeric value. + pub fn new(value: CSSFloat) -> Self { + Self { + value, + calc_clamping_mode: None, + } + } + + /// `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, + } + } + /// Gets the underlying value for this float. + pub fn get(&self) -> CSSFloat { + self.calc_clamping_mode.map_or(self.value, |mode| mode.clamp(self.value)) + } + + /// Returns whether this percentage is a `calc()` value. + pub fn is_calc(&self) -> bool { + self.calc_clamping_mode.is_some() + } + + /// Reverses 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; + } + + /// Parses 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) + } +} + +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) + } +} + +impl ToComputedValue for Percentage { + type ComputedValue = ComputedPercentage; + + #[inline] + fn to_computed_value(&self, _: &Context) -> Self::ComputedValue { + ComputedPercentage(self.get()) + } + + #[inline] + fn from_computed_value(computed: &Self::ComputedValue) -> Self { + Percentage::new(computed.0) + } +} diff --git a/components/style/values/specified/rect.rs b/components/style/values/specified/rect.rs index 1dca6379d77f..ec0ab35e8a1f 100644 --- a/components/style/values/specified/rect.rs +++ b/components/style/values/specified/rect.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -//! Computed types for CSS borders. +//! Specified types for CSS borders. use cssparser::Parser; use parser::ParserContext;