Update cssparser to 0.18

https://github.com/servo/rust-cssparser/pull/171
This commit is contained in:
Simon Sapin 2017-07-20 21:03:53 +02:00
parent 30d6d6024b
commit eb98ae6e04
64 changed files with 541 additions and 512 deletions

26
Cargo.lock generated
View file

@ -325,7 +325,7 @@ version = "0.0.1"
dependencies = [ dependencies = [
"azure 0.20.0 (git+https://github.com/servo/rust-azure)", "azure 0.20.0 (git+https://github.com/servo/rust-azure)",
"canvas_traits 0.0.1", "canvas_traits 0.0.1",
"cssparser 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.4.7 (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.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.1 (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)",
@ -586,7 +586,7 @@ dependencies = [
[[package]] [[package]]
name = "cssparser" name = "cssparser"
version = "0.17.0" version = "0.18.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)",
@ -1018,7 +1018,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.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.18.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)",
@ -1086,7 +1086,7 @@ dependencies = [
name = "gfx_tests" name = "gfx_tests"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"cssparser 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.18.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",
@ -2458,7 +2458,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.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.18.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",
@ -2531,7 +2531,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.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.1 (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)",
@ -2605,7 +2605,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.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.18.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)",
@ -3004,7 +3004,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.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.18.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.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.1 (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)",
@ -3058,7 +3058,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.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.1 (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.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3080,7 +3080,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.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.1 (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)",
@ -3093,7 +3093,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.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.18.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.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
"geckoservo 0.0.1", "geckoservo 0.0.1",
@ -3681,7 +3681,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 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ce16d9ed00181016c11ff48e561314bec92bfbce9fe48f319366618d4e5de6" "checksum core-text 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ce16d9ed00181016c11ff48e561314bec92bfbce9fe48f319366618d4e5de6"
"checksum cssparser 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e7063452c60432cb306ed54d538178c20792d47fa960c240ce6c083239ee55ec" "checksum cssparser 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7cf65dc20c985b085db316cf6e824fbccd4fa2c4641b57b8f42e06b0edb1052d"
"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.17.0" cssparser = "0.18"
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.17.0" cssparser = "0.18"
euclid = "0.15" euclid = "0.15"
heapsize = "0.4" heapsize = "0.4"
heapsize_derive = "0.1" heapsize_derive = "0.1"

View file

@ -34,7 +34,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.17.0" cssparser = "0.18"
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

@ -4,7 +4,7 @@
//! The `ByteString` struct. //! The `ByteString` struct.
use cssparser::CompactCowStr; use cssparser::CowRcStr;
use html5ever::{LocalName, Namespace}; use html5ever::{LocalName, Namespace};
use servo_atoms::Atom; use servo_atoms::Atom;
use std::ascii::AsciiExt; use std::ascii::AsciiExt;
@ -298,8 +298,8 @@ impl<'a> Into<Cow<'a, str>> for DOMString {
} }
} }
impl<'a> Into<CompactCowStr<'a>> for DOMString { impl<'a> Into<CowRcStr<'a>> for DOMString {
fn into(self) -> CompactCowStr<'a> { fn into(self) -> CowRcStr<'a> {
self.0.into() self.0.into()
} }
} }

View file

@ -121,7 +121,7 @@ impl CSSKeyframesRuleMethods for CSSKeyframesRule {
// Spec deviation: https://github.com/w3c/csswg-drafts/issues/801 // Spec deviation: https://github.com/w3c/csswg-drafts/issues/801
// Setting this property to a CSS-wide keyword or `none` does not throw, // Setting this property to a CSS-wide keyword or `none` does not throw,
// it stores a value that serializes as a quoted string. // it stores a value that serializes as a quoted string.
let name = KeyframesName::from_ident(value.into()); let name = KeyframesName::from_ident(&value);
let mut guard = self.cssrule.shared_lock().write(); let mut guard = self.cssrule.shared_lock().write();
self.keyframesrule.write_with(&mut guard).name = name; self.keyframesrule.write_with(&mut guard).name = name;
Ok(()) Ok(())

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.17.0" cssparser = "0.18"
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.17.0" cssparser = "0.18"
log = "0.3" log = "0.3"
fnv = "1.0" fnv = "1.0"
phf = "0.7.18" phf = "0.7.18"

View file

@ -7,7 +7,7 @@ use attr::{ParsedCaseSensitivity, SELECTOR_WHITESPACE, NamespaceConstraint};
use bloom::BLOOM_HASH_MASK; use bloom::BLOOM_HASH_MASK;
use builder::{SelectorBuilder, SpecificityAndFlags}; use builder::{SelectorBuilder, SpecificityAndFlags};
use context::QuirksMode; use context::QuirksMode;
use cssparser::{ParseError, BasicParseError, CompactCowStr}; use cssparser::{ParseError, BasicParseError, CowRcStr};
use cssparser::{Token, Parser as CssParser, parse_nth, ToCss, serialize_identifier, CssStringWriter}; use cssparser::{Token, Parser as CssParser, parse_nth, ToCss, serialize_identifier, CssStringWriter};
use precomputed_hash::PrecomputedHash; use precomputed_hash::PrecomputedHash;
use servo_arc::ThinArc; use servo_arc::ThinArc;
@ -59,8 +59,8 @@ pub enum SelectorParseError<'i, T> {
PseudoElementExpectedColon, PseudoElementExpectedColon,
PseudoElementExpectedIdent, PseudoElementExpectedIdent,
UnsupportedPseudoClass, UnsupportedPseudoClass,
UnexpectedIdent(CompactCowStr<'i>), UnexpectedIdent(CowRcStr<'i>),
ExpectedNamespace(CompactCowStr<'i>), ExpectedNamespace(CowRcStr<'i>),
Custom(T), Custom(T),
} }
@ -76,13 +76,6 @@ macro_rules! with_all_bounds {
[ $( $CommonBounds: tt )* ] [ $( $CommonBounds: tt )* ]
[ $( $FromStr: tt )* ] [ $( $FromStr: tt )* ]
) => { ) => {
fn from_cow_str<T>(cow: Cow<str>) -> T where T: $($FromStr)* {
match cow {
Cow::Borrowed(s) => T::from(s),
Cow::Owned(s) => T::from(s),
}
}
/// This trait allows to define the parser implementation in regards /// This trait allows to define the parser implementation in regards
/// of pseudo-classes/elements /// of pseudo-classes/elements
/// ///
@ -125,7 +118,7 @@ macro_rules! with_bounds {
with_bounds! { with_bounds! {
[Clone + Eq] [Clone + Eq]
[From<String> + for<'a> From<&'a str>] [for<'a> From<&'a str>]
} }
pub trait Parser<'i> { pub trait Parser<'i> {
@ -134,34 +127,34 @@ pub trait Parser<'i> {
/// Whether the name is a pseudo-element that can be specified with /// Whether the name is a pseudo-element that can be specified with
/// the single colon syntax in addition to the double-colon syntax. /// the single colon syntax in addition to the double-colon syntax.
fn is_pseudo_element_allows_single_colon(name: &CompactCowStr<'i>) -> bool { fn is_pseudo_element_allows_single_colon(name: &CowRcStr<'i>) -> bool {
is_css2_pseudo_element(name) is_css2_pseudo_element(name)
} }
/// This function can return an "Err" pseudo-element in order to support CSS2.1 /// This function can return an "Err" pseudo-element in order to support CSS2.1
/// pseudo-elements. /// pseudo-elements.
fn parse_non_ts_pseudo_class(&self, name: CompactCowStr<'i>) fn parse_non_ts_pseudo_class(&self, name: CowRcStr<'i>)
-> Result<<Self::Impl as SelectorImpl>::NonTSPseudoClass, -> Result<<Self::Impl as SelectorImpl>::NonTSPseudoClass,
ParseError<'i, SelectorParseError<'i, Self::Error>>> { ParseError<'i, SelectorParseError<'i, Self::Error>>> {
Err(ParseError::Custom(SelectorParseError::UnexpectedIdent(name))) Err(ParseError::Custom(SelectorParseError::UnexpectedIdent(name)))
} }
fn parse_non_ts_functional_pseudo_class<'t> fn parse_non_ts_functional_pseudo_class<'t>
(&self, name: CompactCowStr<'i>, _arguments: &mut CssParser<'i, 't>) (&self, name: CowRcStr<'i>, _arguments: &mut CssParser<'i, 't>)
-> Result<<Self::Impl as SelectorImpl>::NonTSPseudoClass, -> Result<<Self::Impl as SelectorImpl>::NonTSPseudoClass,
ParseError<'i, SelectorParseError<'i, Self::Error>>> ParseError<'i, SelectorParseError<'i, Self::Error>>>
{ {
Err(ParseError::Custom(SelectorParseError::UnexpectedIdent(name))) Err(ParseError::Custom(SelectorParseError::UnexpectedIdent(name)))
} }
fn parse_pseudo_element(&self, name: CompactCowStr<'i>) fn parse_pseudo_element(&self, name: CowRcStr<'i>)
-> Result<<Self::Impl as SelectorImpl>::PseudoElement, -> Result<<Self::Impl as SelectorImpl>::PseudoElement,
ParseError<'i, SelectorParseError<'i, Self::Error>>> { ParseError<'i, SelectorParseError<'i, Self::Error>>> {
Err(ParseError::Custom(SelectorParseError::UnexpectedIdent(name))) Err(ParseError::Custom(SelectorParseError::UnexpectedIdent(name)))
} }
fn parse_functional_pseudo_element<'t> fn parse_functional_pseudo_element<'t>
(&self, name: CompactCowStr<'i>, _arguments: &mut CssParser<'i, 't>) (&self, name: CowRcStr<'i>, _arguments: &mut CssParser<'i, 't>)
-> Result<<Self::Impl as SelectorImpl>::PseudoElement, -> Result<<Self::Impl as SelectorImpl>::PseudoElement,
ParseError<'i, SelectorParseError<'i, Self::Error>>> { ParseError<'i, SelectorParseError<'i, Self::Error>>> {
Err(ParseError::Custom(SelectorParseError::UnexpectedIdent(name))) Err(ParseError::Custom(SelectorParseError::UnexpectedIdent(name)))
@ -1060,16 +1053,16 @@ fn parse_selector<'i, 't, P, E, Impl>(
let position = input.position(); let position = input.position();
match input.next_including_whitespace() { match input.next_including_whitespace() {
Err(_e) => break 'outer_loop, Err(_e) => break 'outer_loop,
Ok(Token::WhiteSpace(_)) => any_whitespace = true, Ok(&Token::WhiteSpace(_)) => any_whitespace = true,
Ok(Token::Delim('>')) => { Ok(&Token::Delim('>')) => {
combinator = Combinator::Child; combinator = Combinator::Child;
break break
} }
Ok(Token::Delim('+')) => { Ok(&Token::Delim('+')) => {
combinator = Combinator::NextSibling; combinator = Combinator::NextSibling;
break break
} }
Ok(Token::Delim('~')) => { Ok(&Token::Delim('~')) => {
combinator = Combinator::LaterSibling; combinator = Combinator::LaterSibling;
break break
} }
@ -1154,8 +1147,8 @@ fn parse_type_selector<'i, 't, P, E, Impl, S>(parser: &P, input: &mut CssParser<
match local_name { match local_name {
Some(name) => { Some(name) => {
sink.push(Component::LocalName(LocalName { sink.push(Component::LocalName(LocalName {
lower_name: from_cow_str(to_ascii_lowercase(&name)), lower_name: to_ascii_lowercase(&name).as_ref().into(),
name: from_cow_str(name.into()), name: name.as_ref().into(),
})) }))
} }
None => { None => {
@ -1189,7 +1182,7 @@ enum QNamePrefix<Impl: SelectorImpl> {
fn parse_qualified_name<'i, 't, P, E, Impl> fn parse_qualified_name<'i, 't, P, E, Impl>
(parser: &P, input: &mut CssParser<'i, 't>, (parser: &P, input: &mut CssParser<'i, 't>,
in_attr_selector: bool) in_attr_selector: bool)
-> Result<Option<(QNamePrefix<Impl>, Option<CompactCowStr<'i>>)>, -> Result<Option<(QNamePrefix<Impl>, Option<CowRcStr<'i>>)>,
ParseError<'i, SelectorParseError<'i, E>>> ParseError<'i, SelectorParseError<'i, E>>>
where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl
{ {
@ -1203,27 +1196,28 @@ fn parse_qualified_name<'i, 't, P, E, Impl>
let explicit_namespace = |input: &mut CssParser<'i, 't>, namespace| { let explicit_namespace = |input: &mut CssParser<'i, 't>, namespace| {
match input.next_including_whitespace() { match input.next_including_whitespace() {
Ok(Token::Delim('*')) if !in_attr_selector => { Ok(&Token::Delim('*')) if !in_attr_selector => {
Ok(Some((namespace, None))) Ok(Some((namespace, None)))
}, },
Ok(Token::Ident(local_name)) => { Ok(&Token::Ident(ref local_name)) => {
Ok(Some((namespace, Some(local_name)))) Ok(Some((namespace, Some(local_name.clone()))))
}, },
Ok(t) => Err(ParseError::Basic(BasicParseError::UnexpectedToken(t))), Ok(t) => Err(ParseError::Basic(BasicParseError::UnexpectedToken(t.clone()))),
Err(e) => Err(ParseError::Basic(e)), Err(e) => Err(ParseError::Basic(e)),
} }
}; };
let position = input.position(); let position = input.position();
match input.next_including_whitespace() { // FIXME: remove clone() when lifetimes are non-lexical
match input.next_including_whitespace().map(|t| t.clone()) {
Ok(Token::Ident(value)) => { Ok(Token::Ident(value)) => {
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.clone().into()); let prefix = value.as_ref().into();
let result = parser.namespace_for_prefix(&prefix); let result = parser.namespace_for_prefix(&prefix);
let url = result.ok_or(ParseError::Custom( let url = result.ok_or(ParseError::Custom(
SelectorParseError::ExpectedNamespace(value.into())))?; SelectorParseError::ExpectedNamespace(value)))?;
explicit_namespace(input, QNamePrefix::ExplicitNamespace(prefix, url)) explicit_namespace(input, QNamePrefix::ExplicitNamespace(prefix, url))
}, },
_ => { _ => {
@ -1238,7 +1232,8 @@ fn parse_qualified_name<'i, 't, P, E, Impl>
}, },
Ok(Token::Delim('*')) => { Ok(Token::Delim('*')) => {
let position = input.position(); let position = input.position();
match input.next_including_whitespace() { // FIXME: remove clone() when lifetimes are non-lexical
match input.next_including_whitespace().map(|t| t.clone()) {
Ok(Token::Delim('|')) => { Ok(Token::Delim('|')) => {
explicit_namespace(input, QNamePrefix::ExplicitAnyNamespace) explicit_namespace(input, QNamePrefix::ExplicitAnyNamespace)
} }
@ -1303,8 +1298,8 @@ fn parse_attribute_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParse
match input.next() { match input.next() {
// [foo] // [foo]
Err(_) => { Err(_) => {
let local_name_lower = from_cow_str(to_ascii_lowercase(&local_name)); let local_name_lower = to_ascii_lowercase(&local_name).as_ref().into();
let local_name = from_cow_str(local_name.into()); let local_name = local_name.as_ref().into();
if let Some(namespace) = namespace { if let Some(namespace) = namespace {
return Ok(Component::AttributeOther(Box::new(AttrSelectorWithNamespace { return Ok(Component::AttributeOther(Box::new(AttrSelectorWithNamespace {
namespace: namespace, namespace: namespace,
@ -1322,38 +1317,38 @@ fn parse_attribute_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParse
} }
// [foo=bar] // [foo=bar]
Ok(Token::Delim('=')) => { Ok(&Token::Delim('=')) => {
value = input.expect_ident_or_string()?; value = input.expect_ident_or_string()?.clone();
never_matches = false; never_matches = false;
operator = AttrSelectorOperator::Equal; operator = AttrSelectorOperator::Equal;
} }
// [foo~=bar] // [foo~=bar]
Ok(Token::IncludeMatch) => { Ok(&Token::IncludeMatch) => {
value = input.expect_ident_or_string()?; value = input.expect_ident_or_string()?.clone();
never_matches = value.is_empty() || value.contains(SELECTOR_WHITESPACE); never_matches = value.is_empty() || value.contains(SELECTOR_WHITESPACE);
operator = AttrSelectorOperator::Includes; operator = AttrSelectorOperator::Includes;
} }
// [foo|=bar] // [foo|=bar]
Ok(Token::DashMatch) => { Ok(&Token::DashMatch) => {
value = input.expect_ident_or_string()?; value = input.expect_ident_or_string()?.clone();
never_matches = false; never_matches = false;
operator = AttrSelectorOperator::DashMatch; operator = AttrSelectorOperator::DashMatch;
} }
// [foo^=bar] // [foo^=bar]
Ok(Token::PrefixMatch) => { Ok(&Token::PrefixMatch) => {
value = input.expect_ident_or_string()?; value = input.expect_ident_or_string()?.clone();
never_matches = value.is_empty(); never_matches = value.is_empty();
operator = AttrSelectorOperator::Prefix; operator = AttrSelectorOperator::Prefix;
} }
// [foo*=bar] // [foo*=bar]
Ok(Token::SubstringMatch) => { Ok(&Token::SubstringMatch) => {
value = input.expect_ident_or_string()?; value = input.expect_ident_or_string()?.clone();
never_matches = value.is_empty(); never_matches = value.is_empty();
operator = AttrSelectorOperator::Substring; operator = AttrSelectorOperator::Substring;
} }
// [foo$=bar] // [foo$=bar]
Ok(Token::SuffixMatch) => { Ok(&Token::SuffixMatch) => {
value = input.expect_ident_or_string()?; value = input.expect_ident_or_string()?.clone();
never_matches = value.is_empty(); never_matches = value.is_empty();
operator = AttrSelectorOperator::Suffix; operator = AttrSelectorOperator::Suffix;
} }
@ -1362,7 +1357,7 @@ fn parse_attribute_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParse
let mut case_sensitivity = parse_attribute_flags(input)?; let mut case_sensitivity = parse_attribute_flags(input)?;
let value = from_cow_str(value.into()); let value = value.as_ref().into();
let local_name_lower; let local_name_lower;
{ {
let local_name_lower_cow = to_ascii_lowercase(&local_name); let local_name_lower_cow = to_ascii_lowercase(&local_name);
@ -1375,9 +1370,9 @@ fn parse_attribute_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParse
ParsedCaseSensitivity::AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument ParsedCaseSensitivity::AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument
} }
} }
local_name_lower = from_cow_str(local_name_lower_cow.into()); local_name_lower = local_name_lower_cow.as_ref().into();
} }
let local_name = from_cow_str(local_name.into()); let local_name = local_name.as_ref().into();
if let Some(namespace) = namespace { if let Some(namespace) = namespace {
Ok(Component::AttributeOther(Box::new(AttrSelectorWithNamespace { Ok(Component::AttributeOther(Box::new(AttrSelectorWithNamespace {
namespace: namespace, namespace: namespace,
@ -1411,10 +1406,10 @@ fn parse_attribute_flags<'i, 't, E>(input: &mut CssParser<'i, 't>)
// Selectors spec says language-defined, but HTML says sensitive. // Selectors spec says language-defined, but HTML says sensitive.
Ok(ParsedCaseSensitivity::CaseSensitive) Ok(ParsedCaseSensitivity::CaseSensitive)
} }
Ok(Token::Ident(ref value)) if value.eq_ignore_ascii_case("i") => { Ok(&Token::Ident(ref value)) if value.eq_ignore_ascii_case("i") => {
Ok(ParsedCaseSensitivity::AsciiCaseInsensitive) Ok(ParsedCaseSensitivity::AsciiCaseInsensitive)
} }
Ok(t) => Err(ParseError::Basic(BasicParseError::UnexpectedToken(t))) Ok(t) => Err(ParseError::Basic(BasicParseError::UnexpectedToken(t.clone())))
} }
} }
@ -1433,7 +1428,7 @@ fn parse_negation<'i, 't, P, E, Impl>(parser: &P,
// Consume any leading whitespace. // Consume any leading whitespace.
loop { loop {
let position = input.position(); let position = input.position();
if !matches!(input.next_including_whitespace(), Ok(Token::WhiteSpace(_))) { if !matches!(input.next_including_whitespace(), Ok(&Token::WhiteSpace(_))) {
input.reset(position); input.reset(position);
break break
} }
@ -1476,7 +1471,7 @@ fn parse_compound_selector<'i, 't, P, E, Impl>(
// Consume any leading whitespace. // Consume any leading whitespace.
loop { loop {
let position = input.position(); let position = input.position();
if !matches!(input.next_including_whitespace(), Ok(Token::WhiteSpace(_))) { if !matches!(input.next_including_whitespace(), Ok(&Token::WhiteSpace(_))) {
input.reset(position); input.reset(position);
break break
} }
@ -1508,15 +1503,15 @@ fn parse_compound_selector<'i, 't, P, E, Impl>(
loop { loop {
match input.next_including_whitespace() { match input.next_including_whitespace() {
Ok(Token::Colon) => {}, Ok(&Token::Colon) => {},
Ok(Token::WhiteSpace(_)) | Err(_) => break, Ok(&Token::WhiteSpace(_)) | Err(_) => break,
_ => return Err(SelectorParseError::PseudoElementExpectedColon.into()), _ => return Err(SelectorParseError::PseudoElementExpectedColon.into()),
} }
// TODO(emilio): Functional pseudo-classes too? // TODO(emilio): Functional pseudo-classes too?
// We don't need it for now. // We don't need it for now.
let name = match input.next_including_whitespace() { let name = match input.next_including_whitespace() {
Ok(Token::Ident(name)) => name, Ok(&Token::Ident(ref name)) => name.clone(),
_ => return Err(SelectorParseError::PseudoElementExpectedIdent.into()), _ => return Err(SelectorParseError::PseudoElementExpectedIdent.into()),
}; };
@ -1553,7 +1548,7 @@ fn parse_compound_selector<'i, 't, P, E, Impl>(
fn parse_functional_pseudo_class<'i, 't, P, E, Impl>(parser: &P, fn parse_functional_pseudo_class<'i, 't, P, E, Impl>(parser: &P,
input: &mut CssParser<'i, 't>, input: &mut CssParser<'i, 't>,
name: CompactCowStr<'i>, name: CowRcStr<'i>,
inside_negation: bool) inside_negation: bool)
-> Result<Component<Impl>, -> Result<Component<Impl>,
ParseError<'i, SelectorParseError<'i, E>>> ParseError<'i, SelectorParseError<'i, E>>>
@ -1589,7 +1584,7 @@ where Impl: SelectorImpl, F: FnOnce(i32, i32) -> Component<Impl> {
/// Returns whether the name corresponds to a CSS2 pseudo-element that /// Returns whether the name corresponds to a CSS2 pseudo-element that
/// can be specified with the single colon syntax (in addition to the /// can be specified with the single colon syntax (in addition to the
/// double-colon syntax, which can be used for all pseudo-elements). /// double-colon syntax, which can be used for all pseudo-elements).
pub fn is_css2_pseudo_element<'i>(name: &CompactCowStr<'i>) -> bool { pub fn is_css2_pseudo_element<'i>(name: &CowRcStr<'i>) -> bool {
// ** Do not add to this list! ** // ** Do not add to this list! **
return name.eq_ignore_ascii_case("before") || return name.eq_ignore_ascii_case("before") ||
name.eq_ignore_ascii_case("after") || name.eq_ignore_ascii_case("after") ||
@ -1610,18 +1605,19 @@ fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P,
where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl
{ {
let start_position = input.position(); let start_position = input.position();
match input.next_including_whitespace() { // FIXME: remove clone() when lifetimes are non-lexical
match input.next_including_whitespace().map(|t| t.clone()) {
Ok(Token::IDHash(id)) => { Ok(Token::IDHash(id)) => {
let id = Component::ID(from_cow_str(id.into())); let id = Component::ID(id.as_ref().into());
Ok(Some(SimpleSelectorParseResult::SimpleSelector(id))) Ok(Some(SimpleSelectorParseResult::SimpleSelector(id)))
} }
Ok(Token::Delim('.')) => { Ok(Token::Delim('.')) => {
match input.next_including_whitespace()? { match *input.next_including_whitespace()? {
Token::Ident(class) => { Token::Ident(ref class) => {
let class = Component::Class(from_cow_str(class.into())); let class = Component::Class(class.as_ref().into());
Ok(Some(SimpleSelectorParseResult::SimpleSelector(class))) Ok(Some(SimpleSelectorParseResult::SimpleSelector(class)))
} }
t => Err(ParseError::Basic(BasicParseError::UnexpectedToken(t))), ref t => Err(ParseError::Basic(BasicParseError::UnexpectedToken(t.clone()))),
} }
} }
Ok(Token::SquareBracketBlock) => { Ok(Token::SquareBracketBlock) => {
@ -1629,8 +1625,8 @@ fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P,
Ok(Some(SimpleSelectorParseResult::SimpleSelector(attr))) Ok(Some(SimpleSelectorParseResult::SimpleSelector(attr)))
} }
Ok(Token::Colon) => { Ok(Token::Colon) => {
let (is_single_colon, next_token) = match input.next_including_whitespace()? { let (is_single_colon, next_token) = match input.next_including_whitespace()?.clone() {
Token::Colon => (false, input.next_including_whitespace()?), Token::Colon => (false, input.next_including_whitespace()?.clone()),
t => (true, t), t => (true, t),
}; };
let (name, is_functional) = match next_token { let (name, is_functional) = match next_token {
@ -1667,7 +1663,7 @@ fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P,
} }
} }
fn parse_simple_pseudo_class<'i, P, E, Impl>(parser: &P, name: CompactCowStr<'i>) fn parse_simple_pseudo_class<'i, P, E, Impl>(parser: &P, name: CowRcStr<'i>)
-> Result<Component<Impl>, -> Result<Component<Impl>,
ParseError<'i, SelectorParseError<'i, E>>> ParseError<'i, SelectorParseError<'i, E>>>
where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl
@ -1821,7 +1817,7 @@ pub mod tests {
type Impl = DummySelectorImpl; type Impl = DummySelectorImpl;
type Error = (); type Error = ();
fn parse_non_ts_pseudo_class(&self, name: CompactCowStr<'i>) fn parse_non_ts_pseudo_class(&self, name: CowRcStr<'i>)
-> Result<PseudoClass, -> Result<PseudoClass,
ParseError<'i, SelectorParseError<'i, ()>>> { ParseError<'i, SelectorParseError<'i, ()>>> {
match_ignore_ascii_case! { &name, match_ignore_ascii_case! { &name,
@ -1831,17 +1827,17 @@ pub mod tests {
} }
} }
fn parse_non_ts_functional_pseudo_class<'t>(&self, name: CompactCowStr<'i>, fn parse_non_ts_functional_pseudo_class<'t>(&self, name: CowRcStr<'i>,
parser: &mut CssParser<'i, 't>) parser: &mut CssParser<'i, 't>)
-> Result<PseudoClass, -> Result<PseudoClass,
ParseError<'i, SelectorParseError<'i, ()>>> { ParseError<'i, SelectorParseError<'i, ()>>> {
match_ignore_ascii_case! { &name, match_ignore_ascii_case! { &name,
"lang" => Ok(PseudoClass::Lang(parser.expect_ident_or_string()?.into_owned())), "lang" => Ok(PseudoClass::Lang(parser.expect_ident_or_string()?.as_ref().to_owned())),
_ => Err(SelectorParseError::Custom(()).into()) _ => Err(SelectorParseError::Custom(()).into())
} }
} }
fn parse_pseudo_element(&self, name: CompactCowStr<'i>) fn parse_pseudo_element(&self, name: CowRcStr<'i>)
-> Result<PseudoElement, -> Result<PseudoElement,
ParseError<'i, SelectorParseError<'i, ()>>> { ParseError<'i, SelectorParseError<'i, ()>>> {
match_ignore_ascii_case! { &name, match_ignore_ascii_case! { &name,

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.17.0" cssparser = "0.18"
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

@ -8,7 +8,7 @@
use Atom; use Atom;
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser}; use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser};
use cssparser::{Parser, Token, serialize_identifier, BasicParseError, CompactCowStr}; use cssparser::{Parser, Token, serialize_identifier, BasicParseError, CowRcStr};
use error_reporting::ContextualParseError; use error_reporting::ContextualParseError;
#[cfg(feature = "gecko")] use gecko::rules::CounterStyleDescriptors; #[cfg(feature = "gecko")] use gecko::rules::CounterStyleDescriptors;
#[cfg(feature = "gecko")] use gecko_bindings::structs::nsCSSCounterDesc; #[cfg(feature = "gecko")] use gecko_bindings::structs::nsCSSCounterDesc;
@ -184,7 +184,7 @@ macro_rules! counter_style_descriptors {
type Declaration = (); type Declaration = ();
type Error = SelectorParseError<'i, StyleParseError<'i>>; type Error = SelectorParseError<'i, StyleParseError<'i>>;
fn parse_value<'t>(&mut self, name: CompactCowStr<'i>, input: &mut Parser<'i, 't>) fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>)
-> Result<(), ParseError<'i>> { -> Result<(), ParseError<'i>> {
match_ignore_ascii_case! { &*name, match_ignore_ascii_case! { &*name,
$( $(
@ -295,7 +295,7 @@ pub enum System {
impl Parse for System { impl Parse for System {
fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> { fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
try_match_ident_ignore_ascii_case! { input.expect_ident()?, try_match_ident_ignore_ascii_case! { input.expect_ident_cloned()?,
"cyclic" => Ok(System::Cyclic), "cyclic" => Ok(System::Cyclic),
"numeric" => Ok(System::Numeric), "numeric" => Ok(System::Numeric),
"alphabetic" => Ok(System::Alphabetic), "alphabetic" => Ok(System::Alphabetic),
@ -351,9 +351,9 @@ pub enum Symbol {
impl Parse for Symbol { impl Parse for Symbol {
fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> { fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
match input.next() { match input.next() {
Ok(Token::QuotedString(s)) => Ok(Symbol::String(s.into_owned())), Ok(&Token::QuotedString(ref s)) => Ok(Symbol::String(s.as_ref().to_owned())),
Ok(Token::Ident(s)) => Ok(Symbol::Ident(s.into_owned())), Ok(&Token::Ident(ref s)) => Ok(Symbol::Ident(s.as_ref().to_owned())),
Ok(t) => Err(BasicParseError::UnexpectedToken(t).into()), Ok(t) => Err(BasicParseError::UnexpectedToken(t.clone()).into()),
Err(e) => Err(e.into()), Err(e) => Err(e.into()),
} }
} }
@ -419,9 +419,9 @@ impl Parse for Ranges {
fn parse_bound<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Option<i32>, ParseError<'i>> { fn parse_bound<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Option<i32>, ParseError<'i>> {
match input.next() { match input.next() {
Ok(Token::Number { int_value: Some(v), .. }) => Ok(Some(v)), Ok(&Token::Number { int_value: Some(v), .. }) => Ok(Some(v)),
Ok(Token::Ident(ref ident)) if ident.eq_ignore_ascii_case("infinite") => Ok(None), Ok(&Token::Ident(ref ident)) if ident.eq_ignore_ascii_case("infinite") => Ok(None),
Ok(t) => Err(BasicParseError::UnexpectedToken(t).into()), Ok(t) => Err(BasicParseError::UnexpectedToken(t.clone()).into()),
Err(e) => Err(e.into()), Err(e) => Err(e.into()),
} }
} }

View file

@ -252,7 +252,8 @@ fn parse_declaration_value_block<'i, 't>
ParseError<'i>> { ParseError<'i>> {
let mut token_start = input.position(); let mut token_start = input.position();
let mut token = match input.next_including_whitespace_and_comments() { let mut token = match input.next_including_whitespace_and_comments() {
Ok(token) => token, // FIXME: remove clone() when borrows are non-lexical
Ok(token) => token.clone(),
Err(_) => return Ok((TokenSerializationType::nothing(), TokenSerializationType::nothing())) Err(_) => return Ok((TokenSerializationType::nothing(), TokenSerializationType::nothing()))
}; };
let first_token_type = token.serialization_type(); let first_token_type = token.serialization_type();
@ -351,7 +352,8 @@ fn parse_declaration_value_block<'i, 't>
token_start = input.position(); token_start = input.position();
token = match input.next_including_whitespace_and_comments() { token = match input.next_including_whitespace_and_comments() {
Ok(token) => token, // FIXME: remove clone() when borrows are non-lexical
Ok(token) => token.clone(),
Err(..) => return Ok((first_token_type, last_token_type)), Err(..) => return Ok((first_token_type, last_token_type)),
}; };
} }
@ -361,7 +363,7 @@ fn parse_declaration_value_block<'i, 't>
fn parse_var_function<'i, 't>(input: &mut Parser<'i, 't>, fn parse_var_function<'i, 't>(input: &mut Parser<'i, 't>,
references: &mut Option<HashSet<Name>>) references: &mut Option<HashSet<Name>>)
-> Result<(), ParseError<'i>> { -> Result<(), ParseError<'i>> {
let name = input.expect_ident()?; let name = input.expect_ident_cloned()?;
let name: Result<_, ParseError> = let name: Result<_, ParseError> =
parse_name(&name) parse_name(&name)
.map_err(|()| SelectorParseError::UnexpectedIdent(name.clone()).into()); .map_err(|()| SelectorParseError::UnexpectedIdent(name.clone()).into());
@ -597,7 +599,8 @@ fn substitute_block<'i, 't, F>(input: &mut Parser<'i, 't>,
let mut set_position_at_next_iteration = false; let mut set_position_at_next_iteration = false;
loop { loop {
let before_this_token = input.position(); let before_this_token = input.position();
let next = input.next_including_whitespace_and_comments(); // FIXME: remove clone() when borrows are non-lexical
let next = input.next_including_whitespace_and_comments().map(|t| t.clone());
if set_position_at_next_iteration { if set_position_at_next_iteration {
*position = (before_this_token, match next { *position = (before_this_token, match next {
Ok(ref token) => token.serialization_type(), Ok(ref token) => token.serialization_type(),
@ -615,7 +618,7 @@ fn substitute_block<'i, 't, F>(input: &mut Parser<'i, 't>,
input.slice(position.0..before_this_token), position.1, last_token_type); input.slice(position.0..before_this_token), position.1, last_token_type);
input.parse_nested_block(|input| { input.parse_nested_block(|input| {
// parse_var_function() ensures neither .unwrap() will fail. // parse_var_function() ensures neither .unwrap() will fail.
let name = input.expect_ident().unwrap(); let name = input.expect_ident_cloned().unwrap();
let name = Atom::from(parse_name(&name).unwrap()); let name = Atom::from(parse_name(&name).unwrap());
if let Ok(last) = substitute_one(&name, partial_computed_value) { if let Ok(last) = substitute_one(&name, partial_computed_value) {

View file

@ -12,7 +12,7 @@
use computed_values::{font_feature_settings, font_stretch, font_style, font_weight}; use computed_values::{font_feature_settings, font_stretch, font_style, font_weight};
use computed_values::font_family::FamilyName; use computed_values::font_family::FamilyName;
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser}; use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser};
use cssparser::{SourceLocation, CompactCowStr}; use cssparser::{SourceLocation, CowRcStr};
use error_reporting::ContextualParseError; use error_reporting::ContextualParseError;
#[cfg(feature = "gecko")] use gecko_bindings::structs::CSSFontFaceDescriptors; #[cfg(feature = "gecko")] use gecko_bindings::structs::CSSFontFaceDescriptors;
#[cfg(feature = "gecko")] use cssparser::UnicodeRange; #[cfg(feature = "gecko")] use cssparser::UnicodeRange;
@ -197,7 +197,7 @@ impl Parse for Source {
let format_hints = if input.try(|input| input.expect_function_matching("format")).is_ok() { let format_hints = if input.try(|input| input.expect_function_matching("format")).is_ok() {
input.parse_nested_block(|input| { input.parse_nested_block(|input| {
input.parse_comma_separated(|input| { input.parse_comma_separated(|input| {
Ok(input.expect_string()?.into_owned()) Ok(input.expect_string()?.as_ref().to_owned())
}) })
})? })?
} else { } else {
@ -275,7 +275,7 @@ macro_rules! font_face_descriptors_common {
type Declaration = (); type Declaration = ();
type Error = SelectorParseError<'i, StyleParseError<'i>>; type Error = SelectorParseError<'i, StyleParseError<'i>>;
fn parse_value<'t>(&mut self, name: CompactCowStr<'i>, input: &mut Parser<'i, 't>) fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>)
-> Result<(), ParseError<'i>> { -> Result<(), ParseError<'i>> {
match_ignore_ascii_case! { &*name, match_ignore_ascii_case! { &*name,
$( $(

View file

@ -240,11 +240,11 @@ impl Resolution {
} }
fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> { fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
let (value, unit) = match input.next()? { let (value, unit) = match *input.next()? {
Token::Dimension { value, unit, .. } => { Token::Dimension { value, ref unit, .. } => {
(value, unit) (value, unit)
}, },
t => return Err(BasicParseError::UnexpectedToken(t).into()), ref t => return Err(BasicParseError::UnexpectedToken(t.clone()).into()),
}; };
if value <= 0. { if value <= 0. {
@ -256,7 +256,7 @@ impl Resolution {
"dppx" => Ok(Resolution::Dppx(value)), "dppx" => Ok(Resolution::Dppx(value)),
"dpcm" => Ok(Resolution::Dpcm(value)), "dpcm" => Ok(Resolution::Dpcm(value)),
_ => Err(()) _ => Err(())
}).map_err(|()| StyleParseError::UnexpectedDimension(unit).into()) }).map_err(|()| StyleParseError::UnexpectedDimension(unit.clone()).into())
} }
} }
@ -474,11 +474,15 @@ impl Expression {
-> Result<Self, ParseError<'i>> { -> Result<Self, ParseError<'i>> {
input.expect_parenthesis_block()?; input.expect_parenthesis_block()?;
input.parse_nested_block(|input| { input.parse_nested_block(|input| {
// FIXME: remove extra indented block when lifetimes are non-lexical
let feature;
let range;
{
let ident = input.expect_ident()?; let ident = input.expect_ident()?;
let mut flags = 0; let mut flags = 0;
let result = { let result = {
let mut feature_name = &*ident; let mut feature_name = &**ident;
// TODO(emilio): this is under a pref in Gecko. // TODO(emilio): this is under a pref in Gecko.
if starts_with_ignore_ascii_case(feature_name, "-webkit-") { if starts_with_ignore_ascii_case(feature_name, "-webkit-") {
@ -503,18 +507,22 @@ impl Expression {
} }
}; };
let (feature, range) = match result { match result {
Ok((feature, range)) => (feature, range), Ok((f, r)) => {
Err(()) => return Err(SelectorParseError::UnexpectedIdent(ident).into()), feature = f;
}; range = r;
}
Err(()) => return Err(SelectorParseError::UnexpectedIdent(ident.clone()).into()),
}
if (feature.mReqFlags & !flags) != 0 { if (feature.mReqFlags & !flags) != 0 {
return Err(SelectorParseError::UnexpectedIdent(ident).into()); return Err(SelectorParseError::UnexpectedIdent(ident.clone()).into());
} }
if range != nsMediaExpression_Range::eEqual && if range != nsMediaExpression_Range::eEqual &&
feature.mRangeType != nsMediaFeature_RangeType::eMinMaxAllowed { feature.mRangeType != nsMediaFeature_RangeType::eMinMaxAllowed {
return Err(SelectorParseError::UnexpectedIdent(ident).into()); return Err(SelectorParseError::UnexpectedIdent(ident.clone()).into());
}
} }
// If there's no colon, this is a media query of the form // If there's no colon, this is a media query of the form
@ -590,7 +598,7 @@ impl Expression {
MediaExpressionValue::Enumerated(value) MediaExpressionValue::Enumerated(value)
} }
nsMediaFeature_ValueType::eIdent => { nsMediaFeature_ValueType::eIdent => {
MediaExpressionValue::Ident(input.expect_ident()?.into_owned()) MediaExpressionValue::Ident(input.expect_ident()?.as_ref().to_owned())
} }
}; };

View file

@ -4,7 +4,7 @@
//! Gecko-specific bits for selector-parsing. //! Gecko-specific bits for selector-parsing.
use cssparser::{BasicParseError, Parser, ToCss, Token, CompactCowStr}; use cssparser::{BasicParseError, Parser, ToCss, Token, CowRcStr};
use element_state::ElementState; use element_state::ElementState;
use gecko_bindings::structs::CSSPseudoClassType; use gecko_bindings::structs::CSSPseudoClassType;
use selector_parser::{SelectorParser, PseudoElementCascadeType}; use selector_parser::{SelectorParser, PseudoElementCascadeType};
@ -267,12 +267,12 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
type Impl = SelectorImpl; type Impl = SelectorImpl;
type Error = StyleParseError<'i>; type Error = StyleParseError<'i>;
fn is_pseudo_element_allows_single_colon(name: &CompactCowStr<'i>) -> bool { fn is_pseudo_element_allows_single_colon(name: &CowRcStr<'i>) -> bool {
::selectors::parser::is_css2_pseudo_element(name) || ::selectors::parser::is_css2_pseudo_element(name) ||
name.starts_with("-moz-tree-") // tree pseudo-elements name.starts_with("-moz-tree-") // tree pseudo-elements
} }
fn parse_non_ts_pseudo_class(&self, name: CompactCowStr<'i>) fn parse_non_ts_pseudo_class(&self, name: CowRcStr<'i>)
-> Result<NonTSPseudoClass, ParseError<'i>> { -> Result<NonTSPseudoClass, ParseError<'i>> {
macro_rules! pseudo_class_parse { macro_rules! pseudo_class_parse {
(bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*], (bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*],
@ -294,7 +294,7 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
} }
fn parse_non_ts_functional_pseudo_class<'t>(&self, fn parse_non_ts_functional_pseudo_class<'t>(&self,
name: CompactCowStr<'i>, name: CowRcStr<'i>,
parser: &mut Parser<'i, 't>) parser: &mut Parser<'i, 't>)
-> Result<NonTSPseudoClass, ParseError<'i>> { -> Result<NonTSPseudoClass, ParseError<'i>> {
macro_rules! pseudo_class_string_parse { macro_rules! pseudo_class_string_parse {
@ -338,12 +338,12 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
} }
} }
fn parse_pseudo_element(&self, name: CompactCowStr<'i>) -> Result<PseudoElement, ParseError<'i>> { fn parse_pseudo_element(&self, name: CowRcStr<'i>) -> Result<PseudoElement, ParseError<'i>> {
PseudoElement::from_slice(&name, self.in_user_agent_stylesheet()) PseudoElement::from_slice(&name, self.in_user_agent_stylesheet())
.ok_or(SelectorParseError::UnexpectedIdent(name.clone()).into()) .ok_or(SelectorParseError::UnexpectedIdent(name.clone()).into())
} }
fn parse_functional_pseudo_element<'t>(&self, name: CompactCowStr<'i>, fn parse_functional_pseudo_element<'t>(&self, name: CowRcStr<'i>,
parser: &mut Parser<'i, 't>) parser: &mut Parser<'i, 't>)
-> Result<PseudoElement, ParseError<'i>> { -> Result<PseudoElement, ParseError<'i>> {
if name.starts_with("-moz-tree-") { if name.starts_with("-moz-tree-") {
@ -352,9 +352,9 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
let mut args = Vec::new(); let mut args = Vec::new();
loop { loop {
match parser.next() { match parser.next() {
Ok(Token::Ident(ident)) => args.push(ident.into_owned()), Ok(&Token::Ident(ref ident)) => args.push(ident.as_ref().to_owned()),
Ok(Token::Comma) => {}, Ok(&Token::Comma) => {},
Ok(t) => return Err(BasicParseError::UnexpectedToken(t).into()), Ok(t) => return Err(BasicParseError::UnexpectedToken(t.clone()).into()),
Err(BasicParseError::EndOfInput) => break, Err(BasicParseError::EndOfInput) => break,
_ => unreachable!("Parser::next() shouldn't return any other error"), _ => unreachable!("Parser::next() shouldn't return any other error"),
} }

View file

@ -6,7 +6,7 @@
use gecko_bindings::structs::nsIAtom; use gecko_bindings::structs::nsIAtom;
use precomputed_hash::PrecomputedHash; use precomputed_hash::PrecomputedHash;
use std::borrow::{Borrow, Cow}; use std::borrow::Borrow;
use std::fmt; use std::fmt;
use std::ops::Deref; use std::ops::Deref;
use string_cache::{Atom, WeakAtom}; use string_cache::{Atom, WeakAtom};
@ -54,8 +54,8 @@ impl Deref for Namespace {
} }
} }
impl<'a> From<Cow<'a, str>> for Namespace { impl<'a> From<&'a str> for Namespace {
fn from(s: Cow<'a, str>) -> Self { fn from(s: &'a str) -> Self {
Namespace(Atom::from(s)) Namespace(Atom::from(s))
} }
} }

View file

@ -17,7 +17,7 @@ macro_rules! try_match_ident_ignore_ascii_case {
_ => Err(()), _ => Err(()),
}) })
.map_err(|()| { .map_err(|()| {
::selectors::parser::SelectorParseError::UnexpectedIdent(__ident).into() ::selectors::parser::SelectorParseError::UnexpectedIdent(__ident.clone()).into()
}) })
} }
} }

View file

@ -211,10 +211,10 @@ impl MediaQuery {
None None
}; };
let media_type = match input.try(|input| input.expect_ident()) { let media_type = match input.try(|i| i.expect_ident_cloned()) {
Ok(ident) => { Ok(ident) => {
let result: Result<_, ParseError> = MediaQueryType::parse(&*ident) let result: Result<_, ParseError> = MediaQueryType::parse(&*ident)
.map_err(|()| SelectorParseError::UnexpectedIdent(ident).into()); .map_err(|()| SelectorParseError::UnexpectedIdent(ident.clone()).into());
result? result?
} }
Err(_) => { Err(_) => {
@ -263,7 +263,7 @@ pub fn parse_media_query_list(context: &ParserContext, input: &mut Parser) -> Me
} }
match input.next() { match input.next() {
Ok(Token::Comma) => {}, Ok(&Token::Comma) => {},
Ok(_) => unreachable!(), Ok(_) => unreachable!(),
Err(_) => break, Err(_) => break,
} }

View file

@ -7,7 +7,7 @@
#![deny(missing_docs)] #![deny(missing_docs)]
use context::QuirksMode; use context::QuirksMode;
use cssparser::{DeclarationListParser, parse_important, ParserInput, CompactCowStr}; use cssparser::{DeclarationListParser, parse_important, ParserInput, CowRcStr};
use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter, ParseError as CssParseError}; use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter, ParseError as CssParseError};
use error_reporting::{ParseErrorReporter, ContextualParseError}; use error_reporting::{ParseErrorReporter, ContextualParseError};
use parser::{ParserContext, log_css_error}; use parser::{ParserContext, log_css_error};
@ -945,7 +945,7 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for PropertyDeclarationParser<'a, 'b> {
type Declaration = Importance; type Declaration = Importance;
type Error = SelectorParseError<'i, StyleParseError<'i>>; type Error = SelectorParseError<'i, StyleParseError<'i>>;
fn parse_value<'t>(&mut self, name: CompactCowStr<'i>, input: &mut Parser<'i, 't>) fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>)
-> Result<Importance, ParseError<'i>> { -> Result<Importance, ParseError<'i>> {
let id = match PropertyId::parse(&name) { let id = match PropertyId::parse(&name) {
Ok(id) => id, Ok(id) => id,

View file

@ -2808,7 +2808,7 @@ fn static_assert() {
if atom.is_empty() { if atom.is_empty() {
AnimationName(None) AnimationName(None)
} else { } else {
AnimationName(Some(KeyframesName::from_ident(atom.to_string()))) AnimationName(Some(KeyframesName::from_ident(&atom.to_string())))
} }
} }
pub fn copy_animation_name_from(&mut self, other: &Self) { pub fn copy_animation_name_from(&mut self, other: &Self) {

View file

@ -286,7 +286,7 @@ impl TransitionProperty {
match supported { match supported {
Ok(Some(property)) => Ok(property), Ok(Some(property)) => Ok(property),
Ok(None) => CustomIdent::from_ident(ident, &[]).map(TransitionProperty::Unsupported), Ok(None) => CustomIdent::from_ident(ident, &[]).map(TransitionProperty::Unsupported),
Err(()) => Err(SelectorParseError::UnexpectedIdent(ident).into()), Err(()) => Err(SelectorParseError::UnexpectedIdent(ident.clone()).into()),
} }
} }

View file

@ -122,14 +122,14 @@ ${helpers.predefined_type("background-image", "ImageLayer",
pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<SpecifiedValue, ParseError<'i>> { -> Result<SpecifiedValue, ParseError<'i>> {
let ident = input.expect_ident()?; let ident = input.expect_ident_cloned()?;
(match_ignore_ascii_case! { &ident, (match_ignore_ascii_case! { &ident,
"repeat-x" => Ok(SpecifiedValue::RepeatX), "repeat-x" => Ok(SpecifiedValue::RepeatX),
"repeat-y" => Ok(SpecifiedValue::RepeatY), "repeat-y" => Ok(SpecifiedValue::RepeatY),
_ => Err(()), _ => Err(()),
}).or_else(|()| { }).or_else(|()| {
let horizontal: Result<_, ParseError> = RepeatKeyword::from_ident(&ident) let horizontal: Result<_, ParseError> = RepeatKeyword::from_ident(&ident)
.map_err(|()| SelectorParseError::UnexpectedIdent(ident).into()); .map_err(|()| SelectorParseError::UnexpectedIdent(ident.clone()).into());
let horizontal = horizontal?; let horizontal = horizontal?;
let vertical = input.try(RepeatKeyword::parse).ok(); let vertical = input.try(RepeatKeyword::parse).ok();
Ok(SpecifiedValue::Other(horizontal, vertical)) Ok(SpecifiedValue::Other(horizontal, vertical))

View file

@ -1025,7 +1025,7 @@ ${helpers.predefined_type(
} }
Ok(SpecifiedValue(Space::parse(input, |input| { Ok(SpecifiedValue(Space::parse(input, |input| {
let function = input.expect_function()?; let function = input.expect_function()?.clone();
input.parse_nested_block(|input| { input.parse_nested_block(|input| {
let result = match_ignore_ascii_case! { &function, let result = match_ignore_ascii_case! { &function,
"matrix" => { "matrix" => {
@ -1217,7 +1217,7 @@ ${helpers.predefined_type(
_ => Err(()), _ => Err(()),
}; };
result result
.map_err(|()| StyleParseError::UnexpectedFunction(function).into()) .map_err(|()| StyleParseError::UnexpectedFunction(function.clone()).into())
}) })
})?)) })?))
} }
@ -1764,7 +1764,7 @@ ${helpers.predefined_type("transform-origin",
return Ok(result) return Ok(result)
} }
while let Ok(name) = input.try(|input| input.expect_ident()) { while let Ok(name) = input.try(|i| i.expect_ident_cloned()) {
let flag = match_ignore_ascii_case! { &name, let flag = match_ignore_ascii_case! { &name,
"layout" => Some(LAYOUT), "layout" => Some(LAYOUT),
"style" => Some(STYLE), "style" => Some(STYLE),
@ -1773,7 +1773,7 @@ ${helpers.predefined_type("transform-origin",
}; };
let flag = match flag { let flag = match flag {
Some(flag) if !result.contains(flag) => flag, Some(flag) if !result.contains(flag) => flag,
_ => return Err(SelectorParseError::UnexpectedIdent(name).into()) _ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into())
}; };
result.insert(flag); result.insert(flag);
} }
@ -1960,7 +1960,8 @@ ${helpers.predefined_type("shape-outside", "basic_shape::FloatAreaShape",
pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<SpecifiedValue, ParseError<'i>> { -> Result<SpecifiedValue, ParseError<'i>> {
try_match_ident_ignore_ascii_case! { input.expect_ident()?, // FIXME: remove clone() when lifetimes are non-lexical
try_match_ident_ignore_ascii_case! { input.expect_ident()?.clone(),
"auto" => Ok(TOUCH_ACTION_AUTO), "auto" => Ok(TOUCH_ACTION_AUTO),
"none" => Ok(TOUCH_ACTION_NONE), "none" => Ok(TOUCH_ACTION_NONE),
"manipulation" => Ok(TOUCH_ACTION_MANIPULATION), "manipulation" => Ok(TOUCH_ACTION_MANIPULATION),

View file

@ -134,7 +134,7 @@
if let Some(color) = color_name(&ident) { if let Some(color) = color_name(&ident) {
Ok(*color) Ok(*color)
} else { } else {
Err(SelectorParseError::UnexpectedIdent(ident).into()) Err(SelectorParseError::UnexpectedIdent(ident.clone()).into())
} }
} }
} }

View file

@ -179,21 +179,22 @@
continue; continue;
} }
% endif % endif
match input.next() { // FIXME: remove clone() when lifetimes are non-lexical
Ok(Token::QuotedString(value)) => { match input.next().map(|t| t.clone()) {
content.push(ContentItem::String(value.into_owned())) Ok(Token::QuotedString(ref value)) => {
content.push(ContentItem::String(value.as_ref().to_owned()))
} }
Ok(Token::Function(name)) => { Ok(Token::Function(ref name)) => {
let result = match_ignore_ascii_case! { &name, let result = match_ignore_ascii_case! { &name,
"counter" => Some(input.parse_nested_block(|input| { "counter" => Some(input.parse_nested_block(|input| {
let name = input.expect_ident()?.into_owned(); let name = input.expect_ident()?.as_ref().to_owned();
let style = parse_counter_style(context, input); let style = parse_counter_style(context, input);
Ok(ContentItem::Counter(name, style)) Ok(ContentItem::Counter(name, style))
})), })),
"counters" => Some(input.parse_nested_block(|input| { "counters" => Some(input.parse_nested_block(|input| {
let name = input.expect_ident()?.into_owned(); let name = input.expect_ident()?.as_ref().to_owned();
input.expect_comma()?; input.expect_comma()?;
let separator = input.expect_string()?.into_owned(); let separator = input.expect_string()?.as_ref().to_owned();
let style = parse_counter_style(context, input); let style = parse_counter_style(context, input);
Ok(ContentItem::Counters(name, separator, style)) Ok(ContentItem::Counters(name, separator, style))
})), })),
@ -206,10 +207,10 @@
}; };
match result { match result {
Some(result) => content.push(result?), Some(result) => content.push(result?),
None => return Err(StyleParseError::UnexpectedFunction(name).into()) None => return Err(StyleParseError::UnexpectedFunction(name.clone()).into())
} }
} }
Ok(Token::Ident(ident)) => { Ok(Token::Ident(ref ident)) => {
let valid = match_ignore_ascii_case! { &ident, let valid = match_ignore_ascii_case! { &ident,
"open-quote" => { content.push(ContentItem::OpenQuote); true }, "open-quote" => { content.push(ContentItem::OpenQuote); true },
"close-quote" => { content.push(ContentItem::CloseQuote); true }, "close-quote" => { content.push(ContentItem::CloseQuote); true },
@ -219,7 +220,7 @@
_ => false, _ => false,
}; };
if !valid { if !valid {
return Err(SelectorParseError::UnexpectedIdent(ident).into()) return Err(SelectorParseError::UnexpectedIdent(ident.clone()).into())
} }
} }
Err(_) => break, Err(_) => break,
@ -333,8 +334,8 @@
let mut counters = Vec::new(); let mut counters = Vec::new();
loop { loop {
let counter_name = match input.next() { let counter_name = match input.next() {
Ok(Token::Ident(ident)) => CustomIdent::from_ident(ident, &["none"])?, Ok(&Token::Ident(ref ident)) => CustomIdent::from_ident(ident, &["none"])?,
Ok(t) => return Err(BasicParseError::UnexpectedToken(t).into()), Ok(t) => return Err(BasicParseError::UnexpectedToken(t.clone()).into()),
Err(_) => break, Err(_) => break,
}; };
let counter_delta = input.try(|input| specified::parse_integer(context, input)) let counter_delta = input.try(|input| specified::parse_integer(context, input))

View file

@ -145,13 +145,13 @@ macro_rules! impl_gecko_keyword_conversions {
/// Parse a font-family value /// Parse a font-family value
pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> { pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
if let Ok(value) = input.try(|input| input.expect_string()) { if let Ok(value) = input.try(|i| i.expect_string_cloned()) {
return Ok(FontFamily::FamilyName(FamilyName { return Ok(FontFamily::FamilyName(FamilyName {
name: Atom::from(&*value), name: Atom::from(&*value),
quoted: true, quoted: true,
})) }))
} }
let first_ident = input.expect_ident()?; let first_ident = input.expect_ident()?.clone();
// FIXME(bholley): The fast thing to do here would be to look up the // FIXME(bholley): The fast thing to do here would be to look up the
// string (as lowercase) in the static atoms table. We don't have an // string (as lowercase) in the static atoms table. We don't have an
@ -181,7 +181,7 @@ macro_rules! impl_gecko_keyword_conversions {
_ => {} _ => {}
} }
let mut value = first_ident.into_owned(); let mut value = first_ident.as_ref().to_owned();
// These keywords are not allowed by themselves. // These keywords are not allowed by themselves.
// The only way this value can be valid with with another keyword. // The only way this value can be valid with with another keyword.
if css_wide_keyword { if css_wide_keyword {
@ -189,7 +189,7 @@ macro_rules! impl_gecko_keyword_conversions {
value.push_str(" "); value.push_str(" ");
value.push_str(&ident); value.push_str(&ident);
} }
while let Ok(ident) = input.try(|input| input.expect_ident()) { while let Ok(ident) = input.try(|i| i.expect_ident_cloned()) {
value.push_str(" "); value.push_str(" ");
value.push_str(&ident); value.push_str(&ident);
} }
@ -1189,7 +1189,8 @@ ${helpers.single_keyword_system("font-variant-caps",
pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<SpecifiedValue, ParseError<'i>> { -> Result<SpecifiedValue, ParseError<'i>> {
let mut result = SpecifiedValue { weight: false, style: false }; let mut result = SpecifiedValue { weight: false, style: false };
try_match_ident_ignore_ascii_case! { input.expect_ident()?, // FIXME: remove clone() when lifetimes are non-lexical
try_match_ident_ignore_ascii_case! { input.expect_ident()?.clone(),
"none" => Ok(result), "none" => Ok(result),
"weight" => { "weight" => {
result.weight = true; result.weight = true;
@ -1411,9 +1412,10 @@ ${helpers.single_keyword_system("font-kerning",
) )
); );
while let Ok(_) = input.try(|input| { while let Ok(_) = input.try(|input| {
match input.next()? { // FIXME: remove clone() when lifetimes are non-lexical
Token::Ident(ident) => { match input.next()?.clone() {
if ident == "historical-forms" { Token::Ident(ref ident) => {
if *ident == "historical-forms" {
check_if_parsed!(HISTORICAL_FORMS); check_if_parsed!(HISTORICAL_FORMS);
alternates.push(VariantAlternates::HistoricalForms); alternates.push(VariantAlternates::HistoricalForms);
Ok(()) Ok(())
@ -1421,7 +1423,7 @@ ${helpers.single_keyword_system("font-kerning",
return Err(StyleParseError::UnspecifiedError.into()); return Err(StyleParseError::UnspecifiedError.into());
} }
}, },
Token::Function(name) => { Token::Function(ref name) => {
input.parse_nested_block(|i| { input.parse_nested_block(|i| {
match_ignore_ascii_case! { &name, match_ignore_ascii_case! { &name,
% for value in "swash stylistic ornaments annotation".split(): % for value in "swash stylistic ornaments annotation".split():
@ -2136,8 +2138,8 @@ https://drafts.csswg.org/css-fonts-4/#low-level-font-variation-settings-control-
if input.try(|input| input.expect_ident_matching("normal")).is_ok() { if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
Ok(SpecifiedValue::Normal) Ok(SpecifiedValue::Normal)
} else { } else {
input.expect_string().map(|cow| { input.expect_string().map(|s| {
SpecifiedValue::Override(cow.into_owned()) SpecifiedValue::Override(s.as_ref().to_owned())
}).map_err(|e| e.into()) }).map_err(|e| e.into())
} }
} }

View file

@ -590,9 +590,9 @@ ${helpers.predefined_type(
return Ok(SpecifiedValue::None); return Ok(SpecifiedValue::None);
} }
if let Ok(s) = input.try(|input| input.expect_string()) { if let Ok(s) = input.try(|i| i.expect_string().map(|s| s.as_ref().to_owned())) {
// Handle <string> // Handle <string>
return Ok(SpecifiedValue::String(s.into_owned())); return Ok(SpecifiedValue::String(s));
} }
// Handle a pair of keywords // Handle a pair of keywords

View file

@ -94,7 +94,7 @@ ${helpers.single_keyword("list-style-position", "outside inside", animation_valu
Ok(if let Ok(style) = input.try(|i| CounterStyleOrNone::parse(context, i)) { Ok(if let Ok(style) = input.try(|i| CounterStyleOrNone::parse(context, i)) {
SpecifiedValue::CounterStyle(style) SpecifiedValue::CounterStyle(style)
} else { } else {
SpecifiedValue::String(input.expect_string()?.into_owned()) SpecifiedValue::String(input.expect_string()?.as_ref().to_owned())
}) })
} }
</%helpers:longhand> </%helpers:longhand>
@ -197,13 +197,13 @@ ${helpers.single_keyword("list-style-position", "outside inside", animation_valu
let mut quotes = Vec::new(); let mut quotes = Vec::new();
loop { loop {
let first = match input.next() { let first = match input.next() {
Ok(Token::QuotedString(value)) => value.into_owned(), Ok(&Token::QuotedString(ref value)) => value.as_ref().to_owned(),
Ok(t) => return Err(BasicParseError::UnexpectedToken(t).into()), Ok(t) => return Err(BasicParseError::UnexpectedToken(t.clone()).into()),
Err(_) => break, Err(_) => break,
}; };
let second = match input.next() { let second = match input.next() {
Ok(Token::QuotedString(value)) => value.into_owned(), Ok(&Token::QuotedString(ref value)) => value.as_ref().to_owned(),
Ok(t) => return Err(BasicParseError::UnexpectedToken(t).into()), Ok(t) => return Err(BasicParseError::UnexpectedToken(t.clone()).into()),
Err(e) => return Err(e.into()), Err(e) => return Err(e.into()),
}; };
quotes.push((first, second)) quotes.push((first, second))

View file

@ -101,7 +101,7 @@
} else { } else {
Cursor::from_css_keyword(&ident) Cursor::from_css_keyword(&ident)
.map(computed_value::Keyword::Cursor) .map(computed_value::Keyword::Cursor)
.map_err(|()| SelectorParseError::UnexpectedIdent(ident).into()) .map_err(|()| SelectorParseError::UnexpectedIdent(ident.clone()).into())
} }
} }
} }

View file

@ -361,7 +361,7 @@ ${helpers.predefined_type("object-position",
_ => false _ => false
}; };
if !success { if !success {
return Err(SelectorParseError::UnexpectedIdent(ident).into()); return Err(SelectorParseError::UnexpectedIdent(ident.clone()).into());
} }
} }
@ -463,8 +463,8 @@ ${helpers.predefined_type("object-position",
fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<Self, ParseError<'i>> { -> Result<Self, ParseError<'i>> {
let mut strings = vec![]; let mut strings = vec![];
while let Ok(string) = input.try(Parser::expect_string) { while let Ok(string) = input.try(|i| i.expect_string().map(|s| s.as_ref().into())) {
strings.push(string.into_owned().into_boxed_str()); strings.push(string);
} }
TemplateAreas::from_vec(strings) TemplateAreas::from_vec(strings)

View file

@ -117,17 +117,17 @@
impl Parse for Side { impl Parse for Side {
fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<Side, ParseError<'i>> { -> Result<Side, ParseError<'i>> {
match input.next()? { match *input.next()? {
Token::Ident(ident) => { Token::Ident(ref ident) => {
try_match_ident_ignore_ascii_case! { ident, try_match_ident_ignore_ascii_case! { ident,
"clip" => Ok(Side::Clip), "clip" => Ok(Side::Clip),
"ellipsis" => Ok(Side::Ellipsis), "ellipsis" => Ok(Side::Ellipsis),
} }
} }
Token::QuotedString(v) => { Token::QuotedString(ref v) => {
Ok(Side::String(v.into_owned().into_boxed_str())) Ok(Side::String(v.as_ref().to_owned().into_boxed_str()))
} }
other => Err(BasicParseError::UnexpectedToken(other).into()), ref t => Err(BasicParseError::UnexpectedToken(t.clone()).into()),
} }
} }
} }
@ -236,7 +236,7 @@ ${helpers.single_keyword("unicode-bidi",
"blink" => if result.contains(BLINK) { Err(()) } "blink" => if result.contains(BLINK) { Err(()) }
else { empty = false; result.insert(BLINK); Ok(()) }, else { empty = false; result.insert(BLINK); Ok(()) },
_ => Err(()) _ => Err(())
}).map_err(|()| SelectorParseError::UnexpectedIdent(ident).into()) }).map_err(|()| SelectorParseError::UnexpectedIdent(ident.clone()).into())
} }
Err(e) => return Err(e.into()) Err(e) => return Err(e.into())
} }

View file

@ -422,7 +422,7 @@ impl CSSWideKeyword {
impl Parse for CSSWideKeyword { impl Parse for CSSWideKeyword {
fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> { fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
let ident = input.expect_ident()?; let ident = input.expect_ident()?.clone();
input.expect_exhausted()?; input.expect_exhausted()?;
CSSWideKeyword::from_ident(&ident) CSSWideKeyword::from_ident(&ident)
.ok_or(SelectorParseError::UnexpectedIdent(ident).into()) .ok_or(SelectorParseError::UnexpectedIdent(ident).into())

View file

@ -278,12 +278,11 @@
% endfor % endfor
let first_line_names = input.try(parse_line_names).unwrap_or(vec![].into_boxed_slice()); let first_line_names = input.try(parse_line_names).unwrap_or(vec![].into_boxed_slice());
if let Ok(s) = input.try(Parser::expect_string) { if let Ok(mut string) = input.try(|i| i.expect_string().map(|s| s.as_ref().into())) {
let mut strings = vec![]; let mut strings = vec![];
let mut values = vec![]; let mut values = vec![];
let mut line_names = vec![]; let mut line_names = vec![];
let mut names = first_line_names.into_vec(); let mut names = first_line_names.into_vec();
let mut string = s.into_owned().into_boxed_str();
loop { loop {
line_names.push(names.into_boxed_slice()); line_names.push(names.into_boxed_slice());
strings.push(string); strings.push(string);
@ -294,8 +293,8 @@
names.extend(v.into_vec()); names.extend(v.into_vec());
} }
string = match input.try(Parser::expect_string) { string = match input.try(|i| i.expect_string().map(|s| s.as_ref().into())) {
Ok(s) => s.into_owned().into_boxed_str(), Ok(s) => s,
_ => { // only the named area determines whether we should bail out _ => { // only the named area determines whether we should bail out
line_names.push(names.into_boxed_slice()); line_names.push(names.into_boxed_slice());
break break

View file

@ -165,7 +165,7 @@ impl Expression {
-> Result<Self, ParseError<'i>> { -> Result<Self, ParseError<'i>> {
input.expect_parenthesis_block()?; input.expect_parenthesis_block()?;
input.parse_nested_block(|input| { input.parse_nested_block(|input| {
let name = input.expect_ident()?; let name = input.expect_ident_cloned()?;
input.expect_colon()?; input.expect_colon()?;
// TODO: Handle other media features // TODO: Handle other media features
Ok(Expression(match_ignore_ascii_case! { &name, Ok(Expression(match_ignore_ascii_case! { &name,

View file

@ -8,7 +8,7 @@
use {Atom, Prefix, Namespace, LocalName, CaseSensitivityExt}; use {Atom, Prefix, Namespace, LocalName, CaseSensitivityExt};
use attr::{AttrIdentifier, AttrValue}; use attr::{AttrIdentifier, AttrValue};
use cssparser::{Parser as CssParser, ToCss, serialize_identifier, CompactCowStr}; use cssparser::{Parser as CssParser, ToCss, serialize_identifier, CowRcStr};
use dom::{OpaqueNode, TElement, TNode}; use dom::{OpaqueNode, TElement, TNode};
use element_state::ElementState; use element_state::ElementState;
use fnv::FnvHashMap; use fnv::FnvHashMap;
@ -20,7 +20,6 @@ use selectors::attr::{AttrSelectorOperation, NamespaceConstraint, CaseSensitivit
use selectors::parser::{SelectorMethods, SelectorParseError}; use selectors::parser::{SelectorMethods, SelectorParseError};
use selectors::visitor::SelectorVisitor; use selectors::visitor::SelectorVisitor;
use std::ascii::AsciiExt; use std::ascii::AsciiExt;
use std::borrow::Cow;
use std::fmt; use std::fmt;
use std::fmt::Debug; use std::fmt::Debug;
use std::mem; use std::mem;
@ -334,7 +333,7 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
type Impl = SelectorImpl; type Impl = SelectorImpl;
type Error = StyleParseError<'i>; type Error = StyleParseError<'i>;
fn parse_non_ts_pseudo_class(&self, name: CompactCowStr<'i>) fn parse_non_ts_pseudo_class(&self, name: CowRcStr<'i>)
-> Result<NonTSPseudoClass, ParseError<'i>> { -> Result<NonTSPseudoClass, ParseError<'i>> {
use self::NonTSPseudoClass::*; use self::NonTSPseudoClass::*;
let pseudo_class = match_ignore_ascii_case! { &name, let pseudo_class = match_ignore_ascii_case! { &name,
@ -367,19 +366,19 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
} }
fn parse_non_ts_functional_pseudo_class<'t>(&self, fn parse_non_ts_functional_pseudo_class<'t>(&self,
name: CompactCowStr<'i>, name: CowRcStr<'i>,
parser: &mut CssParser<'i, 't>) parser: &mut CssParser<'i, 't>)
-> Result<NonTSPseudoClass, ParseError<'i>> { -> Result<NonTSPseudoClass, ParseError<'i>> {
use self::NonTSPseudoClass::*; use self::NonTSPseudoClass::*;
let pseudo_class = match_ignore_ascii_case!{ &name, let pseudo_class = match_ignore_ascii_case!{ &name,
"lang" => { "lang" => {
Lang(parser.expect_ident_or_string()?.into_owned().into_boxed_str()) Lang(parser.expect_ident_or_string()?.as_ref().into())
} }
"-servo-case-sensitive-type-attr" => { "-servo-case-sensitive-type-attr" => {
if !self.in_user_agent_stylesheet() { if !self.in_user_agent_stylesheet() {
return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()); return Err(SelectorParseError::UnexpectedIdent(name.clone()).into());
} }
ServoCaseSensitiveTypeAttr(Atom::from(Cow::from(parser.expect_ident()?))) ServoCaseSensitiveTypeAttr(Atom::from(parser.expect_ident()?.as_ref()))
} }
_ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) _ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into())
}; };
@ -387,7 +386,7 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
Ok(pseudo_class) Ok(pseudo_class)
} }
fn parse_pseudo_element(&self, name: CompactCowStr<'i>) -> Result<PseudoElement, ParseError<'i>> { fn parse_pseudo_element(&self, name: CowRcStr<'i>) -> Result<PseudoElement, ParseError<'i>> {
use self::PseudoElement::*; use self::PseudoElement::*;
let pseudo_element = match_ignore_ascii_case! { &name, let pseudo_element = match_ignore_ascii_case! { &name,
"before" => Before, "before" => Before,

View file

@ -89,9 +89,9 @@ macro_rules! parse_quoted_or_unquoted_string {
let start = input.position(); let start = input.position();
input.parse_entirely(|input| { input.parse_entirely(|input| {
match input.next() { match input.next() {
Ok(Token::QuotedString(value)) => Ok(&Token::QuotedString(ref value)) =>
Ok($url_matching_function(value.into_owned())), Ok($url_matching_function(value.as_ref().to_owned())),
Ok(t) => Err(BasicParseError::UnexpectedToken(t).into()), Ok(t) => Err(BasicParseError::UnexpectedToken(t.clone()).into()),
Err(e) => Err(e.into()), Err(e) => Err(e.into()),
} }
}).or_else(|_: ParseError| { }).or_else(|_: ParseError| {
@ -112,7 +112,7 @@ impl UrlMatchingFunction {
parse_quoted_or_unquoted_string!(input, UrlMatchingFunction::Domain) parse_quoted_or_unquoted_string!(input, UrlMatchingFunction::Domain)
} else if input.try(|input| input.expect_function_matching("regexp")).is_ok() { } else if input.try(|input| input.expect_function_matching("regexp")).is_ok() {
input.parse_nested_block(|input| { input.parse_nested_block(|input| {
Ok(UrlMatchingFunction::RegExp(input.expect_string()?.into_owned())) Ok(UrlMatchingFunction::RegExp(input.expect_string()?.as_ref().to_owned()))
}) })
} else if let Ok(url) = input.try(|input| SpecifiedUrl::parse(context, input)) { } else if let Ok(url) = input.try(|input| SpecifiedUrl::parse(context, input)) {
Ok(UrlMatchingFunction::Url(url)) Ok(UrlMatchingFunction::Url(url))

View file

@ -4,7 +4,7 @@
//! Keyframes: https://drafts.csswg.org/css-animations/#keyframes //! Keyframes: https://drafts.csswg.org/css-animations/#keyframes
use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, RuleListParser, ParserInput, CompactCowStr}; use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, RuleListParser, ParserInput, CowRcStr};
use cssparser::{DeclarationListParser, DeclarationParser, parse_one_rule, SourceLocation}; use cssparser::{DeclarationListParser, DeclarationParser, parse_one_rule, SourceLocation};
use error_reporting::{NullReporter, ContextualParseError}; use error_reporting::{NullReporter, ContextualParseError};
use parser::{ParserContext, log_css_error}; use parser::{ParserContext, log_css_error};
@ -531,7 +531,7 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for KeyframeDeclarationParser<'a, 'b> {
type Declaration = (); type Declaration = ();
type Error = SelectorParseError<'i, StyleParseError<'i>>; type Error = SelectorParseError<'i, StyleParseError<'i>>;
fn parse_value<'t>(&mut self, name: CompactCowStr<'i>, input: &mut Parser<'i, 't>) fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>)
-> Result<(), ParseError<'i>> { -> Result<(), ParseError<'i>> {
let id = PropertyId::parse(&name) let id = PropertyId::parse(&name)
.map_err(|()| PropertyDeclarationParseError::UnknownProperty(name))?; .map_err(|()| PropertyDeclarationParseError::UnknownProperty(name))?;

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, BasicParseError}; use cssparser::{CowRcStr, 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};
@ -18,7 +18,6 @@ use selectors::SelectorList;
use selectors::parser::SelectorParseError; use selectors::parser::SelectorParseError;
use servo_arc::Arc; use servo_arc::Arc;
use shared_lock::{Locked, SharedRwLock}; use shared_lock::{Locked, SharedRwLock};
use std::borrow::Cow;
use str::starts_with_ignore_ascii_case; use str::starts_with_ignore_ascii_case;
use style_traits::{StyleParseError, ParseError}; use style_traits::{StyleParseError, ParseError};
use stylesheets::{CssRule, CssRules, CssRuleType, Origin, StylesheetLoader}; use stylesheets::{CssRule, CssRules, CssRuleType, Origin, StylesheetLoader};
@ -142,7 +141,7 @@ impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> {
fn parse_prelude<'t>( fn parse_prelude<'t>(
&mut self, &mut self,
name: CompactCowStr<'i>, name: CowRcStr<'i>,
input: &mut Parser<'i, 't> input: &mut Parser<'i, 't>
) -> Result<AtRuleType<AtRulePrelude, CssRule>, ParseError<'i>> { ) -> Result<AtRuleType<AtRulePrelude, CssRule>, ParseError<'i>> {
let location = get_location_with_offset(input.current_source_location(), let location = get_location_with_offset(input.current_source_location(),
@ -156,7 +155,7 @@ impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> {
} }
self.state = State::Imports; self.state = State::Imports;
let url_string = input.expect_url_or_string()?.into_owned(); let url_string = input.expect_url_or_string()?.as_ref().to_owned();
let specified_url = SpecifiedUrl::parse_from_string(url_string, &self.context)?; let specified_url = SpecifiedUrl::parse_from_string(url_string, &self.context)?;
let media = parse_media_query_list(&self.context, input); let media = parse_media_query_list(&self.context, input);
@ -183,14 +182,14 @@ 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(|i| i.expect_ident_cloned());
let maybe_namespace = match input.expect_url_or_string() { let maybe_namespace = match input.expect_url_or_string() {
Ok(url_or_string) => url_or_string, Ok(url_or_string) => url_or_string,
Err(BasicParseError::UnexpectedToken(t)) => Err(BasicParseError::UnexpectedToken(t)) =>
return Err(StyleParseError::UnexpectedTokenWithinNamespace(t).into()), return Err(StyleParseError::UnexpectedTokenWithinNamespace(t).into()),
Err(e) => return Err(e.into()), Err(e) => return Err(e.into()),
}; };
let url = Namespace::from(Cow::from(maybe_namespace)); let url = Namespace::from(maybe_namespace.as_ref());
let id = register_namespace(&url) let id = register_namespace(&url)
.map_err(|()| StyleParseError::UnspecifiedError)?; .map_err(|()| StyleParseError::UnspecifiedError)?;
@ -198,7 +197,7 @@ impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> {
let mut namespaces = self.namespaces.as_mut().unwrap(); let mut namespaces = self.namespaces.as_mut().unwrap();
let opt_prefix = if let Ok(prefix) = prefix_result { let opt_prefix = if let Ok(prefix) = prefix_result {
let prefix = Prefix::from(Cow::from(prefix)); let prefix = Prefix::from(prefix.as_ref());
namespaces namespaces
.prefixes .prefixes
.insert(prefix.clone(), (url.clone(), id)); .insert(prefix.clone(), (url.clone(), id));
@ -324,7 +323,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
fn parse_prelude<'t>( fn parse_prelude<'t>(
&mut self, &mut self,
name: CompactCowStr<'i>, name: CowRcStr<'i>,
input: &mut Parser<'i, 't> input: &mut Parser<'i, 't>
) -> Result<AtRuleType<AtRulePrelude, CssRule>, ParseError<'i>> { ) -> Result<AtRuleType<AtRulePrelude, CssRule>, ParseError<'i>> {
let location = let location =

View file

@ -97,14 +97,14 @@ impl SupportsCondition {
// End of input // End of input
return Ok(in_parens) return Ok(in_parens)
} }
Ok(Token::Ident(ident)) => { Ok(&Token::Ident(ref ident)) => {
match_ignore_ascii_case! { &ident, match_ignore_ascii_case! { &ident,
"and" => ("and", SupportsCondition::And as fn(_) -> _), "and" => ("and", SupportsCondition::And as fn(_) -> _),
"or" => ("or", SupportsCondition::Or as fn(_) -> _), "or" => ("or", SupportsCondition::Or as fn(_) -> _),
_ => return Err(SelectorParseError::UnexpectedIdent(ident.clone()).into()) _ => return Err(SelectorParseError::UnexpectedIdent(ident.clone()).into())
} }
} }
Ok(t) => return Err(CssParseError::Basic(BasicParseError::UnexpectedToken(t))) Ok(t) => return Err(CssParseError::Basic(BasicParseError::UnexpectedToken(t.clone())))
}; };
let mut conditions = Vec::with_capacity(2); let mut conditions = Vec::with_capacity(2);
@ -126,7 +126,8 @@ impl SupportsCondition {
// but we want to not include it in `pos` for the SupportsCondition::FutureSyntax cases. // but we want to not include it in `pos` for the SupportsCondition::FutureSyntax cases.
while input.try(Parser::expect_whitespace).is_ok() {} while input.try(Parser::expect_whitespace).is_ok() {}
let pos = input.position(); let pos = input.position();
match input.next()? { // FIXME: remove clone() when lifetimes are non-lexical
match input.next()?.clone() {
Token::ParenthesisBlock => { Token::ParenthesisBlock => {
let nested = input.try(|input| { let nested = input.try(|input| {
input.parse_nested_block(|i| parse_condition_or_declaration(i)) input.parse_nested_block(|i| parse_condition_or_declaration(i))
@ -244,7 +245,7 @@ impl Declaration {
let mut input = ParserInput::new(&self.0); let mut input = ParserInput::new(&self.0);
let mut input = Parser::new(&mut input); let mut input = Parser::new(&mut input);
input.parse_entirely(|input| { input.parse_entirely(|input| {
let prop = input.expect_ident().unwrap(); let prop = input.expect_ident().unwrap().as_ref().to_owned();
input.expect_colon().unwrap(); input.expect_colon().unwrap();
let id = PropertyId::parse(&prop) let id = PropertyId::parse(&prop)
.map_err(|_| StyleParseError::UnspecifiedError)?; .map_err(|_| StyleParseError::UnspecifiedError)?;

View file

@ -10,7 +10,7 @@
use app_units::Au; use app_units::Au;
use context::QuirksMode; use context::QuirksMode;
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser, parse_important}; use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser, parse_important};
use cssparser::{CompactCowStr, ToCss as ParserToCss}; use cssparser::{CowRcStr, ToCss as ParserToCss};
use error_reporting::ContextualParseError; use error_reporting::ContextualParseError;
use euclid::TypedSize2D; use euclid::TypedSize2D;
use font_metrics::get_metrics_provider_for_product; use font_metrics::get_metrics_provider_for_product;
@ -280,7 +280,7 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for ViewportRuleParser<'a, 'b> {
type Declaration = Vec<ViewportDescriptorDeclaration>; type Declaration = Vec<ViewportDescriptorDeclaration>;
type Error = SelectorParseError<'i, StyleParseError<'i>>; type Error = SelectorParseError<'i, StyleParseError<'i>>;
fn parse_value<'t>(&mut self, name: CompactCowStr<'i>, input: &mut Parser<'i, 't>) fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>)
-> Result<Vec<ViewportDescriptorDeclaration>, ParseError<'i>> { -> Result<Vec<ViewportDescriptorDeclaration>, ParseError<'i>> {
macro_rules! declaration { macro_rules! declaration {
($declaration:ident($parse:expr)) => { ($declaration:ident($parse:expr)) => {

View file

@ -100,11 +100,11 @@ impl Parse for GridLine {
} }
grid_line.line_num = Some(i); grid_line.line_num = Some(i);
} else if let Ok(name) = input.try(|i| i.expect_ident()) { } else if let Ok(name) = input.try(|i| i.expect_ident_cloned()) {
if val_before_span || grid_line.ident.is_some() { if val_before_span || grid_line.ident.is_some() {
return Err(StyleParseError::UnspecifiedError.into()); return Err(StyleParseError::UnspecifiedError.into());
} }
grid_line.ident = Some(CustomIdent::from_ident(name, &[])?); grid_line.ident = Some(CustomIdent::from_ident(&name, &[])?);
} else { } else {
break break
} }

View file

@ -151,6 +151,8 @@ impl<T: Parse> Parse for FontSettingTag<T> {
use byteorder::{ReadBytesExt, BigEndian}; use byteorder::{ReadBytesExt, BigEndian};
use std::io::Cursor; use std::io::Cursor;
let u_tag;
{
let tag = input.expect_string()?; let tag = input.expect_string()?;
// allowed strings of length 4 containing chars: <U+20, U+7E> // allowed strings of length 4 containing chars: <U+20, U+7E>
@ -161,7 +163,8 @@ impl<T: Parse> Parse for FontSettingTag<T> {
} }
let mut raw = Cursor::new(tag.as_bytes()); let mut raw = Cursor::new(tag.as_bytes());
let u_tag = raw.read_u32::<BigEndian>().unwrap(); u_tag = raw.read_u32::<BigEndian>().unwrap();
}
Ok(FontSettingTag { tag: u_tag, value: T::parse(context, input)? }) Ok(FontSettingTag { tag: u_tag, value: T::parse(context, input)? })
} }

View file

@ -9,11 +9,10 @@
#![deny(missing_docs)] #![deny(missing_docs)]
use Atom; use Atom;
pub use cssparser::{RGBA, Token, Parser, serialize_identifier, BasicParseError, CompactCowStr}; pub use cssparser::{RGBA, Token, Parser, serialize_identifier, BasicParseError, CowRcStr};
use parser::{Parse, ParserContext}; use parser::{Parse, ParserContext};
use selectors::parser::SelectorParseError; use selectors::parser::SelectorParseError;
use std::ascii::AsciiExt; use std::ascii::AsciiExt;
use std::borrow::Cow;
use std::fmt::{self, Debug}; use std::fmt::{self, Debug};
use std::hash; use std::hash;
use style_traits::{ToCss, ParseError, StyleParseError}; use style_traits::{ToCss, ParseError, StyleParseError};
@ -87,18 +86,18 @@ pub struct CustomIdent(pub Atom);
impl CustomIdent { impl CustomIdent {
/// Parse an already-tokenizer identifier /// Parse an already-tokenizer identifier
pub fn from_ident<'i>(ident: CompactCowStr<'i>, excluding: &[&str]) -> Result<Self, ParseError<'i>> { pub fn from_ident<'i>(ident: &CowRcStr<'i>, excluding: &[&str]) -> Result<Self, ParseError<'i>> {
let valid = match_ignore_ascii_case! { &ident, let valid = match_ignore_ascii_case! { ident,
"initial" | "inherit" | "unset" | "default" => false, "initial" | "inherit" | "unset" | "default" => false,
_ => true _ => true
}; };
if !valid { if !valid {
return Err(SelectorParseError::UnexpectedIdent(ident).into()); return Err(SelectorParseError::UnexpectedIdent(ident.clone()).into());
} }
if excluding.iter().any(|s| ident.eq_ignore_ascii_case(s)) { if excluding.iter().any(|s| ident.eq_ignore_ascii_case(s)) {
Err(StyleParseError::UnspecifiedError.into()) Err(StyleParseError::UnspecifiedError.into())
} else { } else {
Ok(CustomIdent(Atom::from(Cow::from(ident)))) Ok(CustomIdent(Atom::from(ident.as_ref())))
} }
} }
} }
@ -121,8 +120,8 @@ pub enum KeyframesName {
impl KeyframesName { impl KeyframesName {
/// https://drafts.csswg.org/css-animations/#dom-csskeyframesrule-name /// https://drafts.csswg.org/css-animations/#dom-csskeyframesrule-name
pub fn from_ident(value: String) -> Self { pub fn from_ident(value: &str) -> Self {
let custom_ident = CustomIdent::from_ident((&*value).into(), &["none"]).ok(); let custom_ident = CustomIdent::from_ident(&value.into(), &["none"]).ok();
match custom_ident { match custom_ident {
Some(ident) => KeyframesName::Ident(ident), Some(ident) => KeyframesName::Ident(ident),
None => KeyframesName::QuotedString(value.into()), None => KeyframesName::QuotedString(value.into()),
@ -155,9 +154,9 @@ impl hash::Hash for KeyframesName {
impl Parse for KeyframesName { impl Parse for KeyframesName {
fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> { fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
match input.next() { match input.next() {
Ok(Token::Ident(s)) => Ok(KeyframesName::Ident(CustomIdent::from_ident(s, &["none"])?)), Ok(&Token::Ident(ref s)) => Ok(KeyframesName::Ident(CustomIdent::from_ident(s, &["none"])?)),
Ok(Token::QuotedString(s)) => Ok(KeyframesName::QuotedString(Atom::from(Cow::from(s)))), Ok(&Token::QuotedString(ref s)) => Ok(KeyframesName::QuotedString(Atom::from(s.as_ref()))),
Ok(t) => Err(BasicParseError::UnexpectedToken(t).into()), Ok(t) => Err(BasicParseError::UnexpectedToken(t.clone()).into()),
Err(e) => Err(e.into()), Err(e) => Err(e.into()),
} }
} }

View file

@ -374,7 +374,8 @@ fn parse_normal_or_baseline<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignF
// <baseline-position> // <baseline-position>
fn parse_baseline<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseError<'i>> { fn parse_baseline<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseError<'i>> {
try_match_ident_ignore_ascii_case! { input.expect_ident()?, // FIXME: remove clone() when lifetimes are non-lexical
try_match_ident_ignore_ascii_case! { input.expect_ident()?.clone(),
"baseline" => Ok(ALIGN_BASELINE), "baseline" => Ok(ALIGN_BASELINE),
"first" => { "first" => {
input.expect_ident_matching("baseline")?; input.expect_ident_matching("baseline")?;
@ -471,7 +472,7 @@ fn parse_self_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags,
// [ legacy && [ left | right | center ] ] // [ legacy && [ left | right | center ] ]
fn parse_legacy<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseError<'i>> { fn parse_legacy<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseError<'i>> {
let a = input.expect_ident()?; let a = input.expect_ident()?.clone();
let b = input.expect_ident()?; let b = input.expect_ident()?;
if a.eq_ignore_ascii_case("legacy") { if a.eq_ignore_ascii_case("legacy") {
(match_ignore_ascii_case! { &b, (match_ignore_ascii_case! { &b,
@ -479,7 +480,7 @@ fn parse_legacy<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseE
"right" => Ok(ALIGN_LEGACY | ALIGN_RIGHT), "right" => Ok(ALIGN_LEGACY | ALIGN_RIGHT),
"center" => Ok(ALIGN_LEGACY | ALIGN_CENTER), "center" => Ok(ALIGN_LEGACY | ALIGN_CENTER),
_ => Err(()) _ => Err(())
}).map_err(|()| SelectorParseError::UnexpectedIdent(b).into()) }).map_err(|()| SelectorParseError::UnexpectedIdent(b.clone()).into())
} else if b.eq_ignore_ascii_case("legacy") { } else if b.eq_ignore_ascii_case("legacy") {
(match_ignore_ascii_case! { &a, (match_ignore_ascii_case! { &a,
"left" => Ok(ALIGN_LEGACY | ALIGN_LEFT), "left" => Ok(ALIGN_LEGACY | ALIGN_LEFT),

View file

@ -27,6 +27,6 @@ impl Parse for BackgroundSize {
"cover" => Ok(GenericBackgroundSize::Cover), "cover" => Ok(GenericBackgroundSize::Cover),
"contain" => Ok(GenericBackgroundSize::Contain), "contain" => Ok(GenericBackgroundSize::Contain),
_ => Err(()), _ => Err(()),
}).map_err(|()| SelectorParseError::UnexpectedIdent(ident).into()) }).map_err(|()| SelectorParseError::UnexpectedIdent(ident.clone()).into())
} }
} }

View file

@ -101,7 +101,7 @@ impl Parse for GeometryBox {
impl Parse for BasicShape { impl Parse for BasicShape {
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> { fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
let function = input.expect_function()?; let function = input.expect_function()?.clone();
input.parse_nested_block(move |i| { input.parse_nested_block(move |i| {
(match_ignore_ascii_case! { &function, (match_ignore_ascii_case! { &function,
"inset" => return InsetRect::parse_function_arguments(context, i).map(GenericBasicShape::Inset), "inset" => return InsetRect::parse_function_arguments(context, i).map(GenericBasicShape::Inset),
@ -109,7 +109,7 @@ impl Parse for BasicShape {
"ellipse" => return Ellipse::parse_function_arguments(context, i).map(GenericBasicShape::Ellipse), "ellipse" => return Ellipse::parse_function_arguments(context, i).map(GenericBasicShape::Ellipse),
"polygon" => return Polygon::parse_function_arguments(context, i).map(GenericBasicShape::Polygon), "polygon" => return Polygon::parse_function_arguments(context, i).map(GenericBasicShape::Polygon),
_ => Err(()) _ => Err(())
}).map_err(|()| StyleParseError::UnexpectedFunction(function).into()) }).map_err(|()| StyleParseError::UnexpectedFunction(function.clone()).into())
}) })
} }
} }

View file

@ -150,41 +150,37 @@ impl CalcNode {
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
expected_unit: CalcUnit expected_unit: CalcUnit
) -> Result<Self, ParseError<'i>> { ) -> Result<Self, ParseError<'i>> {
// FIXME: remove early returns when lifetimes are non-lexical
match (input.next()?, expected_unit) { match (input.next()?, expected_unit) {
(Token::Number { value, .. }, _) => Ok(CalcNode::Number(value)), (&Token::Number { value, .. }, _) => return Ok(CalcNode::Number(value)),
(Token::Dimension { value, ref unit, .. }, CalcUnit::Length) | (&Token::Dimension { value, ref unit, .. }, CalcUnit::Length) |
(Token::Dimension { value, ref unit, .. }, CalcUnit::LengthOrPercentage) => { (&Token::Dimension { value, ref unit, .. }, CalcUnit::LengthOrPercentage) => {
NoCalcLength::parse_dimension(context, value, unit) return NoCalcLength::parse_dimension(context, value, unit)
.map(CalcNode::Length) .map(CalcNode::Length)
.map_err(|()| StyleParseError::UnspecifiedError.into()) .map_err(|()| StyleParseError::UnspecifiedError.into())
} }
(Token::Dimension { value, ref unit, .. }, CalcUnit::Angle) => { (&Token::Dimension { value, ref unit, .. }, CalcUnit::Angle) => {
Angle::parse_dimension(value, unit, /* from_calc = */ true) return Angle::parse_dimension(value, unit, /* from_calc = */ true)
.map(CalcNode::Angle) .map(CalcNode::Angle)
.map_err(|()| StyleParseError::UnspecifiedError.into()) .map_err(|()| StyleParseError::UnspecifiedError.into())
} }
(Token::Dimension { value, ref unit, .. }, CalcUnit::Time) => { (&Token::Dimension { value, ref unit, .. }, CalcUnit::Time) => {
Time::parse_dimension(value, unit, /* from_calc = */ true) return Time::parse_dimension(value, unit, /* from_calc = */ true)
.map(CalcNode::Time) .map(CalcNode::Time)
.map_err(|()| StyleParseError::UnspecifiedError.into()) .map_err(|()| StyleParseError::UnspecifiedError.into())
} }
(Token::Percentage { unit_value, .. }, CalcUnit::LengthOrPercentage) | (&Token::Percentage { unit_value, .. }, CalcUnit::LengthOrPercentage) |
(Token::Percentage { unit_value, .. }, CalcUnit::Percentage) => { (&Token::Percentage { unit_value, .. }, CalcUnit::Percentage) => {
Ok(CalcNode::Percentage(unit_value)) return Ok(CalcNode::Percentage(unit_value))
}
(&Token::ParenthesisBlock, _) => {}
(&Token::Function(ref name), _) if name.eq_ignore_ascii_case("calc") => {}
(t, _) => return Err(BasicParseError::UnexpectedToken(t.clone()).into())
} }
(Token::ParenthesisBlock, _) => {
input.parse_nested_block(|i| { input.parse_nested_block(|i| {
CalcNode::parse(context, i, expected_unit) CalcNode::parse(context, i, expected_unit)
}) })
} }
(Token::Function(ref name), _) if name.eq_ignore_ascii_case("calc") => {
input.parse_nested_block(|i| {
CalcNode::parse(context, i, expected_unit)
})
}
(t, _) => Err(BasicParseError::UnexpectedToken(t).into())
}
}
/// Parse a top-level `calc` expression, with all nested sub-expressions. /// Parse a top-level `calc` expression, with all nested sub-expressions.
/// ///
@ -200,11 +196,12 @@ impl CalcNode {
loop { loop {
let position = input.position(); let position = input.position();
match input.next_including_whitespace() { match input.next_including_whitespace() {
Ok(Token::WhiteSpace(_)) => { Ok(&Token::WhiteSpace(_)) => {
if input.is_exhausted() { if input.is_exhausted() {
break; // allow trailing whitespace break; // allow trailing whitespace
} }
match input.next()? { // FIXME: remove clone() when lifetimes are non-lexical
match input.next()?.clone() {
Token::Delim('+') => { Token::Delim('+') => {
let rhs = let rhs =
Self::parse_product(context, input, expected_unit)?; Self::parse_product(context, input, expected_unit)?;
@ -252,13 +249,13 @@ impl CalcNode {
loop { loop {
let position = input.position(); let position = input.position();
match input.next() { match input.next() {
Ok(Token::Delim('*')) => { Ok(&Token::Delim('*')) => {
let rhs = Self::parse_one(context, input, expected_unit)?; let rhs = Self::parse_one(context, input, expected_unit)?;
let new_root = CalcNode::Mul(Box::new(root), Box::new(rhs)); let new_root = CalcNode::Mul(Box::new(root), Box::new(rhs));
root = new_root; root = new_root;
} }
// TODO(emilio): Figure out why the `Integer` check. // TODO(emilio): Figure out why the `Integer` check.
Ok(Token::Delim('/')) if expected_unit != CalcUnit::Integer => { Ok(&Token::Delim('/')) if expected_unit != CalcUnit::Integer => {
let rhs = Self::parse_one(context, input, expected_unit)?; let rhs = Self::parse_one(context, input, expected_unit)?;
let new_root = CalcNode::Div(Box::new(root), Box::new(rhs)); let new_root = CalcNode::Div(Box::new(root), Box::new(rhs));
root = new_root; root = new_root;

View file

@ -72,7 +72,7 @@ impl Parse for Color {
// specified value. // specified value.
let start_position = input.position(); let start_position = input.position();
let authored = match input.next() { let authored = match input.next() {
Ok(Token::Ident(s)) => Some(s.to_lowercase().into_boxed_str()), Ok(&Token::Ident(ref s)) => Some(s.to_lowercase().into_boxed_str()),
_ => None, _ => None,
}; };
input.reset(start_position); input.reset(start_position);
@ -173,22 +173,22 @@ impl Color {
/// ///
/// https://quirks.spec.whatwg.org/#the-hashless-hex-color-quirk /// https://quirks.spec.whatwg.org/#the-hashless-hex-color-quirk
fn parse_quirky_color<'i, 't>(input: &mut Parser<'i, 't>) -> Result<RGBA, ParseError<'i>> { fn parse_quirky_color<'i, 't>(input: &mut Parser<'i, 't>) -> Result<RGBA, ParseError<'i>> {
let (value, unit) = match input.next()? { let (value, unit) = match *input.next()? {
Token::Number { int_value: Some(integer), .. } => { Token::Number { int_value: Some(integer), .. } => {
(integer, None) (integer, None)
}, },
Token::Dimension { int_value: Some(integer), unit, .. } => { Token::Dimension { int_value: Some(integer), ref unit, .. } => {
(integer, Some(unit)) (integer, Some(unit))
}, },
Token::Ident(ident) => { Token::Ident(ref ident) => {
if ident.len() != 3 && ident.len() != 6 { if ident.len() != 3 && ident.len() != 6 {
return Err(StyleParseError::UnspecifiedError.into()); return Err(StyleParseError::UnspecifiedError.into());
} }
return parse_hash_color(ident.as_bytes()) return parse_hash_color(ident.as_bytes())
.map_err(|()| StyleParseError::UnspecifiedError.into()); .map_err(|()| StyleParseError::UnspecifiedError.into());
} }
t => { ref t => {
return Err(BasicParseError::UnexpectedToken(t).into()); return Err(BasicParseError::UnexpectedToken(t.clone()).into());
}, },
}; };
if value < 0 { if value < 0 {

View file

@ -159,7 +159,7 @@ impl Parse for Filter {
return Ok(GenericFilter::Url(url)); return Ok(GenericFilter::Url(url));
} }
} }
let function = input.expect_function()?; let function = input.expect_function()?.clone();
input.parse_nested_block(|i| { input.parse_nested_block(|i| {
try_match_ident_ignore_ascii_case! { function, try_match_ident_ignore_ascii_case! { function,
"blur" => Ok(GenericFilter::Blur(Length::parse_non_negative(context, i)?)), "blur" => Ok(GenericFilter::Blur(Length::parse_non_negative(context, i)?)),

View file

@ -18,10 +18,10 @@ use values::specified::LengthOrPercentage;
/// Parse a single flexible length. /// Parse a single flexible length.
pub fn parse_flex<'i, 't>(input: &mut Parser<'i, 't>) -> Result<CSSFloat, ParseError<'i>> { pub fn parse_flex<'i, 't>(input: &mut Parser<'i, 't>) -> Result<CSSFloat, ParseError<'i>> {
match input.next()? { match *input.next()? {
Token::Dimension { value, ref unit, .. } if unit.eq_ignore_ascii_case("fr") && value.is_sign_positive() Token::Dimension { value, ref unit, .. } if unit.eq_ignore_ascii_case("fr") && value.is_sign_positive()
=> Ok(value), => Ok(value),
t => Err(BasicParseError::UnexpectedToken(t).into()), ref t => Err(BasicParseError::UnexpectedToken(t.clone()).into()),
} }
} }
@ -85,8 +85,8 @@ pub fn parse_line_names<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Box<[Custo
input.expect_square_bracket_block()?; input.expect_square_bracket_block()?;
input.parse_nested_block(|input| { input.parse_nested_block(|input| {
let mut values = vec![]; let mut values = vec![];
while let Ok(ident) = input.try(|i| i.expect_ident()) { while let Ok(ident) = input.try(|i| i.expect_ident_cloned()) {
let ident = CustomIdent::from_ident(ident, &["span"])?; let ident = CustomIdent::from_ident(&ident, &["span"])?;
values.push(ident); values.push(ident);
} }

View file

@ -13,7 +13,6 @@ use parser::{Parse, ParserContext};
use selectors::parser::SelectorParseError; use selectors::parser::SelectorParseError;
#[cfg(feature = "servo")] #[cfg(feature = "servo")]
use servo_url::ServoUrl; use servo_url::ServoUrl;
use std::borrow::Cow;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::f32::consts::PI; use std::f32::consts::PI;
use std::fmt; use std::fmt;
@ -169,9 +168,9 @@ impl Image {
fn parse_element<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Atom, ParseError<'i>> { fn parse_element<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Atom, ParseError<'i>> {
input.try(|i| i.expect_function_matching("-moz-element"))?; input.try(|i| i.expect_function_matching("-moz-element"))?;
input.parse_nested_block(|i| { input.parse_nested_block(|i| {
match i.next()? { match *i.next()? {
Token::IDHash(id) => Ok(Atom::from(Cow::from(id))), Token::IDHash(ref id) => Ok(Atom::from(id.as_ref())),
t => Err(BasicParseError::UnexpectedToken(t).into()), ref t => Err(BasicParseError::UnexpectedToken(t.clone()).into()),
} }
}) })
} }
@ -184,7 +183,8 @@ impl Parse for Gradient {
Radial, Radial,
} }
let func = input.expect_function()?; // FIXME: remove clone() when lifetimes are non-lexical
let func = input.expect_function()?.clone();
let result = match_ignore_ascii_case! { &func, let result = match_ignore_ascii_case! { &func,
"linear-gradient" => { "linear-gradient" => {
Some((Shape::Linear, false, CompatMode::Modern)) Some((Shape::Linear, false, CompatMode::Modern))
@ -234,7 +234,7 @@ impl Parse for Gradient {
let (shape, repeating, mut compat_mode) = match result { let (shape, repeating, mut compat_mode) = match result {
Some(result) => result, Some(result) => result,
None => return Err(StyleParseError::UnexpectedFunction(func).into()), None => return Err(StyleParseError::UnexpectedFunction(func.clone()).into()),
}; };
let (kind, items) = input.parse_nested_block(|i| { let (kind, items) = input.parse_nested_block(|i| {
@ -389,7 +389,7 @@ impl Gradient {
} }
} }
let ident = input.expect_ident()?; let ident = input.expect_ident_cloned()?;
input.expect_comma()?; input.expect_comma()?;
let (kind, reverse_stops) = match_ignore_ascii_case! { &ident, let (kind, reverse_stops) = match_ignore_ascii_case! { &ident,
@ -439,7 +439,7 @@ impl Gradient {
let mut items = input.try(|i| { let mut items = input.try(|i| {
i.expect_comma()?; i.expect_comma()?;
i.parse_comma_separated(|i| { i.parse_comma_separated(|i| {
let function = i.expect_function()?; let function = i.expect_function()?.clone();
let (color, mut p) = i.parse_nested_block(|i| { let (color, mut p) = i.parse_nested_block(|i| {
let p = match_ignore_ascii_case! { &function, let p = match_ignore_ascii_case! { &function,
"color-stop" => { "color-stop" => {
@ -879,7 +879,7 @@ impl Parse for PaintWorklet {
input.parse_nested_block(|i| { input.parse_nested_block(|i| {
let name = i.expect_ident()?; let name = i.expect_ident()?;
Ok(PaintWorklet { Ok(PaintWorklet {
name: Atom::from(Cow::from(name)), name: Atom::from(name.as_ref()),
}) })
}) })
} }
@ -890,7 +890,7 @@ impl Parse for MozImageRect {
input.try(|i| i.expect_function_matching("-moz-image-rect"))?; input.try(|i| i.expect_function_matching("-moz-image-rect"))?;
input.parse_nested_block(|i| { input.parse_nested_block(|i| {
let string = i.expect_url_or_string()?; let string = i.expect_url_or_string()?;
let url = SpecifiedUrl::parse_from_string(string.into_owned(), context)?; let url = SpecifiedUrl::parse_from_string(string.as_ref().to_owned(), context)?;
i.expect_comma()?; i.expect_comma()?;
let top = NumberOrPercentage::parse_non_negative(context, i)?; let top = NumberOrPercentage::parse_non_negative(context, i)?;
i.expect_comma()?; i.expect_comma()?;

View file

@ -619,10 +619,13 @@ impl Length {
num_context: AllowedLengthType, num_context: AllowedLengthType,
allow_quirks: AllowQuirks) allow_quirks: AllowQuirks)
-> Result<Length, ParseError<'i>> { -> Result<Length, ParseError<'i>> {
// FIXME: remove early returns when lifetimes are non-lexical
{
let token = input.next()?; let token = input.next()?;
match token { match *token {
Token::Dimension { value, ref unit, .. } if num_context.is_ok(context.parsing_mode, value) => { Token::Dimension { value, ref unit, .. } if num_context.is_ok(context.parsing_mode, value) => {
Length::parse_dimension(context, value, unit) return Length::parse_dimension(context, value, unit)
.map_err(|()| BasicParseError::UnexpectedToken(token.clone()).into())
} }
Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => { Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => {
if value != 0. && if value != 0. &&
@ -630,16 +633,16 @@ impl Length {
!allow_quirks.allowed(context.quirks_mode) { !allow_quirks.allowed(context.quirks_mode) {
return Err(StyleParseError::UnspecifiedError.into()) return Err(StyleParseError::UnspecifiedError.into())
} }
Ok(Length::NoCalc(NoCalcLength::Absolute(AbsoluteLength::Px(value)))) return Ok(Length::NoCalc(NoCalcLength::Absolute(AbsoluteLength::Px(value))))
}, },
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}
return input.parse_nested_block(|input| { ref token => return Err(BasicParseError::UnexpectedToken(token.clone()).into())
}
}
input.parse_nested_block(|input| {
CalcNode::parse_length(context, input, num_context).map(|calc| Length::Calc(Box::new(calc))) CalcNode::parse_length(context, input, num_context).map(|calc| Length::Calc(Box::new(calc)))
}) })
} }
_ => Err(())
}.map_err(|()| BasicParseError::UnexpectedToken(token).into())
}
/// Parse a non-negative length /// Parse a non-negative length
#[inline] #[inline]
@ -761,11 +764,15 @@ impl Percentage {
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
num_context: AllowedNumericType, num_context: AllowedNumericType,
) -> Result<Self, ParseError<'i>> { ) -> Result<Self, ParseError<'i>> {
match input.next()? { // FIXME: remove early returns when lifetimes are non-lexical
match *input.next()? {
Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => { Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => {
Ok(Percentage::new(unit_value)) return Ok(Percentage::new(unit_value))
} }
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}
ref t => return Err(BasicParseError::UnexpectedToken(t.clone()).into())
}
let result = input.parse_nested_block(|i| { let result = input.parse_nested_block(|i| {
CalcNode::parse_percentage(context, i) CalcNode::parse_percentage(context, i)
})?; })?;
@ -777,9 +784,6 @@ impl Percentage {
calc_clamping_mode: Some(num_context), calc_clamping_mode: Some(num_context),
}) })
} }
t => Err(BasicParseError::UnexpectedToken(t).into())
}
}
/// Parses a percentage token, but rejects it if it's negative. /// Parses a percentage token, but rejects it if it's negative.
pub fn parse_non_negative<'i, 't>(context: &ParserContext, pub fn parse_non_negative<'i, 't>(context: &ParserContext,
@ -876,11 +880,15 @@ impl LengthOrPercentage {
num_context: AllowedLengthType, num_context: AllowedLengthType,
allow_quirks: AllowQuirks) allow_quirks: AllowQuirks)
-> Result<LengthOrPercentage, ParseError<'i>> -> Result<LengthOrPercentage, ParseError<'i>>
{
// FIXME: remove early returns when lifetimes are non-lexical
{ {
let token = input.next()?; let token = input.next()?;
match token { match *token {
Token::Dimension { value, ref unit, .. } if num_context.is_ok(context.parsing_mode, value) => { Token::Dimension { value, ref unit, .. } if num_context.is_ok(context.parsing_mode, value) => {
NoCalcLength::parse_dimension(context, value, unit).map(LengthOrPercentage::Length) return NoCalcLength::parse_dimension(context, value, unit)
.map(LengthOrPercentage::Length)
.map_err(|()| BasicParseError::UnexpectedToken(token.clone()).into())
} }
Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => { Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => {
return Ok(LengthOrPercentage::Percentage(computed::Percentage(unit_value))) return Ok(LengthOrPercentage::Percentage(computed::Percentage(unit_value)))
@ -889,19 +897,20 @@ impl LengthOrPercentage {
if value != 0. && if value != 0. &&
!context.parsing_mode.allows_unitless_lengths() && !context.parsing_mode.allows_unitless_lengths() &&
!allow_quirks.allowed(context.quirks_mode) { !allow_quirks.allowed(context.quirks_mode) {
Err(()) return Err(BasicParseError::UnexpectedToken(token.clone()).into())
} else { } else {
return Ok(LengthOrPercentage::Length(NoCalcLength::from_px(value))) return Ok(LengthOrPercentage::Length(NoCalcLength::from_px(value)))
} }
} }
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}
_ => return Err(BasicParseError::UnexpectedToken(token.clone()).into())
}
}
let calc = input.parse_nested_block(|i| { let calc = input.parse_nested_block(|i| {
CalcNode::parse_length_or_percentage(context, i, num_context) CalcNode::parse_length_or_percentage(context, i, num_context)
})?; })?;
return Ok(LengthOrPercentage::Calc(Box::new(calc))) Ok(LengthOrPercentage::Calc(Box::new(calc)))
}
_ => Err(())
}.map_err(|()| BasicParseError::UnexpectedToken(token).into())
} }
/// Parse a non-negative length. /// Parse a non-negative length.
@ -1013,13 +1022,17 @@ impl LengthOrPercentageOrAuto {
num_context: AllowedLengthType, num_context: AllowedLengthType,
allow_quirks: AllowQuirks) allow_quirks: AllowQuirks)
-> Result<Self, ParseError<'i>> { -> Result<Self, ParseError<'i>> {
// FIXME: remove early returns when lifetimes are non-lexical
{
let token = input.next()?; let token = input.next()?;
match token { match *token {
Token::Dimension { value, ref unit, .. } if num_context.is_ok(context.parsing_mode, value) => { Token::Dimension { value, ref unit, .. } if num_context.is_ok(context.parsing_mode, value) => {
NoCalcLength::parse_dimension(context, value, unit).map(LengthOrPercentageOrAuto::Length) return NoCalcLength::parse_dimension(context, value, unit)
.map(LengthOrPercentageOrAuto::Length)
.map_err(|()| BasicParseError::UnexpectedToken(token.clone()).into())
} }
Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => { Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => {
Ok(LengthOrPercentageOrAuto::Percentage(computed::Percentage(unit_value))) return Ok(LengthOrPercentageOrAuto::Percentage(computed::Percentage(unit_value)))
} }
Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => { Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => {
if value != 0. && if value != 0. &&
@ -1027,22 +1040,23 @@ impl LengthOrPercentageOrAuto {
!allow_quirks.allowed(context.quirks_mode) { !allow_quirks.allowed(context.quirks_mode) {
return Err(StyleParseError::UnspecifiedError.into()) return Err(StyleParseError::UnspecifiedError.into())
} }
Ok(LengthOrPercentageOrAuto::Length( return Ok(LengthOrPercentageOrAuto::Length(
NoCalcLength::Absolute(AbsoluteLength::Px(value)) NoCalcLength::Absolute(AbsoluteLength::Px(value))
)) ))
} }
Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") => { Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") => {
Ok(LengthOrPercentageOrAuto::Auto) return Ok(LengthOrPercentageOrAuto::Auto)
} }
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}
_ => return Err(BasicParseError::UnexpectedToken(token.clone()).into())
}
}
let calc = input.parse_nested_block(|i| { let calc = input.parse_nested_block(|i| {
CalcNode::parse_length_or_percentage(context, i, num_context) CalcNode::parse_length_or_percentage(context, i, num_context)
})?; })?;
Ok(LengthOrPercentageOrAuto::Calc(Box::new(calc))) Ok(LengthOrPercentageOrAuto::Calc(Box::new(calc)))
} }
_ => Err(())
}.map_err(|()| BasicParseError::UnexpectedToken(token).into())
}
/// Parse a non-negative length, percentage, or auto. /// Parse a non-negative length, percentage, or auto.
#[inline] #[inline]
@ -1111,35 +1125,41 @@ impl LengthOrPercentageOrNone {
num_context: AllowedLengthType, num_context: AllowedLengthType,
allow_quirks: AllowQuirks) allow_quirks: AllowQuirks)
-> Result<LengthOrPercentageOrNone, ParseError<'i>> -> Result<LengthOrPercentageOrNone, ParseError<'i>>
{
// FIXME: remove early returns when lifetimes are non-lexical
{ {
let token = input.next()?; let token = input.next()?;
match token { match *token {
Token::Dimension { value, ref unit, .. } if num_context.is_ok(context.parsing_mode, value) => { Token::Dimension { value, ref unit, .. } if num_context.is_ok(context.parsing_mode, value) => {
NoCalcLength::parse_dimension(context, value, unit).map(LengthOrPercentageOrNone::Length) return NoCalcLength::parse_dimension(context, value, unit)
.map(LengthOrPercentageOrNone::Length)
.map_err(|()| BasicParseError::UnexpectedToken(token.clone()).into())
} }
Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => { Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => {
Ok(LengthOrPercentageOrNone::Percentage(computed::Percentage(unit_value))) return Ok(LengthOrPercentageOrNone::Percentage(computed::Percentage(unit_value)))
} }
Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => { Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => {
if value != 0. && !context.parsing_mode.allows_unitless_lengths() && if value != 0. && !context.parsing_mode.allows_unitless_lengths() &&
!allow_quirks.allowed(context.quirks_mode) { !allow_quirks.allowed(context.quirks_mode) {
return Err(StyleParseError::UnspecifiedError.into()) return Err(StyleParseError::UnspecifiedError.into())
} }
Ok(LengthOrPercentageOrNone::Length( return Ok(LengthOrPercentageOrNone::Length(
NoCalcLength::Absolute(AbsoluteLength::Px(value)) NoCalcLength::Absolute(AbsoluteLength::Px(value))
)) ))
} }
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}
Token::Ident(ref value) if value.eq_ignore_ascii_case("none") => {
return Ok(LengthOrPercentageOrNone::None)
}
_ => return Err(BasicParseError::UnexpectedToken(token.clone()).into())
}
}
let calc = input.parse_nested_block(|i| { let calc = input.parse_nested_block(|i| {
CalcNode::parse_length_or_percentage(context, i, num_context) CalcNode::parse_length_or_percentage(context, i, num_context)
})?; })?;
Ok(LengthOrPercentageOrNone::Calc(Box::new(calc))) Ok(LengthOrPercentageOrNone::Calc(Box::new(calc)))
} }
Token::Ident(ref value) if value.eq_ignore_ascii_case("none") =>
Ok(LengthOrPercentageOrNone::None),
_ => Err(())
}.map_err(|()| BasicParseError::UnexpectedToken(token).into())
}
/// Parse a non-negative LengthOrPercentageOrNone. /// Parse a non-negative LengthOrPercentageOrNone.
#[inline] #[inline]

View file

@ -12,7 +12,6 @@ use cssparser::{Parser, Token, serialize_identifier, BasicParseError};
use parser::{ParserContext, Parse}; use parser::{ParserContext, Parse};
use self::url::SpecifiedUrl; use self::url::SpecifiedUrl;
use std::ascii::AsciiExt; use std::ascii::AsciiExt;
use std::borrow::Cow;
use std::f32; use std::f32;
use std::fmt; use std::fmt;
use style_traits::{ToCss, ParseError, StyleParseError}; use style_traits::{ToCss, ParseError, StyleParseError};
@ -83,7 +82,7 @@ pub use ::gecko::url::*;
impl Parse for SpecifiedUrl { impl Parse for SpecifiedUrl {
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> { fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
let url = input.expect_url()?; let url = input.expect_url()?;
Self::parse_from_string(url.into_owned(), context) Self::parse_from_string(url.as_ref().to_owned(), context)
} }
} }
@ -98,17 +97,18 @@ no_viewport_percentage!(SpecifiedUrl);
/// Parse an `<integer>` value, handling `calc()` correctly. /// Parse an `<integer>` value, handling `calc()` correctly.
pub fn parse_integer<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) pub fn parse_integer<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<Integer, ParseError<'i>> { -> Result<Integer, ParseError<'i>> {
match input.next()? { // FIXME: remove early returns when lifetimes are non-lexical
Token::Number { int_value: Some(v), .. } => Ok(Integer::new(v)), match *input.next()? {
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { Token::Number { int_value: Some(v), .. } => return Ok(Integer::new(v)),
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}
ref t => return Err(BasicParseError::UnexpectedToken(t.clone()).into())
}
let result = input.parse_nested_block(|i| { let result = input.parse_nested_block(|i| {
CalcNode::parse_integer(context, i) CalcNode::parse_integer(context, i)
})?; })?;
Ok(Integer::from_calc(result)) Ok(Integer::from_calc(result))
}
t => Err(BasicParseError::UnexpectedToken(t).into())
}
} }
/// Parse a `<number>` value, handling `calc()` correctly, and without length /// Parse a `<number>` value, handling `calc()` correctly, and without length
@ -123,14 +123,18 @@ pub fn parse_number_with_clamping_mode<'i, 't>(context: &ParserContext,
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
clamping_mode: AllowedNumericType) clamping_mode: AllowedNumericType)
-> Result<Number, ParseError<'i>> { -> Result<Number, ParseError<'i>> {
match input.next()? { // FIXME: remove early returns when lifetimes are non-lexical
match *input.next()? {
Token::Number { value, .. } if clamping_mode.is_ok(context.parsing_mode, value) => { Token::Number { value, .. } if clamping_mode.is_ok(context.parsing_mode, value) => {
Ok(Number { return Ok(Number {
value: value.min(f32::MAX).max(f32::MIN), value: value.min(f32::MAX).max(f32::MIN),
calc_clamping_mode: None, calc_clamping_mode: None,
}) })
}, }
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}
ref t => return Err(BasicParseError::UnexpectedToken(t.clone()).into())
}
let result = input.parse_nested_block(|i| { let result = input.parse_nested_block(|i| {
CalcNode::parse_number(context, i) CalcNode::parse_number(context, i)
})?; })?;
@ -139,9 +143,6 @@ pub fn parse_number_with_clamping_mode<'i, 't>(context: &ParserContext,
value: result.min(f32::MAX).max(f32::MIN), value: result.min(f32::MAX).max(f32::MIN),
calc_clamping_mode: Some(clamping_mode), calc_clamping_mode: Some(clamping_mode),
}) })
}
t => Err(BasicParseError::UnexpectedToken(t).into())
}
} }
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq)] #[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq)]
@ -228,7 +229,8 @@ impl Angle {
impl Parse for Angle { impl Parse for Angle {
/// Parses an angle according to CSS-VALUES § 6.1. /// Parses an angle according to CSS-VALUES § 6.1.
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> { fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
let token = input.next()?; // FIXME: remove clone() when lifetimes are non-lexical
let token = input.next()?.clone();
match token { match token {
Token::Dimension { value, ref unit, .. } => { Token::Dimension { value, ref unit, .. } => {
Angle::parse_dimension(value, unit, /* from_calc = */ false) Angle::parse_dimension(value, unit, /* from_calc = */ false)
@ -237,7 +239,7 @@ impl Parse for Angle {
return input.parse_nested_block(|i| CalcNode::parse_angle(context, i)) return input.parse_nested_block(|i| CalcNode::parse_angle(context, i))
} }
_ => Err(()) _ => Err(())
}.map_err(|()| BasicParseError::UnexpectedToken(token).into()) }.map_err(|()| BasicParseError::UnexpectedToken(token.clone()).into())
} }
} }
@ -268,7 +270,8 @@ impl Angle {
/// https://github.com/w3c/csswg-drafts/issues/1162 is resolved. /// https://github.com/w3c/csswg-drafts/issues/1162 is resolved.
pub fn parse_with_unitless<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) pub fn parse_with_unitless<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<Self, ParseError<'i>> { -> Result<Self, ParseError<'i>> {
let token = input.next()?; // FIXME: remove clone() when lifetimes are non-lexical
let token = input.next()?.clone();
match token { match token {
Token::Dimension { value, ref unit, .. } => { Token::Dimension { value, ref unit, .. } => {
Angle::parse_dimension(value, unit, /* from_calc = */ false) Angle::parse_dimension(value, unit, /* from_calc = */ false)
@ -278,7 +281,7 @@ impl Angle {
return input.parse_nested_block(|i| CalcNode::parse_angle(context, i)) return input.parse_nested_block(|i| CalcNode::parse_angle(context, i))
} }
_ => Err(()) _ => Err(())
}.map_err(|()| BasicParseError::UnexpectedToken(token).into()) }.map_err(|()| BasicParseError::UnexpectedToken(token.clone()).into())
} }
} }
@ -366,26 +369,26 @@ impl Time {
-> Result<Self, ParseError<'i>> { -> Result<Self, ParseError<'i>> {
use style_traits::PARSING_MODE_DEFAULT; use style_traits::PARSING_MODE_DEFAULT;
// FIXME: remove early returns when lifetimes are non-lexical
match input.next() { match input.next() {
// Note that we generally pass ParserContext to is_ok() to check // Note that we generally pass ParserContext to is_ok() to check
// that the ParserMode of the ParserContext allows all numeric // that the ParserMode of the ParserContext allows all numeric
// values for SMIL regardless of clamping_mode, but in this Time // values for SMIL regardless of clamping_mode, but in this Time
// value case, the value does not animate for SMIL at all, so we use // value case, the value does not animate for SMIL at all, so we use
// PARSING_MODE_DEFAULT directly. // PARSING_MODE_DEFAULT directly.
Ok(Token::Dimension { value, ref unit, .. }) if clamping_mode.is_ok(PARSING_MODE_DEFAULT, value) => { Ok(&Token::Dimension { value, ref unit, .. }) if clamping_mode.is_ok(PARSING_MODE_DEFAULT, value) => {
Time::parse_dimension(value, unit, /* from_calc = */ false) return Time::parse_dimension(value, unit, /* from_calc = */ false)
.map_err(|()| StyleParseError::UnspecifiedError.into()) .map_err(|()| StyleParseError::UnspecifiedError.into())
} }
Ok(Token::Function(ref name)) if name.eq_ignore_ascii_case("calc") => { Ok(&Token::Function(ref name)) if name.eq_ignore_ascii_case("calc") => {}
Ok(t) => return Err(BasicParseError::UnexpectedToken(t.clone()).into()),
Err(e) => return Err(e.into())
}
match input.parse_nested_block(|i| CalcNode::parse_time(context, i)) { match input.parse_nested_block(|i| CalcNode::parse_time(context, i)) {
Ok(time) if clamping_mode.is_ok(PARSING_MODE_DEFAULT, time.seconds) => Ok(time), Ok(time) if clamping_mode.is_ok(PARSING_MODE_DEFAULT, time.seconds) => Ok(time),
_ => Err(StyleParseError::UnspecifiedError.into()), _ => Err(StyleParseError::UnspecifiedError.into()),
} }
} }
Ok(t) => Err(BasicParseError::UnexpectedToken(t).into()),
Err(e) => Err(e.into())
}
}
/// Parse <time> that values are non-negative. /// Parse <time> that values are non-negative.
pub fn parse_non_negative<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) pub fn parse_non_negative<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
@ -814,10 +817,7 @@ impl ClipRect {
} }
} }
let func = input.expect_function()?; input.expect_function_matching("rect")?;
if !func.eq_ignore_ascii_case("rect") {
return Err(StyleParseError::UnexpectedFunction(func).into())
}
input.parse_nested_block(|input| { input.parse_nested_block(|input| {
let top = parse_argument(context, input, allow_quirks)?; let top = parse_argument(context, input, allow_quirks)?;
@ -939,20 +939,20 @@ impl Attr {
-> Result<Attr, ParseError<'i>> { -> Result<Attr, ParseError<'i>> {
// Syntax is `[namespace? `|`]? ident` // Syntax is `[namespace? `|`]? ident`
// no spaces allowed // no spaces allowed
let first = input.try(|i| i.expect_ident()).ok(); let first = input.try(|i| i.expect_ident_cloned()).ok();
if let Ok(token) = input.try(|i| i.next_including_whitespace()) { if let Ok(token) = input.try(|i| i.next_including_whitespace().map(|t| t.clone())) {
match token { match token {
Token::Delim('|') => {} Token::Delim('|') => {}
t => return Err(BasicParseError::UnexpectedToken(t).into()), ref t => return Err(BasicParseError::UnexpectedToken(t.clone()).into()),
} }
// must be followed by an ident // must be followed by an ident
let second_token = match input.next_including_whitespace()? { let second_token = match *input.next_including_whitespace()? {
Token::Ident(second) => second, Token::Ident(ref second) => second,
t => return Err(BasicParseError::UnexpectedToken(t).into()), ref t => return Err(BasicParseError::UnexpectedToken(t.clone()).into()),
}; };
let ns_with_id = if let Some(ns) = first { let ns_with_id = if let Some(ns) = first {
let ns = Namespace::from(Cow::from(ns)); let ns = Namespace::from(ns.as_ref());
let id: Result<_, ParseError> = let id: Result<_, ParseError> =
get_id_for_namespace(&ns, context) get_id_for_namespace(&ns, context)
.map_err(|()| StyleParseError::UnspecifiedError.into()); .map_err(|()| StyleParseError::UnspecifiedError.into());
@ -962,14 +962,14 @@ impl Attr {
}; };
return Ok(Attr { return Ok(Attr {
namespace: ns_with_id, namespace: ns_with_id,
attribute: second_token.into_owned(), attribute: second_token.as_ref().to_owned(),
}) })
} }
if let Some(first) = first { if let Some(first) = first {
Ok(Attr { Ok(Attr {
namespace: None, namespace: None,
attribute: first.into_owned(), attribute: first.as_ref().to_owned(),
}) })
} else { } else {
Err(StyleParseError::UnspecifiedError.into()) Err(StyleParseError::UnspecifiedError.into())

View file

@ -73,7 +73,7 @@ impl Parse for LineHeight {
ref ident if ident.eq_ignore_ascii_case("-moz-block-height") => { ref ident if ident.eq_ignore_ascii_case("-moz-block-height") => {
Ok(GenericLineHeight::MozBlockHeight) Ok(GenericLineHeight::MozBlockHeight)
}, },
ident => Err(SelectorParseError::UnexpectedIdent(ident).into()), ident => Err(SelectorParseError::UnexpectedIdent(ident.clone()).into()),
} }
} }
} }

View file

@ -147,7 +147,7 @@ impl Parse for TimingFunction {
if let Ok(keyword) = input.try(TimingKeyword::parse) { if let Ok(keyword) = input.try(TimingKeyword::parse) {
return Ok(GenericTimingFunction::Keyword(keyword)); return Ok(GenericTimingFunction::Keyword(keyword));
} }
if let Ok(ident) = input.try(|i| i.expect_ident()) { if let Ok(ident) = input.try(|i| i.expect_ident_cloned()) {
let position = match_ignore_ascii_case! { &ident, let position = match_ignore_ascii_case! { &ident,
"step-start" => StepPosition::Start, "step-start" => StepPosition::Start,
"step-end" => StepPosition::End, "step-end" => StepPosition::End,
@ -155,7 +155,7 @@ impl Parse for TimingFunction {
}; };
return Ok(GenericTimingFunction::Steps(Integer::new(1), position)); return Ok(GenericTimingFunction::Steps(Integer::new(1), position));
} }
let function = input.expect_function()?; let function = input.expect_function()?.clone();
input.parse_nested_block(move |i| { input.parse_nested_block(move |i| {
(match_ignore_ascii_case! { &function, (match_ignore_ascii_case! { &function,
"cubic-bezier" => { "cubic-bezier" => {
@ -190,7 +190,7 @@ impl Parse for TimingFunction {
} }
}, },
_ => Err(()), _ => Err(()),
}).map_err(|()| StyleParseError::UnexpectedFunction(function).into()) }).map_err(|()| StyleParseError::UnexpectedFunction(function.clone()).into())
}) })
} }
} }

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.17.0" cssparser = "0.18"
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, Token}; use cssparser::{CowRcStr, 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.
@ -87,9 +87,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(CompactCowStr<'i>), BadUrlInDeclarationValueBlock(CowRcStr<'i>),
/// A bad string token in a DVB. /// A bad string token in a DVB.
BadStringInDeclarationValueBlock(CompactCowStr<'i>), BadStringInDeclarationValueBlock(CowRcStr<'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.
@ -101,11 +101,11 @@ pub enum StyleParseError<'i> {
/// A property declaration value had input remaining after successfully parsing. /// A property declaration value had input remaining after successfully parsing.
PropertyDeclarationValueNotExhausted, PropertyDeclarationValueNotExhausted,
/// An unexpected dimension token was encountered. /// An unexpected dimension token was encountered.
UnexpectedDimension(CompactCowStr<'i>), UnexpectedDimension(CowRcStr<'i>),
/// A media query using a ranged expression with no value was encountered. /// A media query using a ranged expression with no value was encountered.
RangedExpressionWithNoValue, RangedExpressionWithNoValue,
/// A function was encountered that was not expected. /// A function was encountered that was not expected.
UnexpectedFunction(CompactCowStr<'i>), UnexpectedFunction(CowRcStr<'i>),
/// @namespace must be before any rule but @charset and @import /// @namespace must be before any rule but @charset and @import
UnexpectedNamespaceRule, UnexpectedNamespaceRule,
/// @import must be before any rule but @charset /// @import must be before any rule but @charset
@ -113,7 +113,7 @@ pub enum StyleParseError<'i> {
/// Unexpected @charset rule encountered. /// Unexpected @charset rule encountered.
UnexpectedCharsetRule, UnexpectedCharsetRule,
/// Unsupported @ rule /// Unsupported @ rule
UnsupportedAtRule(CompactCowStr<'i>), UnsupportedAtRule(CowRcStr<'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. /// An unexpected token was found within a namespace rule.
@ -124,13 +124,13 @@ pub enum StyleParseError<'i> {
#[derive(Eq, PartialEq, Clone, Debug)] #[derive(Eq, PartialEq, Clone, Debug)]
pub enum PropertyDeclarationParseError<'i> { pub enum PropertyDeclarationParseError<'i> {
/// The property declaration was for an unknown property. /// The property declaration was for an unknown property.
UnknownProperty(CompactCowStr<'i>), UnknownProperty(CowRcStr<'i>),
/// An unknown vendor-specific identifier was encountered. /// An unknown vendor-specific identifier was encountered.
UnknownVendorProperty, UnknownVendorProperty,
/// 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(CompactCowStr<'i>), InvalidValue(CowRcStr<'i>),
/// 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

@ -409,7 +409,7 @@ macro_rules! __define_css_keyword_enum__actual {
Self::from_ident(&ident) Self::from_ident(&ident)
.map_err(|()| ::cssparser::ParseError::Basic( .map_err(|()| ::cssparser::ParseError::Basic(
::cssparser::BasicParseError::UnexpectedToken( ::cssparser::BasicParseError::UnexpectedToken(
::cssparser::Token::Ident(ident)))) ::cssparser::Token::Ident(ident.clone()))))
} }
/// Parse this property from an already-tokenized identifier. /// Parse this property from an already-tokenized identifier.

View file

@ -154,7 +154,7 @@ impl Zoom {
use cssparser::Token; use cssparser::Token;
use values::specified::AllowedLengthType::NonNegative; use values::specified::AllowedLengthType::NonNegative;
match input.next()? { match *input.next()? {
// TODO: This parse() method should take ParserContext as an // TODO: This parse() method should take ParserContext as an
// argument, and pass ParsingMode owned by the ParserContext to // argument, and pass ParsingMode owned by the ParserContext to
// is_ok() instead of using PARSING_MODE_DEFAULT directly. // is_ok() instead of using PARSING_MODE_DEFAULT directly.
@ -168,7 +168,7 @@ impl Zoom {
Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") => { Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") => {
Ok(Zoom::Auto) Ok(Zoom::Auto)
} }
t => Err(CssParseError::Basic(BasicParseError::UnexpectedToken(t))) ref t => Err(CssParseError::Basic(BasicParseError::UnexpectedToken(t.clone())))
} }
} }

View file

@ -16,7 +16,7 @@ gecko_debug = ["style/gecko_debug"]
[dependencies] [dependencies]
atomic_refcell = "0.1" atomic_refcell = "0.1"
cssparser = "0.17.0" cssparser = "0.18"
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

@ -7,7 +7,7 @@
#![allow(unsafe_code)] #![allow(unsafe_code)]
use cssparser::{Parser, SourcePosition, ParseError as CssParseError, Token, BasicParseError}; use cssparser::{Parser, SourcePosition, ParseError as CssParseError, Token, BasicParseError};
use cssparser::CompactCowStr; use cssparser::CowRcStr;
use selectors::parser::SelectorParseError; 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};
@ -43,15 +43,15 @@ impl Drop for ErrorReporter {
} }
enum ErrorString<'a> { enum ErrorString<'a> {
Snippet(CompactCowStr<'a>), Snippet(CowRcStr<'a>),
Ident(CompactCowStr<'a>), Ident(CowRcStr<'a>),
UnexpectedToken(Token<'a>), UnexpectedToken(Token<'a>),
} }
impl<'a> ErrorString<'a> { impl<'a> ErrorString<'a> {
fn into_str(self) -> String { fn into_str(self) -> String {
match self { match self {
ErrorString::Snippet(s) => s.into_owned(), ErrorString::Snippet(s) => s.as_ref().to_owned(),
ErrorString::Ident(i) => escape_css_ident(&i), ErrorString::Ident(i) => escape_css_ident(&i),
ErrorString::UnexpectedToken(t) => token_to_str(t), ErrorString::UnexpectedToken(t) => token_to_str(t),
} }
@ -186,13 +186,13 @@ fn token_to_str<'a>(t: Token<'a>) -> String {
} }
trait ErrorHelpers<'a> { trait ErrorHelpers<'a> {
fn error_data(self) -> (CompactCowStr<'a>, ParseError<'a>); fn error_data(self) -> (CowRcStr<'a>, ParseError<'a>);
fn error_param(self) -> ErrorString<'a>; fn error_param(self) -> ErrorString<'a>;
fn to_gecko_message(&self) -> &'static [u8]; fn to_gecko_message(&self) -> &'static [u8];
} }
impl<'a> ErrorHelpers<'a> for ContextualParseError<'a> { impl<'a> ErrorHelpers<'a> for ContextualParseError<'a> {
fn error_data(self) -> (CompactCowStr<'a>, ParseError<'a>) { fn error_data(self) -> (CowRcStr<'a>, ParseError<'a>) {
match self { match self {
ContextualParseError::UnsupportedPropertyDeclaration(s, err) | ContextualParseError::UnsupportedPropertyDeclaration(s, err) |
ContextualParseError::UnsupportedFontFaceDescriptor(s, err) | ContextualParseError::UnsupportedFontFaceDescriptor(s, err) |

View file

@ -10,7 +10,7 @@ path = "lib.rs"
doctest = false doctest = false
[dependencies] [dependencies]
cssparser = "0.17.0" cssparser = "0.18"
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.17.0" cssparser = "0.18"
euclid = "0.15" euclid = "0.15"
html5ever = "0.18" html5ever = "0.18"
parking_lot = "0.4" parking_lot = "0.4"

View file

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