mirror of
https://github.com/servo/servo.git
synced 2025-08-07 14:35:33 +01:00
Auto merge of #19194 - emilio:media-query-calc, r=Manishearth
stylo: Bring back support for calc() in media-queries. Bug: 1396057 Reviewed-by: Manishearth <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/19194) <!-- Reviewable:end -->
This commit is contained in:
commit
4970b5d154
2 changed files with 51 additions and 59 deletions
|
@ -18,7 +18,7 @@ use gecko_bindings::structs::{nsMediaExpression_Range, nsMediaFeature};
|
||||||
use gecko_bindings::structs::{nsMediaFeature_ValueType, nsMediaFeature_RangeType};
|
use gecko_bindings::structs::{nsMediaFeature_ValueType, nsMediaFeature_RangeType};
|
||||||
use gecko_bindings::structs::{nsPresContext, RawGeckoPresContextOwned};
|
use gecko_bindings::structs::{nsPresContext, RawGeckoPresContextOwned};
|
||||||
use media_queries::MediaType;
|
use media_queries::MediaType;
|
||||||
use parser::ParserContext;
|
use parser::{Parse, ParserContext};
|
||||||
use properties::ComputedValues;
|
use properties::ComputedValues;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
|
@ -32,7 +32,7 @@ use stylesheets::Origin;
|
||||||
use values::{CSSFloat, CustomIdent};
|
use values::{CSSFloat, CustomIdent};
|
||||||
use values::computed::{self, ToComputedValue};
|
use values::computed::{self, ToComputedValue};
|
||||||
use values::computed::font::FontSize;
|
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,
|
/// The `Device` in Gecko wraps a pres context, has a default values computed,
|
||||||
/// and contains all the viewport rule state.
|
/// and contains all the viewport rule state.
|
||||||
|
@ -307,6 +307,13 @@ impl Resolution {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A value found or expected in a media expression.
|
/// 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)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum MediaExpressionValue {
|
pub enum MediaExpressionValue {
|
||||||
/// A length.
|
/// A length.
|
||||||
|
@ -439,7 +446,8 @@ impl MediaExpressionValue {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_feature<F>(mut f: F) -> Option<&'static nsMediaFeature>
|
fn find_feature<F>(mut f: F) -> Option<&'static nsMediaFeature>
|
||||||
where F: FnMut(&'static nsMediaFeature) -> bool,
|
where
|
||||||
|
F: FnMut(&'static nsMediaFeature) -> bool,
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut features = structs::nsMediaFeatures_features.as_ptr();
|
let mut features = structs::nsMediaFeatures_features.as_ptr();
|
||||||
|
@ -453,10 +461,12 @@ fn find_feature<F>(mut f: F) -> Option<&'static nsMediaFeature>
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn find_in_table<F>(mut current_entry: *const nsCSSProps_KTableEntry,
|
unsafe fn find_in_table<F>(
|
||||||
mut f: F)
|
mut current_entry: *const nsCSSProps_KTableEntry,
|
||||||
-> Option<(nsCSSKeyword, i16)>
|
mut f: F,
|
||||||
where F: FnMut(nsCSSKeyword, i16) -> bool
|
) -> Option<(nsCSSKeyword, i16)>
|
||||||
|
where
|
||||||
|
F: FnMut(nsCSSKeyword, i16) -> bool
|
||||||
{
|
{
|
||||||
loop {
|
loop {
|
||||||
let value = (*current_entry).mValue;
|
let value = (*current_entry).mValue;
|
||||||
|
@ -474,66 +484,50 @@ unsafe fn find_in_table<F>(mut current_entry: *const nsCSSProps_KTableEntry,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_feature_value<'i, 't>(feature: &nsMediaFeature,
|
fn parse_feature_value<'i, 't>(
|
||||||
feature_value_type: nsMediaFeature_ValueType,
|
feature: &nsMediaFeature,
|
||||||
context: &ParserContext,
|
feature_value_type: nsMediaFeature_ValueType,
|
||||||
input: &mut Parser<'i, 't>)
|
context: &ParserContext,
|
||||||
-> Result<MediaExpressionValue, ParseError<'i>> {
|
input: &mut Parser<'i, 't>,
|
||||||
|
) -> Result<MediaExpressionValue, ParseError<'i>> {
|
||||||
let value = match feature_value_type {
|
let value = match feature_value_type {
|
||||||
nsMediaFeature_ValueType::eLength => {
|
nsMediaFeature_ValueType::eLength => {
|
||||||
let length = Length::parse_non_negative(context, input)?;
|
let length = Length::parse_non_negative(context, input)?;
|
||||||
// FIXME(canaltinova): See bug 1396057. Gecko doesn't support calc
|
MediaExpressionValue::Length(length)
|
||||||
// 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 => {
|
nsMediaFeature_ValueType::eInteger => {
|
||||||
// FIXME(emilio): We should use `Integer::parse` to handle `calc`
|
let integer = Integer::parse_non_negative(context, input)?;
|
||||||
// properly in integer expressions. Note that calc is still not
|
MediaExpressionValue::Integer(integer.value() as u32)
|
||||||
// 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)
|
|
||||||
}
|
}
|
||||||
nsMediaFeature_ValueType::eBoolInteger => {
|
nsMediaFeature_ValueType::eBoolInteger => {
|
||||||
let i = input.expect_integer()?;
|
let integer = Integer::parse_non_negative(context, input)?;
|
||||||
if i < 0 || i > 1 {
|
let value = integer.value();
|
||||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
if value > 1 {
|
||||||
}
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
MediaExpressionValue::BoolInteger(i == 1)
|
}
|
||||||
|
MediaExpressionValue::BoolInteger(value == 1)
|
||||||
}
|
}
|
||||||
nsMediaFeature_ValueType::eFloat => {
|
nsMediaFeature_ValueType::eFloat => {
|
||||||
MediaExpressionValue::Float(input.expect_number()?)
|
let number = Number::parse(context, input)?;
|
||||||
|
MediaExpressionValue::Float(number.get())
|
||||||
}
|
}
|
||||||
nsMediaFeature_ValueType::eIntRatio => {
|
nsMediaFeature_ValueType::eIntRatio => {
|
||||||
let a = input.expect_integer()?;
|
let a = Integer::parse_positive(context, input)?;
|
||||||
if a <= 0 {
|
input.expect_delim('/')?;
|
||||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
let b = Integer::parse_positive(context, input)?;
|
||||||
}
|
MediaExpressionValue::IntRatio(a.value() as u32, b.value() as u32)
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
nsMediaFeature_ValueType::eResolution => {
|
nsMediaFeature_ValueType::eResolution => {
|
||||||
MediaExpressionValue::Resolution(Resolution::parse(input)?)
|
MediaExpressionValue::Resolution(Resolution::parse(input)?)
|
||||||
}
|
}
|
||||||
nsMediaFeature_ValueType::eEnumerated => {
|
nsMediaFeature_ValueType::eEnumerated => {
|
||||||
let location = input.current_source_location();
|
let location = input.current_source_location();
|
||||||
let keyword = input.expect_ident()?;
|
let keyword = input.expect_ident()?;
|
||||||
let keyword = unsafe {
|
let keyword = unsafe {
|
||||||
bindings::Gecko_LookupCSSKeyword(keyword.as_bytes().as_ptr(),
|
bindings::Gecko_LookupCSSKeyword(
|
||||||
keyword.len() as u32)
|
keyword.as_bytes().as_ptr(),
|
||||||
|
keyword.len() as u32,
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let first_table_entry: *const nsCSSProps_KTableEntry = unsafe {
|
let first_table_entry: *const nsCSSProps_KTableEntry = unsafe {
|
||||||
|
@ -557,14 +551,12 @@ fn parse_feature_value<'i, 't>(feature: &nsMediaFeature,
|
||||||
|
|
||||||
impl Expression {
|
impl Expression {
|
||||||
/// Trivially construct a new expression.
|
/// Trivially construct a new expression.
|
||||||
fn new(feature: &'static nsMediaFeature,
|
fn new(
|
||||||
value: Option<MediaExpressionValue>,
|
feature: &'static nsMediaFeature,
|
||||||
range: nsMediaExpression_Range) -> Self {
|
value: Option<MediaExpressionValue>,
|
||||||
Expression {
|
range: nsMediaExpression_Range,
|
||||||
feature: feature,
|
) -> Self {
|
||||||
value: value,
|
Self { feature, value, range }
|
||||||
range: range,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a media expression of the form:
|
/// Parse a media expression of the form:
|
||||||
|
|
|
@ -185,7 +185,7 @@ impl FontRelativeLength {
|
||||||
// element, the rem units refer to the property’s initial
|
// element, the rem units refer to the property’s initial
|
||||||
// value.
|
// value.
|
||||||
//
|
//
|
||||||
let reference_size = if context.is_root_element {
|
let reference_size = if context.is_root_element || context.in_media_query {
|
||||||
reference_font_size
|
reference_font_size
|
||||||
} else {
|
} else {
|
||||||
context.device().root_font_size()
|
context.device().root_font_size()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue