From 8191853233fad48fccf4d3ad787729b1a7fb2ce4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 10 Nov 2017 16:49:25 +0100 Subject: [PATCH] style: Support calc() in media queries. Bug: 1396057 Reviewed-by: Manishearth MozReview-Commit-ID: 6YbeqInC5Mw --- components/style/gecko/media_queries.rs | 52 ++++++++++--------------- 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/components/style/gecko/media_queries.rs b/components/style/gecko/media_queries.rs index e99fe51273a..205a6ca0927 100644 --- a/components/style/gecko/media_queries.rs +++ b/components/style/gecko/media_queries.rs @@ -18,7 +18,7 @@ use gecko_bindings::structs::{nsMediaExpression_Range, nsMediaFeature}; use gecko_bindings::structs::{nsMediaFeature_ValueType, nsMediaFeature_RangeType}; use gecko_bindings::structs::{nsPresContext, RawGeckoPresContextOwned}; use media_queries::MediaType; -use parser::ParserContext; +use parser::{Parse, ParserContext}; use properties::ComputedValues; use servo_arc::Arc; use std::fmt::{self, Write}; @@ -32,7 +32,7 @@ use stylesheets::Origin; use values::{CSSFloat, CustomIdent}; use values::computed::{self, ToComputedValue}; use values::computed::font::FontSize; -use values::specified::Length; +use values::specified::{Integer, Length, Number}; /// The `Device` in Gecko wraps a pres context, has a default values computed, /// and contains all the viewport rule state. @@ -307,6 +307,13 @@ impl Resolution { } /// A value found or expected in a media expression. +/// +/// FIXME(emilio): How should calc() serialize in the Number / Integer / +/// BoolInteger / IntRatio case, as computed or as specified value? +/// +/// If the first, this would need to store the relevant values. +/// +/// See: https://github.com/w3c/csswg-drafts/issues/1968 #[derive(Clone, Debug, PartialEq)] pub enum MediaExpressionValue { /// A length. @@ -486,48 +493,29 @@ fn parse_feature_value<'i, 't>( let value = match feature_value_type { nsMediaFeature_ValueType::eLength => { let length = Length::parse_non_negative(context, input)?; - // FIXME(canaltinova): See bug 1396057. Gecko doesn't support calc - // inside media queries. This check is for temporarily remove it - // for parity with gecko. We should remove this check when we want - // to support it. - if let Length::Calc(_) = length { - return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) - } MediaExpressionValue::Length(length) }, nsMediaFeature_ValueType::eInteger => { - // FIXME(emilio): We should use `Integer::parse` to handle `calc` - // properly in integer expressions. Note that calc is still not - // supported in media queries per FIXME above. - let i = input.expect_integer()?; - if i < 0 { - return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) - } - MediaExpressionValue::Integer(i as u32) + let integer = Integer::parse_non_negative(context, input)?; + MediaExpressionValue::Integer(integer.value() as u32) } nsMediaFeature_ValueType::eBoolInteger => { - let i = input.expect_integer()?; - if i < 0 || i > 1 { + let integer = Integer::parse_non_negative(context, input)?; + let value = integer.value(); + if value > 1 { return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } - MediaExpressionValue::BoolInteger(i == 1) + MediaExpressionValue::BoolInteger(value == 1) } nsMediaFeature_ValueType::eFloat => { - MediaExpressionValue::Float(input.expect_number()?) + let number = Number::parse(context, input)?; + MediaExpressionValue::Float(number.get()) } nsMediaFeature_ValueType::eIntRatio => { - let a = input.expect_integer()?; - if a <= 0 { - return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) - } - + let a = Integer::parse_positive(context, input)?; input.expect_delim('/')?; - - let b = input.expect_integer()?; - if b <= 0 { - return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) - } - MediaExpressionValue::IntRatio(a as u32, b as u32) + let b = Integer::parse_positive(context, input)?; + MediaExpressionValue::IntRatio(a.value() as u32, b.value() as u32) } nsMediaFeature_ValueType::eResolution => { MediaExpressionValue::Resolution(Resolution::parse(input)?)