diff --git a/components/style/gecko/media_features.rs b/components/style/gecko/media_features.rs index e3de8dbfaaa..63d5ce10772 100644 --- a/components/style/gecko/media_features.rs +++ b/components/style/gecko/media_features.rs @@ -8,8 +8,9 @@ use crate::gecko_bindings::bindings; use crate::gecko_bindings::structs; use crate::media_queries::media_feature::{AllowsRanges, ParsingRequirements}; use crate::media_queries::media_feature::{Evaluator, MediaFeatureDescription}; -use crate::media_queries::media_feature_expression::{AspectRatio, RangeOrOperator}; +use crate::media_queries::media_feature_expression::RangeOrOperator; use crate::media_queries::{Device, MediaType}; +use crate::values::computed::position::Ratio; use crate::values::computed::CSSPixelLength; use crate::values::computed::Resolution; use crate::Atom; @@ -91,7 +92,7 @@ fn eval_device_height( fn eval_aspect_ratio_for( device: &Device, - query_value: Option, + query_value: Option, range_or_operator: Option, get_size: F, ) -> bool @@ -104,14 +105,14 @@ where }; let size = get_size(device); - let value = AspectRatio(size.width.0 as f32, size.height.0 as f32); + let value = Ratio::new(size.width.0 as f32, size.height.0 as f32); RangeOrOperator::evaluate_with_query_value(range_or_operator, query_value, value) } /// https://drafts.csswg.org/mediaqueries-4/#aspect-ratio fn eval_aspect_ratio( device: &Device, - query_value: Option, + query_value: Option, range_or_operator: Option, ) -> bool { eval_aspect_ratio_for(device, query_value, range_or_operator, viewport_size) @@ -120,7 +121,7 @@ fn eval_aspect_ratio( /// https://drafts.csswg.org/mediaqueries-4/#device-aspect-ratio fn eval_device_aspect_ratio( device: &Device, - query_value: Option, + query_value: Option, range_or_operator: Option, ) -> bool { eval_aspect_ratio_for(device, query_value, range_or_operator, device_size) diff --git a/components/style/media_queries/media_feature.rs b/components/style/media_queries/media_feature.rs index a273e7f51be..cad695413c3 100644 --- a/components/style/media_queries/media_feature.rs +++ b/components/style/media_queries/media_feature.rs @@ -4,9 +4,10 @@ //! Media features. -use super::media_feature_expression::{AspectRatio, RangeOrOperator}; +use super::media_feature_expression::RangeOrOperator; use super::Device; use crate::parser::ParserContext; +use crate::values::computed::position::Ratio; use crate::values::computed::{CSSPixelLength, Resolution}; use crate::Atom; use cssparser::Parser; @@ -45,7 +46,7 @@ pub enum Evaluator { Float(MediaFeatureEvaluator), BoolInteger(MediaFeatureEvaluator), /// A non-negative number ratio, such as the one from device-pixel-ratio. - NumberRatio(MediaFeatureEvaluator), + NumberRatio(MediaFeatureEvaluator), /// A resolution. Resolution(MediaFeatureEvaluator), /// A keyword value. diff --git a/components/style/media_queries/media_feature_expression.rs b/components/style/media_queries/media_feature_expression.rs index 4704fab0ffc..9e2fdd2d47b 100644 --- a/components/style/media_queries/media_feature_expression.rs +++ b/components/style/media_queries/media_feature_expression.rs @@ -15,9 +15,8 @@ use crate::parser::{Parse, ParserContext}; #[cfg(feature = "servo")] use crate::servo::media_queries::MEDIA_FEATURES; use crate::str::{starts_with_ignore_ascii_case, string_as_ascii_lowercase}; +use crate::values::computed::position::Ratio; use crate::values::computed::{self, ToComputedValue}; -#[cfg(feature = "gecko")] -use crate::values::specified::NonNegativeNumber; use crate::values::specified::{Integer, Length, Number, Resolution}; use crate::values::{serialize_atom_identifier, CSSFloat}; use crate::{Atom, Zero}; @@ -26,30 +25,6 @@ use std::cmp::{Ordering, PartialOrd}; use std::fmt::{self, Write}; use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; -/// An aspect ratio, with a numerator and denominator. -#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToShmem)] -pub struct AspectRatio(pub CSSFloat, pub CSSFloat); - -impl ToCss for AspectRatio { - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result - where - W: fmt::Write, - { - self.0.to_css(dest)?; - dest.write_str(" / ")?; - self.1.to_css(dest) - } -} - -impl PartialOrd for AspectRatio { - fn partial_cmp(&self, other: &AspectRatio) -> Option { - f64::partial_cmp( - &(self.0 as f64 * other.1 as f64), - &(self.1 as f64 * other.0 as f64), - ) - } -} - /// The kind of matching that should be performed on a media feature value. #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToShmem)] pub enum Range { @@ -460,7 +435,7 @@ pub enum MediaExpressionValue { BoolInteger(bool), /// A single non-negative number or two non-negative numbers separated by '/', /// with optional whitespace on either side of the '/'. - NumberRatio(AspectRatio), + NumberRatio(Ratio), /// A resolution. Resolution(Resolution), /// An enumerated value, defined by the variant keyword table in the @@ -517,24 +492,14 @@ impl MediaExpressionValue { MediaExpressionValue::Float(number.get()) }, Evaluator::NumberRatio(..) => { - #[cfg(feature = "gecko")] - { - if static_prefs::pref!("layout.css.aspect-ratio-number.enabled") { - let a = NonNegativeNumber::parse(context, input)?.0.get(); - let b = match input.try_parse(|input| input.expect_delim('/')) { - Ok(()) => NonNegativeNumber::parse(context, input)?.0.get(), - _ => 1.0, - }; - return Ok(MediaExpressionValue::NumberRatio(AspectRatio(a, b))); - } - } + use crate::values::generics::position::Ratio as GenericRatio; + use crate::values::generics::NonNegative; + use crate::values::specified::position::Ratio; - let a = Integer::parse_positive(context, input)?; - input.expect_delim('/')?; - let b = Integer::parse_positive(context, input)?; - MediaExpressionValue::NumberRatio(AspectRatio( - a.value() as CSSFloat, - b.value() as CSSFloat, + let ratio = Ratio::parse(context, input)?; + MediaExpressionValue::NumberRatio(GenericRatio( + NonNegative(ratio.0.get()), + NonNegative(ratio.1.get()), )) }, Evaluator::Resolution(..) => { diff --git a/components/style/values/computed/position.rs b/components/style/values/computed/position.rs index 6d09e327e63..9e5fe3be1d2 100644 --- a/components/style/values/computed/position.rs +++ b/components/style/values/computed/position.rs @@ -12,9 +12,11 @@ use crate::values::generics::position::AspectRatio as GenericAspectRatio; use crate::values::generics::position::Position as GenericPosition; use crate::values::generics::position::PositionComponent as GenericPositionComponent; use crate::values::generics::position::PositionOrAuto as GenericPositionOrAuto; +use crate::values::generics::position::Ratio as GenericRatio; use crate::values::generics::position::ZIndex as GenericZIndex; pub use crate::values::specified::position::{GridAutoFlow, GridTemplateAreas, MasonryAutoFlow}; use crate::Zero; +use std::cmp::{Ordering, PartialOrd}; use std::fmt::{self, Write}; use style_traits::{CssWriter, ToCss}; @@ -70,5 +72,24 @@ impl GenericPositionComponent for LengthPercentage { /// A computed value for the `z-index` property. pub type ZIndex = GenericZIndex; +/// A computed value. +pub type Ratio = GenericRatio; + +impl PartialOrd for Ratio { + fn partial_cmp(&self, other: &Self) -> Option { + f64::partial_cmp( + &((self.0).0 as f64 * (other.1).0 as f64), + &((self.1).0 as f64 * (other.0).0 as f64), + ) + } +} + +impl Ratio { + /// Returns a new Ratio. + pub fn new(a: f32, b: f32) -> Self { + GenericRatio(a.into(), b.into()) + } +} + /// A computed value for the `aspect-ratio` property. pub type AspectRatio = GenericAspectRatio; diff --git a/components/style/values/generics/position.rs b/components/style/values/generics/position.rs index 8e2c362ef0b..5f1659d3917 100644 --- a/components/style/values/generics/position.rs +++ b/components/style/values/generics/position.rs @@ -156,7 +156,6 @@ impl ZIndex { } /// A generic value for the `` value. -// FIXME: Use this for aspect-ratio in both css-sizing-4 and media-queries in the following patch. #[derive( Animate, Clone, diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 8fc7dade9ec..e9d25330f64 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -383,7 +383,7 @@ impl One for NonNegativeNumber { #[inline] fn is_one(&self) -> bool { - self.0.get() == 1.0 + self.get() == 1.0 } } @@ -392,6 +392,12 @@ impl NonNegativeNumber { pub fn new(val: CSSFloat) -> Self { NonNegative::(Number::new(val.max(0.))) } + + /// Returns the numeric value. + #[inline] + pub fn get(&self) -> f32 { + self.0.get() + } } /// A Number which is >= 1.0. diff --git a/components/style/values/specified/position.rs b/components/style/values/specified/position.rs index cd1dacc8f26..76fa23152e5 100644 --- a/components/style/values/specified/position.rs +++ b/components/style/values/specified/position.rs @@ -899,8 +899,11 @@ impl Parse for AspectRatio { } } +/// A specified value for the `aspect-ratio` property. +pub type Ratio = GenericRatio; + // https://drafts.csswg.org/css-values-4/#ratios -impl Parse for GenericRatio { +impl Parse for Ratio { fn parse<'i, 't>( context: &ParserContext, input: &mut Parser<'i, 't>,