mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
style: Error reporting fixes for media queries.
Do it so that we always try to evaluate the media expression and the modern syntax last, so that the most specific error message comes up. Bug: 1422225 Reviewed-by: xidorn MozReview-Commit-ID: 2tqdAsWh6Kh
This commit is contained in:
parent
3a92fd1cfc
commit
2d2e84aad5
4 changed files with 28 additions and 56 deletions
|
@ -7,7 +7,7 @@
|
||||||
use app_units::AU_PER_PX;
|
use app_units::AU_PER_PX;
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use context::QuirksMode;
|
use context::QuirksMode;
|
||||||
use cssparser::{BasicParseErrorKind, Parser, RGBA, Token};
|
use cssparser::{Parser, RGBA, Token};
|
||||||
use euclid::Size2D;
|
use euclid::Size2D;
|
||||||
use euclid::TypedScale;
|
use euclid::TypedScale;
|
||||||
use gecko::values::{convert_nscolor_to_rgba, convert_rgba_to_nscolor};
|
use gecko::values::{convert_nscolor_to_rgba, convert_rgba_to_nscolor};
|
||||||
|
@ -292,8 +292,8 @@ enum RangeOrOperator {
|
||||||
Operator(Operator),
|
Operator(Operator),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A range expression for gecko contains a reference to the media feature, the
|
/// A feature expression for gecko contains a reference to the media feature,
|
||||||
/// value the media query contained, and the range to evaluate.
|
/// the value the media query contained, and the range to evaluate.
|
||||||
#[derive(Clone, Debug, MallocSizeOf)]
|
#[derive(Clone, Debug, MallocSizeOf)]
|
||||||
pub struct MediaFeatureExpression {
|
pub struct MediaFeatureExpression {
|
||||||
feature: &'static nsMediaFeature,
|
feature: &'static nsMediaFeature,
|
||||||
|
@ -641,21 +641,13 @@ impl MediaFeatureExpression {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
input.expect_parenthesis_block().map_err(|err| {
|
input.expect_parenthesis_block()?;
|
||||||
err.location.new_custom_error(match err.kind {
|
|
||||||
BasicParseErrorKind::UnexpectedToken(t) => {
|
|
||||||
StyleParseErrorKind::ExpectedIdentifier(t)
|
|
||||||
},
|
|
||||||
_ => StyleParseErrorKind::UnspecifiedError,
|
|
||||||
})
|
|
||||||
})?;
|
|
||||||
|
|
||||||
input.parse_nested_block(|input| {
|
input.parse_nested_block(|input| {
|
||||||
Self::parse_in_parenthesis_block(context, input)
|
Self::parse_in_parenthesis_block(context, input)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a media range expression where we've already consumed the
|
/// Parse a media feature expression where we've already consumed the
|
||||||
/// parenthesis.
|
/// parenthesis.
|
||||||
pub fn parse_in_parenthesis_block<'i, 't>(
|
pub fn parse_in_parenthesis_block<'i, 't>(
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
|
@ -666,14 +658,7 @@ impl MediaFeatureExpression {
|
||||||
let range;
|
let range;
|
||||||
{
|
{
|
||||||
let location = input.current_source_location();
|
let location = input.current_source_location();
|
||||||
let ident = input.expect_ident().map_err(|err| {
|
let ident = input.expect_ident()?;
|
||||||
err.location.new_custom_error(match err.kind {
|
|
||||||
BasicParseErrorKind::UnexpectedToken(t) => {
|
|
||||||
StyleParseErrorKind::ExpectedIdentifier(t)
|
|
||||||
},
|
|
||||||
_ => StyleParseErrorKind::UnspecifiedError,
|
|
||||||
})
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let mut flags = 0;
|
let mut flags = 0;
|
||||||
|
|
||||||
|
@ -768,7 +753,7 @@ impl MediaFeatureExpression {
|
||||||
Some(range) => {
|
Some(range) => {
|
||||||
if operator.is_some() {
|
if operator.is_some() {
|
||||||
return Err(input.new_custom_error(
|
return Err(input.new_custom_error(
|
||||||
StyleParseErrorKind::MediaQueryExpectedFeatureValue
|
StyleParseErrorKind::MediaQueryUnexpectedOperator
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Some(RangeOrOperator::Range(range))
|
Some(RangeOrOperator::Range(range))
|
||||||
|
@ -778,7 +763,7 @@ impl MediaFeatureExpression {
|
||||||
Some(operator) => {
|
Some(operator) => {
|
||||||
if !feature_allows_ranges {
|
if !feature_allows_ranges {
|
||||||
return Err(input.new_custom_error(
|
return Err(input.new_custom_error(
|
||||||
StyleParseErrorKind::MediaQueryExpectedFeatureValue
|
StyleParseErrorKind::MediaQueryUnexpectedOperator
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Some(RangeOrOperator::Operator(operator))
|
Some(RangeOrOperator::Operator(operator))
|
||||||
|
|
|
@ -163,12 +163,11 @@ impl MediaCondition {
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
input.parse_nested_block(|input| {
|
input.parse_nested_block(|input| {
|
||||||
// Base case.
|
// Base case.
|
||||||
if let Ok(expr) = input.try(|i| MediaFeatureExpression::parse_in_parenthesis_block(context, i)) {
|
if let Ok(inner) = input.try(|i| Self::parse(context, i)) {
|
||||||
return Ok(MediaCondition::Feature(expr));
|
return Ok(MediaCondition::InParens(Box::new(inner)))
|
||||||
}
|
}
|
||||||
|
let expr = MediaFeatureExpression::parse_in_parenthesis_block(context, input)?;
|
||||||
let inner = Self::parse(context, input)?;
|
Ok(MediaCondition::Feature(expr))
|
||||||
Ok(MediaCondition::InParens(Box::new(inner)))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
use Atom;
|
use Atom;
|
||||||
use cssparser::Parser;
|
use cssparser::Parser;
|
||||||
use parser::ParserContext;
|
use parser::ParserContext;
|
||||||
use selectors::parser::SelectorParseErrorKind;
|
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
use str::string_as_ascii_lowercase;
|
use str::string_as_ascii_lowercase;
|
||||||
use style_traits::{CssWriter, ParseError, ToCss};
|
use style_traits::{CssWriter, ParseError, ToCss};
|
||||||
|
@ -125,34 +124,23 @@ impl MediaQuery {
|
||||||
pub fn parse<'i, 't>(
|
pub fn parse<'i, 't>(
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<MediaQuery, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if let Ok(condition) = input.try(|i| MediaCondition::parse(context, i)) {
|
let (qualifier, explicit_media_type) = input.try(|input| -> Result<_, ()> {
|
||||||
return Ok(Self {
|
let qualifier = input.try(Qualifier::parse).ok();
|
||||||
qualifier: None,
|
let ident = input.expect_ident().map_err(|_| ())?;
|
||||||
media_type: MediaQueryType::All,
|
let media_type = MediaQueryType::parse(&ident)?;
|
||||||
condition: Some(condition),
|
Ok((qualifier, Some(media_type)))
|
||||||
})
|
}).unwrap_or_default();
|
||||||
}
|
|
||||||
|
|
||||||
let qualifier = input.try(Qualifier::parse).ok();
|
let condition = if explicit_media_type.is_none() {
|
||||||
let media_type = {
|
Some(MediaCondition::parse(context, input)?)
|
||||||
let location = input.current_source_location();
|
} else if input.try(|i| i.expect_ident_matching("and")).is_ok() {
|
||||||
let ident = input.expect_ident()?;
|
Some(MediaCondition::parse_disallow_or(context, input)?)
|
||||||
match MediaQueryType::parse(&ident) {
|
} else {
|
||||||
Ok(t) => t,
|
None
|
||||||
Err(..) => return Err(location.new_custom_error(
|
|
||||||
SelectorParseErrorKind::UnexpectedIdent(ident.clone())
|
|
||||||
))
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let condition =
|
let media_type = explicit_media_type.unwrap_or(MediaQueryType::All);
|
||||||
if input.try(|i| i.expect_ident_matching("and")).is_ok() {
|
|
||||||
Some(MediaCondition::parse_disallow_or(context, input)?)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(Self { qualifier, media_type, condition })
|
Ok(Self { qualifier, media_type, condition })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,12 +106,12 @@ pub enum StyleParseErrorKind<'i> {
|
||||||
PropertyDeclarationValueNotExhausted,
|
PropertyDeclarationValueNotExhausted,
|
||||||
/// An unexpected dimension token was encountered.
|
/// An unexpected dimension token was encountered.
|
||||||
UnexpectedDimension(CowRcStr<'i>),
|
UnexpectedDimension(CowRcStr<'i>),
|
||||||
/// Expected identifier not found.
|
|
||||||
ExpectedIdentifier(Token<'i>),
|
|
||||||
/// Missing or invalid media feature name.
|
/// Missing or invalid media feature name.
|
||||||
MediaQueryExpectedFeatureName(CowRcStr<'i>),
|
MediaQueryExpectedFeatureName(CowRcStr<'i>),
|
||||||
/// Missing or invalid media feature value.
|
/// Missing or invalid media feature value.
|
||||||
MediaQueryExpectedFeatureValue,
|
MediaQueryExpectedFeatureValue,
|
||||||
|
/// A media feature range operator was not expected.
|
||||||
|
MediaQueryUnexpectedOperator,
|
||||||
/// min- or max- properties must have a value.
|
/// min- or max- properties must have a value.
|
||||||
RangedExpressionWithNoValue,
|
RangedExpressionWithNoValue,
|
||||||
/// A function was encountered that was not expected.
|
/// A function was encountered that was not expected.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue