mirror of
https://github.com/servo/servo.git
synced 2025-08-07 14:35:33 +01:00
Thread ParseError return values through CSS parsing.
This commit is contained in:
parent
58e39bfffa
commit
27ae1ef2e7
121 changed files with 2133 additions and 1505 deletions
|
@ -6,7 +6,7 @@
|
|||
|
||||
use app_units::Au;
|
||||
use context::QuirksMode;
|
||||
use cssparser::{CssStringWriter, Parser, RGBA, Token};
|
||||
use cssparser::{CssStringWriter, Parser, RGBA, Token, BasicParseError};
|
||||
use euclid::Size2D;
|
||||
use font_metrics::get_metrics_provider_for_product;
|
||||
use gecko::values::convert_nscolor_to_rgba;
|
||||
|
@ -19,11 +19,12 @@ use media_queries::MediaType;
|
|||
use parser::ParserContext;
|
||||
use properties::{ComputedValues, StyleBuilder};
|
||||
use properties::longhands::font_size;
|
||||
use selectors::parser::SelectorParseError;
|
||||
use std::fmt::{self, Write};
|
||||
use std::sync::atomic::{AtomicBool, AtomicIsize, Ordering};
|
||||
use str::starts_with_ignore_ascii_case;
|
||||
use string_cache::Atom;
|
||||
use style_traits::ToCss;
|
||||
use style_traits::{ToCss, ParseError, StyleParseError};
|
||||
use style_traits::viewport::ViewportConstraints;
|
||||
use stylearc::Arc;
|
||||
use values::{CSSFloat, specified};
|
||||
|
@ -228,24 +229,25 @@ impl Resolution {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse(input: &mut Parser) -> Result<Self, ()> {
|
||||
fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
let (value, unit) = match try!(input.next()) {
|
||||
Token::Dimension(value, unit) => {
|
||||
(value.value, unit)
|
||||
(value, unit)
|
||||
},
|
||||
_ => return Err(()),
|
||||
t => return Err(BasicParseError::UnexpectedToken(t).into()),
|
||||
};
|
||||
|
||||
if value <= 0. {
|
||||
return Err(())
|
||||
let inner_value = value.value;
|
||||
if inner_value <= 0. {
|
||||
return Err(StyleParseError::UnspecifiedError.into())
|
||||
}
|
||||
|
||||
Ok(match_ignore_ascii_case! { &unit,
|
||||
"dpi" => Resolution::Dpi(value),
|
||||
"dppx" => Resolution::Dppx(value),
|
||||
"dpcm" => Resolution::Dpcm(value),
|
||||
_ => return Err(())
|
||||
})
|
||||
(match_ignore_ascii_case! { &unit,
|
||||
"dpi" => Ok(Resolution::Dpi(inner_value)),
|
||||
"dppx" => Ok(Resolution::Dppx(inner_value)),
|
||||
"dpcm" => Ok(Resolution::Dpcm(inner_value)),
|
||||
_ => Err(())
|
||||
}).map_err(|()| StyleParseError::UnexpectedDimension(unit).into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -459,44 +461,51 @@ impl Expression {
|
|||
/// ```
|
||||
/// (media-feature: media-value)
|
||||
/// ```
|
||||
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
pub fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<Self, ParseError<'i>> {
|
||||
try!(input.expect_parenthesis_block());
|
||||
input.parse_nested_block(|input| {
|
||||
let ident = try!(input.expect_ident());
|
||||
|
||||
let mut flags = 0;
|
||||
let mut feature_name = &*ident;
|
||||
let result = {
|
||||
let mut feature_name = &*ident;
|
||||
|
||||
// TODO(emilio): this is under a pref in Gecko.
|
||||
if starts_with_ignore_ascii_case(feature_name, "-webkit-") {
|
||||
feature_name = &feature_name[8..];
|
||||
flags |= nsMediaFeature_RequirementFlags::eHasWebkitPrefix as u8;
|
||||
}
|
||||
// TODO(emilio): this is under a pref in Gecko.
|
||||
if starts_with_ignore_ascii_case(feature_name, "-webkit-") {
|
||||
feature_name = &feature_name[8..];
|
||||
flags |= nsMediaFeature_RequirementFlags::eHasWebkitPrefix as u8;
|
||||
}
|
||||
|
||||
let range = if starts_with_ignore_ascii_case(feature_name, "min-") {
|
||||
feature_name = &feature_name[4..];
|
||||
nsMediaExpression_Range::eMin
|
||||
} else if starts_with_ignore_ascii_case(feature_name, "max-") {
|
||||
feature_name = &feature_name[4..];
|
||||
nsMediaExpression_Range::eMax
|
||||
} else {
|
||||
nsMediaExpression_Range::eEqual
|
||||
};
|
||||
|
||||
let atom = Atom::from(feature_name);
|
||||
let feature =
|
||||
match find_feature(|f| atom.as_ptr() == unsafe { *f.mName }) {
|
||||
Some(f) => f,
|
||||
None => return Err(()),
|
||||
let range = if starts_with_ignore_ascii_case(feature_name, "min-") {
|
||||
feature_name = &feature_name[4..];
|
||||
nsMediaExpression_Range::eMin
|
||||
} else if starts_with_ignore_ascii_case(feature_name, "max-") {
|
||||
feature_name = &feature_name[4..];
|
||||
nsMediaExpression_Range::eMax
|
||||
} else {
|
||||
nsMediaExpression_Range::eEqual
|
||||
};
|
||||
|
||||
let atom = Atom::from(feature_name);
|
||||
match find_feature(|f| atom.as_ptr() == unsafe { *f.mName }) {
|
||||
Some(f) => Ok((f, range)),
|
||||
None => Err(()),
|
||||
}
|
||||
};
|
||||
|
||||
let (feature, range) = match result {
|
||||
Ok((feature, range)) => (feature, range),
|
||||
Err(()) => return Err(SelectorParseError::UnexpectedIdent(ident).into()),
|
||||
};
|
||||
|
||||
if (feature.mReqFlags & !flags) != 0 {
|
||||
return Err(());
|
||||
return Err(SelectorParseError::UnexpectedIdent(ident).into());
|
||||
}
|
||||
|
||||
if range != nsMediaExpression_Range::eEqual &&
|
||||
feature.mRangeType != nsMediaFeature_RangeType::eMinMaxAllowed {
|
||||
return Err(());
|
||||
return Err(SelectorParseError::UnexpectedIdent(ident).into());
|
||||
}
|
||||
|
||||
// If there's no colon, this is a media query of the form
|
||||
|
@ -506,7 +515,7 @@ impl Expression {
|
|||
// reject them here too.
|
||||
if input.try(|i| i.expect_colon()).is_err() {
|
||||
if range != nsMediaExpression_Range::eEqual {
|
||||
return Err(())
|
||||
return Err(StyleParseError::RangedExpressionWithNoValue.into())
|
||||
}
|
||||
return Ok(Expression::new(feature, None, range));
|
||||
}
|
||||
|
@ -519,14 +528,14 @@ impl Expression {
|
|||
nsMediaFeature_ValueType::eInteger => {
|
||||
let i = input.expect_integer()?;
|
||||
if i < 0 {
|
||||
return Err(())
|
||||
return Err(StyleParseError::UnspecifiedError.into())
|
||||
}
|
||||
MediaExpressionValue::Integer(i as u32)
|
||||
}
|
||||
nsMediaFeature_ValueType::eBoolInteger => {
|
||||
let i = input.expect_integer()?;
|
||||
if i < 0 || i > 1 {
|
||||
return Err(())
|
||||
return Err(StyleParseError::UnspecifiedError.into())
|
||||
}
|
||||
MediaExpressionValue::BoolInteger(i == 1)
|
||||
}
|
||||
|
@ -536,14 +545,14 @@ impl Expression {
|
|||
nsMediaFeature_ValueType::eIntRatio => {
|
||||
let a = input.expect_integer()?;
|
||||
if a <= 0 {
|
||||
return Err(())
|
||||
return Err(StyleParseError::UnspecifiedError.into())
|
||||
}
|
||||
|
||||
input.expect_delim('/')?;
|
||||
|
||||
let b = input.expect_integer()?;
|
||||
if b <= 0 {
|
||||
return Err(())
|
||||
return Err(StyleParseError::UnspecifiedError.into())
|
||||
}
|
||||
MediaExpressionValue::IntRatio(a as u32, b as u32)
|
||||
}
|
||||
|
@ -566,7 +575,7 @@ impl Expression {
|
|||
Some((_kw, value)) => {
|
||||
value
|
||||
}
|
||||
None => return Err(()),
|
||||
None => return Err(StyleParseError::UnspecifiedError.into()),
|
||||
};
|
||||
|
||||
MediaExpressionValue::Enumerated(value)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue