diff --git a/components/style/values/generics/position.rs b/components/style/values/generics/position.rs index 5f1659d3917c..2b4448f03352 100644 --- a/components/style/values/generics/position.rs +++ b/components/style/values/generics/position.rs @@ -191,7 +191,7 @@ where } } -/// A generic value for the `aspect-ratio` property. +/// Ratio or None. #[derive( Animate, Clone, @@ -208,19 +208,50 @@ where ToShmem, )] #[repr(C, u8)] -pub enum GenericAspectRatio { - /// The value. +pub enum PreferredRatio { + /// Without specified ratio + #[css(skip)] + None, + /// With specified ratio Ratio(#[css(field_bound)] Ratio), - /// The keyword `auto`. - Auto, +} + +/// A generic value for the `aspect-ratio` property, the value is `auto || `. +#[derive( + Animate, + Clone, + ComputeSquaredDistance, + Copy, + Debug, + MallocSizeOf, + PartialEq, + SpecifiedValueInfo, + ToAnimatedZero, + ToComputedValue, + ToCss, + ToResolvedValue, + ToShmem, +)] +#[repr(C)] +pub struct GenericAspectRatio { + /// Specifiy auto or not. + #[animation(constant)] + #[css(represents_keyword)] + pub auto: bool, + /// The preferred aspect-ratio value. + #[css(field_bound)] + pub ratio: PreferredRatio, } pub use self::GenericAspectRatio as AspectRatio; -impl AspectRatio { +impl AspectRatio { /// Returns `auto` #[inline] pub fn auto() -> Self { - AspectRatio::Auto + AspectRatio { + auto: true, + ratio: PreferredRatio::None, + } } } diff --git a/components/style/values/specified/position.rs b/components/style/values/specified/position.rs index 76fa23152e57..95e1e2ec7120 100644 --- a/components/style/values/specified/position.rs +++ b/components/style/values/specified/position.rs @@ -882,24 +882,49 @@ pub type ZIndex = GenericZIndex; /// A specified value for the `aspect-ratio` property. pub type AspectRatio = GenericAspectRatio; -// FIXME: Add field_bound for parse custom derive, so we can drop this. impl Parse for AspectRatio { fn parse<'i, 't>( context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result> { - if input - .try(|input| input.expect_ident_matching("auto")) - .is_ok() - { - return Ok(AspectRatio::Auto); + use crate::values::generics::position::PreferredRatio; + + let location = input.current_source_location(); + let mut auto = input.try(|i| i.expect_ident_matching("auto")); + let ratio = input.try(|i| Ratio::parse(context, i)); + if auto.is_err() { + auto = input.try(|i| i.expect_ident_matching("auto")); + } + + if auto.is_err() && ratio.is_err() { + return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } - GenericRatio::parse(context, input).map(AspectRatio::Ratio) + Ok(AspectRatio { + auto: auto.is_ok(), + ratio: match ratio { + Ok(ratio) => PreferredRatio::Ratio(ratio), + Err(..) => PreferredRatio::None, + }, + }) } } -/// A specified value for the `aspect-ratio` property. +impl AspectRatio { + /// Returns Self by a valid ratio. + pub fn from_mapped_ratio(w: f32, h: f32) -> Self { + use crate::values::generics::position::PreferredRatio; + AspectRatio { + auto: true, + ratio: PreferredRatio::Ratio(GenericRatio( + NonNegativeNumber::new(w), + NonNegativeNumber::new(h), + )), + } + } +} + +/// A specified value. pub type Ratio = GenericRatio; // https://drafts.csswg.org/css-values-4/#ratios