stylo: Update rust-cssparser; extract more specific error types when reporting (bug 1352669).

This commit is contained in:
Josh Matthews 2017-07-06 13:59:31 -04:00
parent a08371e8eb
commit 0b43d0072c
21 changed files with 318 additions and 80 deletions

26
Cargo.lock generated
View file

@ -325,7 +325,7 @@ version = "0.0.1"
dependencies = [ dependencies = [
"azure 0.19.0 (git+https://github.com/servo/rust-azure)", "azure 0.19.0 (git+https://github.com/servo/rust-azure)",
"canvas_traits 0.0.1", "canvas_traits 0.0.1",
"cssparser 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -340,7 +340,7 @@ dependencies = [
name = "canvas_traits" name = "canvas_traits"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"cssparser 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -585,7 +585,7 @@ dependencies = [
[[package]] [[package]]
name = "cssparser" name = "cssparser"
version = "0.16.1" version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1017,7 +1017,7 @@ name = "geckoservo"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1083,7 +1083,7 @@ dependencies = [
name = "gfx_tests" name = "gfx_tests"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"cssparser 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx 0.0.1", "gfx 0.0.1",
"ipc-channel 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1", "style 0.0.1",
@ -2418,7 +2418,7 @@ dependencies = [
"caseless 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "caseless 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"cmake 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
"cookie 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "cookie 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"deny_public_fields 0.0.1", "deny_public_fields 0.0.1",
"devtools_traits 0.0.1", "devtools_traits 0.0.1",
"dom_struct 0.0.1", "dom_struct 0.0.1",
@ -2491,7 +2491,7 @@ dependencies = [
"app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"canvas_traits 0.0.1", "canvas_traits 0.0.1",
"cssparser 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx_traits 0.0.1", "gfx_traits 0.0.1",
"heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2562,7 +2562,7 @@ name = "selectors"
version = "0.19.0" version = "0.19.0"
dependencies = [ dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2954,7 +2954,7 @@ dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3007,7 +3007,7 @@ version = "0.0.1"
dependencies = [ dependencies = [
"app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"html5ever 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", "html5ever 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3028,7 +3028,7 @@ version = "0.0.1"
dependencies = [ dependencies = [
"app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3041,7 +3041,7 @@ name = "stylo_tests"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"geckoservo 0.0.1", "geckoservo 0.0.1",
@ -3624,7 +3624,7 @@ dependencies = [
"checksum core-foundation-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "41115a6aa5d3e1e5ef98148373f25971d1fad53818553f216495f9e67e90a624" "checksum core-foundation-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "41115a6aa5d3e1e5ef98148373f25971d1fad53818553f216495f9e67e90a624"
"checksum core-graphics 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a9f841e9637adec70838c537cae52cb4c751cc6514ad05669b51d107c2021c79" "checksum core-graphics 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a9f841e9637adec70838c537cae52cb4c751cc6514ad05669b51d107c2021c79"
"checksum core-text 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74ba2a7abdccb94fb6c00822addef48504182b285aa45a30e78286487888fcb4" "checksum core-text 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74ba2a7abdccb94fb6c00822addef48504182b285aa45a30e78286487888fcb4"
"checksum cssparser 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2842253baded8e712e9d8d80ebfe5ea8e95c5b27071e6a6db6080ca1e81c07d1" "checksum cssparser 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e7063452c60432cb306ed54d538178c20792d47fa960c240ce6c083239ee55ec"
"checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df" "checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df"
"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850"
"checksum dbus 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4aee01fb76ada3e5e7ca642ea6664ebf7308a810739ca2aca44909a1191ac254" "checksum dbus 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4aee01fb76ada3e5e7ca642ea6664ebf7308a810739ca2aca44909a1191ac254"

View file

@ -12,7 +12,7 @@ path = "lib.rs"
[dependencies] [dependencies]
azure = {git = "https://github.com/servo/rust-azure"} azure = {git = "https://github.com/servo/rust-azure"}
canvas_traits = {path = "../canvas_traits"} canvas_traits = {path = "../canvas_traits"}
cssparser = "0.16.1" cssparser = "0.17.0"
euclid = "0.15" euclid = "0.15"
gleam = "0.4" gleam = "0.4"
ipc-channel = "0.8" ipc-channel = "0.8"

View file

@ -10,7 +10,7 @@ name = "canvas_traits"
path = "lib.rs" path = "lib.rs"
[dependencies] [dependencies]
cssparser = "0.16.1" cssparser = "0.17.0"
euclid = "0.15" euclid = "0.15"
heapsize = "0.4" heapsize = "0.4"
heapsize_derive = "0.1" heapsize_derive = "0.1"

View file

@ -35,7 +35,7 @@ byteorder = "1.0"
canvas_traits = {path = "../canvas_traits"} canvas_traits = {path = "../canvas_traits"}
caseless = "0.1.0" caseless = "0.1.0"
cookie = "0.6" cookie = "0.6"
cssparser = "0.16.1" cssparser = "0.17.0"
deny_public_fields = {path = "../deny_public_fields"} deny_public_fields = {path = "../deny_public_fields"}
devtools_traits = {path = "../devtools_traits"} devtools_traits = {path = "../devtools_traits"}
dom_struct = {path = "../dom_struct"} dom_struct = {path = "../dom_struct"}

View file

@ -13,7 +13,7 @@ path = "lib.rs"
app_units = "0.5" app_units = "0.5"
atomic_refcell = "0.1" atomic_refcell = "0.1"
canvas_traits = {path = "../canvas_traits"} canvas_traits = {path = "../canvas_traits"}
cssparser = "0.16.1" cssparser = "0.17.0"
euclid = "0.15" euclid = "0.15"
gfx_traits = {path = "../gfx_traits"} gfx_traits = {path = "../gfx_traits"}
heapsize = "0.4" heapsize = "0.4"

View file

@ -25,7 +25,7 @@ unstable = []
[dependencies] [dependencies]
bitflags = "0.7" bitflags = "0.7"
matches = "0.1" matches = "0.1"
cssparser = "0.16.1" cssparser = "0.17.0"
log = "0.3" log = "0.3"
fnv = "1.0" fnv = "1.0"
phf = "0.7.18" phf = "0.7.18"

View file

@ -59,7 +59,7 @@ pub enum SelectorParseError<'i, T> {
PseudoElementExpectedIdent, PseudoElementExpectedIdent,
UnsupportedPseudoClass, UnsupportedPseudoClass,
UnexpectedIdent(CompactCowStr<'i>), UnexpectedIdent(CompactCowStr<'i>),
ExpectedNamespace, ExpectedNamespace(CompactCowStr<'i>),
Custom(T), Custom(T),
} }
@ -1105,9 +1105,10 @@ fn parse_qualified_name<'i, 't, P, E, Impl>
let position = input.position(); let position = input.position();
match input.next_including_whitespace() { match input.next_including_whitespace() {
Ok(Token::Delim('|')) => { Ok(Token::Delim('|')) => {
let prefix = from_cow_str(value.into()); let prefix = from_cow_str(value.clone().into());
let result = parser.namespace_for_prefix(&prefix); let result = parser.namespace_for_prefix(&prefix);
let url = result.ok_or(ParseError::Custom(SelectorParseError::ExpectedNamespace))?; let url = result.ok_or(ParseError::Custom(
SelectorParseError::ExpectedNamespace(value.into())))?;
explicit_namespace(input, QNamePrefix::ExplicitNamespace(prefix, url)) explicit_namespace(input, QNamePrefix::ExplicitNamespace(prefix, url))
}, },
_ => { _ => {

View file

@ -38,7 +38,7 @@ bitflags = "0.7"
bit-vec = "0.4.3" bit-vec = "0.4.3"
byteorder = "1.0" byteorder = "1.0"
cfg-if = "0.1.0" cfg-if = "0.1.0"
cssparser = "0.16.1" cssparser = "0.17.0"
encoding = {version = "0.2", optional = true} encoding = {version = "0.2", optional = true}
euclid = "0.15" euclid = "0.15"
fnv = "1.0" fnv = "1.0"

View file

@ -280,10 +280,10 @@ fn parse_declaration_value_block<'i, 't>
} }
token.serialization_type() token.serialization_type()
} }
Token::BadUrl => Token::BadUrl(u) =>
return Err(StyleParseError::BadUrlInDeclarationValueBlock.into()), return Err(StyleParseError::BadUrlInDeclarationValueBlock(u).into()),
Token::BadString => Token::BadString(s) =>
return Err(StyleParseError::BadStringInDeclarationValueBlock.into()), return Err(StyleParseError::BadStringInDeclarationValueBlock(s).into()),
Token::CloseParenthesis => Token::CloseParenthesis =>
return Err(StyleParseError::UnbalancedCloseParenthesisInDeclarationValueBlock.into()), return Err(StyleParseError::UnbalancedCloseParenthesisInDeclarationValueBlock.into()),
Token::CloseSquareBracket => Token::CloseSquareBracket =>

View file

@ -76,8 +76,8 @@ impl<'a> ContextualParseError<'a> {
Token::ParenthesisBlock => format!("parenthesis ("), Token::ParenthesisBlock => format!("parenthesis ("),
Token::SquareBracketBlock => format!("square bracket ["), Token::SquareBracketBlock => format!("square bracket ["),
Token::CurlyBracketBlock => format!("curly bracket {{"), Token::CurlyBracketBlock => format!("curly bracket {{"),
Token::BadUrl => format!("bad url parse error"), Token::BadUrl(ref _u) => format!("bad url parse error"),
Token::BadString => format!("bad string parse error"), Token::BadString(ref _s) => format!("bad string parse error"),
Token::CloseParenthesis => format!("unmatched close parenthesis"), Token::CloseParenthesis => format!("unmatched close parenthesis"),
Token::CloseSquareBracket => format!("unmatched close square bracket"), Token::CloseSquareBracket => format!("unmatched close square bracket"),
Token::CloseCurlyBracket => format!("unmatched close curly bracket"), Token::CloseCurlyBracket => format!("unmatched close curly bracket"),
@ -88,11 +88,11 @@ impl<'a> ContextualParseError<'a> {
match *err { match *err {
CssParseError::Basic(BasicParseError::UnexpectedToken(ref t)) => CssParseError::Basic(BasicParseError::UnexpectedToken(ref t)) =>
format!("found unexpected {}", token_to_str(t)), format!("found unexpected {}", token_to_str(t)),
CssParseError::Basic(BasicParseError::ExpectedToken(ref t)) =>
format!("expected {}", token_to_str(t)),
CssParseError::Basic(BasicParseError::EndOfInput) => CssParseError::Basic(BasicParseError::EndOfInput) =>
format!("unexpected end of input"), format!("unexpected end of input"),
CssParseError::Basic(BasicParseError::AtRuleInvalid) => CssParseError::Basic(BasicParseError::AtRuleInvalid(ref i)) =>
format!("@ rule invalid: {}", i),
CssParseError::Basic(BasicParseError::AtRuleBodyInvalid) =>
format!("@ rule invalid"), format!("@ rule invalid"),
CssParseError::Basic(BasicParseError::QualifiedRuleInvalid) => CssParseError::Basic(BasicParseError::QualifiedRuleInvalid) =>
format!("qualified rule invalid"), format!("qualified rule invalid"),

View file

@ -908,10 +908,17 @@ pub fn parse_one_declaration_into(declarations: &mut SourcePropertyDeclaration,
parsing_mode, parsing_mode,
quirks_mode); quirks_mode);
let mut input = ParserInput::new(input); let mut input = ParserInput::new(input);
Parser::new(&mut input).parse_entirely(|parser| { let mut parser = Parser::new(&mut input);
let start = parser.position();
parser.parse_entirely(|parser| {
PropertyDeclaration::parse_into(declarations, id, &context, parser) PropertyDeclaration::parse_into(declarations, id, &context, parser)
.map_err(|e| e.into()) .map_err(|e| e.into())
}).map_err(|_| ()) }).map_err(|err| {
let end = parser.position();
let error = ContextualParseError::UnsupportedPropertyDeclaration(
parser.slice(start..end), err);
log_css_error(&mut parser, start, error, &context);
})
} }
/// A struct to parse property declarations. /// A struct to parse property declarations.

View file

@ -37,7 +37,8 @@ use properties::animated_properties::AnimatableLonghand;
use selectors::parser::SelectorParseError; use selectors::parser::SelectorParseError;
#[cfg(feature = "servo")] use servo_config::prefs::PREFS; #[cfg(feature = "servo")] use servo_config::prefs::PREFS;
use shared_lock::StylesheetGuards; use shared_lock::StylesheetGuards;
use style_traits::{PARSING_MODE_DEFAULT, HasViewportPercentage, ToCss, ParseError, PropertyDeclarationParseError}; use style_traits::{PARSING_MODE_DEFAULT, HasViewportPercentage, ToCss, ParseError};
use style_traits::{PropertyDeclarationParseError, StyleParseError};
use stylesheets::{CssRuleType, MallocSizeOf, MallocSizeOfFn, Origin, UrlExtraData}; use stylesheets::{CssRuleType, MallocSizeOf, MallocSizeOfFn, Origin, UrlExtraData};
#[cfg(feature = "servo")] use values::Either; #[cfg(feature = "servo")] use values::Either;
use values::generics::text::LineHeight; use values::generics::text::LineHeight;
@ -1009,7 +1010,7 @@ impl PropertyId {
match static_id(&property_name) { match static_id(&property_name) {
Some(&StaticId::Longhand(id)) => Ok(PropertyId::Longhand(id)), Some(&StaticId::Longhand(id)) => Ok(PropertyId::Longhand(id)),
Some(&StaticId::Shorthand(id)) => Ok(PropertyId::Shorthand(id)), Some(&StaticId::Shorthand(id)) => Ok(PropertyId::Shorthand(id)),
None => Err(SelectorParseError::UnexpectedIdent(property_name).into()), None => Err(StyleParseError::UnknownProperty(property_name).into()),
} }
} }
@ -1414,7 +1415,7 @@ impl PropertyDeclaration {
Ok(keyword) => DeclaredValueOwned::CSSWideKeyword(keyword), Ok(keyword) => DeclaredValueOwned::CSSWideKeyword(keyword),
Err(_) => match ::custom_properties::SpecifiedValue::parse(context, input) { Err(_) => match ::custom_properties::SpecifiedValue::parse(context, input) {
Ok(value) => DeclaredValueOwned::Value(value), Ok(value) => DeclaredValueOwned::Value(value),
Err(_) => return Err(PropertyDeclarationParseError::InvalidValue), Err(_) => return Err(PropertyDeclarationParseError::InvalidValue(name.to_string())),
} }
}; };
declarations.push(PropertyDeclaration::Custom(name, value)); declarations.push(PropertyDeclaration::Custom(name, value));
@ -1442,7 +1443,7 @@ impl PropertyDeclaration {
declarations.push(value); declarations.push(value);
Ok(()) Ok(())
}, },
Err(_) => Err(PropertyDeclarationParseError::InvalidValue), Err(_) => Err(PropertyDeclarationParseError::InvalidValue("${property.ident}".into())),
} }
% else: % else:
Err(PropertyDeclarationParseError::UnknownProperty) Err(PropertyDeclarationParseError::UnknownProperty)
@ -1482,7 +1483,7 @@ impl PropertyDeclaration {
}, },
Err(_) => { Err(_) => {
shorthands::${shorthand.ident}::parse_into(declarations, context, input) shorthands::${shorthand.ident}::parse_into(declarations, context, input)
.map_err(|_| PropertyDeclarationParseError::InvalidValue) .map_err(|_| PropertyDeclarationParseError::InvalidValue("${shorthand.ident}".into()))
} }
} }
} }

View file

@ -7,7 +7,7 @@
use {Namespace, Prefix}; use {Namespace, Prefix};
use counter_style::{parse_counter_style_body, parse_counter_style_name}; use counter_style::{parse_counter_style_body, parse_counter_style_name};
use cssparser::{AtRuleParser, AtRuleType, Parser, QualifiedRuleParser, RuleListParser}; use cssparser::{AtRuleParser, AtRuleType, Parser, QualifiedRuleParser, RuleListParser};
use cssparser::{CompactCowStr, SourceLocation}; use cssparser::{CompactCowStr, SourceLocation, BasicParseError};
use error_reporting::ContextualParseError; use error_reporting::ContextualParseError;
use font_face::parse_font_face_block; use font_face::parse_font_face_block;
use media_queries::{parse_media_query_list, MediaList}; use media_queries::{parse_media_query_list, MediaList};
@ -184,7 +184,13 @@ impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> {
self.state = State::Namespaces; self.state = State::Namespaces;
let prefix_result = input.try(|input| input.expect_ident()); let prefix_result = input.try(|input| input.expect_ident());
let url = Namespace::from(Cow::from(input.expect_url_or_string()?)); let maybe_namespace = match input.expect_url_or_string() {
Ok(url_or_string) => url_or_string,
Err(BasicParseError::UnexpectedToken(t)) =>
return Err(StyleParseError::UnexpectedTokenWithinNamespace(t).into()),
Err(e) => return Err(e.into()),
};
let url = Namespace::from(Cow::from(maybe_namespace));
let id = register_namespace(&url) let id = register_namespace(&url)
.map_err(|()| StyleParseError::UnspecifiedError)?; .map_err(|()| StyleParseError::UnspecifiedError)?;
@ -509,7 +515,7 @@ fn get_location_with_offset(
offset: u64 offset: u64
) -> SourceLocation { ) -> SourceLocation {
SourceLocation { SourceLocation {
line: location.line + offset as u32 - 1, line: location.line + offset as u32,
column: location.column, column: location.column,
} }
} }

View file

@ -16,7 +16,7 @@ gecko = []
[dependencies] [dependencies]
app_units = "0.5" app_units = "0.5"
bitflags = "0.7" bitflags = "0.7"
cssparser = "0.16.1" cssparser = "0.17.0"
euclid = "0.15" euclid = "0.15"
heapsize = {version = "0.4", optional = true} heapsize = {version = "0.4", optional = true}
heapsize_derive = {version = "0.1", optional = true} heapsize_derive = {version = "0.1", optional = true}

View file

@ -22,7 +22,7 @@ extern crate euclid;
extern crate selectors; extern crate selectors;
#[cfg(feature = "servo")] #[macro_use] extern crate serde; #[cfg(feature = "servo")] #[macro_use] extern crate serde;
use cssparser::CompactCowStr; use cssparser::{CompactCowStr, Token};
use selectors::parser::SelectorParseError; use selectors::parser::SelectorParseError;
/// Opaque type stored in type-unsafe work queues for parallel layout. /// Opaque type stored in type-unsafe work queues for parallel layout.
@ -81,9 +81,9 @@ pub type ParseError<'i> = cssparser::ParseError<'i, SelectorParseError<'i, Style
/// Errors that can be encountered while parsing CSS values. /// Errors that can be encountered while parsing CSS values.
pub enum StyleParseError<'i> { pub enum StyleParseError<'i> {
/// A bad URL token in a DVB. /// A bad URL token in a DVB.
BadUrlInDeclarationValueBlock, BadUrlInDeclarationValueBlock(CompactCowStr<'i>),
/// A bad string token in a DVB. /// A bad string token in a DVB.
BadStringInDeclarationValueBlock, BadStringInDeclarationValueBlock(CompactCowStr<'i>),
/// Unexpected closing parenthesis in a DVB. /// Unexpected closing parenthesis in a DVB.
UnbalancedCloseParenthesisInDeclarationValueBlock, UnbalancedCloseParenthesisInDeclarationValueBlock,
/// Unexpected closing bracket in a DVB. /// Unexpected closing bracket in a DVB.
@ -110,17 +110,21 @@ pub enum StyleParseError<'i> {
UnsupportedAtRule(CompactCowStr<'i>), UnsupportedAtRule(CompactCowStr<'i>),
/// A placeholder for many sources of errors that require more specific variants. /// A placeholder for many sources of errors that require more specific variants.
UnspecifiedError, UnspecifiedError,
/// An unexpected token was found within a namespace rule.
UnexpectedTokenWithinNamespace(Token<'i>),
/// An unknown CSS property was encountered.
UnknownProperty(CompactCowStr<'i>),
} }
/// The result of parsing a property declaration. /// The result of parsing a property declaration.
#[derive(Eq, PartialEq, Copy, Clone, Debug)] #[derive(Eq, PartialEq, Clone, Debug)]
pub enum PropertyDeclarationParseError { pub enum PropertyDeclarationParseError {
/// The property declaration was for an unknown property. /// The property declaration was for an unknown property.
UnknownProperty, UnknownProperty,
/// The property declaration was for a disabled experimental property. /// The property declaration was for a disabled experimental property.
ExperimentalProperty, ExperimentalProperty,
/// The property declaration contained an invalid value. /// The property declaration contained an invalid value.
InvalidValue, InvalidValue(String),
/// The declaration contained an animation property, and we were parsing /// The declaration contained an animation property, and we were parsing
/// this as a keyframe block (so that property should be ignored). /// this as a keyframe block (so that property should be ignored).
/// ///

View file

@ -16,7 +16,7 @@ gecko_debug = ["style/gecko_debug"]
[dependencies] [dependencies]
atomic_refcell = "0.1" atomic_refcell = "0.1"
cssparser = "0.16.1" cssparser = "0.17.0"
env_logger = {version = "0.4", default-features = false} # disable `regex` to reduce code size env_logger = {version = "0.4", default-features = false} # disable `regex` to reduce code size
libc = "0.2" libc = "0.2"
log = {version = "0.3.5", features = ["release_max_level_info"]} log = {version = "0.3.5", features = ["release_max_level_info"]}

View file

@ -6,7 +6,9 @@
#![allow(unsafe_code)] #![allow(unsafe_code)]
use cssparser::{Parser, SourcePosition}; use cssparser::{Parser, SourcePosition, ParseError as CssParseError, Token, BasicParseError};
use cssparser::CompactCowStr;
use selectors::parser::SelectorParseError;
use style::error_reporting::{ParseErrorReporter, ContextualParseError}; use style::error_reporting::{ParseErrorReporter, ContextualParseError};
use style::gecko_bindings::bindings::{Gecko_CreateCSSErrorReporter, Gecko_DestroyCSSErrorReporter}; use style::gecko_bindings::bindings::{Gecko_CreateCSSErrorReporter, Gecko_DestroyCSSErrorReporter};
use style::gecko_bindings::bindings::Gecko_ReportUnexpectedCSSError; use style::gecko_bindings::bindings::Gecko_ReportUnexpectedCSSError;
@ -15,6 +17,7 @@ use style::gecko_bindings::structs::ErrorReporter as GeckoErrorReporter;
use style::gecko_bindings::structs::URLExtraData as RawUrlExtraData; use style::gecko_bindings::structs::URLExtraData as RawUrlExtraData;
use style::gecko_bindings::sugar::refptr::RefPtr; use style::gecko_bindings::sugar::refptr::RefPtr;
use style::stylesheets::UrlExtraData; use style::stylesheets::UrlExtraData;
use style_traits::{ParseError, StyleParseError, PropertyDeclarationParseError};
/// Wrapper around an instance of Gecko's CSS error reporter. /// Wrapper around an instance of Gecko's CSS error reporter.
pub struct ErrorReporter(*mut GeckoErrorReporter); pub struct ErrorReporter(*mut GeckoErrorReporter);
@ -39,25 +42,239 @@ impl Drop for ErrorReporter {
} }
} }
enum ErrorString<'a> {
Snippet(CompactCowStr<'a>),
Ident(CompactCowStr<'a>),
UnexpectedToken(Token<'a>),
}
impl<'a> ErrorString<'a> {
fn into_str(self) -> String {
match self {
ErrorString::Snippet(s) => s.into_owned(),
ErrorString::Ident(i) => escape_css_ident(&i),
ErrorString::UnexpectedToken(t) => token_to_str(t),
}
}
}
// This is identical to the behaviour of cssparser::serialize_identifier, except that
// it uses numerical escapes for a larger set of characters.
fn escape_css_ident(ident: &str) -> String {
// The relevant parts of the CSS grammar are:
// ident ([-]?{nmstart}|[-][-]){nmchar}*
// nmstart [_a-z]|{nonascii}|{escape}
// nmchar [_a-z0-9-]|{nonascii}|{escape}
// nonascii [^\0-\177]
// escape {unicode}|\\[^\n\r\f0-9a-f]
// unicode \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
// from http://www.w3.org/TR/CSS21/syndata.html#tokenization but
// modified for idents by
// http://dev.w3.org/csswg/cssom/#serialize-an-identifier and
// http://dev.w3.org/csswg/css-syntax/#would-start-an-identifier
if ident.is_empty() {
return ident.into()
}
let mut escaped = String::new();
// A leading dash does not need to be escaped as long as it is not the
// *only* character in the identifier.
let mut iter = ident.chars().peekable();
if iter.peek() == Some(&'-') {
if ident.len() == 1 {
return "\\-".into();
}
escaped.push('-');
// Skip the first character.
let _ = iter.next();
}
// Escape a digit at the start (including after a dash),
// numerically. If we didn't escape it numerically, it would get
// interpreted as a numeric escape for the wrong character.
if iter.peek().map_or(false, |&c| '0' <= c && c <= '9') {
let ch = iter.next().unwrap();
escaped.push_str(&format!("\\{:x} ", ch as u32));
}
while let Some(ch) = iter.next() {
if ch == '\0' {
escaped.push_str("\u{FFFD}");
} else if ch < (0x20 as char) || (0x7f as char <= ch && ch < (0xA0 as char)) {
// Escape U+0000 through U+001F and U+007F through U+009F numerically.
escaped.push_str(&format!("\\{:x} ", ch as u32));
} else {
// Escape ASCII non-identifier printables as a backslash plus
// the character.
if (ch < (0x7F as char)) &&
ch != '_' && ch != '-' &&
(ch < '0' || '9' < ch) &&
(ch < 'A' || 'Z' < ch) &&
(ch < 'a' || 'z' < ch)
{
escaped.push('\\');
}
escaped.push(ch);
}
}
escaped
}
// This is identical to the behaviour of cssparser::CssStringWriter, except that
// the characters between 0x7F and 0xA0 as numerically escaped as well.
fn escape_css_string(s: &str) -> String {
let mut escaped = String::new();
for ch in s.chars() {
if ch < ' ' || (ch >= (0x7F as char) && ch < (0xA0 as char)) {
escaped.push_str(&format!("\\{:x} ", ch as u32));
} else {
if ch == '"' || ch == '\'' || ch == '\\' {
// Escape backslash and quote characters symbolically.
// It's not technically necessary to escape the quote
// character that isn't being used to delimit the string,
// but we do it anyway because that makes testing simpler.
escaped.push('\\');
}
escaped.push(ch);
}
}
escaped
}
fn token_to_str<'a>(t: Token<'a>) -> String {
match t {
Token::Ident(i) => escape_css_ident(&i),
Token::AtKeyword(kw) => format!("@{}", escape_css_ident(&kw)),
Token::Hash(h) | Token::IDHash(h) => format!("#{}", escape_css_ident(&h)),
Token::QuotedString(s) => format!("'{}'", escape_css_string(&s)),
Token::UnquotedUrl(u) => format!("'{}'", escape_css_string(&u)),
Token::Delim(d) => d.to_string(),
Token::Number { int_value: Some(i), .. } => i.to_string(),
Token::Number { value, .. } => value.to_string(),
Token::Percentage { int_value: Some(i), .. } => i.to_string(),
Token::Percentage { unit_value, .. } => unit_value.to_string(),
Token::Dimension { int_value: Some(i), ref unit, .. } =>
format!("{}{}", i.to_string(), escape_css_ident(&unit.to_string())),
Token::Dimension { value, ref unit, .. } =>
format!("{}{}", value.to_string(), escape_css_ident(&unit.to_string())),
Token::WhiteSpace(_) => "whitespace".into(),
Token::Comment(_) => "comment".into(),
Token::Colon => ":".into(),
Token::Semicolon => ";".into(),
Token::Comma => ",".into(),
Token::IncludeMatch => "~=".into(),
Token::DashMatch => "|=".into(),
Token::PrefixMatch => "^=".into(),
Token::SuffixMatch => "$=".into(),
Token::SubstringMatch => "*=".into(),
Token::Column => "||".into(),
Token::CDO => "<!--".into(),
Token::CDC => "-->".into(),
Token::Function(f) => format!("{}(", escape_css_ident(&f)),
Token::ParenthesisBlock => "(".into(),
Token::SquareBracketBlock => "[".into(),
Token::CurlyBracketBlock => "{".into(),
Token::BadUrl(url) => format!("url('{}", escape_css_string(&url)).into(),
Token::BadString(s) => format!("'{}", escape_css_string(&s)).into(),
Token::CloseParenthesis => "unmatched close parenthesis".into(),
Token::CloseSquareBracket => "unmatched close square bracket".into(),
Token::CloseCurlyBracket => "unmatched close curly bracket".into(),
}
}
trait ErrorHelpers<'a> { trait ErrorHelpers<'a> {
fn to_gecko_message(&self) -> (&'static [u8], &'a str); fn error_data(self) -> (CompactCowStr<'a>, ParseError<'a>);
fn error_param(self) -> ErrorString<'a>;
fn to_gecko_message(&self) -> &'static [u8];
} }
impl<'a> ErrorHelpers<'a> for ContextualParseError<'a> { impl<'a> ErrorHelpers<'a> for ContextualParseError<'a> {
fn to_gecko_message(&self) -> (&'static [u8], &'a str) { fn error_data(self) -> (CompactCowStr<'a>, ParseError<'a>) {
match self {
ContextualParseError::UnsupportedPropertyDeclaration(s, err) |
ContextualParseError::UnsupportedFontFaceDescriptor(s, err) |
ContextualParseError::InvalidKeyframeRule(s, err) |
ContextualParseError::UnsupportedKeyframePropertyDeclaration(s, err) |
ContextualParseError::InvalidRule(s, err) |
ContextualParseError::UnsupportedRule(s, err) |
ContextualParseError::UnsupportedViewportDescriptorDeclaration(s, err) |
ContextualParseError::UnsupportedCounterStyleDescriptorDeclaration(s, err) =>
(s.into(), err),
ContextualParseError::InvalidCounterStyleWithoutSymbols(s) |
ContextualParseError::InvalidCounterStyleNotEnoughSymbols(s) =>
(s.into(), StyleParseError::UnspecifiedError.into()),
ContextualParseError::InvalidCounterStyleWithoutAdditiveSymbols |
ContextualParseError::InvalidCounterStyleExtendsWithSymbols |
ContextualParseError::InvalidCounterStyleExtendsWithAdditiveSymbols =>
("".into(), StyleParseError::UnspecifiedError.into())
}
}
fn error_param(self) -> ErrorString<'a> {
match self.error_data() {
(_, CssParseError::Basic(BasicParseError::UnexpectedToken(t))) =>
ErrorString::UnexpectedToken(t),
(_, CssParseError::Basic(BasicParseError::AtRuleInvalid(i))) =>
ErrorString::Snippet(format!("@{}", escape_css_ident(&i)).into()),
(_, CssParseError::Custom(SelectorParseError::Custom(
StyleParseError::PropertyDeclaration(
PropertyDeclarationParseError::InvalidValue(property))))) =>
ErrorString::Snippet(property.into()),
(_, CssParseError::Custom(SelectorParseError::UnexpectedIdent(ident))) =>
ErrorString::Ident(ident),
(_, CssParseError::Custom(SelectorParseError::ExpectedNamespace(namespace))) =>
ErrorString::Ident(namespace),
(_, CssParseError::Custom(SelectorParseError::Custom(
StyleParseError::UnknownProperty(property)))) =>
ErrorString::Ident(property),
(_, CssParseError::Custom(SelectorParseError::Custom(
StyleParseError::UnexpectedTokenWithinNamespace(token)))) =>
ErrorString::UnexpectedToken(token),
(s, _) => ErrorString::Snippet(s)
}
}
fn to_gecko_message(&self) -> &'static [u8] {
match *self { match *self {
ContextualParseError::UnsupportedPropertyDeclaration(decl, _) => ContextualParseError::UnsupportedPropertyDeclaration(
(b"PEUnknownProperty\0", decl), _, CssParseError::Basic(BasicParseError::UnexpectedToken(_))) |
ContextualParseError::UnsupportedFontFaceDescriptor(decl, _) => ContextualParseError::UnsupportedPropertyDeclaration(
(b"PEUnknwnFontDesc\0", decl), _, CssParseError::Basic(BasicParseError::AtRuleInvalid(_))) =>
ContextualParseError::InvalidKeyframeRule(rule, _) => b"PEParseDeclarationDeclExpected\0",
(b"PEKeyframeBadName\0", rule), ContextualParseError::UnsupportedPropertyDeclaration(
ContextualParseError::UnsupportedKeyframePropertyDeclaration(decl, _) => _, CssParseError::Custom(SelectorParseError::Custom(
(b"PEBadSelectorKeyframeRuleIgnored\0", decl), StyleParseError::PropertyDeclaration(
ContextualParseError::InvalidRule(rule, _) => PropertyDeclarationParseError::InvalidValue(_))))) =>
(b"PEDeclDropped\0", rule), b"PEValueParsingError\0",
ContextualParseError::UnsupportedRule(rule, _) => ContextualParseError::UnsupportedPropertyDeclaration(..) =>
(b"PEDeclDropped\0", rule), b"PEUnknownProperty\0",
ContextualParseError::UnsupportedFontFaceDescriptor(..) =>
b"PEUnknwnFontDesc\0",
ContextualParseError::InvalidKeyframeRule(..) =>
b"PEKeyframeBadName\0",
ContextualParseError::UnsupportedKeyframePropertyDeclaration(..) =>
b"PEBadSelectorKeyframeRuleIgnored\0",
ContextualParseError::InvalidRule(
_, CssParseError::Custom(SelectorParseError::ExpectedNamespace(_))) =>
b"PEUnknownNamespacePrefix\0",
ContextualParseError::InvalidRule(
_, CssParseError::Custom(SelectorParseError::Custom(
StyleParseError::UnexpectedTokenWithinNamespace(_)))) =>
b"PEAtNSUnexpected\0",
ContextualParseError::InvalidRule(..) =>
b"PEBadSelectorRSIgnored\0",
ContextualParseError::UnsupportedRule(..) =>
b"PEDeclDropped\0",
ContextualParseError::UnsupportedViewportDescriptorDeclaration(..) | ContextualParseError::UnsupportedViewportDescriptorDeclaration(..) |
ContextualParseError::UnsupportedCounterStyleDescriptorDeclaration(..) | ContextualParseError::UnsupportedCounterStyleDescriptorDeclaration(..) |
ContextualParseError::InvalidCounterStyleWithoutSymbols(..) | ContextualParseError::InvalidCounterStyleWithoutSymbols(..) |
@ -65,7 +282,7 @@ impl<'a> ErrorHelpers<'a> for ContextualParseError<'a> {
ContextualParseError::InvalidCounterStyleWithoutAdditiveSymbols | ContextualParseError::InvalidCounterStyleWithoutAdditiveSymbols |
ContextualParseError::InvalidCounterStyleExtendsWithSymbols | ContextualParseError::InvalidCounterStyleExtendsWithSymbols |
ContextualParseError::InvalidCounterStyleExtendsWithAdditiveSymbols => ContextualParseError::InvalidCounterStyleExtendsWithAdditiveSymbols =>
(b"PEUnknownAtRule\0", ""), b"PEUnknownAtRule\0",
} }
} }
} }
@ -80,8 +297,9 @@ impl ParseErrorReporter for ErrorReporter {
let location = input.source_location(position); let location = input.source_location(position);
let line_number = location.line + line_number_offset as u32; let line_number = location.line + line_number_offset as u32;
let (name, param) = error.to_gecko_message(); let name = error.to_gecko_message();
let source = ""; let param = error.error_param().into_str();
let source = input.current_line();
unsafe { unsafe {
Gecko_ReportUnexpectedCSSError(self.0, Gecko_ReportUnexpectedCSSError(self.0,
name.as_ptr() as *const _, name.as_ptr() as *const _,

View file

@ -10,7 +10,7 @@ path = "lib.rs"
doctest = false doctest = false
[dependencies] [dependencies]
cssparser = "0.16.1" cssparser = "0.17.0"
gfx = {path = "../../../components/gfx"} gfx = {path = "../../../components/gfx"}
ipc-channel = "0.8" ipc-channel = "0.8"
style = {path = "../../../components/style"} style = {path = "../../../components/style"}

View file

@ -15,7 +15,7 @@ testing = ["style/testing"]
[dependencies] [dependencies]
byteorder = "1.0" byteorder = "1.0"
app_units = "0.5" app_units = "0.5"
cssparser = "0.16.1" cssparser = "0.17.0"
euclid = "0.15" euclid = "0.15"
html5ever = "0.18" html5ever = "0.18"
parking_lot = "0.3" parking_lot = "0.3"

View file

@ -84,7 +84,7 @@ fn test_parse_stylesheet() {
url: NsAtom::from("http://www.w3.org/1999/xhtml"), url: NsAtom::from("http://www.w3.org/1999/xhtml"),
source_location: SourceLocation { source_location: SourceLocation {
line: 1, line: 1,
column: 19, column: 18,
}, },
}))), }))),
CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule { CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule {
@ -114,7 +114,7 @@ fn test_parse_stylesheet() {
]))), ]))),
source_location: SourceLocation { source_location: SourceLocation {
line: 3, line: 3,
column: 9, column: 8,
}, },
}))), }))),
CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule { CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule {
@ -141,7 +141,7 @@ fn test_parse_stylesheet() {
]))), ]))),
source_location: SourceLocation { source_location: SourceLocation {
line: 11, line: 11,
column: 9, column: 8,
}, },
}))), }))),
CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule { CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule {
@ -203,7 +203,7 @@ fn test_parse_stylesheet() {
]))), ]))),
source_location: SourceLocation { source_location: SourceLocation {
line: 15, line: 15,
column: 9, column: 8,
}, },
}))), }))),
CssRule::Keyframes(Arc::new(stylesheet.shared_lock.wrap(KeyframesRule { CssRule::Keyframes(Arc::new(stylesheet.shared_lock.wrap(KeyframesRule {
@ -235,7 +235,7 @@ fn test_parse_stylesheet() {
vendor_prefix: None, vendor_prefix: None,
source_location: SourceLocation { source_location: SourceLocation {
line: 16, line: 16,
column: 19, column: 18,
}, },
}))) })))
@ -314,15 +314,16 @@ fn test_report_error_stylesheet() {
let mut errors = errors.lock().unwrap(); let mut errors = errors.lock().unwrap();
let error = errors.pop().unwrap(); let error = errors.pop().unwrap();
assert_eq!("Unsupported property declaration: 'invalid: true;', found unexpected identifier true", error.message); assert_eq!("Unsupported property declaration: 'invalid: true;', \
assert_eq!(10, error.line); Custom(UnknownProperty(\"invalid\"))", error.message);
assert_eq!(9, error.column); assert_eq!(9, error.line);
assert_eq!(8, error.column);
let error = errors.pop().unwrap(); let error = errors.pop().unwrap();
assert_eq!("Unsupported property declaration: 'display: invalid;', \ assert_eq!("Unsupported property declaration: 'display: invalid;', \
Custom(PropertyDeclaration(InvalidValue))", error.message); Custom(PropertyDeclaration(InvalidValue(\"display\")))", error.message);
assert_eq!(9, error.line); assert_eq!(8, error.line);
assert_eq!(9, error.column); assert_eq!(8, error.column);
// testing for the url // testing for the url
assert_eq!(url, error.url); assert_eq!(url, error.url);

View file

@ -16,7 +16,7 @@ testing = ["style/testing"]
[dependencies] [dependencies]
atomic_refcell = "0.1" atomic_refcell = "0.1"
cssparser = "0.16.1" cssparser = "0.17.0"
env_logger = "0.4" env_logger = "0.4"
euclid = "0.15" euclid = "0.15"
geckoservo = {path = "../../../ports/geckolib"} geckoservo = {path = "../../../ports/geckolib"}