diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index da5c84aed39..aaa2677777b 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -465,6 +465,54 @@ trivial_to_computed_value!(String); trivial_to_computed_value!(Box); trivial_to_computed_value!(crate::OwnedStr); +#[allow(missing_docs)] +#[derive( + Animate, + Clone, + ComputeSquaredDistance, + Copy, + Debug, + MallocSizeOf, + PartialEq, + ToAnimatedZero, + ToCss, + ToResolvedValue, +)] +#[repr(C, u8)] +pub enum AngleOrPercentage { + Percentage(Percentage), + Angle(Angle), +} + +impl ToComputedValue for specified::AngleOrPercentage { + type ComputedValue = AngleOrPercentage; + + #[inline] + fn to_computed_value(&self, context: &Context) -> AngleOrPercentage { + match *self { + specified::AngleOrPercentage::Percentage(percentage) => { + AngleOrPercentage::Percentage(percentage.to_computed_value(context)) + }, + specified::AngleOrPercentage::Angle(angle) => { + AngleOrPercentage::Angle(angle.to_computed_value(context)) + }, + } + } + #[inline] + fn from_computed_value(computed: &AngleOrPercentage) -> Self { + match *computed { + AngleOrPercentage::Percentage(percentage) => { + specified::AngleOrPercentage::Percentage(ToComputedValue::from_computed_value( + &percentage, + )) + }, + AngleOrPercentage::Angle(angle) => { + specified::AngleOrPercentage::Angle(ToComputedValue::from_computed_value(&angle)) + }, + } + } +} + /// A `` value. pub type Number = CSSFloat; diff --git a/components/style/values/specified/angle.rs b/components/style/values/specified/angle.rs index 6485bca6f8f..b42d5d5038f 100644 --- a/components/style/values/specified/angle.rs +++ b/components/style/values/specified/angle.rs @@ -163,7 +163,8 @@ impl Angle { /// https://github.com/w3c/fxtf-drafts/issues/228 /// /// See also: https://github.com/w3c/csswg-drafts/issues/1162. -enum AllowUnitlessZeroAngle { +#[allow(missing_docs)] +pub enum AllowUnitlessZeroAngle { Yes, No, } @@ -203,7 +204,7 @@ impl Angle { Self::parse_internal(context, input, AllowUnitlessZeroAngle::Yes) } - fn parse_internal<'i, 't>( + pub(super) fn parse_internal<'i, 't>( context: &ParserContext, input: &mut Parser<'i, 't>, allow_unitless_zero: AllowUnitlessZeroAngle, diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 8399456a491..2d8160b17b9 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -31,7 +31,7 @@ use style_traits::{CssWriter, ParseError, SpecifiedValueInfo, StyleParseErrorKin pub use self::align::{AlignContent, AlignItems, AlignSelf, ContentDistribution}; #[cfg(feature = "gecko")] pub use self::align::{JustifyContent, JustifyItems, JustifySelf, SelfAlignment}; -pub use self::angle::Angle; +pub use self::angle::{Angle, AllowUnitlessZeroAngle}; pub use self::background::{BackgroundRepeat, BackgroundSize}; pub use self::basic_shape::FillRule; pub use self::border::{BorderCornerRadius, BorderImageSlice, BorderImageWidth}; @@ -130,6 +130,47 @@ pub mod transform; pub mod ui; pub mod url; +/// | +/// https://drafts.csswg.org/css-values/#typedef-angle-percentage +#[allow(missing_docs)] +#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss, ToShmem)] +pub enum AngleOrPercentage { + Percentage(Percentage), + Angle(Angle), +} + +impl AngleOrPercentage { + fn parse_internal<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + allow_unitless_zero: AllowUnitlessZeroAngle, + ) -> Result> { + if let Ok(per) = input.try(|i| Percentage::parse(context, i)) { + return Ok(AngleOrPercentage::Percentage(per)); + } + + Angle::parse_internal(context, input, allow_unitless_zero).map(AngleOrPercentage::Angle) + } + + /// Allow unitless angles, used for conic-gradients as specified by the spec. + /// https://drafts.csswg.org/css-images-4/#valdef-conic-gradient-angle + pub fn parse_with_unitless<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { + AngleOrPercentage::parse_internal(context, input, AllowUnitlessZeroAngle::Yes) + } +} + +impl Parse for AngleOrPercentage { + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { + AngleOrPercentage::parse_internal(context, input, AllowUnitlessZeroAngle::No) + } +} + /// Parse a `` value, with a given clamping mode. fn parse_number_with_clamping_mode<'i, 't>( context: &ParserContext,