From b49ad75e0f7d941f17eb8d5e4cc7b9c0e98ce4df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 17 Jul 2017 01:29:11 -0700 Subject: [PATCH] servo: Merge #17731 - style: Respect calc for percentages (from emilio:percentage-calc); r=nox Source-Repo: https://github.com/servo/servo Source-Revision: 2d37700cf819d901552cfb3954e948f1fbadcf78 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 375b4076885e4a0de0333329409bf6662d2d394b --- .../components/layout/display_list_builder.rs | 3 +- servo/components/script/dom/element.rs | 6 +- servo/components/style/gecko/conversions.rs | 3 +- servo/components/style/gecko/values.rs | 3 +- .../gecko_bindings/sugar/ns_css_value.rs | 3 +- .../components/style/properties/gecko.mako.rs | 2 +- .../helpers/animated_properties.mako.rs | 4 +- .../style/properties/longhand/border.mako.rs | 2 +- .../style/properties/longhand/box.mako.rs | 8 +- .../style/properties/longhand/font.mako.rs | 7 +- .../style/values/computed/length.rs | 43 +++++- servo/components/style/values/computed/mod.rs | 4 +- .../style/values/computed/position.rs | 3 +- .../style/values/computed/transform.rs | 3 +- .../components/style/values/generics/flex.rs | 2 +- .../style/values/specified/basic_shape.rs | 3 +- .../components/style/values/specified/calc.rs | 96 +++++++++---- .../style/values/specified/effects.rs | 78 ++++------ .../style/values/specified/image.rs | 22 +-- .../style/values/specified/length.rs | 135 +++++++++++++----- .../components/style/values/specified/mod.rs | 14 +- .../style/values/specified/position.rs | 9 +- .../style/values/specified/transform.rs | 11 +- servo/ports/geckolib/glue.rs | 3 +- servo/tests/unit/style/animated_properties.rs | 2 +- servo/tests/unit/style/attr.rs | 2 +- .../unit/style/properties/serialization.rs | 10 +- servo/tests/unit/style/stylesheets.rs | 3 +- 28 files changed, 308 insertions(+), 176 deletions(-) diff --git a/servo/components/layout/display_list_builder.rs b/servo/components/layout/display_list_builder.rs index 9fdd405a90d1..4b79c5e7a684 100644 --- a/servo/components/layout/display_list_builder.rs +++ b/servo/components/layout/display_list_builder.rs @@ -56,7 +56,7 @@ use style::properties::longhands::border_image_repeat::computed_value::RepeatKey use style::properties::style_structs; use style::servo::restyle_damage::REPAINT; use style::values::{Either, RGBA}; -use style::values::computed::{Angle, Gradient, GradientItem, LengthOrPercentage}; +use style::values::computed::{Angle, Gradient, GradientItem, LengthOrPercentage, Percentage}; use style::values::computed::{LengthOrPercentageOrAuto, NumberOrPercentage, Position}; use style::values::computed::effects::SimpleShadow; use style::values::computed::image::{EndingShape, LineDirection}; @@ -66,7 +66,6 @@ use style::values::generics::image::{Circle, Ellipse, EndingShape as GenericEndi use style::values::generics::image::{GradientItem as GenericGradientItem, GradientKind}; use style::values::generics::image::{Image, ShapeExtent}; use style::values::generics::image::PaintWorklet; -use style::values::specified::length::Percentage; use style::values::specified::position::{X, Y}; use style_traits::CSSPixel; use style_traits::cursor::Cursor; diff --git a/servo/components/script/dom/element.rs b/servo/components/script/dom/element.rs index a78520426e05..fcb08ba54c8b 100644 --- a/servo/components/script/dom/element.rs +++ b/servo/components/script/dom/element.rs @@ -113,7 +113,7 @@ use style::shared_lock::{SharedRwLock, Locked}; use style::stylearc::Arc; use style::thread_state; use style::values::{CSSFloat, Either}; -use style::values::specified; +use style::values::{specified, computed}; use stylesheet_loader::StylesheetOwner; // TODO: Update focus state when the top-level browsing context gains or loses system focus, @@ -576,7 +576,7 @@ impl LayoutElementHelpers for LayoutJS { LengthOrPercentageOrAuto::Auto => {} LengthOrPercentageOrAuto::Percentage(percentage) => { let width_value = - specified::LengthOrPercentageOrAuto::Percentage(specified::Percentage(percentage)); + specified::LengthOrPercentageOrAuto::Percentage(computed::Percentage(percentage)); hints.push(from_declaration( shared_lock, PropertyDeclaration::Width(width_value))); @@ -605,7 +605,7 @@ impl LayoutElementHelpers for LayoutJS { LengthOrPercentageOrAuto::Auto => {} LengthOrPercentageOrAuto::Percentage(percentage) => { let height_value = - specified::LengthOrPercentageOrAuto::Percentage(specified::Percentage(percentage)); + specified::LengthOrPercentageOrAuto::Percentage(computed::Percentage(percentage)); hints.push(from_declaration( shared_lock, PropertyDeclaration::Height(height_value))); diff --git a/servo/components/style/gecko/conversions.rs b/servo/components/style/gecko/conversions.rs index 0bc666db0b10..ea4e4588ee0d 100644 --- a/servo/components/style/gecko/conversions.rs +++ b/servo/components/style/gecko/conversions.rs @@ -18,11 +18,10 @@ use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordData use std::f32::consts::PI; use stylesheets::{Origin, RulesMutateError}; use values::computed::{Angle, CalcLengthOrPercentage, Gradient, Image}; -use values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto}; +use values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, Percentage}; use values::generics::grid::TrackSize; use values::generics::image::{CompatMode, Image as GenericImage, GradientItem}; use values::generics::rect::Rect; -use values::specified::length::Percentage; use values::specified::url::SpecifiedUrl; impl From for nsStyleCoord_CalcValue { diff --git a/servo/components/style/gecko/values.rs b/servo/components/style/gecko/values.rs index f05ede6b4897..a48152224094 100644 --- a/servo/components/style/gecko/values.rs +++ b/servo/components/style/gecko/values.rs @@ -18,13 +18,12 @@ use std::cmp::max; use values::{Auto, Either, ExtremumLength, None_, Normal}; use values::computed::{Angle, LengthOrPercentage, LengthOrPercentageOrAuto}; use values::computed::{LengthOrPercentageOrNone, Number, NumberOrPercentage}; -use values::computed::{MaxLength, MozLength}; +use values::computed::{MaxLength, MozLength, Percentage}; use values::computed::basic_shape::ShapeRadius as ComputedShapeRadius; use values::generics::CounterStyleOrNone; use values::generics::basic_shape::ShapeRadius; use values::generics::gecko::ScrollSnapPoint; use values::generics::grid::{TrackBreadth, TrackKeyword}; -use values::specified::Percentage; /// A trait that defines an interface to convert from and to `nsStyleCoord`s. pub trait GeckoStyleCoordConvertible : Sized { diff --git a/servo/components/style/gecko_bindings/sugar/ns_css_value.rs b/servo/components/style/gecko_bindings/sugar/ns_css_value.rs index 5a4d143125d1..e3e0ee9c898b 100644 --- a/servo/components/style/gecko_bindings/sugar/ns_css_value.rs +++ b/servo/components/style/gecko_bindings/sugar/ns_css_value.rs @@ -14,8 +14,7 @@ use std::marker::PhantomData; use std::mem; use std::ops::{Index, IndexMut}; use std::slice; -use values::computed::{Angle, LengthOrPercentage}; -use values::specified::length::Percentage; +use values::computed::{Angle, LengthOrPercentage, Percentage}; use values::specified::url::SpecifiedUrl; impl nsCSSValue { diff --git a/servo/components/style/properties/gecko.mako.rs b/servo/components/style/properties/gecko.mako.rs index 640d6880d9dc..d30b81ff7cbb 100644 --- a/servo/components/style/properties/gecko.mako.rs +++ b/servo/components/style/properties/gecko.mako.rs @@ -66,7 +66,7 @@ use std::cmp; use values::{Auto, CustomIdent, Either, KeyframesName}; use values::computed::ToComputedValue; use values::computed::effects::{BoxShadow, Filter, SimpleShadow}; -use values::specified::length::Percentage; +use values::computed::length::Percentage; use computed_values::border_style; pub mod style_structs { diff --git a/servo/components/style/properties/helpers/animated_properties.mako.rs b/servo/components/style/properties/helpers/animated_properties.mako.rs index abceb90629dc..d81028284e3c 100644 --- a/servo/components/style/properties/helpers/animated_properties.mako.rs +++ b/servo/components/style/properties/helpers/animated_properties.mako.rs @@ -41,12 +41,11 @@ use values::animated::effects::TextShadowList as AnimatedTextShadowList; use values::computed::{Angle, LengthOrPercentageOrAuto, LengthOrPercentageOrNone}; use values::computed::{BorderCornerRadius, ClipRect}; use values::computed::{CalcLengthOrPercentage, Color, Context, ComputedValueAsSpecified}; -use values::computed::{LengthOrPercentage, MaxLength, MozLength, ToComputedValue}; +use values::computed::{LengthOrPercentage, MaxLength, MozLength, Percentage, ToComputedValue}; use values::generics::{SVGPaint, SVGPaintKind}; use values::generics::border::BorderCornerRadius as GenericBorderCornerRadius; use values::generics::effects::Filter; use values::generics::position as generic_position; -use values::specified::length::Percentage; /// A longhand property whose animation type is not "none". @@ -1686,7 +1685,6 @@ fn add_weighted_transform_lists(from_list: &[TransformOperation], } } } else { - use values::specified::Percentage; let from_transform_list = TransformList(Some(from_list.to_vec())); let to_transform_list = TransformList(Some(to_list.to_vec())); result.push( diff --git a/servo/components/style/properties/longhand/border.mako.rs b/servo/components/style/properties/longhand/border.mako.rs index 740f2d9fd250..b5aafda574bb 100644 --- a/servo/components/style/properties/longhand/border.mako.rs +++ b/servo/components/style/properties/longhand/border.mako.rs @@ -278,7 +278,7 @@ ${helpers.predefined_type("border-image-width", "BorderImageWidth", ${helpers.predefined_type("border-image-slice", "BorderImageSlice", initial_value="computed::NumberOrPercentage::Percentage(computed::Percentage(1.)).into()", - initial_specified_value="specified::NumberOrPercentage::Percentage(specified::Percentage(1.)).into()", + initial_specified_value="specified::NumberOrPercentage::Percentage(specified::Percentage::new(1.)).into()", spec="https://drafts.csswg.org/css-backgrounds/#border-image-slice", animation_value_type="discrete", boxed=True)} diff --git a/servo/components/style/properties/longhand/box.mako.rs b/servo/components/style/properties/longhand/box.mako.rs index 47d45d824cd8..f2c3c8d517e7 100644 --- a/servo/components/style/properties/longhand/box.mako.rs +++ b/servo/components/style/properties/longhand/box.mako.rs @@ -736,7 +736,7 @@ ${helpers.predefined_type( use values::computed::{LengthOrPercentageOrNumber as ComputedLoPoNumber, LengthOrNumber as ComputedLoN}; use values::computed::{LengthOrPercentage as ComputedLoP, Length as ComputedLength}; use values::generics::transform::Matrix; - use values::specified::{Angle, Integer, Length, LengthOrPercentage, Percentage}; + use values::specified::{Angle, Integer, Length, LengthOrPercentage}; use values::specified::{LengthOrNumber, LengthOrPercentageOrNumber as LoPoNumber, Number}; use style_traits::ToCss; use style_traits::values::Css; @@ -747,7 +747,7 @@ ${helpers.predefined_type( use app_units::Au; use values::CSSFloat; use values::computed; - use values::computed::{Length, LengthOrPercentage, Percentage}; + use values::computed::{Length, LengthOrPercentage}; #[derive(Clone, Copy, Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] @@ -817,7 +817,7 @@ ${helpers.predefined_type( // progress: ... } ] InterpolateMatrix { from_list: T, to_list: T, - progress: Percentage }, + progress: computed::Percentage }, // For accumulate operation of mismatched transform lists. AccumulateMatrix { from_list: T, to_list: T, @@ -904,7 +904,7 @@ ${helpers.predefined_type( /// A intermediate type for interpolation of mismatched transform lists. InterpolateMatrix { from_list: SpecifiedValue, to_list: SpecifiedValue, - progress: Percentage }, + progress: computed::Percentage }, /// A intermediate type for accumulation of mismatched transform lists. AccumulateMatrix { from_list: SpecifiedValue, to_list: SpecifiedValue, diff --git a/servo/components/style/properties/longhand/font.mako.rs b/servo/components/style/properties/longhand/font.mako.rs index 972395496744..f4c0332b3ebb 100644 --- a/servo/components/style/properties/longhand/font.mako.rs +++ b/servo/components/style/properties/longhand/font.mako.rs @@ -566,8 +566,7 @@ ${helpers.single_keyword_system("font-variant-caps", use std::fmt; use style_traits::{HasViewportPercentage, ToCss}; use values::FONT_MEDIUM_PX; - use values::specified::{AllowQuirks, FontRelativeLength, LengthOrPercentage}; - use values::specified::{NoCalcLength, Percentage}; + use values::specified::{AllowQuirks, FontRelativeLength, LengthOrPercentage, NoCalcLength}; use values::specified::length::FontBaseSize; impl ToCss for SpecifiedValue { @@ -810,8 +809,8 @@ ${helpers.single_keyword_system("font-variant-caps", SpecifiedValue::Length(LengthOrPercentage::Length(ref l)) => { l.to_computed_value(context) } - SpecifiedValue::Length(LengthOrPercentage::Percentage(Percentage(value))) => { - base_size.resolve(context).scale_by(value) + SpecifiedValue::Length(LengthOrPercentage::Percentage(pc)) => { + base_size.resolve(context).scale_by(pc.0) } SpecifiedValue::Length(LengthOrPercentage::Calc(ref calc)) => { let calc = calc.to_computed_value(context); diff --git a/servo/components/style/values/computed/length.rs b/servo/components/style/values/computed/length.rs index 731c51a5c703..8682487f47d9 100644 --- a/servo/components/style/values/computed/length.rs +++ b/servo/components/style/values/computed/length.rs @@ -12,11 +12,52 @@ use style_traits::values::specified::AllowedLengthType; use super::{Number, ToComputedValue, Context}; use values::{Auto, CSSFloat, Either, ExtremumLength, None_, Normal, specified}; use values::specified::length::{AbsoluteLength, FontBaseSize, FontRelativeLength}; -use values::specified::length::{Percentage, ViewportPercentageLength}; +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/servo/components/style/values/computed/mod.rs b/servo/components/style/values/computed/mod.rs index 6fffa82e6d05..deb74f75022a 100644 --- a/servo/components/style/values/computed/mod.rs +++ b/servo/components/style/values/computed/mod.rs @@ -38,11 +38,11 @@ pub use self::rect::LengthOrNumberRect; pub use super::{Auto, Either, None_}; #[cfg(feature = "gecko")] pub use super::specified::{AlignItems, AlignJustifyContent, AlignJustifySelf, JustifyItems}; -pub use super::specified::{BorderStyle, Percentage, UrlOrNone}; +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}; +pub use self::length::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone, MaxLength, MozLength, Percentage}; pub use self::position::Position; pub use self::text::{InitialLetter, LetterSpacing, LineHeight, WordSpacing}; pub use self::transform::{TimingFunction, TransformOrigin}; diff --git a/servo/components/style/values/computed/position.rs b/servo/components/style/values/computed/position.rs index 98037ca21b93..d17f6172310d 100644 --- a/servo/components/style/values/computed/position.rs +++ b/servo/components/style/values/computed/position.rs @@ -9,9 +9,8 @@ use std::fmt; use style_traits::ToCss; -use values::computed::LengthOrPercentage; +use values::computed::{LengthOrPercentage, Percentage}; use values::generics::position::Position as GenericPosition; -use values::specified::length::Percentage; /// The computed value of a CSS `` pub type Position = GenericPosition; diff --git a/servo/components/style/values/computed/transform.rs b/servo/components/style/values/computed/transform.rs index 5354717bc7c3..a4f352155601 100644 --- a/servo/components/style/values/computed/transform.rs +++ b/servo/components/style/values/computed/transform.rs @@ -5,10 +5,9 @@ //! Computed types for CSS values that are related to transformations. use properties::animated_properties::Animatable; -use values::computed::{Length, LengthOrPercentage, Number}; +use values::computed::{Length, LengthOrPercentage, Number, Percentage}; use values::generics::transform::TimingFunction as GenericTimingFunction; use values::generics::transform::TransformOrigin as GenericTransformOrigin; -use values::specified::length::Percentage; /// The computed value of a CSS `` pub type TransformOrigin = GenericTransformOrigin; diff --git a/servo/components/style/values/generics/flex.rs b/servo/components/style/values/generics/flex.rs index 3d77b8e8e752..3d7f2098fcea 100644 --- a/servo/components/style/values/generics/flex.rs +++ b/servo/components/style/values/generics/flex.rs @@ -4,7 +4,7 @@ //! Generic types for CSS values related to flexbox. -use values::specified::Percentage; +use values::computed::Percentage; /// A generic value for the `flex-basis` property. #[cfg_attr(feature = "servo", derive(HeapSizeOf))] diff --git a/servo/components/style/values/specified/basic_shape.rs b/servo/components/style/values/specified/basic_shape.rs index ee27e3267941..fe4b10bb0454 100644 --- a/servo/components/style/values/specified/basic_shape.rs +++ b/servo/components/style/values/specified/basic_shape.rs @@ -12,6 +12,7 @@ use parser::{Parse, ParserContext}; use std::borrow::Cow; use std::fmt; use style_traits::{ToCss, ParseError, StyleParseError}; +use values::computed::Percentage; use values::generics::basic_shape::{Circle as GenericCircle}; use values::generics::basic_shape::{ClippingShape as GenericClippingShape, Ellipse as GenericEllipse}; use values::generics::basic_shape::{FillRule, BasicShape as GenericBasicShape}; @@ -19,7 +20,7 @@ use values::generics::basic_shape::{FloatAreaShape as GenericFloatAreaShape, Ins use values::generics::basic_shape::{GeometryBox, ShapeBox, ShapeSource}; use values::generics::basic_shape::{Polygon as GenericPolygon, ShapeRadius as GenericShapeRadius}; use values::generics::rect::Rect; -use values::specified::{LengthOrPercentage, Percentage}; +use values::specified::LengthOrPercentage; use values::specified::border::BorderRadius; use values::specified::position::{HorizontalPosition, Position, PositionComponent, Side, VerticalPosition}; use values::specified::url::SpecifiedUrl; diff --git a/servo/components/style/values/specified/calc.rs b/servo/components/style/values/specified/calc.rs index f5853bbf3bf2..dd29a201e7c3 100644 --- a/servo/components/style/values/specified/calc.rs +++ b/servo/components/style/values/specified/calc.rs @@ -14,9 +14,9 @@ use std::fmt; use style_traits::{HasViewportPercentage, ToCss, ParseError, StyleParseError}; use style_traits::values::specified::AllowedLengthType; use values::{CSSInteger, CSSFloat}; +use values::computed; use values::specified::{Angle, Time}; -use values::specified::length::{FontRelativeLength, NoCalcLength}; -use values::specified::length::{Percentage, ViewportPercentageLength}; +use values::specified::length::{FontRelativeLength, NoCalcLength, ViewportPercentageLength}; /// A node inside a `Calc` expression's AST. #[derive(Clone, Debug)] @@ -52,6 +52,8 @@ pub enum CalcUnit { Integer, /// `` Length, + /// `` + Percentage, /// ` | ` LengthOrPercentage, /// `` @@ -75,7 +77,7 @@ pub struct CalcLengthOrPercentage { pub ex: Option, pub ch: Option, pub rem: Option, - pub percentage: Option, + pub percentage: Option, #[cfg(feature = "gecko")] pub mozmm: Option, } @@ -146,9 +148,8 @@ impl CalcNode { fn parse_one<'i, 't>( context: &ParserContext, input: &mut Parser<'i, 't>, - expected_unit: CalcUnit) - -> Result> - { + expected_unit: CalcUnit + ) -> Result> { match (input.next()?, expected_unit) { (Token::Number { value, .. }, _) => Ok(CalcNode::Number(value)), (Token::Dimension { value, ref unit, .. }, CalcUnit::Length) | @@ -167,7 +168,8 @@ impl CalcNode { .map(CalcNode::Time) .map_err(|()| StyleParseError::UnspecifiedError.into()) } - (Token::Percentage { unit_value, .. }, CalcUnit::LengthOrPercentage) => { + (Token::Percentage { unit_value, .. }, CalcUnit::LengthOrPercentage) | + (Token::Percentage { unit_value, .. }, CalcUnit::Percentage) => { Ok(CalcNode::Percentage(unit_value)) } (Token::ParenthesisBlock, _) => { @@ -283,6 +285,44 @@ impl CalcNode { Ok(ret) } + /// Tries to simplify this expression into a `` value. + fn to_percentage(&self) -> Result { + Ok(match *self { + CalcNode::Percentage(percentage) => percentage, + CalcNode::Sub(ref a, ref b) => { + a.to_percentage()? - b.to_percentage()? + } + CalcNode::Sum(ref a, ref b) => { + a.to_percentage()? + b.to_percentage()? + } + CalcNode::Mul(ref a, ref b) => { + match a.to_percentage() { + Ok(lhs) => { + let rhs = b.to_number()?; + lhs * rhs + } + Err(..) => { + let lhs = a.to_number()?; + let rhs = b.to_percentage()?; + lhs * rhs + } + } + } + CalcNode::Div(ref a, ref b) => { + let lhs = a.to_percentage()?; + let rhs = b.to_number()?; + if rhs == 0. { + return Err(()) + } + lhs / rhs + } + CalcNode::Number(..) | + CalcNode::Length(..) | + CalcNode::Angle(..) | + CalcNode::Time(..) => return Err(()), + }) + } + /// Puts this `` or `` into `ret`, or error. /// /// `factor` is the sign or multiplicative factor to account for the sign @@ -295,7 +335,7 @@ impl CalcNode { { match *self { CalcNode::Percentage(pct) => { - ret.percentage = Some(Percentage( + ret.percentage = Some(computed::Percentage( ret.percentage.map_or(0., |p| p.0) + pct * factor, )); } @@ -495,9 +535,8 @@ impl CalcNode { /// Convenience parsing function for integers. pub fn parse_integer<'i, 't>( context: &ParserContext, - input: &mut Parser<'i, 't>) - -> Result> - { + input: &mut Parser<'i, 't> + ) -> Result> { Self::parse(context, input, CalcUnit::Integer)? .to_number() .map(|n| n as CSSInteger) @@ -508,21 +547,29 @@ impl CalcNode { pub fn parse_length_or_percentage<'i, 't>( context: &ParserContext, input: &mut Parser<'i, 't>, - clamping_mode: AllowedLengthType) - -> Result> - { + clamping_mode: AllowedLengthType + ) -> Result> { Self::parse(context, input, CalcUnit::LengthOrPercentage)? .to_length_or_percentage(clamping_mode) .map_err(|()| StyleParseError::UnspecifiedError.into()) } + /// Convenience parsing function for percentages. + pub fn parse_percentage<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't> + ) -> Result> { + Self::parse(context, input, CalcUnit::Percentage)? + .to_percentage() + .map_err(|()| StyleParseError::UnspecifiedError.into()) + } + /// Convenience parsing function for ``. pub fn parse_length<'i, 't>( context: &ParserContext, input: &mut Parser<'i, 't>, - clamping_mode: AllowedLengthType) - -> Result> - { + clamping_mode: AllowedLengthType + ) -> Result> { Self::parse(context, input, CalcUnit::Length)? .to_length_or_percentage(clamping_mode) .map_err(|()| StyleParseError::UnspecifiedError.into()) @@ -531,9 +578,8 @@ impl CalcNode { /// Convenience parsing function for ``. pub fn parse_number<'i, 't>( context: &ParserContext, - input: &mut Parser<'i, 't>) - -> Result> - { + input: &mut Parser<'i, 't> + ) -> Result> { Self::parse(context, input, CalcUnit::Number)? .to_number() .map_err(|()| StyleParseError::UnspecifiedError.into()) @@ -542,9 +588,8 @@ impl CalcNode { /// Convenience parsing function for ``. pub fn parse_angle<'i, 't>( context: &ParserContext, - input: &mut Parser<'i, 't>) - -> Result> - { + input: &mut Parser<'i, 't> + ) -> Result> { Self::parse(context, input, CalcUnit::Angle)? .to_angle() .map_err(|()| StyleParseError::UnspecifiedError.into()) @@ -553,9 +598,8 @@ impl CalcNode { /// Convenience parsing function for `