mirror of
https://github.com/servo/servo.git
synced 2025-08-02 20:20:14 +01:00
Auto merge of #18808 - servo:error-location_, r=emilio
Use the current parser location for CSS error … rather than the start location of the current construct. This likely places the error just *after* of the unexpected token whereas before would be best, but that’s likely a much bigger change. See https://bugzilla.mozilla.org/show_bug.cgi?id=1378861 <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/18808) <!-- Reviewable:end -->
This commit is contained in:
commit
c79a54dbd9
91 changed files with 1146 additions and 926 deletions
28
Cargo.lock
generated
28
Cargo.lock
generated
|
@ -309,7 +309,7 @@ dependencies = [
|
||||||
"azure 0.21.2 (git+https://github.com/servo/rust-azure)",
|
"azure 0.21.2 (git+https://github.com/servo/rust-azure)",
|
||||||
"canvas_traits 0.0.1",
|
"canvas_traits 0.0.1",
|
||||||
"compositing 0.0.1",
|
"compositing 0.0.1",
|
||||||
"cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.15.3 (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)",
|
||||||
"gleam 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gleam 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -325,7 +325,7 @@ dependencies = [
|
||||||
name = "canvas_traits"
|
name = "canvas_traits"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.15.3 (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)",
|
||||||
|
@ -573,7 +573,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cssparser"
|
name = "cssparser"
|
||||||
version = "0.21.2"
|
version = "0.22.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)",
|
||||||
|
@ -1060,7 +1060,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.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.22.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)",
|
||||||
|
@ -1130,7 +1130,7 @@ dependencies = [
|
||||||
name = "gfx_tests"
|
name = "gfx_tests"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.22.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",
|
||||||
|
@ -1737,7 +1737,7 @@ name = "malloc_size_of"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hashglobe 0.1.0",
|
"hashglobe 0.1.0",
|
||||||
"servo_arc 0.0.1",
|
"servo_arc 0.0.1",
|
||||||
|
@ -2594,7 +2594,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.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.22.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",
|
||||||
|
@ -2667,7 +2667,7 @@ dependencies = [
|
||||||
"app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"app_units 0.5.6 (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.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.15.3 (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)",
|
||||||
|
@ -2740,7 +2740,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.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.22.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)",
|
||||||
"malloc_size_of 0.0.1",
|
"malloc_size_of 0.0.1",
|
||||||
|
@ -3145,7 +3145,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.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.22.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.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"fallible 0.0.1",
|
"fallible 0.0.1",
|
||||||
|
@ -3207,7 +3207,7 @@ version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"app_units 0.5.6 (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.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"html5ever 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"html5ever 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -3229,7 +3229,7 @@ version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"app_units 0.5.6 (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.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.15.3 (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)",
|
||||||
|
@ -3247,7 +3247,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.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.22.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.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"geckoservo 0.0.1",
|
"geckoservo 0.0.1",
|
||||||
|
@ -3836,7 +3836,7 @@ dependencies = [
|
||||||
"checksum core-foundation-sys 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bc9fb3d6cb663e6fd7cf1c63f9b144ee2b1e4a78595a0451dd34bff85b9a3387"
|
"checksum core-foundation-sys 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bc9fb3d6cb663e6fd7cf1c63f9b144ee2b1e4a78595a0451dd34bff85b9a3387"
|
||||||
"checksum core-graphics 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2fd47addfc77b7e574d24e5434f95bb64a863769dfd4f1d451ca4ff5530ba01a"
|
"checksum core-graphics 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2fd47addfc77b7e574d24e5434f95bb64a863769dfd4f1d451ca4ff5530ba01a"
|
||||||
"checksum core-text 7.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2a23bef779fab70e5e6af23e36eed03a48e1c1687dea8929505d405ea48d1f5e"
|
"checksum core-text 7.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2a23bef779fab70e5e6af23e36eed03a48e1c1687dea8929505d405ea48d1f5e"
|
||||||
"checksum cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)" = "05012fcdbdeb4c6f59f67db47c1f879929339274a691ee1fb90c26b297783629"
|
"checksum cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44313341610282488e1156ad1fedebca51c54766c87a041d0287b10499c04ba1"
|
||||||
"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 darling 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9861a8495606435477df581bc858ccf15a3469747edf175b94a4704fd9aaedac"
|
"checksum darling 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9861a8495606435477df581bc858ccf15a3469747edf175b94a4704fd9aaedac"
|
||||||
"checksum darling_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1486a8b00b45062c997f767738178b43219133dd0c8c826cb811e60563810821"
|
"checksum darling_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1486a8b00b45062c997f767738178b43219133dd0c8c826cb811e60563810821"
|
||||||
|
|
|
@ -13,7 +13,7 @@ path = "lib.rs"
|
||||||
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"}
|
||||||
compositing = {path = "../compositing"}
|
compositing = {path = "../compositing"}
|
||||||
cssparser = "0.21.1"
|
cssparser = "0.22.0"
|
||||||
euclid = "0.15"
|
euclid = "0.15"
|
||||||
fnv = "1.0"
|
fnv = "1.0"
|
||||||
gleam = "0.4"
|
gleam = "0.4"
|
||||||
|
|
|
@ -10,7 +10,7 @@ name = "canvas_traits"
|
||||||
path = "lib.rs"
|
path = "lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cssparser = "0.21.1"
|
cssparser = "0.22.0"
|
||||||
euclid = "0.15"
|
euclid = "0.15"
|
||||||
heapsize = "0.4"
|
heapsize = "0.4"
|
||||||
heapsize_derive = "0.1"
|
heapsize_derive = "0.1"
|
||||||
|
|
|
@ -10,7 +10,7 @@ path = "lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
app_units = "0.5.5"
|
app_units = "0.5.5"
|
||||||
cssparser = "0.21.1"
|
cssparser = "0.22.0"
|
||||||
euclid = "0.15"
|
euclid = "0.15"
|
||||||
hashglobe = { path = "../hashglobe" }
|
hashglobe = { path = "../hashglobe" }
|
||||||
servo_arc = { path = "../servo_arc" }
|
servo_arc = { path = "../servo_arc" }
|
||||||
|
|
|
@ -33,7 +33,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.21.1"
|
cssparser = "0.22.0"
|
||||||
deny_public_fields = {path = "../deny_public_fields"}
|
deny_public_fields = {path = "../deny_public_fields"}
|
||||||
devtools_traits = {path = "../devtools_traits"}
|
devtools_traits = {path = "../devtools_traits"}
|
||||||
dom_struct = {path = "../dom_struct"}
|
dom_struct = {path = "../dom_struct"}
|
||||||
|
|
|
@ -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.21.1"
|
cssparser = "0.22.0"
|
||||||
euclid = "0.15"
|
euclid = "0.15"
|
||||||
gfx_traits = {path = "../gfx_traits"}
|
gfx_traits = {path = "../gfx_traits"}
|
||||||
heapsize = "0.4"
|
heapsize = "0.4"
|
||||||
|
|
|
@ -25,7 +25,7 @@ unstable = []
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bitflags = "0.7"
|
bitflags = "0.7"
|
||||||
matches = "0.1"
|
matches = "0.1"
|
||||||
cssparser = "0.21.1"
|
cssparser = "0.22.0"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
fnv = "1.0"
|
fnv = "1.0"
|
||||||
malloc_size_of = { path = "../malloc_size_of" }
|
malloc_size_of = { path = "../malloc_size_of" }
|
||||||
|
|
|
@ -7,7 +7,8 @@ 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, CowRcStr, Delimiter};
|
use cssparser::{ParseError, ParseErrorKind, BasicParseError, BasicParseErrorKind};
|
||||||
|
use cssparser::{SourceLocation, CowRcStr, Delimiter};
|
||||||
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;
|
||||||
|
@ -46,8 +47,10 @@ fn to_ascii_lowercase(s: &str) -> Cow<str> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type SelectorParseError<'i> = ParseError<'i, SelectorParseErrorKind<'i>>;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum SelectorParseError<'i, T> {
|
pub enum SelectorParseErrorKind<'i> {
|
||||||
PseudoElementInComplexSelector,
|
PseudoElementInComplexSelector,
|
||||||
NoQualifiedNameInAttributeSelector(Token<'i>),
|
NoQualifiedNameInAttributeSelector(Token<'i>),
|
||||||
EmptySelector,
|
EmptySelector,
|
||||||
|
@ -66,13 +69,6 @@ pub enum SelectorParseError<'i, T> {
|
||||||
ExplicitNamespaceUnexpectedToken(Token<'i>),
|
ExplicitNamespaceUnexpectedToken(Token<'i>),
|
||||||
ClassNeedsIdent(Token<'i>),
|
ClassNeedsIdent(Token<'i>),
|
||||||
EmptyNegation,
|
EmptyNegation,
|
||||||
Custom(T),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T> Into<ParseError<'a, SelectorParseError<'a, T>>> for SelectorParseError<'a, T> {
|
|
||||||
fn into(self) -> ParseError<'a, SelectorParseError<'a, T>> {
|
|
||||||
ParseError::Custom(self)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! with_all_bounds {
|
macro_rules! with_all_bounds {
|
||||||
|
@ -128,7 +124,7 @@ with_bounds! {
|
||||||
|
|
||||||
pub trait Parser<'i> {
|
pub trait Parser<'i> {
|
||||||
type Impl: SelectorImpl;
|
type Impl: SelectorImpl;
|
||||||
type Error: 'i;
|
type Error: 'i + From<SelectorParseErrorKind<'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.
|
||||||
|
@ -138,31 +134,32 @@ pub trait Parser<'i> {
|
||||||
|
|
||||||
/// 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: CowRcStr<'i>)
|
fn parse_non_ts_pseudo_class(&self, location: SourceLocation, name: CowRcStr<'i>)
|
||||||
-> Result<<Self::Impl as SelectorImpl>::NonTSPseudoClass,
|
-> Result<<Self::Impl as SelectorImpl>::NonTSPseudoClass,
|
||||||
ParseError<'i, SelectorParseError<'i, Self::Error>>> {
|
ParseError<'i, Self::Error>>
|
||||||
Err(ParseError::Custom(SelectorParseError::UnsupportedPseudoClassOrElement(name)))
|
{
|
||||||
|
Err(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_non_ts_functional_pseudo_class<'t>
|
fn parse_non_ts_functional_pseudo_class<'t>
|
||||||
(&self, name: CowRcStr<'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, Self::Error>>
|
||||||
ParseError<'i, SelectorParseError<'i, Self::Error>>>
|
|
||||||
{
|
{
|
||||||
Err(ParseError::Custom(SelectorParseError::UnsupportedPseudoClassOrElement(name)))
|
Err(arguments.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_pseudo_element(&self, name: CowRcStr<'i>)
|
fn parse_pseudo_element(&self, location: SourceLocation, name: CowRcStr<'i>)
|
||||||
-> Result<<Self::Impl as SelectorImpl>::PseudoElement,
|
-> Result<<Self::Impl as SelectorImpl>::PseudoElement,
|
||||||
ParseError<'i, SelectorParseError<'i, Self::Error>>> {
|
ParseError<'i, Self::Error>>
|
||||||
Err(ParseError::Custom(SelectorParseError::UnsupportedPseudoClassOrElement(name)))
|
{
|
||||||
|
Err(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_functional_pseudo_element<'t>
|
fn parse_functional_pseudo_element<'t>
|
||||||
(&self, name: CowRcStr<'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, Self::Error>>
|
||||||
ParseError<'i, SelectorParseError<'i, Self::Error>>> {
|
{
|
||||||
Err(ParseError::Custom(SelectorParseError::UnsupportedPseudoClassOrElement(name)))
|
Err(arguments.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_namespace(&self) -> Option<<Self::Impl as SelectorImpl>::NamespaceUrl> {
|
fn default_namespace(&self) -> Option<<Self::Impl as SelectorImpl>::NamespaceUrl> {
|
||||||
|
@ -183,9 +180,9 @@ impl<Impl: SelectorImpl> SelectorList<Impl> {
|
||||||
/// https://drafts.csswg.org/selectors/#grouping
|
/// https://drafts.csswg.org/selectors/#grouping
|
||||||
///
|
///
|
||||||
/// Return the Selectors or Err if there is an invalid selector.
|
/// Return the Selectors or Err if there is an invalid selector.
|
||||||
pub fn parse<'i, 't, P, E>(parser: &P, input: &mut CssParser<'i, 't>)
|
pub fn parse<'i, 't, P>(parser: &P, input: &mut CssParser<'i, 't>)
|
||||||
-> Result<Self, ParseError<'i, SelectorParseError<'i, E>>>
|
-> Result<Self, ParseError<'i, P::Error>>
|
||||||
where P: Parser<'i, Impl=Impl, Error=E> {
|
where P: Parser<'i, Impl=Impl> {
|
||||||
let mut values = SmallVec::new();
|
let mut values = SmallVec::new();
|
||||||
loop {
|
loop {
|
||||||
values.push(input.parse_until_before(Delimiter::Comma, |input| parse_selector(parser, input))?);
|
values.push(input.parse_until_before(Delimiter::Comma, |input| parse_selector(parser, input))?);
|
||||||
|
@ -1052,24 +1049,28 @@ fn display_to_css_identifier<T: Display, W: fmt::Write>(x: &T, dest: &mut W) ->
|
||||||
/// selector : simple_selector_sequence [ combinator simple_selector_sequence ]* ;
|
/// selector : simple_selector_sequence [ combinator simple_selector_sequence ]* ;
|
||||||
///
|
///
|
||||||
/// `Err` means invalid selector.
|
/// `Err` means invalid selector.
|
||||||
fn parse_selector<'i, 't, P, E, Impl>(
|
fn parse_selector<'i, 't, P, Impl>(
|
||||||
parser: &P,
|
parser: &P,
|
||||||
input: &mut CssParser<'i, 't>)
|
input: &mut CssParser<'i, 't>)
|
||||||
-> Result<Selector<Impl>, ParseError<'i, SelectorParseError<'i, E>>>
|
-> Result<Selector<Impl>, ParseError<'i, P::Error>>
|
||||||
where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl
|
where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl
|
||||||
{
|
{
|
||||||
let mut builder = SelectorBuilder::default();
|
let mut builder = SelectorBuilder::default();
|
||||||
|
|
||||||
let mut parsed_pseudo_element;
|
let mut has_pseudo_element;
|
||||||
'outer_loop: loop {
|
'outer_loop: loop {
|
||||||
// Parse a sequence of simple selectors.
|
// Parse a sequence of simple selectors.
|
||||||
parsed_pseudo_element = match parse_compound_selector(parser, input, &mut builder) {
|
has_pseudo_element = match parse_compound_selector(parser, input, &mut builder)? {
|
||||||
Ok(result) => result,
|
Some(has_pseudo_element) => has_pseudo_element,
|
||||||
Err(ParseError::Custom(SelectorParseError::EmptySelector)) if builder.has_combinators() =>
|
None => {
|
||||||
return Err(SelectorParseError::DanglingCombinator.into()),
|
return Err(input.new_custom_error(if builder.has_combinators() {
|
||||||
Err(e) => return Err(e),
|
SelectorParseErrorKind::DanglingCombinator
|
||||||
|
} else {
|
||||||
|
SelectorParseErrorKind::EmptySelector
|
||||||
|
}))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
if parsed_pseudo_element {
|
if has_pseudo_element {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1107,18 +1108,18 @@ fn parse_selector<'i, 't, P, E, Impl>(
|
||||||
builder.push_combinator(combinator);
|
builder.push_combinator(combinator);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Selector(builder.build(parsed_pseudo_element)))
|
Ok(Selector(builder.build(has_pseudo_element)))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Impl: SelectorImpl> Selector<Impl> {
|
impl<Impl: SelectorImpl> Selector<Impl> {
|
||||||
/// Parse a selector, without any pseudo-element.
|
/// Parse a selector, without any pseudo-element.
|
||||||
pub fn parse<'i, 't, P, E>(parser: &P, input: &mut CssParser<'i, 't>)
|
pub fn parse<'i, 't, P>(parser: &P, input: &mut CssParser<'i, 't>)
|
||||||
-> Result<Self, ParseError<'i, SelectorParseError<'i, E>>>
|
-> Result<Self, ParseError<'i, P::Error>>
|
||||||
where P: Parser<'i, Impl=Impl, Error=E>
|
where P: Parser<'i, Impl=Impl>
|
||||||
{
|
{
|
||||||
let selector = parse_selector(parser, input)?;
|
let selector = parse_selector(parser, input)?;
|
||||||
if selector.has_pseudo_element() {
|
if selector.has_pseudo_element() {
|
||||||
return Err(ParseError::Custom(SelectorParseError::PseudoElementInComplexSelector))
|
return Err(input.new_custom_error(SelectorParseErrorKind::PseudoElementInComplexSelector))
|
||||||
}
|
}
|
||||||
Ok(selector)
|
Ok(selector)
|
||||||
}
|
}
|
||||||
|
@ -1127,14 +1128,14 @@ impl<Impl: SelectorImpl> Selector<Impl> {
|
||||||
/// * `Err(())`: Invalid selector, abort
|
/// * `Err(())`: Invalid selector, abort
|
||||||
/// * `Ok(false)`: Not a type selector, could be something else. `input` was not consumed.
|
/// * `Ok(false)`: Not a type selector, could be something else. `input` was not consumed.
|
||||||
/// * `Ok(true)`: Length 0 (`*|*`), 1 (`*|E` or `ns|*`) or 2 (`|E` or `ns|E`)
|
/// * `Ok(true)`: Length 0 (`*|*`), 1 (`*|E` or `ns|*`) or 2 (`|E` or `ns|E`)
|
||||||
fn parse_type_selector<'i, 't, P, E, Impl, S>(parser: &P, input: &mut CssParser<'i, 't>, sink: &mut S)
|
fn parse_type_selector<'i, 't, P, Impl, S>(parser: &P, input: &mut CssParser<'i, 't>, sink: &mut S)
|
||||||
-> Result<bool, ParseError<'i, SelectorParseError<'i, E>>>
|
-> Result<bool, ParseError<'i, P::Error>>
|
||||||
where P: Parser<'i, Impl=Impl, Error=E>,
|
where P: Parser<'i, Impl=Impl>,
|
||||||
Impl: SelectorImpl,
|
Impl: SelectorImpl,
|
||||||
S: Push<Component<Impl>>,
|
S: Push<Component<Impl>>,
|
||||||
{
|
{
|
||||||
match parse_qualified_name(parser, input, /* in_attr_selector = */ false) {
|
match parse_qualified_name(parser, input, /* in_attr_selector = */ false) {
|
||||||
Err(ParseError::Basic(BasicParseError::EndOfInput)) |
|
Err(ParseError { kind: ParseErrorKind::Basic(BasicParseErrorKind::EndOfInput), .. }) |
|
||||||
Ok(OptionalQName::None(_)) => Ok(false),
|
Ok(OptionalQName::None(_)) => Ok(false),
|
||||||
Ok(OptionalQName::Some(namespace, local_name)) => {
|
Ok(OptionalQName::Some(namespace, local_name)) => {
|
||||||
match namespace {
|
match namespace {
|
||||||
|
@ -1214,12 +1215,11 @@ enum OptionalQName<'i, Impl: SelectorImpl> {
|
||||||
/// * `Ok(None(token))`: Not a simple selector, could be something else. `input` was not consumed,
|
/// * `Ok(None(token))`: Not a simple selector, could be something else. `input` was not consumed,
|
||||||
/// but the token is still returned.
|
/// but the token is still returned.
|
||||||
/// * `Ok(Some(namespace, local_name))`: `None` for the local name means a `*` universal selector
|
/// * `Ok(Some(namespace, local_name))`: `None` for the local name means a `*` universal selector
|
||||||
fn parse_qualified_name<'i, 't, P, E, Impl>
|
fn parse_qualified_name<'i, 't, P, Impl>
|
||||||
(parser: &P, input: &mut CssParser<'i, 't>,
|
(parser: &P, input: &mut CssParser<'i, 't>,
|
||||||
in_attr_selector: bool)
|
in_attr_selector: bool)
|
||||||
-> Result<OptionalQName<'i, Impl>,
|
-> Result<OptionalQName<'i, Impl>, ParseError<'i, P::Error>>
|
||||||
ParseError<'i, SelectorParseError<'i, E>>>
|
where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl
|
||||||
where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl
|
|
||||||
{
|
{
|
||||||
let default_namespace = |local_name| {
|
let default_namespace = |local_name| {
|
||||||
let namespace = match parser.default_namespace() {
|
let namespace = match parser.default_namespace() {
|
||||||
|
@ -1230,16 +1230,25 @@ 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| {
|
||||||
|
let location = input.current_source_location();
|
||||||
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(OptionalQName::Some(namespace, None))
|
Ok(OptionalQName::Some(namespace, None))
|
||||||
},
|
}
|
||||||
Ok(&Token::Ident(ref local_name)) => {
|
Ok(&Token::Ident(ref local_name)) => {
|
||||||
Ok(OptionalQName::Some(namespace, Some(local_name.clone())))
|
Ok(OptionalQName::Some(namespace, Some(local_name.clone())))
|
||||||
},
|
}
|
||||||
Ok(t) if in_attr_selector => Err(SelectorParseError::InvalidQualNameInAttr(t.clone()).into()),
|
Ok(t) if in_attr_selector => {
|
||||||
Ok(t) => Err(SelectorParseError::ExplicitNamespaceUnexpectedToken(t.clone()).into()),
|
Err(location.new_custom_error(
|
||||||
Err(e) => Err(ParseError::Basic(e)),
|
SelectorParseErrorKind::InvalidQualNameInAttr(t.clone())
|
||||||
|
))
|
||||||
|
}
|
||||||
|
Ok(t) => {
|
||||||
|
Err(location.new_custom_error(
|
||||||
|
SelectorParseErrorKind::ExplicitNamespaceUnexpectedToken(t.clone())
|
||||||
|
))
|
||||||
|
}
|
||||||
|
Err(e) => Err(e.into()),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1252,8 +1261,8 @@ fn parse_qualified_name<'i, 't, P, E, Impl>
|
||||||
Ok(&Token::Delim('|')) => {
|
Ok(&Token::Delim('|')) => {
|
||||||
let prefix = value.as_ref().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(after_ident.source_location().new_custom_error(
|
||||||
SelectorParseError::ExpectedNamespace(value)))?;
|
SelectorParseErrorKind::ExpectedNamespace(value)))?;
|
||||||
explicit_namespace(input, QNamePrefix::ExplicitNamespace(prefix, url))
|
explicit_namespace(input, QNamePrefix::ExplicitNamespace(prefix, url))
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -1277,8 +1286,10 @@ fn parse_qualified_name<'i, 't, P, E, Impl>
|
||||||
input.reset(&after_star);
|
input.reset(&after_star);
|
||||||
if in_attr_selector {
|
if in_attr_selector {
|
||||||
match result {
|
match result {
|
||||||
Ok(t) => Err(SelectorParseError::ExpectedBarInAttr(t).into()),
|
Ok(t) => Err(after_star.source_location().new_custom_error(
|
||||||
Err(e) => Err(ParseError::Basic(e)),
|
SelectorParseErrorKind::ExpectedBarInAttr(t)
|
||||||
|
)),
|
||||||
|
Err(e) => Err(e.into()),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
default_namespace(None)
|
default_namespace(None)
|
||||||
|
@ -1301,16 +1312,18 @@ fn parse_qualified_name<'i, 't, P, E, Impl>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn parse_attribute_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParser<'i, 't>)
|
fn parse_attribute_selector<'i, 't, P, Impl>(parser: &P, input: &mut CssParser<'i, 't>)
|
||||||
-> Result<Component<Impl>,
|
-> Result<Component<Impl>, ParseError<'i, P::Error>>
|
||||||
ParseError<'i, SelectorParseError<'i, E>>>
|
where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl
|
||||||
where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl
|
|
||||||
{
|
{
|
||||||
let namespace;
|
let namespace;
|
||||||
let local_name;
|
let local_name;
|
||||||
match parse_qualified_name(parser, input, /* in_attr_selector = */ true)? {
|
match parse_qualified_name(parser, input, /* in_attr_selector = */ true)? {
|
||||||
OptionalQName::None(t) =>
|
OptionalQName::None(t) => {
|
||||||
return Err(ParseError::Custom(SelectorParseError::NoQualifiedNameInAttributeSelector(t))),
|
return Err(input.new_custom_error(
|
||||||
|
SelectorParseErrorKind::NoQualifiedNameInAttributeSelector(t)
|
||||||
|
))
|
||||||
|
}
|
||||||
OptionalQName::Some(_, None) => unreachable!(),
|
OptionalQName::Some(_, None) => unreachable!(),
|
||||||
OptionalQName::Some(ns, Some(ln)) => {
|
OptionalQName::Some(ns, Some(ln)) => {
|
||||||
local_name = ln;
|
local_name = ln;
|
||||||
|
@ -1333,6 +1346,7 @@ fn parse_attribute_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParse
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let location = input.current_source_location();
|
||||||
let operator = match input.next() {
|
let operator = match input.next() {
|
||||||
// [foo]
|
// [foo]
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
|
@ -1366,13 +1380,16 @@ fn parse_attribute_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParse
|
||||||
Ok(&Token::SubstringMatch) => AttrSelectorOperator::Substring,
|
Ok(&Token::SubstringMatch) => AttrSelectorOperator::Substring,
|
||||||
// [foo$=bar]
|
// [foo$=bar]
|
||||||
Ok(&Token::SuffixMatch) => AttrSelectorOperator::Suffix,
|
Ok(&Token::SuffixMatch) => AttrSelectorOperator::Suffix,
|
||||||
Ok(t) => return Err(SelectorParseError::UnexpectedTokenInAttributeSelector(t.clone()).into())
|
Ok(t) => return Err(location.new_custom_error(
|
||||||
|
SelectorParseErrorKind::UnexpectedTokenInAttributeSelector(t.clone())
|
||||||
|
))
|
||||||
};
|
};
|
||||||
|
|
||||||
let value = match input.expect_ident_or_string() {
|
let value = match input.expect_ident_or_string() {
|
||||||
Ok(t) => t.clone(),
|
Ok(t) => t.clone(),
|
||||||
Err(BasicParseError::UnexpectedToken(t)) =>
|
Err(BasicParseError { kind: BasicParseErrorKind::UnexpectedToken(t), location }) => {
|
||||||
return Err(SelectorParseError::BadValueInAttr(t.clone()).into()),
|
return Err(location.new_custom_error(SelectorParseErrorKind::BadValueInAttr(t)))
|
||||||
|
}
|
||||||
Err(e) => return Err(e.into()),
|
Err(e) => return Err(e.into()),
|
||||||
};
|
};
|
||||||
let never_matches = match operator {
|
let never_matches = match operator {
|
||||||
|
@ -1431,9 +1448,10 @@ fn parse_attribute_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParse
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn parse_attribute_flags<'i, 't, E>(input: &mut CssParser<'i, 't>)
|
fn parse_attribute_flags<'i, 't>(input: &mut CssParser<'i, 't>)
|
||||||
-> Result<ParsedCaseSensitivity,
|
-> Result<ParsedCaseSensitivity, BasicParseError<'i>>
|
||||||
ParseError<'i, SelectorParseError<'i, E>>> {
|
{
|
||||||
|
let location = input.current_source_location();
|
||||||
match input.next() {
|
match input.next() {
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
// Selectors spec says language-defined, but HTML says sensitive.
|
// Selectors spec says language-defined, but HTML says sensitive.
|
||||||
|
@ -1442,18 +1460,17 @@ fn parse_attribute_flags<'i, 't, E>(input: &mut CssParser<'i, 't>)
|
||||||
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.clone())))
|
Ok(t) => Err(location.new_basic_unexpected_token_error(t.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Level 3: Parse **one** simple_selector. (Though we might insert a second
|
/// Level 3: Parse **one** simple_selector. (Though we might insert a second
|
||||||
/// implied "<defaultns>|*" type selector.)
|
/// implied "<defaultns>|*" type selector.)
|
||||||
fn parse_negation<'i, 't, P, E, Impl>(parser: &P,
|
fn parse_negation<'i, 't, P, Impl>(parser: &P,
|
||||||
input: &mut CssParser<'i, 't>)
|
input: &mut CssParser<'i, 't>)
|
||||||
-> Result<Component<Impl>,
|
-> Result<Component<Impl>, ParseError<'i, P::Error>>
|
||||||
ParseError<'i, SelectorParseError<'i, E>>>
|
where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl
|
||||||
where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl
|
|
||||||
{
|
{
|
||||||
// We use a sequence because a type selector may be represented as two Components.
|
// We use a sequence because a type selector may be represented as two Components.
|
||||||
let mut sequence = SmallVec::<[Component<Impl>; 2]>::new();
|
let mut sequence = SmallVec::<[Component<Impl>; 2]>::new();
|
||||||
|
@ -1464,8 +1481,9 @@ fn parse_negation<'i, 't, P, E, Impl>(parser: &P,
|
||||||
// that there are no trailing tokens after we're done.
|
// that there are no trailing tokens after we're done.
|
||||||
let is_type_sel = match parse_type_selector(parser, input, &mut sequence) {
|
let is_type_sel = match parse_type_selector(parser, input, &mut sequence) {
|
||||||
Ok(result) => result,
|
Ok(result) => result,
|
||||||
Err(ParseError::Basic(BasicParseError::EndOfInput)) =>
|
Err(ParseError { kind: ParseErrorKind::Basic(BasicParseErrorKind::EndOfInput), .. }) => {
|
||||||
return Err(SelectorParseError::EmptyNegation.into()),
|
return Err(input.new_custom_error(SelectorParseErrorKind::EmptyNegation))
|
||||||
|
}
|
||||||
Err(e) => return Err(e.into()),
|
Err(e) => return Err(e.into()),
|
||||||
};
|
};
|
||||||
if !is_type_sel {
|
if !is_type_sel {
|
||||||
|
@ -1474,10 +1492,10 @@ fn parse_negation<'i, 't, P, E, Impl>(parser: &P,
|
||||||
sequence.push(s);
|
sequence.push(s);
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
return Err(ParseError::Custom(SelectorParseError::EmptyNegation));
|
return Err(input.new_custom_error(SelectorParseErrorKind::EmptyNegation));
|
||||||
},
|
},
|
||||||
Some(SimpleSelectorParseResult::PseudoElement(_)) => {
|
Some(SimpleSelectorParseResult::PseudoElement(_)) => {
|
||||||
return Err(ParseError::Custom(SelectorParseError::NonSimpleSelectorInNegation));
|
return Err(input.new_custom_error(SelectorParseErrorKind::NonSimpleSelectorInNegation));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1491,14 +1509,15 @@ fn parse_negation<'i, 't, P, E, Impl>(parser: &P,
|
||||||
/// | [ HASH | class | attrib | pseudo | negation ]+
|
/// | [ HASH | class | attrib | pseudo | negation ]+
|
||||||
///
|
///
|
||||||
/// `Err(())` means invalid selector.
|
/// `Err(())` means invalid selector.
|
||||||
|
/// `Ok(None)` is an empty selector
|
||||||
///
|
///
|
||||||
/// The boolean represent whether a pseudo-element has been parsed.
|
/// The boolean represent whether a pseudo-element has been parsed.
|
||||||
fn parse_compound_selector<'i, 't, P, E, Impl>(
|
fn parse_compound_selector<'i, 't, P, Impl>(
|
||||||
parser: &P,
|
parser: &P,
|
||||||
input: &mut CssParser<'i, 't>,
|
input: &mut CssParser<'i, 't>,
|
||||||
builder: &mut SelectorBuilder<Impl>)
|
builder: &mut SelectorBuilder<Impl>)
|
||||||
-> Result<bool, ParseError<'i, SelectorParseError<'i, E>>>
|
-> Result<Option<bool>, ParseError<'i, P::Error>>
|
||||||
where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl
|
where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl
|
||||||
{
|
{
|
||||||
input.skip_whitespace();
|
input.skip_whitespace();
|
||||||
|
|
||||||
|
@ -1528,24 +1547,32 @@ fn parse_compound_selector<'i, 't, P, E, Impl>(
|
||||||
let mut state_selectors = SmallVec::<[Component<Impl>; 3]>::new();
|
let mut state_selectors = SmallVec::<[Component<Impl>; 3]>::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
let location = input.current_source_location();
|
||||||
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,
|
||||||
Ok(t) =>
|
Ok(t) =>
|
||||||
return Err(SelectorParseError::PseudoElementExpectedColon(t.clone()).into()),
|
return Err(location.new_custom_error(
|
||||||
|
SelectorParseErrorKind::PseudoElementExpectedColon(t.clone())
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let location = input.current_source_location();
|
||||||
// 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()? {
|
||||||
&Token::Ident(ref name) => name.clone(),
|
&Token::Ident(ref name) => name.clone(),
|
||||||
t => return Err(SelectorParseError::NoIdentForPseudo(t.clone()).into()),
|
t => return Err(location.new_custom_error(
|
||||||
|
SelectorParseErrorKind::NoIdentForPseudo(t.clone())
|
||||||
|
)),
|
||||||
};
|
};
|
||||||
|
|
||||||
let pseudo_class =
|
let pseudo_class =
|
||||||
P::parse_non_ts_pseudo_class(parser, name.clone())?;
|
P::parse_non_ts_pseudo_class(parser, location, name.clone())?;
|
||||||
if !p.supports_pseudo_class(&pseudo_class) {
|
if !p.supports_pseudo_class(&pseudo_class) {
|
||||||
return Err(SelectorParseError::UnsupportedPseudoClassOrElement(name).into());
|
return Err(input.new_custom_error(
|
||||||
|
SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name)
|
||||||
|
));
|
||||||
}
|
}
|
||||||
state_selectors.push(Component::NonTSPseudoClass(pseudo_class));
|
state_selectors.push(Component::NonTSPseudoClass(pseudo_class));
|
||||||
}
|
}
|
||||||
|
@ -1567,28 +1594,29 @@ fn parse_compound_selector<'i, 't, P, E, Impl>(
|
||||||
}
|
}
|
||||||
if empty {
|
if empty {
|
||||||
// An empty selector is invalid.
|
// An empty selector is invalid.
|
||||||
Err(ParseError::Custom(SelectorParseError::EmptySelector))
|
Ok(None)
|
||||||
} else {
|
} else {
|
||||||
Ok(pseudo)
|
Ok(Some(pseudo))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_functional_pseudo_class<'i, 't, P, E, Impl>(parser: &P,
|
fn parse_functional_pseudo_class<'i, 't, P, Impl>(parser: &P,
|
||||||
input: &mut CssParser<'i, 't>,
|
input: &mut CssParser<'i, 't>,
|
||||||
name: CowRcStr<'i>,
|
name: CowRcStr<'i>,
|
||||||
inside_negation: bool)
|
inside_negation: bool)
|
||||||
-> Result<Component<Impl>,
|
-> Result<Component<Impl>, ParseError<'i, P::Error>>
|
||||||
ParseError<'i, SelectorParseError<'i, E>>>
|
where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl
|
||||||
where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl
|
|
||||||
{
|
{
|
||||||
match_ignore_ascii_case! { &name,
|
match_ignore_ascii_case! { &name,
|
||||||
"nth-child" => return parse_nth_pseudo_class(input, Component::NthChild),
|
"nth-child" => return Ok(parse_nth_pseudo_class(input, Component::NthChild)?),
|
||||||
"nth-of-type" => return parse_nth_pseudo_class(input, Component::NthOfType),
|
"nth-of-type" => return Ok(parse_nth_pseudo_class(input, Component::NthOfType)?),
|
||||||
"nth-last-child" => return parse_nth_pseudo_class(input, Component::NthLastChild),
|
"nth-last-child" => return Ok(parse_nth_pseudo_class(input, Component::NthLastChild)?),
|
||||||
"nth-last-of-type" => return parse_nth_pseudo_class(input, Component::NthLastOfType),
|
"nth-last-of-type" => return Ok(parse_nth_pseudo_class(input, Component::NthLastOfType)?),
|
||||||
"not" => {
|
"not" => {
|
||||||
if inside_negation {
|
if inside_negation {
|
||||||
return Err(ParseError::Custom(SelectorParseError::UnexpectedIdent("not".into())));
|
return Err(input.new_custom_error(
|
||||||
|
SelectorParseErrorKind::UnexpectedIdent("not".into())
|
||||||
|
));
|
||||||
}
|
}
|
||||||
return parse_negation(parser, input)
|
return parse_negation(parser, input)
|
||||||
},
|
},
|
||||||
|
@ -1599,9 +1627,8 @@ fn parse_functional_pseudo_class<'i, 't, P, E, Impl>(parser: &P,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn parse_nth_pseudo_class<'i, 't, Impl, F, E>(input: &mut CssParser<'i, 't>, selector: F)
|
fn parse_nth_pseudo_class<'i, 't, Impl, F>(input: &mut CssParser<'i, 't>, selector: F)
|
||||||
-> Result<Component<Impl>,
|
-> Result<Component<Impl>, BasicParseError<'i>>
|
||||||
ParseError<'i, SelectorParseError<'i, E>>>
|
|
||||||
where Impl: SelectorImpl, F: FnOnce(i32, i32) -> Component<Impl> {
|
where Impl: SelectorImpl, F: FnOnce(i32, i32) -> Component<Impl> {
|
||||||
let (a, b) = parse_nth(input)?;
|
let (a, b) = parse_nth(input)?;
|
||||||
Ok(selector(a, b))
|
Ok(selector(a, b))
|
||||||
|
@ -1624,12 +1651,12 @@ pub fn is_css2_pseudo_element<'i>(name: &CowRcStr<'i>) -> bool {
|
||||||
/// * `Err(())`: Invalid selector, abort
|
/// * `Err(())`: Invalid selector, abort
|
||||||
/// * `Ok(None)`: Not a simple selector, could be something else. `input` was not consumed.
|
/// * `Ok(None)`: Not a simple selector, could be something else. `input` was not consumed.
|
||||||
/// * `Ok(Some(_))`: Parsed a simple selector or pseudo-element
|
/// * `Ok(Some(_))`: Parsed a simple selector or pseudo-element
|
||||||
fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P,
|
fn parse_one_simple_selector<'i, 't, P, Impl>(parser: &P,
|
||||||
input: &mut CssParser<'i, 't>,
|
input: &mut CssParser<'i, 't>,
|
||||||
inside_negation: bool)
|
inside_negation: bool)
|
||||||
-> Result<Option<SimpleSelectorParseResult<Impl>>,
|
-> Result<Option<SimpleSelectorParseResult<Impl>>,
|
||||||
ParseError<'i, SelectorParseError<'i, E>>>
|
ParseError<'i, P::Error>>
|
||||||
where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl
|
where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl
|
||||||
{
|
{
|
||||||
let start = input.state();
|
let start = input.state();
|
||||||
// FIXME: remove clone() when lifetimes are non-lexical
|
// FIXME: remove clone() when lifetimes are non-lexical
|
||||||
|
@ -1639,12 +1666,15 @@ fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P,
|
||||||
Ok(Some(SimpleSelectorParseResult::SimpleSelector(id)))
|
Ok(Some(SimpleSelectorParseResult::SimpleSelector(id)))
|
||||||
}
|
}
|
||||||
Ok(Token::Delim('.')) => {
|
Ok(Token::Delim('.')) => {
|
||||||
|
let location = input.current_source_location();
|
||||||
match *input.next_including_whitespace()? {
|
match *input.next_including_whitespace()? {
|
||||||
Token::Ident(ref class) => {
|
Token::Ident(ref class) => {
|
||||||
let class = Component::Class(class.as_ref().into());
|
let class = Component::Class(class.as_ref().into());
|
||||||
Ok(Some(SimpleSelectorParseResult::SimpleSelector(class)))
|
Ok(Some(SimpleSelectorParseResult::SimpleSelector(class)))
|
||||||
}
|
}
|
||||||
ref t => Err(SelectorParseError::ClassNeedsIdent(t.clone()).into()),
|
ref t => Err(location.new_custom_error(
|
||||||
|
SelectorParseErrorKind::ClassNeedsIdent(t.clone())
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Token::SquareBracketBlock) => {
|
Ok(Token::SquareBracketBlock) => {
|
||||||
|
@ -1652,6 +1682,7 @@ 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 location = input.current_source_location();
|
||||||
let (is_single_colon, next_token) = match input.next_including_whitespace()?.clone() {
|
let (is_single_colon, next_token) = match input.next_including_whitespace()?.clone() {
|
||||||
Token::Colon => (false, input.next_including_whitespace()?.clone()),
|
Token::Colon => (false, input.next_including_whitespace()?.clone()),
|
||||||
t => (true, t),
|
t => (true, t),
|
||||||
|
@ -1659,7 +1690,9 @@ fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P,
|
||||||
let (name, is_functional) = match next_token {
|
let (name, is_functional) = match next_token {
|
||||||
Token::Ident(name) => (name, false),
|
Token::Ident(name) => (name, false),
|
||||||
Token::Function(name) => (name, true),
|
Token::Function(name) => (name, true),
|
||||||
t => return Err(SelectorParseError::PseudoElementExpectedIdent(t).into()),
|
t => return Err(input.new_custom_error(
|
||||||
|
SelectorParseErrorKind::PseudoElementExpectedIdent(t)
|
||||||
|
)),
|
||||||
};
|
};
|
||||||
let is_pseudo_element = !is_single_colon ||
|
let is_pseudo_element = !is_single_colon ||
|
||||||
P::is_pseudo_element_allows_single_colon(&name);
|
P::is_pseudo_element_allows_single_colon(&name);
|
||||||
|
@ -1669,7 +1702,7 @@ fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P,
|
||||||
P::parse_functional_pseudo_element(parser, name, input)
|
P::parse_functional_pseudo_element(parser, name, input)
|
||||||
})?
|
})?
|
||||||
} else {
|
} else {
|
||||||
P::parse_pseudo_element(parser, name)?
|
P::parse_pseudo_element(parser, location, name)?
|
||||||
};
|
};
|
||||||
Ok(Some(SimpleSelectorParseResult::PseudoElement(pseudo_element)))
|
Ok(Some(SimpleSelectorParseResult::PseudoElement(pseudo_element)))
|
||||||
} else {
|
} else {
|
||||||
|
@ -1678,7 +1711,7 @@ fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P,
|
||||||
parse_functional_pseudo_class(parser, input, name, inside_negation)
|
parse_functional_pseudo_class(parser, input, name, inside_negation)
|
||||||
})?
|
})?
|
||||||
} else {
|
} else {
|
||||||
parse_simple_pseudo_class(parser, name)?
|
parse_simple_pseudo_class(parser, location, name)?
|
||||||
};
|
};
|
||||||
Ok(Some(SimpleSelectorParseResult::SimpleSelector(pseudo_class)))
|
Ok(Some(SimpleSelectorParseResult::SimpleSelector(pseudo_class)))
|
||||||
}
|
}
|
||||||
|
@ -1690,10 +1723,10 @@ fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_simple_pseudo_class<'i, P, E, Impl>(parser: &P, name: CowRcStr<'i>)
|
fn parse_simple_pseudo_class<'i, P, Impl>(parser: &P, location: SourceLocation,
|
||||||
-> Result<Component<Impl>,
|
name: CowRcStr<'i>)
|
||||||
ParseError<'i, SelectorParseError<'i, E>>>
|
-> Result<Component<Impl>, ParseError<'i, P::Error>>
|
||||||
where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl
|
where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl
|
||||||
{
|
{
|
||||||
(match_ignore_ascii_case! { &name,
|
(match_ignore_ascii_case! { &name,
|
||||||
"first-child" => Ok(Component::FirstChild),
|
"first-child" => Ok(Component::FirstChild),
|
||||||
|
@ -1707,7 +1740,7 @@ fn parse_simple_pseudo_class<'i, P, E, Impl>(parser: &P, name: CowRcStr<'i>)
|
||||||
"only-of-type" => Ok(Component::OnlyOfType),
|
"only-of-type" => Ok(Component::OnlyOfType),
|
||||||
_ => Err(())
|
_ => Err(())
|
||||||
}).or_else(|()| {
|
}).or_else(|()| {
|
||||||
P::parse_non_ts_pseudo_class(parser, name)
|
P::parse_non_ts_pseudo_class(parser, location, name)
|
||||||
.map(Component::NonTSPseudoClass)
|
.map(Component::NonTSPseudoClass)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1843,36 +1876,37 @@ pub mod tests {
|
||||||
|
|
||||||
impl<'i> Parser<'i> for DummyParser {
|
impl<'i> Parser<'i> for DummyParser {
|
||||||
type Impl = DummySelectorImpl;
|
type Impl = DummySelectorImpl;
|
||||||
type Error = ();
|
type Error = SelectorParseErrorKind<'i>;
|
||||||
|
|
||||||
fn parse_non_ts_pseudo_class(&self, name: CowRcStr<'i>)
|
fn parse_non_ts_pseudo_class(&self, location: SourceLocation, name: CowRcStr<'i>)
|
||||||
-> Result<PseudoClass,
|
-> Result<PseudoClass, SelectorParseError<'i>> {
|
||||||
ParseError<'i, SelectorParseError<'i, ()>>> {
|
|
||||||
match_ignore_ascii_case! { &name,
|
match_ignore_ascii_case! { &name,
|
||||||
"hover" => Ok(PseudoClass::Hover),
|
"hover" => return Ok(PseudoClass::Hover),
|
||||||
"active" => Ok(PseudoClass::Active),
|
"active" => return Ok(PseudoClass::Active),
|
||||||
_ => Err(SelectorParseError::Custom(()).into())
|
_ => {}
|
||||||
}
|
}
|
||||||
|
Err(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_non_ts_functional_pseudo_class<'t>(&self, name: CowRcStr<'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, 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()?.as_ref().to_owned())),
|
"lang" => return Ok(PseudoClass::Lang(parser.expect_ident_or_string()?.as_ref().to_owned())),
|
||||||
_ => Err(SelectorParseError::Custom(()).into())
|
_ => {}
|
||||||
}
|
}
|
||||||
|
Err(parser.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_pseudo_element(&self, name: CowRcStr<'i>)
|
fn parse_pseudo_element(&self, location: SourceLocation, name: CowRcStr<'i>)
|
||||||
-> Result<PseudoElement,
|
-> Result<PseudoElement,
|
||||||
ParseError<'i, SelectorParseError<'i, ()>>> {
|
SelectorParseError<'i>> {
|
||||||
match_ignore_ascii_case! { &name,
|
match_ignore_ascii_case! { &name,
|
||||||
"before" => Ok(PseudoElement::Before),
|
"before" => return Ok(PseudoElement::Before),
|
||||||
"after" => Ok(PseudoElement::After),
|
"after" => return Ok(PseudoElement::After),
|
||||||
_ => Err(SelectorParseError::Custom(()).into())
|
_ => {}
|
||||||
}
|
}
|
||||||
|
Err(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_namespace(&self) -> Option<DummyAtom> {
|
fn default_namespace(&self) -> Option<DummyAtom> {
|
||||||
|
@ -1885,17 +1919,17 @@ pub mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse<'i>(input: &'i str)
|
fn parse<'i>(input: &'i str)
|
||||||
-> Result<SelectorList<DummySelectorImpl>, ParseError<'i, SelectorParseError<'i, ()>>> {
|
-> Result<SelectorList<DummySelectorImpl>, SelectorParseError<'i>> {
|
||||||
parse_ns(input, &DummyParser::default())
|
parse_ns(input, &DummyParser::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_expected<'i, 'a>(input: &'i str, expected: Option<&'a str>)
|
fn parse_expected<'i, 'a>(input: &'i str, expected: Option<&'a str>)
|
||||||
-> Result<SelectorList<DummySelectorImpl>, ParseError<'i, SelectorParseError<'i, ()>>> {
|
-> Result<SelectorList<DummySelectorImpl>, SelectorParseError<'i>> {
|
||||||
parse_ns_expected(input, &DummyParser::default(), expected)
|
parse_ns_expected(input, &DummyParser::default(), expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_ns<'i>(input: &'i str, parser: &DummyParser)
|
fn parse_ns<'i>(input: &'i str, parser: &DummyParser)
|
||||||
-> Result<SelectorList<DummySelectorImpl>, ParseError<'i, SelectorParseError<'i, ()>>> {
|
-> Result<SelectorList<DummySelectorImpl>, SelectorParseError<'i>> {
|
||||||
parse_ns_expected(input, parser, None)
|
parse_ns_expected(input, parser, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1903,7 +1937,7 @@ pub mod tests {
|
||||||
input: &'i str,
|
input: &'i str,
|
||||||
parser: &DummyParser,
|
parser: &DummyParser,
|
||||||
expected: Option<&'a str>
|
expected: Option<&'a str>
|
||||||
) -> Result<SelectorList<DummySelectorImpl>, ParseError<'i, SelectorParseError<'i, ()>>> {
|
) -> Result<SelectorList<DummySelectorImpl>, SelectorParseError<'i>> {
|
||||||
let mut parser_input = ParserInput::new(input);
|
let mut parser_input = ParserInput::new(input);
|
||||||
let result = SelectorList::parse(parser, &mut CssParser::new(&mut parser_input));
|
let result = SelectorList::parse(parser, &mut CssParser::new(&mut parser_input));
|
||||||
if let Ok(ref selectors) = result {
|
if let Ok(ref selectors) = result {
|
||||||
|
|
|
@ -36,7 +36,7 @@ atomic_refcell = "0.1"
|
||||||
bitflags = "0.7"
|
bitflags = "0.7"
|
||||||
byteorder = "1.0"
|
byteorder = "1.0"
|
||||||
cfg-if = "0.1.0"
|
cfg-if = "0.1.0"
|
||||||
cssparser = "0.21.2"
|
cssparser = "0.22.0"
|
||||||
encoding = {version = "0.2", optional = true}
|
encoding = {version = "0.2", optional = true}
|
||||||
euclid = "0.15"
|
euclid = "0.15"
|
||||||
fallible = { path = "../fallible" }
|
fallible = { path = "../fallible" }
|
||||||
|
|
|
@ -8,18 +8,18 @@
|
||||||
|
|
||||||
use Atom;
|
use Atom;
|
||||||
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser};
|
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser};
|
||||||
use cssparser::{Parser, Token, serialize_identifier, BasicParseError, CowRcStr};
|
use cssparser::{Parser, Token, serialize_identifier, CowRcStr};
|
||||||
use error_reporting::{ContextualParseError, ParseErrorReporter};
|
use error_reporting::{ContextualParseError, ParseErrorReporter};
|
||||||
#[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;
|
||||||
use parser::{ParserContext, ParserErrorContext, Parse};
|
use parser::{ParserContext, ParserErrorContext, Parse};
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
|
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseError, ToCss};
|
use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseErrorKind, ToCss};
|
||||||
use values::CustomIdent;
|
use values::CustomIdent;
|
||||||
|
|
||||||
/// Parse the prelude of an @counter-style rule
|
/// Parse the prelude of an @counter-style rule
|
||||||
|
@ -36,12 +36,13 @@ pub fn parse_counter_style_name<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Cu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let location = input.current_source_location();
|
||||||
let ident = input.expect_ident()?;
|
let ident = input.expect_ident()?;
|
||||||
if let Some(&lower_cased) = predefined(&ident) {
|
if let Some(&lower_cased) = predefined(&ident) {
|
||||||
Ok(CustomIdent(Atom::from(lower_cased)))
|
Ok(CustomIdent(Atom::from(lower_cased)))
|
||||||
} else {
|
} else {
|
||||||
// https://github.com/w3c/csswg-drafts/issues/1295 excludes "none"
|
// https://github.com/w3c/csswg-drafts/issues/1295 excludes "none"
|
||||||
CustomIdent::from_ident(ident, &["none"])
|
CustomIdent::from_ident(location, ident, &["none"])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,9 +67,10 @@ pub fn parse_counter_style_body<'i, 't, R>(name: CustomIdent,
|
||||||
};
|
};
|
||||||
let mut iter = DeclarationListParser::new(input, parser);
|
let mut iter = DeclarationListParser::new(input, parser);
|
||||||
while let Some(declaration) = iter.next() {
|
while let Some(declaration) = iter.next() {
|
||||||
if let Err(err) = declaration {
|
if let Err((error, slice)) = declaration {
|
||||||
let error = ContextualParseError::UnsupportedCounterStyleDescriptorDeclaration(err.slice, err.error);
|
let location = error.location;
|
||||||
context.log_css_error(error_context, err.location, error)
|
let error = ContextualParseError::UnsupportedCounterStyleDescriptorDeclaration(slice, error);
|
||||||
|
context.log_css_error(error_context, location, error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,7 +103,7 @@ pub fn parse_counter_style_body<'i, 't, R>(name: CustomIdent,
|
||||||
};
|
};
|
||||||
if let Some(error) = error {
|
if let Some(error) = error {
|
||||||
context.log_css_error(error_context, start, error);
|
context.log_css_error(error_context, start, error);
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
} else {
|
} else {
|
||||||
Ok(rule)
|
Ok(rule)
|
||||||
}
|
}
|
||||||
|
@ -117,7 +119,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for CounterStyleRuleParser<'a, 'b> {
|
||||||
type PreludeNoBlock = ();
|
type PreludeNoBlock = ();
|
||||||
type PreludeBlock = ();
|
type PreludeBlock = ();
|
||||||
type AtRule = ();
|
type AtRule = ();
|
||||||
type Error = SelectorParseError<'i, StyleParseError<'i>>;
|
type Error = StyleParseErrorKind<'i>;
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! accessor {
|
macro_rules! accessor {
|
||||||
|
@ -186,7 +188,7 @@ macro_rules! counter_style_descriptors {
|
||||||
|
|
||||||
impl<'a, 'b, 'i> DeclarationParser<'i> for CounterStyleRuleParser<'a, 'b> {
|
impl<'a, 'b, 'i> DeclarationParser<'i> for CounterStyleRuleParser<'a, 'b> {
|
||||||
type Declaration = ();
|
type Declaration = ();
|
||||||
type Error = SelectorParseError<'i, StyleParseError<'i>>;
|
type Error = StyleParseErrorKind<'i>;
|
||||||
|
|
||||||
fn parse_value<'t>(&mut self, name: CowRcStr<'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>> {
|
||||||
|
@ -201,7 +203,7 @@ macro_rules! counter_style_descriptors {
|
||||||
self.rule.$ident = Some(value)
|
self.rule.$ident = Some(value)
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
_ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into())
|
_ => return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone())))
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -299,7 +301,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_cloned()?,
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
"cyclic" => Ok(System::Cyclic),
|
"cyclic" => Ok(System::Cyclic),
|
||||||
"numeric" => Ok(System::Numeric),
|
"numeric" => Ok(System::Numeric),
|
||||||
"alphabetic" => Ok(System::Alphabetic),
|
"alphabetic" => Ok(System::Alphabetic),
|
||||||
|
@ -356,10 +358,11 @@ 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>> {
|
||||||
|
let location = input.current_source_location();
|
||||||
match input.next() {
|
match input.next() {
|
||||||
Ok(&Token::QuotedString(ref s)) => Ok(Symbol::String(s.as_ref().to_owned())),
|
Ok(&Token::QuotedString(ref s)) => Ok(Symbol::String(s.as_ref().to_owned())),
|
||||||
Ok(&Token::Ident(ref s)) => Ok(Symbol::Ident(s.as_ref().to_owned())),
|
Ok(&Token::Ident(ref s)) => Ok(Symbol::Ident(s.as_ref().to_owned())),
|
||||||
Ok(t) => Err(BasicParseError::UnexpectedToken(t.clone()).into()),
|
Ok(t) => Err(location.new_unexpected_token_error(t.clone())),
|
||||||
Err(e) => Err(e.into()),
|
Err(e) => Err(e.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -414,7 +417,7 @@ impl Parse for Ranges {
|
||||||
let opt_end = parse_bound(input)?;
|
let opt_end = parse_bound(input)?;
|
||||||
if let (Some(start), Some(end)) = (opt_start, opt_end) {
|
if let (Some(start), Some(end)) = (opt_start, opt_end) {
|
||||||
if start > end {
|
if start > end {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(opt_start..opt_end)
|
Ok(opt_start..opt_end)
|
||||||
|
@ -424,10 +427,11 @@ 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>> {
|
||||||
|
let location = input.current_source_location();
|
||||||
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.clone()).into()),
|
Ok(t) => Err(location.new_unexpected_token_error(t.clone())),
|
||||||
Err(e) => Err(e.into()),
|
Err(e) => Err(e.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -472,7 +476,7 @@ impl Parse for Pad {
|
||||||
let pad_with = input.try(|input| Symbol::parse(context, input));
|
let pad_with = input.try(|input| Symbol::parse(context, input));
|
||||||
let min_length = input.expect_integer()?;
|
let min_length = input.expect_integer()?;
|
||||||
if min_length < 0 {
|
if min_length < 0 {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
let pad_with = pad_with.or_else(|_| Symbol::parse(context, input))?;
|
let pad_with = pad_with.or_else(|_| Symbol::parse(context, input))?;
|
||||||
Ok(Pad(min_length as u32, pad_with))
|
Ok(Pad(min_length as u32, pad_with))
|
||||||
|
@ -502,7 +506,7 @@ impl Parse for Symbols {
|
||||||
symbols.push(s)
|
symbols.push(s)
|
||||||
} else {
|
} else {
|
||||||
if symbols.is_empty() {
|
if symbols.is_empty() {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
} else {
|
} else {
|
||||||
return Ok(Symbols(symbols))
|
return Ok(Symbols(symbols))
|
||||||
}
|
}
|
||||||
|
@ -533,7 +537,7 @@ impl Parse for AdditiveSymbols {
|
||||||
let tuples = Vec::<AdditiveTuple>::parse(context, input)?;
|
let tuples = Vec::<AdditiveTuple>::parse(context, input)?;
|
||||||
// FIXME maybe? https://github.com/w3c/csswg-drafts/issues/1220
|
// FIXME maybe? https://github.com/w3c/csswg-drafts/issues/1220
|
||||||
if tuples.windows(2).any(|window| window[0].weight <= window[1].weight) {
|
if tuples.windows(2).any(|window| window[0].weight <= window[1].weight) {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
Ok(AdditiveSymbols(tuples))
|
Ok(AdditiveSymbols(tuples))
|
||||||
}
|
}
|
||||||
|
@ -557,7 +561,7 @@ impl Parse for AdditiveTuple {
|
||||||
let symbol = input.try(|input| Symbol::parse(context, input));
|
let symbol = input.try(|input| Symbol::parse(context, input));
|
||||||
let weight = input.expect_integer()?;
|
let weight = input.expect_integer()?;
|
||||||
if weight < 0 {
|
if weight < 0 {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
let symbol = symbol.or_else(|_| Symbol::parse(context, input))?;
|
let symbol = symbol.or_else(|_| Symbol::parse(context, input))?;
|
||||||
Ok(AdditiveTuple {
|
Ok(AdditiveTuple {
|
||||||
|
@ -604,7 +608,7 @@ impl Parse for SpeakAs {
|
||||||
if is_spell_out {
|
if is_spell_out {
|
||||||
// spell-out is not supported, but don’t parse it as a <counter-style-name>.
|
// spell-out is not supported, but don’t parse it as a <counter-style-name>.
|
||||||
// See bug 1024178.
|
// See bug 1024178.
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
result.or_else(|_| {
|
result.or_else(|_| {
|
||||||
Ok(SpeakAs::Other(parse_counter_style_name(input)?))
|
Ok(SpeakAs::Other(parse_counter_style_name(input)?))
|
||||||
|
|
|
@ -11,14 +11,14 @@ use cssparser::{Delimiter, Parser, ParserInput, SourcePosition, Token, TokenSeri
|
||||||
use precomputed_hash::PrecomputedHash;
|
use precomputed_hash::PrecomputedHash;
|
||||||
use properties::{CSSWideKeyword, DeclaredValue};
|
use properties::{CSSWideKeyword, DeclaredValue};
|
||||||
use selector_map::{PrecomputedHashSet, PrecomputedHashMap, PrecomputedDiagnosticHashMap};
|
use selector_map::{PrecomputedHashSet, PrecomputedHashMap, PrecomputedDiagnosticHashMap};
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::borrow::{Borrow, Cow};
|
use std::borrow::{Borrow, Cow};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use style_traits::{ToCss, StyleParseError, ParseError};
|
use style_traits::{ToCss, StyleParseErrorKind, ParseError};
|
||||||
|
|
||||||
/// A custom property name is just an `Atom`.
|
/// A custom property name is just an `Atom`.
|
||||||
///
|
///
|
||||||
|
@ -357,16 +357,27 @@ fn parse_declaration_value_block<'i, 't>(
|
||||||
}
|
}
|
||||||
token.serialization_type()
|
token.serialization_type()
|
||||||
}
|
}
|
||||||
Token::BadUrl(u) =>
|
Token::BadUrl(u) => {
|
||||||
return Err(StyleParseError::BadUrlInDeclarationValueBlock(u).into()),
|
return Err(input.new_custom_error(StyleParseErrorKind::BadUrlInDeclarationValueBlock(u)))
|
||||||
Token::BadString(s) =>
|
}
|
||||||
return Err(StyleParseError::BadStringInDeclarationValueBlock(s).into()),
|
Token::BadString(s) => {
|
||||||
Token::CloseParenthesis =>
|
return Err(input.new_custom_error(StyleParseErrorKind::BadStringInDeclarationValueBlock(s)))
|
||||||
return Err(StyleParseError::UnbalancedCloseParenthesisInDeclarationValueBlock.into()),
|
}
|
||||||
Token::CloseSquareBracket =>
|
Token::CloseParenthesis => {
|
||||||
return Err(StyleParseError::UnbalancedCloseSquareBracketInDeclarationValueBlock.into()),
|
return Err(input.new_custom_error(
|
||||||
Token::CloseCurlyBracket =>
|
StyleParseErrorKind::UnbalancedCloseParenthesisInDeclarationValueBlock
|
||||||
return Err(StyleParseError::UnbalancedCloseCurlyBracketInDeclarationValueBlock.into()),
|
))
|
||||||
|
}
|
||||||
|
Token::CloseSquareBracket => {
|
||||||
|
return Err(input.new_custom_error(
|
||||||
|
StyleParseErrorKind::UnbalancedCloseSquareBracketInDeclarationValueBlock
|
||||||
|
))
|
||||||
|
}
|
||||||
|
Token::CloseCurlyBracket => {
|
||||||
|
return Err(input.new_custom_error(
|
||||||
|
StyleParseErrorKind::UnbalancedCloseCurlyBracketInDeclarationValueBlock
|
||||||
|
))
|
||||||
|
}
|
||||||
Token::Function(ref name) => {
|
Token::Function(ref name) => {
|
||||||
if name.eq_ignore_ascii_case("var") {
|
if name.eq_ignore_ascii_case("var") {
|
||||||
let args_start = input.state();
|
let args_start = input.state();
|
||||||
|
@ -446,7 +457,7 @@ fn parse_var_function<'i, 't>(
|
||||||
let name = input.expect_ident_cloned()?;
|
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(|()| input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone())));
|
||||||
let name = name?;
|
let name = name?;
|
||||||
if input.try(|input| input.expect_comma()).is_ok() {
|
if input.try(|input| input.expect_comma()).is_ok() {
|
||||||
// Exclude `!` and `;` at the top level
|
// Exclude `!` and `;` at the top level
|
||||||
|
|
|
@ -6,8 +6,7 @@
|
||||||
|
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
use cssparser::{BasicParseError, Token, SourceLocation};
|
use cssparser::{Token, SourceLocation, ParseErrorKind, BasicParseErrorKind};
|
||||||
use cssparser::ParseError as CssParseError;
|
|
||||||
use log;
|
use log;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::ParseError;
|
use style_traits::ParseError;
|
||||||
|
@ -91,24 +90,24 @@ impl<'a> fmt::Display for ContextualParseError<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_error_to_str(err: &ParseError, f: &mut fmt::Formatter) -> fmt::Result {
|
fn parse_error_to_str(err: &ParseError, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *err {
|
match err.kind {
|
||||||
CssParseError::Basic(BasicParseError::UnexpectedToken(ref t)) => {
|
ParseErrorKind::Basic(BasicParseErrorKind::UnexpectedToken(ref t)) => {
|
||||||
write!(f, "found unexpected ")?;
|
write!(f, "found unexpected ")?;
|
||||||
token_to_str(t, f)
|
token_to_str(t, f)
|
||||||
}
|
}
|
||||||
CssParseError::Basic(BasicParseError::EndOfInput) => {
|
ParseErrorKind::Basic(BasicParseErrorKind::EndOfInput) => {
|
||||||
write!(f, "unexpected end of input")
|
write!(f, "unexpected end of input")
|
||||||
}
|
}
|
||||||
CssParseError::Basic(BasicParseError::AtRuleInvalid(ref i)) => {
|
ParseErrorKind::Basic(BasicParseErrorKind::AtRuleInvalid(ref i)) => {
|
||||||
write!(f, "@ rule invalid: {}", i)
|
write!(f, "@ rule invalid: {}", i)
|
||||||
}
|
}
|
||||||
CssParseError::Basic(BasicParseError::AtRuleBodyInvalid) => {
|
ParseErrorKind::Basic(BasicParseErrorKind::AtRuleBodyInvalid) => {
|
||||||
write!(f, "@ rule invalid")
|
write!(f, "@ rule invalid")
|
||||||
}
|
}
|
||||||
CssParseError::Basic(BasicParseError::QualifiedRuleInvalid) => {
|
ParseErrorKind::Basic(BasicParseErrorKind::QualifiedRuleInvalid) => {
|
||||||
write!(f, "qualified rule invalid")
|
write!(f, "qualified rule invalid")
|
||||||
}
|
}
|
||||||
CssParseError::Custom(ref err) => {
|
ParseErrorKind::Custom(ref err) => {
|
||||||
write!(f, "{:?}", err)
|
write!(f, "{:?}", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,10 @@ use error_reporting::{ContextualParseError, ParseErrorReporter};
|
||||||
use parser::{ParserContext, ParserErrorContext, Parse};
|
use parser::{ParserContext, ParserErrorContext, Parse};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use properties::longhands::font_language_override;
|
use properties::longhands::font_language_override;
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
|
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseError, ToCss};
|
use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseErrorKind, ToCss};
|
||||||
use values::specified::url::SpecifiedUrl;
|
use values::specified::url::SpecifiedUrl;
|
||||||
|
|
||||||
/// A source for a font-face rule.
|
/// A source for a font-face rule.
|
||||||
|
@ -100,7 +100,7 @@ impl Parse for FontWeight {
|
||||||
result.or_else(|_| {
|
result.or_else(|_| {
|
||||||
font_weight::T::from_int(input.expect_integer()?)
|
font_weight::T::from_int(input.expect_integer()?)
|
||||||
.map(FontWeight::Weight)
|
.map(FontWeight::Weight)
|
||||||
.map_err(|()| StyleParseError::UnspecifiedError.into())
|
.map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,9 +123,10 @@ pub fn parse_font_face_block<R>(context: &ParserContext,
|
||||||
};
|
};
|
||||||
let mut iter = DeclarationListParser::new(input, parser);
|
let mut iter = DeclarationListParser::new(input, parser);
|
||||||
while let Some(declaration) = iter.next() {
|
while let Some(declaration) = iter.next() {
|
||||||
if let Err(err) = declaration {
|
if let Err((error, slice)) = declaration {
|
||||||
let error = ContextualParseError::UnsupportedFontFaceDescriptor(err.slice, err.error);
|
let location = error.location;
|
||||||
context.log_css_error(error_context, err.location, error)
|
let error = ContextualParseError::UnsupportedFontFaceDescriptor(slice, error);
|
||||||
|
context.log_css_error(error_context, location, error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,7 +187,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for FontFaceRuleParser<'a, 'b> {
|
||||||
type PreludeNoBlock = ();
|
type PreludeNoBlock = ();
|
||||||
type PreludeBlock = ();
|
type PreludeBlock = ();
|
||||||
type AtRule = ();
|
type AtRule = ();
|
||||||
type Error = SelectorParseError<'i, StyleParseError<'i>>;
|
type Error = StyleParseErrorKind<'i>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for Source {
|
impl Parse for Source {
|
||||||
|
@ -287,7 +288,7 @@ macro_rules! font_face_descriptors_common {
|
||||||
|
|
||||||
impl<'a, 'b, 'i> DeclarationParser<'i> for FontFaceRuleParser<'a, 'b> {
|
impl<'a, 'b, 'i> DeclarationParser<'i> for FontFaceRuleParser<'a, 'b> {
|
||||||
type Declaration = ();
|
type Declaration = ();
|
||||||
type Error = SelectorParseError<'i, StyleParseError<'i>>;
|
type Error = StyleParseErrorKind<'i>;
|
||||||
|
|
||||||
fn parse_value<'t>(&mut self, name: CowRcStr<'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>> {
|
||||||
|
@ -302,7 +303,7 @@ macro_rules! font_face_descriptors_common {
|
||||||
self.rule.$ident = Some(value)
|
self.rule.$ident = Some(value)
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
_ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into())
|
_ => return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone())))
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
use app_units::AU_PER_PX;
|
use app_units::AU_PER_PX;
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use context::QuirksMode;
|
use context::QuirksMode;
|
||||||
use cssparser::{CssStringWriter, Parser, RGBA, Token, BasicParseError};
|
use cssparser::{CssStringWriter, Parser, RGBA, Token, BasicParseErrorKind};
|
||||||
use euclid::ScaleFactor;
|
use euclid::ScaleFactor;
|
||||||
use euclid::Size2D;
|
use euclid::Size2D;
|
||||||
use font_metrics::get_metrics_provider_for_product;
|
use font_metrics::get_metrics_provider_for_product;
|
||||||
|
@ -30,7 +30,7 @@ use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize, Ordering};
|
||||||
use str::starts_with_ignore_ascii_case;
|
use str::starts_with_ignore_ascii_case;
|
||||||
use string_cache::Atom;
|
use string_cache::Atom;
|
||||||
use style_traits::{CSSPixel, DevicePixel};
|
use style_traits::{CSSPixel, DevicePixel};
|
||||||
use style_traits::{ToCss, ParseError, StyleParseError};
|
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
|
||||||
use style_traits::viewport::ViewportConstraints;
|
use style_traits::viewport::ViewportConstraints;
|
||||||
use stylesheets::Origin;
|
use stylesheets::Origin;
|
||||||
use values::{CSSFloat, CustomIdent, serialize_dimension};
|
use values::{CSSFloat, CustomIdent, serialize_dimension};
|
||||||
|
@ -285,15 +285,16 @@ 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 location = input.current_source_location();
|
||||||
let (value, unit) = match *input.next()? {
|
let (value, unit) = match *input.next()? {
|
||||||
Token::Dimension { value, ref unit, .. } => {
|
Token::Dimension { value, ref unit, .. } => {
|
||||||
(value, unit)
|
(value, unit)
|
||||||
},
|
},
|
||||||
ref t => return Err(BasicParseError::UnexpectedToken(t.clone()).into()),
|
ref t => return Err(location.new_unexpected_token_error(t.clone())),
|
||||||
};
|
};
|
||||||
|
|
||||||
if value <= 0. {
|
if value <= 0. {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
||||||
(match_ignore_ascii_case! { &unit,
|
(match_ignore_ascii_case! { &unit,
|
||||||
|
@ -301,7 +302,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.clone()).into())
|
}).map_err(|()| location.new_custom_error(StyleParseErrorKind::UnexpectedDimension(unit.clone())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,7 +499,7 @@ fn parse_feature_value<'i, 't>(feature: &nsMediaFeature,
|
||||||
// for parity with gecko. We should remove this check when we want
|
// for parity with gecko. We should remove this check when we want
|
||||||
// to support it.
|
// to support it.
|
||||||
if let Length::Calc(_) = length {
|
if let Length::Calc(_) = length {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
MediaExpressionValue::Length(length)
|
MediaExpressionValue::Length(length)
|
||||||
},
|
},
|
||||||
|
@ -508,14 +509,14 @@ fn parse_feature_value<'i, 't>(feature: &nsMediaFeature,
|
||||||
// supported in media queries per FIXME above.
|
// supported in media queries per FIXME above.
|
||||||
let i = input.expect_integer()?;
|
let i = input.expect_integer()?;
|
||||||
if i < 0 {
|
if i < 0 {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
MediaExpressionValue::Integer(i as u32)
|
MediaExpressionValue::Integer(i as u32)
|
||||||
}
|
}
|
||||||
nsMediaFeature_ValueType::eBoolInteger => {
|
nsMediaFeature_ValueType::eBoolInteger => {
|
||||||
let i = input.expect_integer()?;
|
let i = input.expect_integer()?;
|
||||||
if i < 0 || i > 1 {
|
if i < 0 || i > 1 {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
MediaExpressionValue::BoolInteger(i == 1)
|
MediaExpressionValue::BoolInteger(i == 1)
|
||||||
}
|
}
|
||||||
|
@ -525,14 +526,14 @@ fn parse_feature_value<'i, 't>(feature: &nsMediaFeature,
|
||||||
nsMediaFeature_ValueType::eIntRatio => {
|
nsMediaFeature_ValueType::eIntRatio => {
|
||||||
let a = input.expect_integer()?;
|
let a = input.expect_integer()?;
|
||||||
if a <= 0 {
|
if a <= 0 {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
||||||
input.expect_delim('/')?;
|
input.expect_delim('/')?;
|
||||||
|
|
||||||
let b = input.expect_integer()?;
|
let b = input.expect_integer()?;
|
||||||
if b <= 0 {
|
if b <= 0 {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
MediaExpressionValue::IntRatio(a as u32, b as u32)
|
MediaExpressionValue::IntRatio(a as u32, b as u32)
|
||||||
}
|
}
|
||||||
|
@ -540,28 +541,26 @@ fn parse_feature_value<'i, 't>(feature: &nsMediaFeature,
|
||||||
MediaExpressionValue::Resolution(Resolution::parse(input)?)
|
MediaExpressionValue::Resolution(Resolution::parse(input)?)
|
||||||
}
|
}
|
||||||
nsMediaFeature_ValueType::eEnumerated => {
|
nsMediaFeature_ValueType::eEnumerated => {
|
||||||
let keyword = input.expect_ident()?;
|
let location = input.current_source_location();
|
||||||
let keyword = unsafe {
|
let keyword = input.expect_ident()?;
|
||||||
bindings::Gecko_LookupCSSKeyword(keyword.as_bytes().as_ptr(),
|
let keyword = unsafe {
|
||||||
keyword.len() as u32)
|
bindings::Gecko_LookupCSSKeyword(keyword.as_bytes().as_ptr(),
|
||||||
};
|
keyword.len() as u32)
|
||||||
|
};
|
||||||
|
|
||||||
let first_table_entry: *const nsCSSProps_KTableEntry = unsafe {
|
let first_table_entry: *const nsCSSProps_KTableEntry = unsafe {
|
||||||
*feature.mData.mKeywordTable.as_ref()
|
*feature.mData.mKeywordTable.as_ref()
|
||||||
};
|
};
|
||||||
|
|
||||||
let value =
|
let value = match unsafe { find_in_table(first_table_entry, |kw, _| kw == keyword) } {
|
||||||
match unsafe { find_in_table(first_table_entry, |kw, _| kw == keyword) } {
|
Some((_kw, value)) => value,
|
||||||
Some((_kw, value)) => {
|
None => return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
|
||||||
value
|
};
|
||||||
}
|
|
||||||
None => return Err(StyleParseError::UnspecifiedError.into()),
|
|
||||||
};
|
|
||||||
|
|
||||||
MediaExpressionValue::Enumerated(value)
|
MediaExpressionValue::Enumerated(value)
|
||||||
}
|
}
|
||||||
nsMediaFeature_ValueType::eIdent => {
|
nsMediaFeature_ValueType::eIdent => {
|
||||||
MediaExpressionValue::Ident(input.expect_ident()?.as_ref().to_owned())
|
MediaExpressionValue::Ident(input.expect_ident()?.as_ref().to_owned())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -590,10 +589,10 @@ impl Expression {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
input.expect_parenthesis_block().map_err(|err|
|
input.expect_parenthesis_block().map_err(|err|
|
||||||
match err {
|
err.location.new_custom_error(match err.kind {
|
||||||
BasicParseError::UnexpectedToken(t) => StyleParseError::ExpectedIdentifier(t),
|
BasicParseErrorKind::UnexpectedToken(t) => StyleParseErrorKind::ExpectedIdentifier(t),
|
||||||
_ => StyleParseError::UnspecifiedError,
|
_ => StyleParseErrorKind::UnspecifiedError,
|
||||||
}
|
})
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
input.parse_nested_block(|input| {
|
input.parse_nested_block(|input| {
|
||||||
|
@ -601,11 +600,12 @@ impl Expression {
|
||||||
let feature;
|
let feature;
|
||||||
let range;
|
let range;
|
||||||
{
|
{
|
||||||
|
let location = input.current_source_location();
|
||||||
let ident = input.expect_ident().map_err(|err|
|
let ident = input.expect_ident().map_err(|err|
|
||||||
match err {
|
err.location.new_custom_error(match err.kind {
|
||||||
BasicParseError::UnexpectedToken(t) => StyleParseError::ExpectedIdentifier(t),
|
BasicParseErrorKind::UnexpectedToken(t) => StyleParseErrorKind::ExpectedIdentifier(t),
|
||||||
_ => StyleParseError::UnspecifiedError,
|
_ => StyleParseErrorKind::UnspecifiedError,
|
||||||
}
|
})
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut flags = 0;
|
let mut flags = 0;
|
||||||
|
@ -648,19 +648,25 @@ impl Expression {
|
||||||
Ok((f, r)) => {
|
Ok((f, r)) => {
|
||||||
feature = f;
|
feature = f;
|
||||||
range = r;
|
range = r;
|
||||||
},
|
}
|
||||||
Err(()) => {
|
Err(()) => {
|
||||||
return Err(StyleParseError::MediaQueryExpectedFeatureName(ident.clone()).into())
|
return Err(location.new_custom_error(
|
||||||
},
|
StyleParseErrorKind::MediaQueryExpectedFeatureName(ident.clone())
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (feature.mReqFlags & !flags) != 0 {
|
if (feature.mReqFlags & !flags) != 0 {
|
||||||
return Err(StyleParseError::MediaQueryExpectedFeatureName(ident.clone()).into());
|
return Err(location.new_custom_error(
|
||||||
|
StyleParseErrorKind::MediaQueryExpectedFeatureName(ident.clone())
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
if range != nsMediaExpression_Range::eEqual &&
|
if range != nsMediaExpression_Range::eEqual &&
|
||||||
feature.mRangeType != nsMediaFeature_RangeType::eMinMaxAllowed {
|
feature.mRangeType != nsMediaFeature_RangeType::eMinMaxAllowed {
|
||||||
return Err(StyleParseError::MediaQueryExpectedFeatureName(ident.clone()).into());
|
return Err(location.new_custom_error(
|
||||||
|
StyleParseErrorKind::MediaQueryExpectedFeatureName(ident.clone())
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -671,15 +677,15 @@ impl Expression {
|
||||||
// reject them here too.
|
// reject them here too.
|
||||||
if input.try(|i| i.expect_colon()).is_err() {
|
if input.try(|i| i.expect_colon()).is_err() {
|
||||||
if range != nsMediaExpression_Range::eEqual {
|
if range != nsMediaExpression_Range::eEqual {
|
||||||
return Err(StyleParseError::RangedExpressionWithNoValue.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::RangedExpressionWithNoValue))
|
||||||
}
|
}
|
||||||
return Ok(Expression::new(feature, None, range));
|
return Ok(Expression::new(feature, None, range));
|
||||||
}
|
}
|
||||||
|
|
||||||
let value = parse_feature_value(feature,
|
let value = parse_feature_value(feature,
|
||||||
feature.mValueType,
|
feature.mValueType,
|
||||||
context, input).map_err(|_|
|
context, input).map_err(|err|
|
||||||
StyleParseError::MediaQueryExpectedFeatureValue
|
err.location.new_custom_error(StyleParseErrorKind::MediaQueryExpectedFeatureValue)
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(Expression::new(feature, Some(value), range))
|
Ok(Expression::new(feature, Some(value), range))
|
||||||
|
|
|
@ -4,18 +4,18 @@
|
||||||
|
|
||||||
//! Gecko-specific bits for selector-parsing.
|
//! Gecko-specific bits for selector-parsing.
|
||||||
|
|
||||||
use cssparser::{BasicParseError, Parser, ToCss, Token, CowRcStr};
|
use cssparser::{BasicParseError, BasicParseErrorKind, Parser, ToCss, Token, CowRcStr, SourceLocation};
|
||||||
use element_state::ElementState;
|
use element_state::ElementState;
|
||||||
use gecko_bindings::structs::CSSPseudoClassType;
|
use gecko_bindings::structs::CSSPseudoClassType;
|
||||||
use gecko_bindings::structs::RawServoSelectorList;
|
use gecko_bindings::structs::RawServoSelectorList;
|
||||||
use gecko_bindings::sugar::ownership::{HasBoxFFI, HasFFI, HasSimpleFFI};
|
use gecko_bindings::sugar::ownership::{HasBoxFFI, HasFFI, HasSimpleFFI};
|
||||||
use selector_parser::{SelectorParser, PseudoElementCascadeType};
|
use selector_parser::{SelectorParser, PseudoElementCascadeType};
|
||||||
use selectors::SelectorList;
|
use selectors::SelectorList;
|
||||||
use selectors::parser::{Selector, SelectorMethods, SelectorParseError};
|
use selectors::parser::{Selector, SelectorMethods, SelectorParseErrorKind};
|
||||||
use selectors::visitor::SelectorVisitor;
|
use selectors::visitor::SelectorVisitor;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use string_cache::{Atom, Namespace, WeakAtom, WeakNamespace};
|
use string_cache::{Atom, Namespace, WeakAtom, WeakNamespace};
|
||||||
use style_traits::{ParseError, StyleParseError};
|
use style_traits::{ParseError, StyleParseErrorKind};
|
||||||
|
|
||||||
pub use gecko::pseudo_element::{PseudoElement, EAGER_PSEUDOS, EAGER_PSEUDO_COUNT, SIMPLE_PSEUDO_COUNT};
|
pub use gecko::pseudo_element::{PseudoElement, EAGER_PSEUDOS, EAGER_PSEUDO_COUNT, SIMPLE_PSEUDO_COUNT};
|
||||||
pub use gecko::snapshot::SnapshotMap;
|
pub use gecko::snapshot::SnapshotMap;
|
||||||
|
@ -298,14 +298,14 @@ impl<'a> SelectorParser<'a> {
|
||||||
|
|
||||||
impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
|
impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
|
||||||
type Impl = SelectorImpl;
|
type Impl = SelectorImpl;
|
||||||
type Error = StyleParseError<'i>;
|
type Error = StyleParseErrorKind<'i>;
|
||||||
|
|
||||||
fn is_pseudo_element_allows_single_colon(name: &CowRcStr<'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: CowRcStr<'i>)
|
fn parse_non_ts_pseudo_class(&self, location: SourceLocation, 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),)*],
|
||||||
|
@ -313,8 +313,9 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
|
||||||
keyword: [$(($k_css:expr, $k_name:ident, $k_gecko_type:tt, $k_state:tt, $k_flags:tt),)*]) => {
|
keyword: [$(($k_css:expr, $k_name:ident, $k_gecko_type:tt, $k_state:tt, $k_flags:tt),)*]) => {
|
||||||
match_ignore_ascii_case! { &name,
|
match_ignore_ascii_case! { &name,
|
||||||
$($css => NonTSPseudoClass::$name,)*
|
$($css => NonTSPseudoClass::$name,)*
|
||||||
_ => return Err(::selectors::parser::SelectorParseError::UnsupportedPseudoClassOrElement(
|
_ => return Err(location.new_custom_error(
|
||||||
name.clone()).into())
|
SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name.clone())
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -322,7 +323,7 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
|
||||||
if self.is_pseudo_class_enabled(&pseudo_class) {
|
if self.is_pseudo_class_enabled(&pseudo_class) {
|
||||||
Ok(pseudo_class)
|
Ok(pseudo_class)
|
||||||
} else {
|
} else {
|
||||||
Err(SelectorParseError::UnsupportedPseudoClassOrElement(name).into())
|
Err(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,11 +356,15 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
|
||||||
})?;
|
})?;
|
||||||
// Selectors inside `:-moz-any` may not include combinators.
|
// Selectors inside `:-moz-any` may not include combinators.
|
||||||
if selectors.iter().flat_map(|x| x.iter_raw_match_order()).any(|s| s.is_combinator()) {
|
if selectors.iter().flat_map(|x| x.iter_raw_match_order()).any(|s| s.is_combinator()) {
|
||||||
return Err(SelectorParseError::UnexpectedIdent("-moz-any".into()).into())
|
return Err(parser.new_custom_error(
|
||||||
|
SelectorParseErrorKind::UnexpectedIdent("-moz-any".into())
|
||||||
|
))
|
||||||
}
|
}
|
||||||
NonTSPseudoClass::MozAny(selectors.into_boxed_slice())
|
NonTSPseudoClass::MozAny(selectors.into_boxed_slice())
|
||||||
}
|
}
|
||||||
_ => return Err(SelectorParseError::UnsupportedPseudoClassOrElement(name.clone()).into())
|
_ => return Err(parser.new_custom_error(
|
||||||
|
SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name.clone())
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -367,13 +372,14 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
|
||||||
if self.is_pseudo_class_enabled(&pseudo_class) {
|
if self.is_pseudo_class_enabled(&pseudo_class) {
|
||||||
Ok(pseudo_class)
|
Ok(pseudo_class)
|
||||||
} else {
|
} else {
|
||||||
Err(SelectorParseError::UnsupportedPseudoClassOrElement(name).into())
|
Err(parser.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_pseudo_element(&self, name: CowRcStr<'i>) -> Result<PseudoElement, ParseError<'i>> {
|
fn parse_pseudo_element(&self, location: SourceLocation, 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::UnsupportedPseudoClassOrElement(name.clone()).into())
|
.ok_or(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name.clone())))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_functional_pseudo_element<'t>(&self, name: CowRcStr<'i>,
|
fn parse_functional_pseudo_element<'t>(&self, name: CowRcStr<'i>,
|
||||||
|
@ -384,11 +390,12 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
|
||||||
// separated by either comma or space.
|
// separated by either comma or space.
|
||||||
let mut args = Vec::new();
|
let mut args = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
|
let location = parser.current_source_location();
|
||||||
match parser.next() {
|
match parser.next() {
|
||||||
Ok(&Token::Ident(ref ident)) => args.push(ident.as_ref().to_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.clone()).into()),
|
Ok(t) => return Err(location.new_unexpected_token_error(t.clone())),
|
||||||
Err(BasicParseError::EndOfInput) => break,
|
Err(BasicParseError { kind: BasicParseErrorKind::EndOfInput, .. }) => break,
|
||||||
_ => unreachable!("Parser::next() shouldn't return any other error"),
|
_ => unreachable!("Parser::next() shouldn't return any other error"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -397,7 +404,7 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
|
||||||
return Ok(pseudo);
|
return Ok(pseudo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(SelectorParseError::UnsupportedPseudoClassOrElement(name.clone()).into())
|
Err(parser.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name.clone())))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_namespace(&self) -> Option<Namespace> {
|
fn default_namespace(&self) -> Option<Namespace> {
|
||||||
|
|
|
@ -26,14 +26,17 @@ macro_rules! trivial_to_computed_value {
|
||||||
/// FIXME(emilio): The fact that `UnexpectedIdent` is a `SelectorParseError`
|
/// FIXME(emilio): The fact that `UnexpectedIdent` is a `SelectorParseError`
|
||||||
/// doesn't make a lot of sense to me.
|
/// doesn't make a lot of sense to me.
|
||||||
macro_rules! try_match_ident_ignore_ascii_case {
|
macro_rules! try_match_ident_ignore_ascii_case {
|
||||||
($ident:expr, $( $match_body:tt )*) => {
|
($input:expr, $( $match_body:tt )*) => {
|
||||||
let __ident = $ident;
|
let location = $input.current_source_location();
|
||||||
(match_ignore_ascii_case! { &*__ident,
|
let ident = $input.expect_ident_cloned()?;
|
||||||
|
(match_ignore_ascii_case! { &ident,
|
||||||
$( $match_body )*
|
$( $match_body )*
|
||||||
_ => Err(()),
|
_ => Err(()),
|
||||||
})
|
})
|
||||||
.map_err(|()| {
|
.map_err(|()| {
|
||||||
::selectors::parser::SelectorParseError::UnexpectedIdent(__ident.clone()).into()
|
location.new_custom_error(
|
||||||
|
::selectors::parser::SelectorParseErrorKind::UnexpectedIdent(ident.clone())
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,7 +59,7 @@ macro_rules! define_numbered_css_keyword_enum {
|
||||||
_context: &$crate::parser::ParserContext,
|
_context: &$crate::parser::ParserContext,
|
||||||
input: &mut ::cssparser::Parser<'i, 't>,
|
input: &mut ::cssparser::Parser<'i, 't>,
|
||||||
) -> Result<$name, ::style_traits::ParseError<'i>> {
|
) -> Result<$name, ::style_traits::ParseError<'i>> {
|
||||||
try_match_ident_ignore_ascii_case! { input.expect_ident()?,
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
$( $css => Ok($name::$variant), )+
|
$( $css => Ok($name::$variant), )+
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,11 @@ use cssparser::{Delimiter, Parser};
|
||||||
use cssparser::{Token, ParserInput};
|
use cssparser::{Token, ParserInput};
|
||||||
use error_reporting::{ContextualParseError, ParseErrorReporter};
|
use error_reporting::{ContextualParseError, ParseErrorReporter};
|
||||||
use parser::{ParserContext, ParserErrorContext};
|
use parser::{ParserContext, ParserErrorContext};
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use serialize_comma_separated_list;
|
use serialize_comma_separated_list;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use str::string_as_ascii_lowercase;
|
use str::string_as_ascii_lowercase;
|
||||||
use style_traits::{ToCss, ParseError, StyleParseError};
|
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
|
||||||
use values::CustomIdent;
|
use values::CustomIdent;
|
||||||
|
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
|
@ -210,13 +210,13 @@ impl MediaQuery {
|
||||||
let media_type = match input.try(|i| i.expect_ident_cloned()) {
|
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.clone()).into());
|
.map_err(|()| input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone())));
|
||||||
result?
|
result?
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
// Media type is only optional if qualifier is not specified.
|
// Media type is only optional if qualifier is not specified.
|
||||||
if qualifier.is_some() {
|
if qualifier.is_some() {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Without a media type, require at least one expression.
|
// Without a media type, require at least one expression.
|
||||||
|
@ -257,17 +257,17 @@ where
|
||||||
let mut media_queries = vec![];
|
let mut media_queries = vec![];
|
||||||
loop {
|
loop {
|
||||||
let start_position = input.position();
|
let start_position = input.position();
|
||||||
let start_location = input.current_source_location();
|
|
||||||
match input.parse_until_before(Delimiter::Comma, |i| MediaQuery::parse(context, i)) {
|
match input.parse_until_before(Delimiter::Comma, |i| MediaQuery::parse(context, i)) {
|
||||||
Ok(mq) => {
|
Ok(mq) => {
|
||||||
media_queries.push(mq);
|
media_queries.push(mq);
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
media_queries.push(MediaQuery::never_matching());
|
media_queries.push(MediaQuery::never_matching());
|
||||||
|
let location = err.location;
|
||||||
let error = ContextualParseError::InvalidMediaRule(
|
let error = ContextualParseError::InvalidMediaRule(
|
||||||
input.slice_from(start_position), err);
|
input.slice_from(start_position), err);
|
||||||
let error_context = ParserErrorContext { error_reporter };
|
let error_context = ParserErrorContext { error_reporter };
|
||||||
context.log_css_error(&error_context, start_location, error);
|
context.log_css_error(&error_context, location, error);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,19 +8,18 @@
|
||||||
|
|
||||||
use context::QuirksMode;
|
use context::QuirksMode;
|
||||||
use cssparser::{DeclarationListParser, parse_important, ParserInput, CowRcStr};
|
use cssparser::{DeclarationListParser, parse_important, ParserInput, CowRcStr};
|
||||||
use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter, ParseError as CssParseError};
|
use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter, ParseErrorKind};
|
||||||
use custom_properties::CustomPropertiesBuilder;
|
use custom_properties::CustomPropertiesBuilder;
|
||||||
use error_reporting::{ParseErrorReporter, ContextualParseError};
|
use error_reporting::{ParseErrorReporter, ContextualParseError};
|
||||||
use parser::{ParserContext, ParserErrorContext};
|
use parser::{ParserContext, ParserErrorContext};
|
||||||
use properties::animated_properties::AnimationValue;
|
use properties::animated_properties::AnimationValue;
|
||||||
use selectors::parser::SelectorParseError;
|
|
||||||
use shared_lock::Locked;
|
use shared_lock::Locked;
|
||||||
use smallbitvec::{self, SmallBitVec};
|
use smallbitvec::{self, SmallBitVec};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::iter::{DoubleEndedIterator, Zip};
|
use std::iter::{DoubleEndedIterator, Zip};
|
||||||
use std::slice::Iter;
|
use std::slice::Iter;
|
||||||
use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, ParsingMode, StyleParseError};
|
use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, ParsingMode, StyleParseErrorKind};
|
||||||
use stylesheets::{CssRuleType, Origin, UrlExtraData};
|
use stylesheets::{CssRuleType, Origin, UrlExtraData};
|
||||||
use super::*;
|
use super::*;
|
||||||
use values::computed::Context;
|
use values::computed::Context;
|
||||||
|
@ -1035,16 +1034,16 @@ pub fn parse_one_declaration_into<R>(declarations: &mut SourcePropertyDeclaratio
|
||||||
let mut input = ParserInput::new(input);
|
let mut input = ParserInput::new(input);
|
||||||
let mut parser = Parser::new(&mut input);
|
let mut parser = Parser::new(&mut input);
|
||||||
let start_position = parser.position();
|
let start_position = parser.position();
|
||||||
let start_location = parser.current_source_location();
|
|
||||||
parser.parse_entirely(|parser| {
|
parser.parse_entirely(|parser| {
|
||||||
let name = id.name().into();
|
let name = id.name().into();
|
||||||
PropertyDeclaration::parse_into(declarations, id, name, &context, parser)
|
PropertyDeclaration::parse_into(declarations, id, name, &context, parser)
|
||||||
.map_err(|e| e.into())
|
.map_err(|e| e.into())
|
||||||
}).map_err(|err| {
|
}).map_err(|err| {
|
||||||
|
let location = err.location;
|
||||||
let error = ContextualParseError::UnsupportedPropertyDeclaration(
|
let error = ContextualParseError::UnsupportedPropertyDeclaration(
|
||||||
parser.slice_from(start_position), err);
|
parser.slice_from(start_position), err);
|
||||||
let error_context = ParserErrorContext { error_reporter: error_reporter };
|
let error_context = ParserErrorContext { error_reporter: error_reporter };
|
||||||
context.log_css_error(&error_context, start_location, error);
|
context.log_css_error(&error_context, location, error);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1060,7 +1059,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for PropertyDeclarationParser<'a, 'b> {
|
||||||
type PreludeNoBlock = ();
|
type PreludeNoBlock = ();
|
||||||
type PreludeBlock = ();
|
type PreludeBlock = ();
|
||||||
type AtRule = Importance;
|
type AtRule = Importance;
|
||||||
type Error = SelectorParseError<'i, StyleParseError<'i>>;
|
type Error = StyleParseErrorKind<'i>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Based on NonMozillaVendorIdentifier from Gecko's CSS parser.
|
/// Based on NonMozillaVendorIdentifier from Gecko's CSS parser.
|
||||||
|
@ -1071,7 +1070,7 @@ fn is_non_mozilla_vendor_identifier(name: &str) -> bool {
|
||||||
|
|
||||||
impl<'a, 'b, 'i> DeclarationParser<'i> for PropertyDeclarationParser<'a, 'b> {
|
impl<'a, 'b, 'i> DeclarationParser<'i> for PropertyDeclarationParser<'a, 'b> {
|
||||||
type Declaration = Importance;
|
type Declaration = Importance;
|
||||||
type Error = SelectorParseError<'i, StyleParseError<'i>>;
|
type Error = StyleParseErrorKind<'i>;
|
||||||
|
|
||||||
fn parse_value<'t>(&mut self, name: CowRcStr<'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>> {
|
||||||
|
@ -1079,11 +1078,11 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for PropertyDeclarationParser<'a, 'b> {
|
||||||
let id = match PropertyId::parse(&name, Some(&prop_context)) {
|
let id = match PropertyId::parse(&name, Some(&prop_context)) {
|
||||||
Ok(id) => id,
|
Ok(id) => id,
|
||||||
Err(()) => {
|
Err(()) => {
|
||||||
return Err(if is_non_mozilla_vendor_identifier(&name) {
|
return Err(input.new_custom_error(if is_non_mozilla_vendor_identifier(&name) {
|
||||||
PropertyDeclarationParseError::UnknownVendorProperty
|
StyleParseErrorKind::UnknownVendorProperty
|
||||||
} else {
|
} else {
|
||||||
PropertyDeclarationParseError::UnknownProperty(name)
|
StyleParseErrorKind::UnknownProperty(name)
|
||||||
}.into());
|
}));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
input.parse_until_before(Delimiter::Bang, |input| {
|
input.parse_until_before(Delimiter::Bang, |input| {
|
||||||
|
@ -1121,19 +1120,18 @@ pub fn parse_property_declaration_list<R>(context: &ParserContext,
|
||||||
Ok(importance) => {
|
Ok(importance) => {
|
||||||
block.extend(iter.parser.declarations.drain(), importance);
|
block.extend(iter.parser.declarations.drain(), importance);
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err((error, slice)) => {
|
||||||
iter.parser.declarations.clear();
|
iter.parser.declarations.clear();
|
||||||
|
|
||||||
// If the unrecognized property looks like a vendor-specific property,
|
// If the unrecognized property looks like a vendor-specific property,
|
||||||
// silently ignore it instead of polluting the error output.
|
// silently ignore it instead of polluting the error output.
|
||||||
if let CssParseError::Custom(SelectorParseError::Custom(
|
if let ParseErrorKind::Custom(StyleParseErrorKind::UnknownVendorProperty) = error.kind {
|
||||||
StyleParseError::PropertyDeclaration(
|
|
||||||
PropertyDeclarationParseError::UnknownVendorProperty))) = err.error {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let error = ContextualParseError::UnsupportedPropertyDeclaration(err.slice, err.error);
|
let location = error.location;
|
||||||
context.log_css_error(error_context, err.location, error);
|
let error = ContextualParseError::UnsupportedPropertyDeclaration(slice, error);
|
||||||
|
context.log_css_error(error_context, location, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,9 +93,9 @@
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use properties::ShorthandId;
|
use properties::ShorthandId;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use style_traits::{ParseError, StyleParseError};
|
use style_traits::{ParseError, StyleParseErrorKind};
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use values::computed::{Context, ToComputedValue};
|
use values::computed::{Context, ToComputedValue};
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
|
@ -285,11 +285,11 @@
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use properties::style_structs;
|
use properties::style_structs;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use style_traits::{ParseError, StyleParseError};
|
use style_traits::{ParseError, StyleParseErrorKind};
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use values::computed::{Context, ToComputedValue};
|
use values::computed::{Context, ToComputedValue};
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
|
@ -699,11 +699,11 @@
|
||||||
use parser::ParserContext;
|
use parser::ParserContext;
|
||||||
use properties::{PropertyDeclaration, SourcePropertyDeclaration, MaybeBoxed, longhands};
|
use properties::{PropertyDeclaration, SourcePropertyDeclaration, MaybeBoxed, longhands};
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use style_traits::{ParseError, StyleParseError};
|
use style_traits::{ParseError, StyleParseErrorKind};
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
|
|
||||||
|
@ -992,7 +992,7 @@
|
||||||
// Keyword values don't make sense in the block direction; don't parse them
|
// Keyword values don't make sense in the block direction; don't parse them
|
||||||
% if "block" in name:
|
% if "block" in name:
|
||||||
if let Ok(${length_type}::ExtremumLength(..)) = ret {
|
if let Ok(${length_type}::ExtremumLength(..)) = ret {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
% endif
|
% endif
|
||||||
ret.map(SpecifiedValue)
|
ret.map(SpecifiedValue)
|
||||||
|
|
|
@ -25,7 +25,7 @@ use properties::longhands::visibility::computed_value::T as Visibility;
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use properties::PropertyId;
|
use properties::PropertyId;
|
||||||
use properties::{LonghandId, ShorthandId};
|
use properties::{LonghandId, ShorthandId};
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
@ -134,6 +134,7 @@ impl TransitionProperty {
|
||||||
|
|
||||||
/// Parse a transition-property value.
|
/// Parse a transition-property 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>> {
|
||||||
|
let location = input.current_source_location();
|
||||||
let ident = input.expect_ident()?;
|
let ident = input.expect_ident()?;
|
||||||
match_ignore_ascii_case! { &ident,
|
match_ignore_ascii_case! { &ident,
|
||||||
"all" => Ok(TransitionProperty::All),
|
"all" => Ok(TransitionProperty::All),
|
||||||
|
@ -143,8 +144,8 @@ impl TransitionProperty {
|
||||||
% for prop in data.longhands:
|
% for prop in data.longhands:
|
||||||
"${prop.name}" => Ok(TransitionProperty::Longhand(LonghandId::${prop.camel_case})),
|
"${prop.name}" => Ok(TransitionProperty::Longhand(LonghandId::${prop.camel_case})),
|
||||||
% endfor
|
% endfor
|
||||||
"none" => Err(SelectorParseError::UnexpectedIdent(ident.clone()).into()),
|
"none" => Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))),
|
||||||
_ => CustomIdent::from_ident(ident, &[]).map(TransitionProperty::Unsupported),
|
_ => CustomIdent::from_ident(location, ident, &[]).map(TransitionProperty::Unsupported),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,7 +132,7 @@ ${helpers.predefined_type("background-image", "ImageLayer",
|
||||||
_ => 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.clone()).into());
|
.map_err(|()| input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone())));
|
||||||
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))
|
||||||
|
|
|
@ -187,7 +187,7 @@ ${helpers.gecko_keyword_conversion(Keyword('border-style',
|
||||||
if !result.is_empty() {
|
if !result.is_empty() {
|
||||||
Ok(SpecifiedValue::Colors(result))
|
Ok(SpecifiedValue::Colors(result))
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
|
@ -165,7 +165,7 @@
|
||||||
/// Parse a display value.
|
/// Parse a display value.
|
||||||
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()?,
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
% for value in values:
|
% for value in values:
|
||||||
"${value}" => {
|
"${value}" => {
|
||||||
Ok(computed_value::T::${to_rust_ident(value)})
|
Ok(computed_value::T::${to_rust_ident(value)})
|
||||||
|
@ -545,7 +545,7 @@ ${helpers.predefined_type("animation-timing-function",
|
||||||
|
|
||||||
let number = input.expect_number()?;
|
let number = input.expect_number()?;
|
||||||
if number < 0.0 {
|
if number < 0.0 {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(SpecifiedValue::Number(number))
|
Ok(SpecifiedValue::Number(number))
|
||||||
|
@ -1177,7 +1177,7 @@ ${helpers.predefined_type(
|
||||||
_ => Err(()),
|
_ => Err(()),
|
||||||
};
|
};
|
||||||
result
|
result
|
||||||
.map_err(|()| StyleParseError::UnexpectedFunction(function.clone()).into())
|
.map_err(|()| input.new_custom_error(StyleParseErrorKind::UnexpectedFunction(function.clone())))
|
||||||
})
|
})
|
||||||
})?))
|
})?))
|
||||||
}
|
}
|
||||||
|
@ -1730,7 +1730,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.clone()).into())
|
_ => return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone())))
|
||||||
};
|
};
|
||||||
result.insert(flag);
|
result.insert(flag);
|
||||||
}
|
}
|
||||||
|
@ -1738,7 +1738,7 @@ ${helpers.predefined_type("transform-origin",
|
||||||
if !result.is_empty() {
|
if !result.is_empty() {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
@ -1839,7 +1839,8 @@ ${helpers.single_keyword("-moz-orient",
|
||||||
Ok(computed_value::T::Auto)
|
Ok(computed_value::T::Auto)
|
||||||
} else {
|
} else {
|
||||||
input.parse_comma_separated(|i| {
|
input.parse_comma_separated(|i| {
|
||||||
CustomIdent::from_ident(i.expect_ident()?, &[
|
let location = i.current_source_location();
|
||||||
|
CustomIdent::from_ident(location, i.expect_ident()?, &[
|
||||||
"will-change",
|
"will-change",
|
||||||
"none",
|
"none",
|
||||||
"all",
|
"all",
|
||||||
|
@ -1914,7 +1915,7 @@ ${helpers.predefined_type(
|
||||||
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>> {
|
||||||
// FIXME: remove clone() when lifetimes are non-lexical
|
// FIXME: remove clone() when lifetimes are non-lexical
|
||||||
try_match_ident_ignore_ascii_case! { input.expect_ident()?.clone(),
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
"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),
|
||||||
|
|
|
@ -205,7 +205,9 @@
|
||||||
};
|
};
|
||||||
match result {
|
match result {
|
||||||
Some(result) => content.push(result?),
|
Some(result) => content.push(result?),
|
||||||
None => return Err(StyleParseError::UnexpectedFunction(name.clone()).into())
|
None => return Err(input.new_custom_error(
|
||||||
|
StyleParseErrorKind::UnexpectedFunction(name.clone())
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Token::Ident(ref ident)) => {
|
Ok(Token::Ident(ref ident)) => {
|
||||||
|
@ -218,15 +220,15 @@
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
if !valid {
|
if !valid {
|
||||||
return Err(SelectorParseError::UnexpectedIdent(ident.clone()).into())
|
return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(_) => break,
|
Err(_) => break,
|
||||||
Ok(t) => return Err(BasicParseError::UnexpectedToken(t).into())
|
Ok(t) => return Err(input.new_unexpected_token_error(t))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if content.is_empty() {
|
if content.is_empty() {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
Ok(SpecifiedValue::Items(content))
|
Ok(SpecifiedValue::Items(content))
|
||||||
}
|
}
|
||||||
|
@ -332,9 +334,10 @@
|
||||||
|
|
||||||
let mut counters = Vec::new();
|
let mut counters = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
|
let location = input.current_source_location();
|
||||||
let counter_name = match input.next() {
|
let counter_name = match input.next() {
|
||||||
Ok(&Token::Ident(ref ident)) => CustomIdent::from_ident(ident, &["none"])?,
|
Ok(&Token::Ident(ref ident)) => CustomIdent::from_ident(location, ident, &["none"])?,
|
||||||
Ok(t) => return Err(BasicParseError::UnexpectedToken(t.clone()).into()),
|
Ok(t) => return Err(location.new_unexpected_token_error(t.clone())),
|
||||||
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))
|
||||||
|
@ -345,7 +348,7 @@
|
||||||
if !counters.is_empty() {
|
if !counters.is_empty() {
|
||||||
Ok(SpecifiedValue(counters))
|
Ok(SpecifiedValue(counters))
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
|
@ -587,7 +587,7 @@ macro_rules! impl_gecko_keyword_conversions {
|
||||||
fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||||
match FontFamily::parse(input) {
|
match FontFamily::parse(input) {
|
||||||
Ok(FontFamily::FamilyName(name)) => Ok(name),
|
Ok(FontFamily::FamilyName(name)) => Ok(name),
|
||||||
Ok(FontFamily::Generic(_)) => Err(StyleParseError::UnspecifiedError.into()),
|
Ok(FontFamily::Generic(_)) => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
|
||||||
Err(e) => Err(e)
|
Err(e) => Err(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -744,7 +744,7 @@ ${helpers.single_keyword_system("font-variant-caps",
|
||||||
fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>)
|
fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>)
|
||||||
-> Result<Self, ParseError<'i>> {
|
-> Result<Self, ParseError<'i>> {
|
||||||
Self::from_int(input.expect_integer()?)
|
Self::from_int(input.expect_integer()?)
|
||||||
.map_err(|_| StyleParseError::UnspecifiedError.into())
|
.map_err(|_| input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -837,7 +837,7 @@ ${helpers.single_keyword_system("font-variant-caps",
|
||||||
return Ok(SpecifiedValue::Keyword(kw.into()))
|
return Ok(SpecifiedValue::Keyword(kw.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
try_match_ident_ignore_ascii_case! { input.expect_ident()?,
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
"smaller" => Ok(SpecifiedValue::Smaller),
|
"smaller" => Ok(SpecifiedValue::Smaller),
|
||||||
"larger" => Ok(SpecifiedValue::Larger),
|
"larger" => Ok(SpecifiedValue::Larger),
|
||||||
}
|
}
|
||||||
|
@ -1082,7 +1082,7 @@ ${helpers.single_keyword_system("font-variant-caps",
|
||||||
-> Result<SpecifiedValue, ParseError<'i>> {
|
-> Result<SpecifiedValue, ParseError<'i>> {
|
||||||
let mut result = SpecifiedValue { weight: false, style: false };
|
let mut result = SpecifiedValue { weight: false, style: false };
|
||||||
// FIXME: remove clone() when lifetimes are non-lexical
|
// FIXME: remove clone() when lifetimes are non-lexical
|
||||||
try_match_ident_ignore_ascii_case! { input.expect_ident()?.clone(),
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
"none" => Ok(result),
|
"none" => Ok(result),
|
||||||
"weight" => {
|
"weight" => {
|
||||||
result.weight = true;
|
result.weight = true;
|
||||||
|
@ -1298,9 +1298,9 @@ ${helpers.single_keyword_system("font-kerning",
|
||||||
|
|
||||||
let mut parsed_alternates = ParsingFlags::empty();
|
let mut parsed_alternates = ParsingFlags::empty();
|
||||||
macro_rules! check_if_parsed(
|
macro_rules! check_if_parsed(
|
||||||
($flag:ident) => (
|
($input:expr, $flag:ident) => (
|
||||||
if parsed_alternates.contains($flag) {
|
if parsed_alternates.contains($flag) {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err($input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
parsed_alternates |= $flag;
|
parsed_alternates |= $flag;
|
||||||
)
|
)
|
||||||
|
@ -1310,11 +1310,11 @@ ${helpers.single_keyword_system("font-kerning",
|
||||||
match input.next()?.clone() {
|
match input.next()?.clone() {
|
||||||
Token::Ident(ref ident) => {
|
Token::Ident(ref ident) => {
|
||||||
if *ident == "historical-forms" {
|
if *ident == "historical-forms" {
|
||||||
check_if_parsed!(HISTORICAL_FORMS);
|
check_if_parsed!(input, HISTORICAL_FORMS);
|
||||||
alternates.push(VariantAlternates::HistoricalForms);
|
alternates.push(VariantAlternates::HistoricalForms);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Token::Function(ref name) => {
|
Token::Function(ref name) => {
|
||||||
|
@ -1322,31 +1322,34 @@ ${helpers.single_keyword_system("font-kerning",
|
||||||
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():
|
||||||
"${value}" => {
|
"${value}" => {
|
||||||
check_if_parsed!(${value.upper()});
|
check_if_parsed!(i, ${value.upper()});
|
||||||
let ident = CustomIdent::from_ident(i.expect_ident()?, &[])?;
|
let location = i.current_source_location();
|
||||||
|
let ident = CustomIdent::from_ident(location, i.expect_ident()?, &[])?;
|
||||||
alternates.push(VariantAlternates::${to_camel_case(value)}(ident));
|
alternates.push(VariantAlternates::${to_camel_case(value)}(ident));
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
% endfor
|
% endfor
|
||||||
% for value in "styleset character-variant".split():
|
% for value in "styleset character-variant".split():
|
||||||
"${value}" => {
|
"${value}" => {
|
||||||
check_if_parsed!(${to_rust_ident(value).upper()});
|
check_if_parsed!(i, ${to_rust_ident(value).upper()});
|
||||||
let idents = i.parse_comma_separated(|i|
|
let idents = i.parse_comma_separated(|i| {
|
||||||
CustomIdent::from_ident(i.expect_ident()?, &[]))?;
|
let location = i.current_source_location();
|
||||||
|
CustomIdent::from_ident(location, i.expect_ident()?, &[])
|
||||||
|
})?;
|
||||||
alternates.push(VariantAlternates::${to_camel_case(value)}(idents.into_boxed_slice()));
|
alternates.push(VariantAlternates::${to_camel_case(value)}(idents.into_boxed_slice()));
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
% endfor
|
% endfor
|
||||||
_ => return Err(StyleParseError::UnspecifiedError.into()),
|
_ => return Err(i.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
_ => Err(StyleParseError::UnspecifiedError.into()),
|
_ => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
|
||||||
}
|
}
|
||||||
}) { }
|
}) { }
|
||||||
|
|
||||||
if parsed_alternates.is_empty() {
|
if parsed_alternates.is_empty() {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
Ok(SpecifiedValue::Value(VariantAlternatesList(alternates.into_boxed_slice())))
|
Ok(SpecifiedValue::Value(VariantAlternatesList(alternates.into_boxed_slice())))
|
||||||
}
|
}
|
||||||
|
@ -1501,7 +1504,7 @@ macro_rules! exclusive_value {
|
||||||
if !result.is_empty() {
|
if !result.is_empty() {
|
||||||
Ok(SpecifiedValue::Value(result))
|
Ok(SpecifiedValue::Value(result))
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1661,7 +1664,7 @@ macro_rules! exclusive_value {
|
||||||
if !result.is_empty() {
|
if !result.is_empty() {
|
||||||
Ok(SpecifiedValue::Value(result))
|
Ok(SpecifiedValue::Value(result))
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1809,7 +1812,7 @@ macro_rules! exclusive_value {
|
||||||
if !result.is_empty() {
|
if !result.is_empty() {
|
||||||
Ok(SpecifiedValue::Value(result))
|
Ok(SpecifiedValue::Value(result))
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2082,10 +2085,10 @@ https://drafts.csswg.org/css-fonts-4/#low-level-font-variation-settings-control-
|
||||||
computed_value::T(atom!(""))
|
computed_value::T(atom!(""))
|
||||||
}
|
}
|
||||||
|
|
||||||
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>> {
|
||||||
debug_assert!(false, "Should be set directly by presentation attributes only.");
|
debug_assert!(false, "Should be set directly by presentation attributes only.");
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
||||||
|
@ -2105,10 +2108,10 @@ https://drafts.csswg.org/css-fonts-4/#low-level-font-variation-settings-control-
|
||||||
::gecko_bindings::structs::NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER as f32
|
::gecko_bindings::structs::NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER as f32
|
||||||
}
|
}
|
||||||
|
|
||||||
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>> {
|
||||||
debug_assert!(false, "Should be set directly by presentation attributes only.");
|
debug_assert!(false, "Should be set directly by presentation attributes only.");
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
||||||
|
@ -2254,10 +2257,10 @@ ${helpers.single_keyword("-moz-math-variant",
|
||||||
Length::new(NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT as f32 * (AU_PER_PT / AU_PER_PX))
|
Length::new(NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT as f32 * (AU_PER_PT / AU_PER_PX))
|
||||||
}
|
}
|
||||||
|
|
||||||
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>> {
|
||||||
debug_assert!(false, "Should be set directly by presentation attributes only.");
|
debug_assert!(false, "Should be set directly by presentation attributes only.");
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
||||||
|
@ -2287,10 +2290,10 @@ ${helpers.single_keyword("-moz-math-variant",
|
||||||
computed_value::T(true)
|
computed_value::T(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
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>> {
|
||||||
debug_assert!(false, "Should be set directly by presentation attributes only.");
|
debug_assert!(false, "Should be set directly by presentation attributes only.");
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
||||||
|
@ -2445,7 +2448,7 @@ ${helpers.single_keyword("-moz-math-variant",
|
||||||
|
|
||||||
impl SystemFont {
|
impl SystemFont {
|
||||||
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>> {
|
||||||
try_match_ident_ignore_ascii_case! { input.expect_ident()?,
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
% for font in system_fonts:
|
% for font in system_fonts:
|
||||||
"${font}" => Ok(SystemFont::${to_camel_case(font)}),
|
"${font}" => Ok(SystemFont::${to_camel_case(font)}),
|
||||||
% endfor
|
% endfor
|
||||||
|
|
|
@ -241,7 +241,7 @@ ${helpers.single_keyword("image-rendering",
|
||||||
// Handle <angle> | <angle> flip
|
// Handle <angle> | <angle> flip
|
||||||
let angle = input.try(|input| Angle::parse(context, input)).ok();
|
let angle = input.try(|input| Angle::parse(context, input)).ok();
|
||||||
if angle.is_none() {
|
if angle.is_none() {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
|
|
||||||
let flipped = input.try(|input| input.expect_ident_matching("flip")).is_ok();
|
let flipped = input.try(|input| input.expect_ident_matching("flip")).is_ok();
|
||||||
|
|
|
@ -207,8 +207,8 @@ ${helpers.predefined_type("marker-end", "UrlOrNone", "Either::Second(None_)",
|
||||||
let mut pos = 0;
|
let mut pos = 0;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let result: Result<_, ParseError> = input.try(|i| {
|
let result: Result<_, ParseError> = input.try(|input| {
|
||||||
try_match_ident_ignore_ascii_case! { i.expect_ident()?,
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
"fill" => Ok(PaintOrder::Fill),
|
"fill" => Ok(PaintOrder::Fill),
|
||||||
"stroke" => Ok(PaintOrder::Stroke),
|
"stroke" => Ok(PaintOrder::Stroke),
|
||||||
"markers" => Ok(PaintOrder::Markers),
|
"markers" => Ok(PaintOrder::Markers),
|
||||||
|
@ -219,7 +219,7 @@ ${helpers.predefined_type("marker-end", "UrlOrNone", "Either::Second(None_)",
|
||||||
Ok(val) => {
|
Ok(val) => {
|
||||||
if (seen & (1 << val as u8)) != 0 {
|
if (seen & (1 << val as u8)) != 0 {
|
||||||
// don't parse the same ident twice
|
// don't parse the same ident twice
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
||||||
value |= (val as u8) << (pos * SHIFT);
|
value |= (val as u8) << (pos * SHIFT);
|
||||||
|
@ -232,7 +232,7 @@ ${helpers.predefined_type("marker-end", "UrlOrNone", "Either::Second(None_)",
|
||||||
|
|
||||||
if value == 0 {
|
if value == 0 {
|
||||||
// Couldn't find any keyword
|
// Couldn't find any keyword
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill in rest
|
// fill in rest
|
||||||
|
@ -293,7 +293,8 @@ ${helpers.predefined_type("marker-end", "UrlOrNone", "Either::Second(None_)",
|
||||||
|
|
||||||
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 location = input.current_source_location();
|
||||||
let i = input.expect_ident()?;
|
let i = input.expect_ident()?;
|
||||||
CustomIdent::from_ident(i, &["all", "none", "auto"])
|
CustomIdent::from_ident(location, i, &["all", "none", "auto"])
|
||||||
}
|
}
|
||||||
</%helpers:vector_longhand>
|
</%helpers:vector_longhand>
|
||||||
|
|
|
@ -585,7 +585,7 @@ ${helpers.predefined_type(
|
||||||
(Some(fill), Ok(shape)) => KeywordValue::FillAndShape(fill,shape),
|
(Some(fill), Ok(shape)) => KeywordValue::FillAndShape(fill,shape),
|
||||||
(Some(fill), Err(_)) => KeywordValue::Fill(fill),
|
(Some(fill), Err(_)) => KeywordValue::Fill(fill),
|
||||||
(None, Ok(shape)) => KeywordValue::Shape(shape),
|
(None, Ok(shape)) => KeywordValue::Shape(shape),
|
||||||
_ => return Err(StyleParseError::UnspecifiedError.into()),
|
_ => return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
|
||||||
};
|
};
|
||||||
Ok(SpecifiedValue::Keyword(keyword_value))
|
Ok(SpecifiedValue::Keyword(keyword_value))
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,14 +188,16 @@ ${helpers.single_keyword("list-style-position", "outside inside", animation_valu
|
||||||
|
|
||||||
let mut quotes = Vec::new();
|
let mut quotes = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
|
let location = input.current_source_location();
|
||||||
let first = match input.next() {
|
let first = match input.next() {
|
||||||
Ok(&Token::QuotedString(ref value)) => value.as_ref().to_owned(),
|
Ok(&Token::QuotedString(ref value)) => value.as_ref().to_owned(),
|
||||||
Ok(t) => return Err(BasicParseError::UnexpectedToken(t.clone()).into()),
|
Ok(t) => return Err(location.new_unexpected_token_error(t.clone())),
|
||||||
Err(_) => break,
|
Err(_) => break,
|
||||||
};
|
};
|
||||||
|
let location = input.current_source_location();
|
||||||
let second = match input.next() {
|
let second = match input.next() {
|
||||||
Ok(&Token::QuotedString(ref value)) => value.as_ref().to_owned(),
|
Ok(&Token::QuotedString(ref value)) => value.as_ref().to_owned(),
|
||||||
Ok(t) => return Err(BasicParseError::UnexpectedToken(t.clone()).into()),
|
Ok(t) => return Err(location.new_unexpected_token_error(t.clone())),
|
||||||
Err(e) => return Err(e.into()),
|
Err(e) => return Err(e.into()),
|
||||||
};
|
};
|
||||||
quotes.push((first, second))
|
quotes.push((first, second))
|
||||||
|
@ -203,7 +205,7 @@ ${helpers.single_keyword("list-style-position", "outside inside", animation_valu
|
||||||
if !quotes.is_empty() {
|
if !quotes.is_empty() {
|
||||||
Ok(SpecifiedValue(quotes))
|
Ok(SpecifiedValue(quotes))
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
|
@ -58,7 +58,7 @@ ${helpers.predefined_type(
|
||||||
// The outline-style property accepts the same values as
|
// The outline-style property accepts the same values as
|
||||||
// border-style, except that 'hidden' is not a legal outline
|
// border-style, except that 'hidden' is not a legal outline
|
||||||
// style.
|
// style.
|
||||||
Err(SelectorParseError::UnexpectedIdent("hidden".into()).into())
|
Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent("hidden".into())))
|
||||||
} else {
|
} else {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,13 +92,14 @@
|
||||||
-> Result<computed_value::Keyword, ParseError<'i>> {
|
-> Result<computed_value::Keyword, ParseError<'i>> {
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use style_traits::cursor::Cursor;
|
use style_traits::cursor::Cursor;
|
||||||
|
let location = input.current_source_location();
|
||||||
let ident = input.expect_ident()?;
|
let ident = input.expect_ident()?;
|
||||||
if ident.eq_ignore_ascii_case("auto") {
|
if ident.eq_ignore_ascii_case("auto") {
|
||||||
Ok(computed_value::Keyword::Auto)
|
Ok(computed_value::Keyword::Auto)
|
||||||
} 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.clone()).into())
|
.map_err(|()| location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -340,6 +340,7 @@ ${helpers.predefined_type("object-position",
|
||||||
let mut dense = false;
|
let mut dense = false;
|
||||||
|
|
||||||
while !input.is_exhausted() {
|
while !input.is_exhausted() {
|
||||||
|
let location = input.current_source_location();
|
||||||
let ident = input.expect_ident()?;
|
let ident = input.expect_ident()?;
|
||||||
let success = match_ignore_ascii_case! { &ident,
|
let success = match_ignore_ascii_case! { &ident,
|
||||||
"row" if value.is_none() => {
|
"row" if value.is_none() => {
|
||||||
|
@ -357,7 +358,7 @@ ${helpers.predefined_type("object-position",
|
||||||
_ => false
|
_ => false
|
||||||
};
|
};
|
||||||
if !success {
|
if !success {
|
||||||
return Err(SelectorParseError::UnexpectedIdent(ident.clone()).into());
|
return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,7 +368,7 @@ ${helpers.predefined_type("object-position",
|
||||||
dense: dense,
|
dense: dense,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,7 +466,7 @@ ${helpers.predefined_type("object-position",
|
||||||
}
|
}
|
||||||
|
|
||||||
TemplateAreas::from_vec(strings)
|
TemplateAreas::from_vec(strings)
|
||||||
.map_err(|()| StyleParseError::UnspecifiedError.into())
|
.map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,8 +39,8 @@ ${helpers.single_keyword("table-layout", "auto fixed",
|
||||||
// never parse it, only set via presentation attribute
|
// never parse it, only set via presentation attribute
|
||||||
fn parse<'i, 't>(
|
fn parse<'i, 't>(
|
||||||
_: &ParserContext,
|
_: &ParserContext,
|
||||||
_: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<SpecifiedValue, ParseError<'i>> {
|
) -> Result<SpecifiedValue, ParseError<'i>> {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
|
@ -119,17 +119,21 @@
|
||||||
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>> {
|
||||||
|
let location = input.current_source_location();
|
||||||
match *input.next()? {
|
match *input.next()? {
|
||||||
Token::Ident(ref ident) => {
|
Token::Ident(ref ident) => {
|
||||||
try_match_ident_ignore_ascii_case! { ident,
|
match_ignore_ascii_case! { ident,
|
||||||
"clip" => Ok(Side::Clip),
|
"clip" => Ok(Side::Clip),
|
||||||
"ellipsis" => Ok(Side::Ellipsis),
|
"ellipsis" => Ok(Side::Ellipsis),
|
||||||
|
_ => Err(location.new_custom_error(
|
||||||
|
SelectorParseErrorKind::UnexpectedIdent(ident.clone())
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Token::QuotedString(ref v) => {
|
Token::QuotedString(ref v) => {
|
||||||
Ok(Side::String(v.as_ref().to_owned().into_boxed_str()))
|
Ok(Side::String(v.as_ref().to_owned().into_boxed_str()))
|
||||||
}
|
}
|
||||||
ref t => Err(BasicParseError::UnexpectedToken(t.clone()).into()),
|
ref t => Err(location.new_unexpected_token_error(t.clone())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,6 +226,7 @@ ${helpers.single_keyword("unicode-bidi",
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let result: Result<_, ParseError> = input.try(|input| {
|
let result: Result<_, ParseError> = input.try(|input| {
|
||||||
|
let location = input.current_source_location();
|
||||||
match input.expect_ident() {
|
match input.expect_ident() {
|
||||||
Ok(ident) => {
|
Ok(ident) => {
|
||||||
(match_ignore_ascii_case! { &ident,
|
(match_ignore_ascii_case! { &ident,
|
||||||
|
@ -234,7 +239,9 @@ ${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.clone()).into())
|
}).map_err(|()| {
|
||||||
|
location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
Err(e) => return Err(e.into())
|
Err(e) => return Err(e.into())
|
||||||
}
|
}
|
||||||
|
@ -244,7 +251,7 @@ ${helpers.single_keyword("unicode-bidi",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !empty { Ok(result) } else { Err(StyleParseError::UnspecifiedError.into()) }
|
if !empty { Ok(result) } else { Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
% if product == "servo":
|
% if product == "servo":
|
||||||
|
|
|
@ -77,7 +77,7 @@ ${helpers.single_keyword("-moz-window-shadow", "none default menu tooltip sheet"
|
||||||
match input.expect_integer()? {
|
match input.expect_integer()? {
|
||||||
0 => Ok(computed_value::T(false)),
|
0 => Ok(computed_value::T(false)),
|
||||||
1 => Ok(computed_value::T(true)),
|
1 => Ok(computed_value::T(true)),
|
||||||
_ => Err(StyleParseError::UnspecifiedError.into()),
|
_ => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,11 +35,10 @@ use parser::ParserContext;
|
||||||
#[cfg(feature = "gecko")] use properties::longhands::system_font::SystemFont;
|
#[cfg(feature = "gecko")] use properties::longhands::system_font::SystemFont;
|
||||||
use rule_cache::{RuleCache, RuleCacheConditions};
|
use rule_cache::{RuleCache, RuleCacheConditions};
|
||||||
use selector_parser::PseudoElement;
|
use selector_parser::PseudoElement;
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
#[cfg(feature = "servo")] use servo_config::prefs::PREFS;
|
#[cfg(feature = "servo")] use servo_config::prefs::PREFS;
|
||||||
use shared_lock::StylesheetGuards;
|
use shared_lock::StylesheetGuards;
|
||||||
use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError};
|
use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, StyleParseErrorKind};
|
||||||
use style_traits::{PropertyDeclarationParseError, StyleParseError, ValueParseError};
|
|
||||||
use stylesheets::{CssRuleType, Origin, UrlExtraData};
|
use stylesheets::{CssRuleType, Origin, UrlExtraData};
|
||||||
#[cfg(feature = "servo")] use values::Either;
|
#[cfg(feature = "servo")] use values::Either;
|
||||||
use values::generics::text::LineHeight;
|
use values::generics::text::LineHeight;
|
||||||
|
@ -153,7 +152,7 @@ macro_rules! unwrap_or_initial {
|
||||||
pub mod shorthands {
|
pub mod shorthands {
|
||||||
use cssparser::Parser;
|
use cssparser::Parser;
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use style_traits::{ParseError, StyleParseError};
|
use style_traits::{ParseError, StyleParseErrorKind};
|
||||||
use values::specified;
|
use values::specified;
|
||||||
|
|
||||||
<%include file="/shorthand/serialize.mako.rs" />
|
<%include file="/shorthand/serialize.mako.rs" />
|
||||||
|
@ -553,7 +552,9 @@ impl LonghandId {
|
||||||
% if not property.derived_from:
|
% if not property.derived_from:
|
||||||
longhands::${property.ident}::parse_declared(context, input)
|
longhands::${property.ident}::parse_declared(context, input)
|
||||||
% else:
|
% else:
|
||||||
Err(PropertyDeclarationParseError::UnknownProperty("${property.ident}".into()).into())
|
Err(input.new_custom_error(
|
||||||
|
StyleParseErrorKind::UnknownProperty("${property.ident}".into())
|
||||||
|
))
|
||||||
% endif
|
% endif
|
||||||
}
|
}
|
||||||
% endfor
|
% endfor
|
||||||
|
@ -878,7 +879,7 @@ impl ShorthandId {
|
||||||
}
|
}
|
||||||
% endfor
|
% endfor
|
||||||
// 'all' accepts no value other than CSS-wide keywords
|
// 'all' accepts no value other than CSS-wide keywords
|
||||||
ShorthandId::All => Err(StyleParseError::UnspecifiedError.into())
|
ShorthandId::All => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -962,7 +963,7 @@ impl UnparsedValue {
|
||||||
Some(ShorthandId::All) => {
|
Some(ShorthandId::All) => {
|
||||||
// No need to parse the 'all' shorthand as anything other than a CSS-wide
|
// No need to parse the 'all' shorthand as anything other than a CSS-wide
|
||||||
// keyword, after variable substitution.
|
// keyword, after variable substitution.
|
||||||
Err(SelectorParseError::UnexpectedIdent("all".into()).into())
|
Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent("all".into())))
|
||||||
}
|
}
|
||||||
% for shorthand in data.shorthands_except_all():
|
% for shorthand in data.shorthands_except_all():
|
||||||
Some(ShorthandId::${shorthand.camel_case}) => {
|
Some(ShorthandId::${shorthand.camel_case}) => {
|
||||||
|
@ -1630,7 +1631,7 @@ impl PropertyDeclaration {
|
||||||
pub fn parse_into<'i, 't>(declarations: &mut SourcePropertyDeclaration,
|
pub fn parse_into<'i, 't>(declarations: &mut SourcePropertyDeclaration,
|
||||||
id: PropertyId, name: CowRcStr<'i>,
|
id: PropertyId, name: CowRcStr<'i>,
|
||||||
context: &ParserContext, input: &mut Parser<'i, 't>)
|
context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||||
-> Result<(), PropertyDeclarationParseError<'i>> {
|
-> Result<(), ParseError<'i>> {
|
||||||
assert!(declarations.is_empty());
|
assert!(declarations.is_empty());
|
||||||
let start = input.state();
|
let start = input.state();
|
||||||
match id {
|
match id {
|
||||||
|
@ -1642,8 +1643,7 @@ impl PropertyDeclaration {
|
||||||
Ok(keyword) => DeclaredValueOwned::CSSWideKeyword(keyword),
|
Ok(keyword) => DeclaredValueOwned::CSSWideKeyword(keyword),
|
||||||
Err(()) => match ::custom_properties::SpecifiedValue::parse(input) {
|
Err(()) => match ::custom_properties::SpecifiedValue::parse(input) {
|
||||||
Ok(value) => DeclaredValueOwned::Value(value),
|
Ok(value) => DeclaredValueOwned::Value(value),
|
||||||
Err(e) => return Err(PropertyDeclarationParseError::InvalidValue(name.to_string().into(),
|
Err(e) => return Err(StyleParseErrorKind::new_invalid(name, e)),
|
||||||
ValueParseError::from_parse_error(e))),
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
declarations.push(PropertyDeclaration::Custom(property_name, value));
|
declarations.push(PropertyDeclaration::Custom(property_name, value));
|
||||||
|
@ -1662,8 +1662,7 @@ impl PropertyDeclaration {
|
||||||
input.reset(&start);
|
input.reset(&start);
|
||||||
let (first_token_type, css) =
|
let (first_token_type, css) =
|
||||||
::custom_properties::parse_non_custom_with_var(input).map_err(|e| {
|
::custom_properties::parse_non_custom_with_var(input).map_err(|e| {
|
||||||
PropertyDeclarationParseError::InvalidValue(name,
|
StyleParseErrorKind::new_invalid(name, e)
|
||||||
ValueParseError::from_parse_error(e))
|
|
||||||
})?;
|
})?;
|
||||||
Ok(PropertyDeclaration::WithVariables(id, Arc::new(UnparsedValue {
|
Ok(PropertyDeclaration::WithVariables(id, Arc::new(UnparsedValue {
|
||||||
css: css.into_owned(),
|
css: css.into_owned(),
|
||||||
|
@ -1672,8 +1671,7 @@ impl PropertyDeclaration {
|
||||||
from_shorthand: None,
|
from_shorthand: None,
|
||||||
})))
|
})))
|
||||||
} else {
|
} else {
|
||||||
Err(PropertyDeclarationParseError::InvalidValue(name,
|
Err(StyleParseErrorKind::new_invalid(name, err))
|
||||||
ValueParseError::from_parse_error(err)))
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}).map(|declaration| {
|
}).map(|declaration| {
|
||||||
|
@ -1701,8 +1699,7 @@ impl PropertyDeclaration {
|
||||||
input.reset(&start);
|
input.reset(&start);
|
||||||
let (first_token_type, css) =
|
let (first_token_type, css) =
|
||||||
::custom_properties::parse_non_custom_with_var(input).map_err(|e| {
|
::custom_properties::parse_non_custom_with_var(input).map_err(|e| {
|
||||||
PropertyDeclarationParseError::InvalidValue(name,
|
StyleParseErrorKind::new_invalid(name, e)
|
||||||
ValueParseError::from_parse_error(e))
|
|
||||||
})?;
|
})?;
|
||||||
let unparsed = Arc::new(UnparsedValue {
|
let unparsed = Arc::new(UnparsedValue {
|
||||||
css: css.into_owned(),
|
css: css.into_owned(),
|
||||||
|
@ -1721,8 +1718,7 @@ impl PropertyDeclaration {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(PropertyDeclarationParseError::InvalidValue(name,
|
Err(StyleParseErrorKind::new_invalid(name, err))
|
||||||
ValueParseError::from_parse_error(err)))
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
// background-color can only be in the last element, so if it
|
// background-color can only be in the last element, so if it
|
||||||
// is parsed anywhere before, the value is invalid.
|
// is parsed anywhere before, the value is invalid.
|
||||||
if background_color.is_some() {
|
if background_color.is_some() {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
|
|
||||||
% for name in "image position repeat size attachment origin clip".split():
|
% for name in "image position repeat size attachment origin clip".split():
|
||||||
|
@ -112,7 +112,7 @@
|
||||||
% endfor
|
% endfor
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -217,7 +217,7 @@
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
if !any {
|
if !any {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(expanded! {
|
Ok(expanded! {
|
||||||
|
|
|
@ -83,7 +83,7 @@ pub fn parse_border<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||||
style.unwrap_or(BorderStyle::none),
|
style.unwrap_or(BorderStyle::none),
|
||||||
width.unwrap_or(BorderSideWidth::Medium)))
|
width.unwrap_or(BorderSideWidth::Medium)))
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ pub fn parse_border<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||||
border_image_outset::parse(context, input)
|
border_image_outset::parse(context, input)
|
||||||
}).ok();
|
}).ok();
|
||||||
if w.is_none() && o.is_none() {
|
if w.is_none() && o.is_none() {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Ok((w, o))
|
Ok((w, o))
|
||||||
|
@ -312,7 +312,7 @@ pub fn parse_border<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||||
% endfor
|
% endfor
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
result?;
|
result?;
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||||
-> Result<Longhands, ParseError<'i>> {
|
-> Result<Longhands, ParseError<'i>> {
|
||||||
% if product == "gecko":
|
% if product == "gecko":
|
||||||
let moz_kw_found = input.try(|i| {
|
let moz_kw_found = input.try(|input| {
|
||||||
try_match_ident_ignore_ascii_case! { i.expect_ident()?,
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
"-moz-scrollbars-horizontal" => {
|
"-moz-scrollbars-horizontal" => {
|
||||||
Ok(expanded! {
|
Ok(expanded! {
|
||||||
overflow_x: SpecifiedValue::scroll,
|
overflow_x: SpecifiedValue::scroll,
|
||||||
|
@ -141,7 +141,7 @@ macro_rules! try_parse_one {
|
||||||
Some(transition_property::single_value::get_initial_specified_value())),
|
Some(transition_property::single_value::get_initial_specified_value())),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ macro_rules! try_parse_one {
|
||||||
// If there is more than one item, and any of transitions has 'none',
|
// If there is more than one item, and any of transitions has 'none',
|
||||||
// then it's invalid. Othersize, leave propertys to be empty (which
|
// then it's invalid. Othersize, leave propertys to be empty (which
|
||||||
// means "transition-property: none");
|
// means "transition-property: none");
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
|
|
||||||
% for prop in "duration timing_function delay".split():
|
% for prop in "duration timing_function delay".split():
|
||||||
|
@ -269,7 +269,7 @@ macro_rules! try_parse_one {
|
||||||
|
|
||||||
// If nothing is parsed, this is an invalid entry.
|
// If nothing is parsed, this is an invalid entry.
|
||||||
if parsed == 0 {
|
if parsed == 0 {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
} else {
|
} else {
|
||||||
Ok(SingleAnimation {
|
Ok(SingleAnimation {
|
||||||
% for prop in props:
|
% for prop in props:
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
|
|
||||||
let values = autos + column_count.iter().len() + column_width.iter().len();
|
let values = autos + column_count.iter().len() + column_width.iter().len();
|
||||||
if values == 0 || values > 2 {
|
if values == 0 || values > 2 {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
} else {
|
} else {
|
||||||
Ok(expanded! {
|
Ok(expanded! {
|
||||||
column_count: unwrap_or_initial!(column_count),
|
column_count: unwrap_or_initial!(column_count),
|
||||||
|
@ -89,7 +89,7 @@
|
||||||
column_rule_color: unwrap_or_initial!(column_rule_color),
|
column_rule_color: unwrap_or_initial!(column_rule_color),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%helpers:shorthand>
|
</%helpers:shorthand>
|
||||||
|
|
|
@ -98,7 +98,7 @@
|
||||||
}
|
}
|
||||||
if size.is_none() ||
|
if size.is_none() ||
|
||||||
(count(&style) + count(&weight) + count(&variant_caps) + count(&stretch) + nb_normals) > 4 {
|
(count(&style) + count(&weight) + count(&variant_caps) + count(&stretch) + nb_normals) > 4 {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
let line_height = if input.try(|input| input.expect_delim('/')).is_ok() {
|
let line_height = if input.try(|input| input.expect_delim('/')).is_ok() {
|
||||||
Some(LineHeight::parse(context, input)?)
|
Some(LineHeight::parse(context, input)?)
|
||||||
|
@ -262,7 +262,7 @@
|
||||||
loop {
|
loop {
|
||||||
if input.try(|input| input.expect_ident_matching("normal")).is_ok() ||
|
if input.try(|input| input.expect_ident_matching("normal")).is_ok() ||
|
||||||
input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
% for prop in sub_properties:
|
% for prop in sub_properties:
|
||||||
if ${prop}.is_none() {
|
if ${prop}.is_none() {
|
||||||
|
@ -278,7 +278,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if !has_custom_value {
|
if !has_custom_value {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
text_emphasis_style: unwrap_or_initial!(text_emphasis_style, style),
|
text_emphasis_style: unwrap_or_initial!(text_emphasis_style, style),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%helpers:shorthand>
|
</%helpers:shorthand>
|
||||||
|
@ -78,7 +78,7 @@
|
||||||
_webkit_text_stroke_width: unwrap_or_initial!(_webkit_text_stroke_width, width),
|
_webkit_text_stroke_width: unwrap_or_initial!(_webkit_text_stroke_width, width),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%helpers:shorthand>
|
</%helpers:shorthand>
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
||||||
nones = nones + 1;
|
nones = nones + 1;
|
||||||
if nones > 2 {
|
if nones > 2 {
|
||||||
return Err(SelectorParseError::UnexpectedIdent("none".into()).into())
|
return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent("none".into())))
|
||||||
}
|
}
|
||||||
any = true;
|
any = true;
|
||||||
continue
|
continue
|
||||||
|
@ -106,7 +106,7 @@
|
||||||
list_style_type: unwrap_or_initial!(list_style_type),
|
list_style_type: unwrap_or_initial!(list_style_type),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_ => Err(StyleParseError::UnspecifiedError.into()),
|
_ => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%helpers:shorthand>
|
</%helpers:shorthand>
|
||||||
|
|
|
@ -108,7 +108,7 @@
|
||||||
% endfor
|
% endfor
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
if any == false {
|
if any == false {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(expanded! {
|
Ok(expanded! {
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
outline_width: unwrap_or_initial!(outline_width, width),
|
outline_width: unwrap_or_initial!(outline_width, width),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%helpers:shorthand>
|
</%helpers:shorthand>
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if direction.is_none() && wrap.is_none() {
|
if direction.is_none() && wrap.is_none() {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
Ok(expanded! {
|
Ok(expanded! {
|
||||||
flex_direction: unwrap_or_initial!(flex_direction, direction),
|
flex_direction: unwrap_or_initial!(flex_direction, direction),
|
||||||
|
@ -87,7 +87,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if grow.is_none() && basis.is_none() {
|
if grow.is_none() && basis.is_none() {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
Ok(expanded! {
|
Ok(expanded! {
|
||||||
flex_grow: grow.unwrap_or(NonNegativeNumber::new(1.0)),
|
flex_grow: grow.unwrap_or(NonNegativeNumber::new(1.0)),
|
||||||
|
@ -309,7 +309,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
let template_areas = TemplateAreas::from_vec(strings)
|
let template_areas = TemplateAreas::from_vec(strings)
|
||||||
.map_err(|()| StyleParseError::UnspecifiedError)?;
|
.map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError))?;
|
||||||
let template_rows = TrackList {
|
let template_rows = TrackList {
|
||||||
list_type: TrackListType::Normal,
|
list_type: TrackListType::Normal,
|
||||||
values: values,
|
values: values,
|
||||||
|
@ -321,7 +321,7 @@
|
||||||
let value = GridTemplateComponent::parse_without_none(context, input)?;
|
let value = GridTemplateComponent::parse_without_none(context, input)?;
|
||||||
if let GenericGridTemplateComponent::TrackList(ref list) = value {
|
if let GenericGridTemplateComponent::TrackList(ref list) = value {
|
||||||
if list.list_type != TrackListType::Explicit {
|
if list.list_type != TrackListType::Explicit {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,7 +340,7 @@
|
||||||
if list.line_names[0].is_empty() {
|
if list.line_names[0].is_empty() {
|
||||||
list.line_names[0] = first_line_names; // won't panic
|
list.line_names[0] = first_line_names; // won't panic
|
||||||
} else {
|
} else {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,7 +501,7 @@
|
||||||
autoflow: flow,
|
autoflow: flow,
|
||||||
dense: dense,
|
dense: dense,
|
||||||
}
|
}
|
||||||
}).ok_or(StyleParseError::UnspecifiedError.into())
|
}).ok_or(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok((rows, cols, areas)) = input.try(|i| super::grid_template::parse_grid_template(context, i)) {
|
if let Ok((rows, cols, areas)) = input.try(|i| super::grid_template::parse_grid_template(context, i)) {
|
||||||
|
@ -617,12 +617,12 @@
|
||||||
-> Result<Longhands, ParseError<'i>> {
|
-> Result<Longhands, ParseError<'i>> {
|
||||||
let align = align_content::parse(context, input)?;
|
let align = align_content::parse(context, input)?;
|
||||||
if align.has_extra_flags() {
|
if align.has_extra_flags() {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
let justify = input.try(|input| justify_content::parse(context, input))
|
let justify = input.try(|input| justify_content::parse(context, input))
|
||||||
.unwrap_or(justify_content::SpecifiedValue::from(align));
|
.unwrap_or(justify_content::SpecifiedValue::from(align));
|
||||||
if justify.has_extra_flags() {
|
if justify.has_extra_flags() {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(expanded! {
|
Ok(expanded! {
|
||||||
|
@ -653,11 +653,11 @@
|
||||||
-> Result<Longhands, ParseError<'i>> {
|
-> Result<Longhands, ParseError<'i>> {
|
||||||
let align = AlignJustifySelf::parse(context, input)?;
|
let align = AlignJustifySelf::parse(context, input)?;
|
||||||
if align.has_extra_flags() {
|
if align.has_extra_flags() {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
let justify = input.try(|input| AlignJustifySelf::parse(context, input)).unwrap_or(align.clone());
|
let justify = input.try(|input| AlignJustifySelf::parse(context, input)).unwrap_or(align.clone());
|
||||||
if justify.has_extra_flags() {
|
if justify.has_extra_flags() {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(expanded! {
|
Ok(expanded! {
|
||||||
|
@ -695,12 +695,12 @@
|
||||||
-> Result<Longhands, ParseError<'i>> {
|
-> Result<Longhands, ParseError<'i>> {
|
||||||
let align = AlignItems::parse(context, input)?;
|
let align = AlignItems::parse(context, input)?;
|
||||||
if align.has_extra_flags() {
|
if align.has_extra_flags() {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
let justify = input.try(|input| JustifyItems::parse(context, input))
|
let justify = input.try(|input| JustifyItems::parse(context, input))
|
||||||
.unwrap_or(JustifyItems::from(align));
|
.unwrap_or(JustifyItems::from(align));
|
||||||
if justify.has_extra_flags() {
|
if justify.has_extra_flags() {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(expanded! {
|
Ok(expanded! {
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if !any {
|
if !any {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(expanded! {
|
Ok(expanded! {
|
||||||
|
|
|
@ -14,7 +14,7 @@ use parser::ParserContext;
|
||||||
use properties::{ComputedValues, StyleBuilder};
|
use properties::{ComputedValues, StyleBuilder};
|
||||||
use properties::longhands::font_size;
|
use properties::longhands::font_size;
|
||||||
use rule_cache::RuleCacheConditions;
|
use rule_cache::RuleCacheConditions;
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::sync::atomic::{AtomicBool, AtomicIsize, Ordering};
|
use std::sync::atomic::{AtomicBool, AtomicIsize, Ordering};
|
||||||
|
@ -198,7 +198,7 @@ impl Expression {
|
||||||
"width" => {
|
"width" => {
|
||||||
ExpressionKind::Width(Range::Eq(specified::Length::parse_non_negative(context, input)?))
|
ExpressionKind::Width(Range::Eq(specified::Length::parse_non_negative(context, input)?))
|
||||||
},
|
},
|
||||||
_ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into())
|
_ => return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone())))
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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, CowRcStr};
|
use cssparser::{Parser as CssParser, ToCss, serialize_identifier, CowRcStr, SourceLocation};
|
||||||
use dom::{OpaqueNode, TElement, TNode};
|
use dom::{OpaqueNode, TElement, TNode};
|
||||||
use element_state::ElementState;
|
use element_state::ElementState;
|
||||||
use fnv::FnvHashMap;
|
use fnv::FnvHashMap;
|
||||||
|
@ -19,14 +19,14 @@ use properties::longhands::display::computed_value as display;
|
||||||
use selector_parser::{AttrValue as SelectorAttrValue, ElementExt, PseudoElementCascadeType, SelectorParser};
|
use selector_parser::{AttrValue as SelectorAttrValue, ElementExt, PseudoElementCascadeType, SelectorParser};
|
||||||
use selectors::Element;
|
use selectors::Element;
|
||||||
use selectors::attr::{AttrSelectorOperation, NamespaceConstraint, CaseSensitivity};
|
use selectors::attr::{AttrSelectorOperation, NamespaceConstraint, CaseSensitivity};
|
||||||
use selectors::parser::{SelectorMethods, SelectorParseError};
|
use selectors::parser::{SelectorMethods, SelectorParseErrorKind};
|
||||||
use selectors::visitor::SelectorVisitor;
|
use selectors::visitor::SelectorVisitor;
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use style_traits::{ParseError, StyleParseError};
|
use style_traits::{ParseError, StyleParseErrorKind};
|
||||||
|
|
||||||
/// A pseudo-element, both public and private.
|
/// A pseudo-element, both public and private.
|
||||||
///
|
///
|
||||||
|
@ -395,9 +395,9 @@ impl ::selectors::SelectorImpl for SelectorImpl {
|
||||||
|
|
||||||
impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
|
impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
|
||||||
type Impl = SelectorImpl;
|
type Impl = SelectorImpl;
|
||||||
type Error = StyleParseError<'i>;
|
type Error = StyleParseErrorKind<'i>;
|
||||||
|
|
||||||
fn parse_non_ts_pseudo_class(&self, name: CowRcStr<'i>)
|
fn parse_non_ts_pseudo_class(&self, location: SourceLocation, 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,
|
||||||
|
@ -418,12 +418,13 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
|
||||||
"visited" => Visited,
|
"visited" => Visited,
|
||||||
"-servo-nonzero-border" => {
|
"-servo-nonzero-border" => {
|
||||||
if !self.in_user_agent_stylesheet() {
|
if !self.in_user_agent_stylesheet() {
|
||||||
return Err(SelectorParseError::UnexpectedIdent(
|
return Err(location.new_custom_error(
|
||||||
"-servo-nonzero-border".into()).into());
|
SelectorParseErrorKind::UnexpectedIdent("-servo-nonzero-border".into())
|
||||||
|
))
|
||||||
}
|
}
|
||||||
ServoNonZeroBorder
|
ServoNonZeroBorder
|
||||||
},
|
},
|
||||||
_ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()),
|
_ => return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(pseudo_class)
|
Ok(pseudo_class)
|
||||||
|
@ -440,17 +441,18 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
|
||||||
}
|
}
|
||||||
"-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(parser.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone())));
|
||||||
}
|
}
|
||||||
ServoCaseSensitiveTypeAttr(Atom::from(parser.expect_ident()?.as_ref()))
|
ServoCaseSensitiveTypeAttr(Atom::from(parser.expect_ident()?.as_ref()))
|
||||||
}
|
}
|
||||||
_ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into())
|
_ => return Err(parser.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone())))
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(pseudo_class)
|
Ok(pseudo_class)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_pseudo_element(&self, name: CowRcStr<'i>) -> Result<PseudoElement, ParseError<'i>> {
|
fn parse_pseudo_element(&self, location: SourceLocation, 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,
|
||||||
|
@ -458,77 +460,77 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
|
||||||
"selection" => Selection,
|
"selection" => Selection,
|
||||||
"-servo-details-summary" => {
|
"-servo-details-summary" => {
|
||||||
if !self.in_user_agent_stylesheet() {
|
if !self.in_user_agent_stylesheet() {
|
||||||
return Err(SelectorParseError::UnexpectedIdent(name.clone()).into())
|
return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone())))
|
||||||
}
|
}
|
||||||
DetailsSummary
|
DetailsSummary
|
||||||
},
|
},
|
||||||
"-servo-details-content" => {
|
"-servo-details-content" => {
|
||||||
if !self.in_user_agent_stylesheet() {
|
if !self.in_user_agent_stylesheet() {
|
||||||
return Err(SelectorParseError::UnexpectedIdent(name.clone()).into())
|
return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone())))
|
||||||
}
|
}
|
||||||
DetailsContent
|
DetailsContent
|
||||||
},
|
},
|
||||||
"-servo-text" => {
|
"-servo-text" => {
|
||||||
if !self.in_user_agent_stylesheet() {
|
if !self.in_user_agent_stylesheet() {
|
||||||
return Err(SelectorParseError::UnexpectedIdent(name.clone()).into())
|
return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone())))
|
||||||
}
|
}
|
||||||
ServoText
|
ServoText
|
||||||
},
|
},
|
||||||
"-servo-input-text" => {
|
"-servo-input-text" => {
|
||||||
if !self.in_user_agent_stylesheet() {
|
if !self.in_user_agent_stylesheet() {
|
||||||
return Err(SelectorParseError::UnexpectedIdent(name.clone()).into())
|
return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone())))
|
||||||
}
|
}
|
||||||
ServoInputText
|
ServoInputText
|
||||||
},
|
},
|
||||||
"-servo-table-wrapper" => {
|
"-servo-table-wrapper" => {
|
||||||
if !self.in_user_agent_stylesheet() {
|
if !self.in_user_agent_stylesheet() {
|
||||||
return Err(SelectorParseError::UnexpectedIdent(name.clone()).into())
|
return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone())))
|
||||||
}
|
}
|
||||||
ServoTableWrapper
|
ServoTableWrapper
|
||||||
},
|
},
|
||||||
"-servo-anonymous-table-wrapper" => {
|
"-servo-anonymous-table-wrapper" => {
|
||||||
if !self.in_user_agent_stylesheet() {
|
if !self.in_user_agent_stylesheet() {
|
||||||
return Err(SelectorParseError::UnexpectedIdent(name.clone()).into())
|
return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone())))
|
||||||
}
|
}
|
||||||
ServoAnonymousTableWrapper
|
ServoAnonymousTableWrapper
|
||||||
},
|
},
|
||||||
"-servo-anonymous-table" => {
|
"-servo-anonymous-table" => {
|
||||||
if !self.in_user_agent_stylesheet() {
|
if !self.in_user_agent_stylesheet() {
|
||||||
return Err(SelectorParseError::UnexpectedIdent(name.clone()).into())
|
return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone())))
|
||||||
}
|
}
|
||||||
ServoAnonymousTable
|
ServoAnonymousTable
|
||||||
},
|
},
|
||||||
"-servo-anonymous-table-row" => {
|
"-servo-anonymous-table-row" => {
|
||||||
if !self.in_user_agent_stylesheet() {
|
if !self.in_user_agent_stylesheet() {
|
||||||
return Err(SelectorParseError::UnexpectedIdent(name.clone()).into())
|
return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone())))
|
||||||
}
|
}
|
||||||
ServoAnonymousTableRow
|
ServoAnonymousTableRow
|
||||||
},
|
},
|
||||||
"-servo-anonymous-table-cell" => {
|
"-servo-anonymous-table-cell" => {
|
||||||
if !self.in_user_agent_stylesheet() {
|
if !self.in_user_agent_stylesheet() {
|
||||||
return Err(SelectorParseError::UnexpectedIdent(name.clone()).into())
|
return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone())))
|
||||||
}
|
}
|
||||||
ServoAnonymousTableCell
|
ServoAnonymousTableCell
|
||||||
},
|
},
|
||||||
"-servo-anonymous-block" => {
|
"-servo-anonymous-block" => {
|
||||||
if !self.in_user_agent_stylesheet() {
|
if !self.in_user_agent_stylesheet() {
|
||||||
return Err(SelectorParseError::UnexpectedIdent(name.clone()).into())
|
return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone())))
|
||||||
}
|
}
|
||||||
ServoAnonymousBlock
|
ServoAnonymousBlock
|
||||||
},
|
},
|
||||||
"-servo-inline-block-wrapper" => {
|
"-servo-inline-block-wrapper" => {
|
||||||
if !self.in_user_agent_stylesheet() {
|
if !self.in_user_agent_stylesheet() {
|
||||||
return Err(SelectorParseError::UnexpectedIdent(name.clone()).into())
|
return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone())))
|
||||||
}
|
}
|
||||||
ServoInlineBlockWrapper
|
ServoInlineBlockWrapper
|
||||||
},
|
},
|
||||||
"-servo-input-absolute" => {
|
"-servo-input-absolute" => {
|
||||||
if !self.in_user_agent_stylesheet() {
|
if !self.in_user_agent_stylesheet() {
|
||||||
return Err(SelectorParseError::UnexpectedIdent(name.clone()).into())
|
return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone())))
|
||||||
}
|
}
|
||||||
ServoInlineAbsolute
|
ServoInlineAbsolute
|
||||||
},
|
},
|
||||||
_ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into())
|
_ => return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone())))
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
//! initially in CSS Conditional Rules Module Level 3, @document has been postponed to the level 4.
|
//! initially in CSS Conditional Rules Module Level 3, @document has been postponed to the level 4.
|
||||||
//! We implement the prefixed `@-moz-document`.
|
//! We implement the prefixed `@-moz-document`.
|
||||||
|
|
||||||
use cssparser::{Parser, Token, SourceLocation, BasicParseError};
|
use cssparser::{Parser, Token, SourceLocation};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
|
use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
|
||||||
use media_queries::Device;
|
use media_queries::Device;
|
||||||
|
@ -14,7 +14,7 @@ use parser::{Parse, ParserContext};
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
|
use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{ToCss, ParseError, StyleParseError};
|
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
|
||||||
use stylesheets::CssRules;
|
use stylesheets::CssRules;
|
||||||
use values::specified::url::SpecifiedUrl;
|
use values::specified::url::SpecifiedUrl;
|
||||||
|
|
||||||
|
@ -100,10 +100,11 @@ macro_rules! parse_quoted_or_unquoted_string {
|
||||||
$input.parse_nested_block(|input| {
|
$input.parse_nested_block(|input| {
|
||||||
let start = input.position();
|
let start = input.position();
|
||||||
input.parse_entirely(|input| {
|
input.parse_entirely(|input| {
|
||||||
|
let location = input.current_source_location();
|
||||||
match input.next() {
|
match input.next() {
|
||||||
Ok(&Token::QuotedString(ref value)) =>
|
Ok(&Token::QuotedString(ref value)) =>
|
||||||
Ok($url_matching_function(value.as_ref().to_owned())),
|
Ok($url_matching_function(value.as_ref().to_owned())),
|
||||||
Ok(t) => Err(BasicParseError::UnexpectedToken(t.clone()).into()),
|
Ok(t) => Err(location.new_unexpected_token_error(t.clone())),
|
||||||
Err(e) => Err(e.into()),
|
Err(e) => Err(e.into()),
|
||||||
}
|
}
|
||||||
}).or_else(|_: ParseError| {
|
}).or_else(|_: ParseError| {
|
||||||
|
@ -129,7 +130,7 @@ impl UrlMatchingFunction {
|
||||||
} 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))
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
use Atom;
|
use Atom;
|
||||||
use computed_values::font_family::FamilyName;
|
use computed_values::font_family::FamilyName;
|
||||||
use cssparser::{AtRuleParser, AtRuleType, BasicParseError, DeclarationListParser, DeclarationParser, Parser};
|
use cssparser::{AtRuleParser, AtRuleType, BasicParseErrorKind, DeclarationListParser, DeclarationParser, Parser};
|
||||||
use cssparser::{CowRcStr, RuleListParser, SourceLocation, QualifiedRuleParser, Token, serialize_identifier};
|
use cssparser::{CowRcStr, RuleListParser, SourceLocation, QualifiedRuleParser, Token, serialize_identifier};
|
||||||
use error_reporting::{ContextualParseError, ParseErrorReporter};
|
use error_reporting::{ContextualParseError, ParseErrorReporter};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
@ -16,10 +16,9 @@ use gecko_bindings::bindings::Gecko_AppendFeatureValueHashEntry;
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use gecko_bindings::structs::{self, gfxFontFeatureValueSet, nsTArray};
|
use gecko_bindings::structs::{self, gfxFontFeatureValueSet, nsTArray};
|
||||||
use parser::{ParserContext, ParserErrorContext, Parse};
|
use parser::{ParserContext, ParserErrorContext, Parse};
|
||||||
use selectors::parser::SelectorParseError;
|
|
||||||
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
|
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{ParseError, StyleParseError, ToCss};
|
use style_traits::{ParseError, StyleParseErrorKind, ToCss};
|
||||||
use stylesheets::CssRuleType;
|
use stylesheets::CssRuleType;
|
||||||
|
|
||||||
/// A @font-feature-values block declaration.
|
/// A @font-feature-values block declaration.
|
||||||
|
@ -59,9 +58,10 @@ pub struct SingleValue(pub u32);
|
||||||
impl Parse for SingleValue {
|
impl Parse for SingleValue {
|
||||||
fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
|
fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||||
-> Result<SingleValue, ParseError<'i>> {
|
-> Result<SingleValue, ParseError<'i>> {
|
||||||
|
let location = input.current_source_location();
|
||||||
match *input.next()? {
|
match *input.next()? {
|
||||||
Token::Number { int_value: Some(v), .. } if v >= 0 => Ok(SingleValue(v as u32)),
|
Token::Number { int_value: Some(v), .. } if v >= 0 => Ok(SingleValue(v as u32)),
|
||||||
ref t => Err(BasicParseError::UnexpectedToken(t.clone()).into()),
|
ref t => Err(location.new_unexpected_token_error(t.clone())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,16 +87,18 @@ pub struct PairValues(pub u32, pub Option<u32>);
|
||||||
impl Parse for PairValues {
|
impl Parse for PairValues {
|
||||||
fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
|
fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||||
-> Result<PairValues, ParseError<'i>> {
|
-> Result<PairValues, ParseError<'i>> {
|
||||||
|
let location = input.current_source_location();
|
||||||
let first = match *input.next()? {
|
let first = match *input.next()? {
|
||||||
Token::Number { int_value: Some(a), .. } if a >= 0 => a as u32,
|
Token::Number { int_value: Some(a), .. } if a >= 0 => a as u32,
|
||||||
ref t => return Err(BasicParseError::UnexpectedToken(t.clone()).into()),
|
ref t => return Err(location.new_unexpected_token_error(t.clone())),
|
||||||
};
|
};
|
||||||
|
let location = input.current_source_location();
|
||||||
match input.next() {
|
match input.next() {
|
||||||
Ok(&Token::Number { int_value: Some(b), .. }) if b >= 0 => {
|
Ok(&Token::Number { int_value: Some(b), .. }) if b >= 0 => {
|
||||||
Ok(PairValues(first, Some(b as u32)))
|
Ok(PairValues(first, Some(b as u32)))
|
||||||
}
|
}
|
||||||
// It can't be anything other than number.
|
// It can't be anything other than number.
|
||||||
Ok(t) => Err(BasicParseError::UnexpectedToken(t.clone()).into()),
|
Ok(t) => Err(location.new_unexpected_token_error(t.clone())),
|
||||||
// It can be just one value.
|
// It can be just one value.
|
||||||
Err(_) => Ok(PairValues(first, None))
|
Err(_) => Ok(PairValues(first, None))
|
||||||
}
|
}
|
||||||
|
@ -136,18 +138,19 @@ impl Parse for VectorValues {
|
||||||
-> Result<VectorValues, ParseError<'i>> {
|
-> Result<VectorValues, ParseError<'i>> {
|
||||||
let mut vec = vec![];
|
let mut vec = vec![];
|
||||||
loop {
|
loop {
|
||||||
|
let location = input.current_source_location();
|
||||||
match input.next() {
|
match input.next() {
|
||||||
Ok(&Token::Number { int_value: Some(a), .. }) if a >= 0 => {
|
Ok(&Token::Number { int_value: Some(a), .. }) if a >= 0 => {
|
||||||
vec.push(a as u32);
|
vec.push(a as u32);
|
||||||
},
|
},
|
||||||
// It can't be anything other than number.
|
// It can't be anything other than number.
|
||||||
Ok(t) => return Err(BasicParseError::UnexpectedToken(t.clone()).into()),
|
Ok(t) => return Err(location.new_unexpected_token_error(t.clone())),
|
||||||
Err(_) => break,
|
Err(_) => break,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if vec.len() == 0 {
|
if vec.len() == 0 {
|
||||||
return Err(BasicParseError::EndOfInput.into());
|
return Err(input.new_error(BasicParseErrorKind::EndOfInput));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(VectorValues(vec))
|
Ok(VectorValues(vec))
|
||||||
|
@ -197,14 +200,14 @@ impl<'a, 'b, 'i, T> AtRuleParser<'i> for FFVDeclarationsParser<'a, 'b, T> {
|
||||||
type PreludeNoBlock = ();
|
type PreludeNoBlock = ();
|
||||||
type PreludeBlock = ();
|
type PreludeBlock = ();
|
||||||
type AtRule = ();
|
type AtRule = ();
|
||||||
type Error = SelectorParseError<'i, StyleParseError<'i>>;
|
type Error = StyleParseErrorKind<'i>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, 'i, T> DeclarationParser<'i> for FFVDeclarationsParser<'a, 'b, T>
|
impl<'a, 'b, 'i, T> DeclarationParser<'i> for FFVDeclarationsParser<'a, 'b, T>
|
||||||
where T: Parse
|
where T: Parse
|
||||||
{
|
{
|
||||||
type Declaration = ();
|
type Declaration = ();
|
||||||
type Error = SelectorParseError<'i, StyleParseError<'i>>;
|
type Error = StyleParseErrorKind<'i>;
|
||||||
|
|
||||||
fn parse_value<'t>(&mut self, name: CowRcStr<'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>> {
|
||||||
|
@ -271,9 +274,10 @@ macro_rules! font_feature_values_blocks {
|
||||||
rule: &mut rule,
|
rule: &mut rule,
|
||||||
});
|
});
|
||||||
while let Some(result) = iter.next() {
|
while let Some(result) = iter.next() {
|
||||||
if let Err(err) = result {
|
if let Err((error, slice)) = result {
|
||||||
let error = ContextualParseError::UnsupportedRule(err.slice, err.error);
|
let location = error.location;
|
||||||
context.log_css_error(error_context, err.location, error);
|
let error = ContextualParseError::UnsupportedRule(slice, error);
|
||||||
|
context.log_css_error(error_context, location, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -387,24 +391,24 @@ macro_rules! font_feature_values_blocks {
|
||||||
impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for FontFeatureValuesRuleParser<'a, R> {
|
impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for FontFeatureValuesRuleParser<'a, R> {
|
||||||
type Prelude = ();
|
type Prelude = ();
|
||||||
type QualifiedRule = ();
|
type QualifiedRule = ();
|
||||||
type Error = SelectorParseError<'i, StyleParseError<'i>>;
|
type Error = StyleParseErrorKind<'i>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for FontFeatureValuesRuleParser<'a, R> {
|
impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for FontFeatureValuesRuleParser<'a, R> {
|
||||||
type PreludeNoBlock = ();
|
type PreludeNoBlock = ();
|
||||||
type PreludeBlock = BlockType;
|
type PreludeBlock = BlockType;
|
||||||
type AtRule = ();
|
type AtRule = ();
|
||||||
type Error = SelectorParseError<'i, StyleParseError<'i>>;
|
type Error = StyleParseErrorKind<'i>;
|
||||||
|
|
||||||
fn parse_prelude<'t>(&mut self,
|
fn parse_prelude<'t>(&mut self,
|
||||||
name: CowRcStr<'i>,
|
name: CowRcStr<'i>,
|
||||||
_input: &mut Parser<'i, 't>)
|
input: &mut Parser<'i, 't>)
|
||||||
-> Result<AtRuleType<(), BlockType>, ParseError<'i>> {
|
-> Result<AtRuleType<(), BlockType>, ParseError<'i>> {
|
||||||
match_ignore_ascii_case! { &*name,
|
match_ignore_ascii_case! { &*name,
|
||||||
$(
|
$(
|
||||||
$name => Ok(AtRuleType::WithBlock(BlockType::$ident_camel)),
|
$name => Ok(AtRuleType::WithBlock(BlockType::$ident_camel)),
|
||||||
)*
|
)*
|
||||||
_ => Err(BasicParseError::AtRuleBodyInvalid.into()),
|
_ => Err(input.new_error(BasicParseErrorKind::AtRuleBodyInvalid)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,10 +428,12 @@ macro_rules! font_feature_values_blocks {
|
||||||
|
|
||||||
let mut iter = DeclarationListParser::new(input, parser);
|
let mut iter = DeclarationListParser::new(input, parser);
|
||||||
while let Some(declaration) = iter.next() {
|
while let Some(declaration) = iter.next() {
|
||||||
if let Err(err) = declaration {
|
if let Err((error, slice)) = declaration {
|
||||||
|
let location = error.location;
|
||||||
let error = ContextualParseError::UnsupportedKeyframePropertyDeclaration(
|
let error = ContextualParseError::UnsupportedKeyframePropertyDeclaration(
|
||||||
err.slice, err.error);
|
slice, error
|
||||||
self.context.log_css_error(self.error_context, err.location, error);
|
);
|
||||||
|
self.context.log_css_error(self.error_context, location, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -12,12 +12,10 @@ use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock, Prop
|
||||||
use properties::{PropertyDeclarationId, LonghandId, SourcePropertyDeclaration};
|
use properties::{PropertyDeclarationId, LonghandId, SourcePropertyDeclaration};
|
||||||
use properties::LonghandIdSet;
|
use properties::LonghandIdSet;
|
||||||
use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction;
|
use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction;
|
||||||
use selectors::parser::SelectorParseError;
|
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use shared_lock::{DeepCloneParams, DeepCloneWithLock, SharedRwLock, SharedRwLockReadGuard, Locked, ToCssWithGuard};
|
use shared_lock::{DeepCloneParams, DeepCloneWithLock, SharedRwLock, SharedRwLockReadGuard, Locked, ToCssWithGuard};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, StyleParseError};
|
use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, StyleParseErrorKind};
|
||||||
use style_traits::PropertyDeclarationParseError;
|
|
||||||
use stylesheets::{CssRuleType, StylesheetContents};
|
use stylesheets::{CssRuleType, StylesheetContents};
|
||||||
use stylesheets::rule_parser::VendorPrefix;
|
use stylesheets::rule_parser::VendorPrefix;
|
||||||
use values::{KeyframesName, serialize_percentage};
|
use values::{KeyframesName, serialize_percentage};
|
||||||
|
@ -137,7 +135,7 @@ impl KeyframePercentage {
|
||||||
if percentage >= 0. && percentage <= 1. {
|
if percentage >= 0. && percentage <= 1. {
|
||||||
KeyframePercentage::new(percentage)
|
KeyframePercentage::new(percentage)
|
||||||
} else {
|
} else {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -500,7 +498,7 @@ impl<'a, 'i, R> AtRuleParser<'i> for KeyframeListParser<'a, R> {
|
||||||
type PreludeNoBlock = ();
|
type PreludeNoBlock = ();
|
||||||
type PreludeBlock = ();
|
type PreludeBlock = ();
|
||||||
type AtRule = Arc<Locked<Keyframe>>;
|
type AtRule = Arc<Locked<Keyframe>>;
|
||||||
type Error = SelectorParseError<'i, StyleParseError<'i>>;
|
type Error = StyleParseErrorKind<'i>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A wrapper to wraps the KeyframeSelector with its source location
|
/// A wrapper to wraps the KeyframeSelector with its source location
|
||||||
|
@ -512,7 +510,7 @@ struct KeyframeSelectorParserPrelude {
|
||||||
impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListParser<'a, R> {
|
impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListParser<'a, R> {
|
||||||
type Prelude = KeyframeSelectorParserPrelude;
|
type Prelude = KeyframeSelectorParserPrelude;
|
||||||
type QualifiedRule = Arc<Locked<Keyframe>>;
|
type QualifiedRule = Arc<Locked<Keyframe>>;
|
||||||
type Error = SelectorParseError<'i, StyleParseError<'i>>;
|
type Error = StyleParseErrorKind<'i>;
|
||||||
|
|
||||||
fn parse_prelude<'t>(&mut self, input: &mut Parser<'i, 't>) -> Result<Self::Prelude, ParseError<'i>> {
|
fn parse_prelude<'t>(&mut self, input: &mut Parser<'i, 't>) -> Result<Self::Prelude, ParseError<'i>> {
|
||||||
let start_position = input.position();
|
let start_position = input.position();
|
||||||
|
@ -525,8 +523,9 @@ impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListPars
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
let location = e.location;
|
||||||
let error = ContextualParseError::InvalidKeyframeRule(input.slice_from(start_position), e.clone());
|
let error = ContextualParseError::InvalidKeyframeRule(input.slice_from(start_position), e.clone());
|
||||||
self.context.log_css_error(self.error_context, start_location, error);
|
self.context.log_css_error(self.error_context, location, error);
|
||||||
Err(e)
|
Err(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -552,10 +551,11 @@ impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListPars
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
block.extend(iter.parser.declarations.drain(), Importance::Normal);
|
block.extend(iter.parser.declarations.drain(), Importance::Normal);
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err((error, slice)) => {
|
||||||
iter.parser.declarations.clear();
|
iter.parser.declarations.clear();
|
||||||
let error = ContextualParseError::UnsupportedKeyframePropertyDeclaration(err.slice, err.error);
|
let location = error.location;
|
||||||
context.log_css_error(self.error_context, err.location, error);
|
let error = ContextualParseError::UnsupportedKeyframePropertyDeclaration(slice, error);
|
||||||
|
context.log_css_error(self.error_context, location, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// `parse_important` is not called here, `!important` is not allowed in keyframe blocks.
|
// `parse_important` is not called here, `!important` is not allowed in keyframe blocks.
|
||||||
|
@ -578,25 +578,26 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for KeyframeDeclarationParser<'a, 'b> {
|
||||||
type PreludeNoBlock = ();
|
type PreludeNoBlock = ();
|
||||||
type PreludeBlock = ();
|
type PreludeBlock = ();
|
||||||
type AtRule = ();
|
type AtRule = ();
|
||||||
type Error = SelectorParseError<'i, StyleParseError<'i>>;
|
type Error = StyleParseErrorKind<'i>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, 'i> DeclarationParser<'i> for KeyframeDeclarationParser<'a, 'b> {
|
impl<'a, 'b, 'i> DeclarationParser<'i> for KeyframeDeclarationParser<'a, 'b> {
|
||||||
type Declaration = ();
|
type Declaration = ();
|
||||||
type Error = SelectorParseError<'i, StyleParseError<'i>>;
|
type Error = StyleParseErrorKind<'i>;
|
||||||
|
|
||||||
fn parse_value<'t>(&mut self, name: CowRcStr<'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 property_context = PropertyParserContext::new(self.context);
|
let property_context = PropertyParserContext::new(self.context);
|
||||||
|
|
||||||
let id = PropertyId::parse(&name, Some(&property_context))
|
let id = PropertyId::parse(&name, Some(&property_context)).map_err(|()| {
|
||||||
.map_err(|()| PropertyDeclarationParseError::UnknownProperty(name.clone()))?;
|
input.new_custom_error(StyleParseErrorKind::UnknownProperty(name.clone()))
|
||||||
|
})?;
|
||||||
match PropertyDeclaration::parse_into(self.declarations, id, name, self.context, input) {
|
match PropertyDeclaration::parse_into(self.declarations, id, name, self.context, input) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
// In case there is still unparsed text in the declaration, we should roll back.
|
// In case there is still unparsed text in the declaration, we should roll back.
|
||||||
input.expect_exhausted().map_err(|e| e.into())
|
input.expect_exhausted().map_err(|e| e.into())
|
||||||
}
|
}
|
||||||
Err(_e) => Err(StyleParseError::UnspecifiedError.into())
|
Err(e) => Err(e.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use {Namespace, Prefix};
|
||||||
use computed_values::font_family::FamilyName;
|
use computed_values::font_family::FamilyName;
|
||||||
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::{CowRcStr, SourceLocation, BasicParseError};
|
use cssparser::{CowRcStr, SourceLocation, BasicParseError, BasicParseErrorKind};
|
||||||
use error_reporting::{ContextualParseError, ParseErrorReporter};
|
use error_reporting::{ContextualParseError, ParseErrorReporter};
|
||||||
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};
|
||||||
|
@ -16,11 +16,10 @@ use parser::{Parse, ParserContext, ParserErrorContext};
|
||||||
use properties::parse_property_declaration_list;
|
use properties::parse_property_declaration_list;
|
||||||
use selector_parser::{SelectorImpl, SelectorParser};
|
use selector_parser::{SelectorImpl, SelectorParser};
|
||||||
use selectors::SelectorList;
|
use selectors::SelectorList;
|
||||||
use selectors::parser::SelectorParseError;
|
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use shared_lock::{Locked, SharedRwLock};
|
use shared_lock::{Locked, SharedRwLock};
|
||||||
use str::starts_with_ignore_ascii_case;
|
use str::starts_with_ignore_ascii_case;
|
||||||
use style_traits::{StyleParseError, ParseError};
|
use style_traits::{StyleParseErrorKind, ParseError};
|
||||||
use stylesheets::{CssRule, CssRules, CssRuleType, Origin, StylesheetLoader};
|
use stylesheets::{CssRule, CssRules, CssRuleType, Origin, StylesheetLoader};
|
||||||
use stylesheets::{DocumentRule, FontFeatureValuesRule, KeyframesRule, MediaRule};
|
use stylesheets::{DocumentRule, FontFeatureValuesRule, KeyframesRule, MediaRule};
|
||||||
use stylesheets::{NamespaceRule, PageRule, StyleRule, SupportsRule, ViewportRule};
|
use stylesheets::{NamespaceRule, PageRule, StyleRule, SupportsRule, ViewportRule};
|
||||||
|
@ -160,7 +159,7 @@ impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a,
|
||||||
type PreludeNoBlock = AtRuleNonBlockPrelude;
|
type PreludeNoBlock = AtRuleNonBlockPrelude;
|
||||||
type PreludeBlock = AtRuleBlockPrelude;
|
type PreludeBlock = AtRuleBlockPrelude;
|
||||||
type AtRule = CssRule;
|
type AtRule = CssRule;
|
||||||
type Error = SelectorParseError<'i, StyleParseError<'i>>;
|
type Error = StyleParseErrorKind<'i>;
|
||||||
|
|
||||||
fn parse_prelude<'t>(
|
fn parse_prelude<'t>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -173,7 +172,7 @@ impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a,
|
||||||
if self.state > State::Imports {
|
if self.state > State::Imports {
|
||||||
// "@import must be before any rule but @charset"
|
// "@import must be before any rule but @charset"
|
||||||
self.had_hierarchy_error = true;
|
self.had_hierarchy_error = true;
|
||||||
return Err(StyleParseError::UnexpectedImportRule.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnexpectedImportRule))
|
||||||
}
|
}
|
||||||
|
|
||||||
let url_string = input.expect_url_or_string()?.as_ref().to_owned();
|
let url_string = input.expect_url_or_string()?.as_ref().to_owned();
|
||||||
|
@ -190,15 +189,16 @@ impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a,
|
||||||
if self.state > State::Namespaces {
|
if self.state > State::Namespaces {
|
||||||
// "@namespace must be before any rule but @charset and @import"
|
// "@namespace must be before any rule but @charset and @import"
|
||||||
self.had_hierarchy_error = true;
|
self.had_hierarchy_error = true;
|
||||||
return Err(StyleParseError::UnexpectedNamespaceRule.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnexpectedNamespaceRule))
|
||||||
}
|
}
|
||||||
|
|
||||||
let prefix = input.try(|i| i.expect_ident_cloned())
|
let prefix = input.try(|i| i.expect_ident_cloned())
|
||||||
.map(|s| Prefix::from(s.as_ref())).ok();
|
.map(|s| Prefix::from(s.as_ref())).ok();
|
||||||
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 { kind: BasicParseErrorKind::UnexpectedToken(t), location }) => {
|
||||||
return Err(StyleParseError::UnexpectedTokenWithinNamespace(t).into()),
|
return Err(location.new_custom_error(StyleParseErrorKind::UnexpectedTokenWithinNamespace(t)))
|
||||||
|
}
|
||||||
Err(e) => return Err(e.into()),
|
Err(e) => return Err(e.into()),
|
||||||
};
|
};
|
||||||
let url = Namespace::from(maybe_namespace.as_ref());
|
let url = Namespace::from(maybe_namespace.as_ref());
|
||||||
|
@ -209,7 +209,7 @@ impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a,
|
||||||
// anything left is invalid.
|
// anything left is invalid.
|
||||||
"charset" => {
|
"charset" => {
|
||||||
self.had_hierarchy_error = true;
|
self.had_hierarchy_error = true;
|
||||||
return Err(StyleParseError::UnexpectedCharsetRule.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnexpectedCharsetRule))
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -279,7 +279,7 @@ pub struct QualifiedRuleParserPrelude {
|
||||||
impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for TopLevelRuleParser<'a, R> {
|
impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for TopLevelRuleParser<'a, R> {
|
||||||
type Prelude = QualifiedRuleParserPrelude;
|
type Prelude = QualifiedRuleParserPrelude;
|
||||||
type QualifiedRule = CssRule;
|
type QualifiedRule = CssRule;
|
||||||
type Error = SelectorParseError<'i, StyleParseError<'i>>;
|
type Error = StyleParseErrorKind<'i>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn parse_prelude<'t>(
|
fn parse_prelude<'t>(
|
||||||
|
@ -331,9 +331,10 @@ impl<'a, 'b, R: ParseErrorReporter> NestedRuleParser<'a, 'b, R> {
|
||||||
while let Some(result) = iter.next() {
|
while let Some(result) = iter.next() {
|
||||||
match result {
|
match result {
|
||||||
Ok(rule) => rules.push(rule),
|
Ok(rule) => rules.push(rule),
|
||||||
Err(err) => {
|
Err((error, slice)) => {
|
||||||
let error = ContextualParseError::UnsupportedRule(err.slice, err.error);
|
let location = error.location;
|
||||||
self.context.log_css_error(self.error_context, err.location, error);
|
let error = ContextualParseError::UnsupportedRule(slice, error);
|
||||||
|
self.context.log_css_error(self.error_context, location, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -345,7 +346,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
|
||||||
type PreludeNoBlock = AtRuleNonBlockPrelude;
|
type PreludeNoBlock = AtRuleNonBlockPrelude;
|
||||||
type PreludeBlock = AtRuleBlockPrelude;
|
type PreludeBlock = AtRuleBlockPrelude;
|
||||||
type AtRule = CssRule;
|
type AtRule = CssRule;
|
||||||
type Error = SelectorParseError<'i, StyleParseError<'i>>;
|
type Error = StyleParseErrorKind<'i>;
|
||||||
|
|
||||||
fn parse_prelude<'t>(
|
fn parse_prelude<'t>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -371,7 +372,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
|
||||||
"font-feature-values" => {
|
"font-feature-values" => {
|
||||||
if !cfg!(feature = "gecko") {
|
if !cfg!(feature = "gecko") {
|
||||||
// Support for this rule is not fully implemented in Servo yet.
|
// Support for this rule is not fully implemented in Servo yet.
|
||||||
return Err(StyleParseError::UnsupportedAtRule(name.clone()).into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone())))
|
||||||
}
|
}
|
||||||
let family_names = parse_family_name_list(self.context, input)?;
|
let family_names = parse_family_name_list(self.context, input)?;
|
||||||
Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::FontFeatureValues(family_names, location)))
|
Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::FontFeatureValues(family_names, location)))
|
||||||
|
@ -379,14 +380,14 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
|
||||||
"counter-style" => {
|
"counter-style" => {
|
||||||
if !cfg!(feature = "gecko") {
|
if !cfg!(feature = "gecko") {
|
||||||
// Support for this rule is not fully implemented in Servo yet.
|
// Support for this rule is not fully implemented in Servo yet.
|
||||||
return Err(StyleParseError::UnsupportedAtRule(name.clone()).into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone())))
|
||||||
}
|
}
|
||||||
let name = parse_counter_style_name(input)?;
|
let name = parse_counter_style_name(input)?;
|
||||||
// ASCII-case-insensitive matches for "decimal" and "disc".
|
// ASCII-case-insensitive matches for "decimal" and "disc".
|
||||||
// The name is already lower-cased by `parse_counter_style_name`
|
// The name is already lower-cased by `parse_counter_style_name`
|
||||||
// so we can use == here.
|
// so we can use == here.
|
||||||
if name.0 == atom!("decimal") || name.0 == atom!("disc") {
|
if name.0 == atom!("decimal") || name.0 == atom!("disc") {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::CounterStyle(name)))
|
Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::CounterStyle(name)))
|
||||||
},
|
},
|
||||||
|
@ -394,7 +395,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
|
||||||
if viewport_rule::enabled() {
|
if viewport_rule::enabled() {
|
||||||
Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::Viewport))
|
Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::Viewport))
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnsupportedAtRule(name.clone()).into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone())))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"keyframes" | "-webkit-keyframes" | "-moz-keyframes" => {
|
"keyframes" | "-webkit-keyframes" | "-moz-keyframes" => {
|
||||||
|
@ -408,7 +409,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
|
||||||
if cfg!(feature = "servo") &&
|
if cfg!(feature = "servo") &&
|
||||||
prefix.as_ref().map_or(false, |p| matches!(*p, VendorPrefix::Moz)) {
|
prefix.as_ref().map_or(false, |p| matches!(*p, VendorPrefix::Moz)) {
|
||||||
// Servo should not support @-moz-keyframes.
|
// Servo should not support @-moz-keyframes.
|
||||||
return Err(StyleParseError::UnsupportedAtRule(name.clone()).into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone())))
|
||||||
}
|
}
|
||||||
let name = KeyframesName::parse(self.context, input)?;
|
let name = KeyframesName::parse(self.context, input)?;
|
||||||
|
|
||||||
|
@ -418,7 +419,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
|
||||||
if cfg!(feature = "gecko") {
|
if cfg!(feature = "gecko") {
|
||||||
Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::Page(location)))
|
Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::Page(location)))
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnsupportedAtRule(name.clone()).into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone())))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"-moz-document" => {
|
"-moz-document" => {
|
||||||
|
@ -426,10 +427,10 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
|
||||||
let cond = DocumentCondition::parse(self.context, input)?;
|
let cond = DocumentCondition::parse(self.context, input)?;
|
||||||
Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::Document(cond, location)))
|
Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::Document(cond, location)))
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnsupportedAtRule(name.clone()).into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone())))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => Err(StyleParseError::UnsupportedAtRule(name.clone()).into())
|
_ => Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,7 +549,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
|
||||||
impl<'a, 'b, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for NestedRuleParser<'a, 'b, R> {
|
impl<'a, 'b, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for NestedRuleParser<'a, 'b, R> {
|
||||||
type Prelude = QualifiedRuleParserPrelude;
|
type Prelude = QualifiedRuleParserPrelude;
|
||||||
type QualifiedRule = CssRule;
|
type QualifiedRule = CssRule;
|
||||||
type Error = SelectorParseError<'i, StyleParseError<'i>>;
|
type Error = StyleParseErrorKind<'i>;
|
||||||
|
|
||||||
fn parse_prelude<'t>(
|
fn parse_prelude<'t>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
|
@ -394,10 +394,11 @@ impl Stylesheet {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err((error, slice)) => {
|
||||||
let error = ContextualParseError::InvalidRule(err.slice, err.error);
|
let location = error.location;
|
||||||
|
let error = ContextualParseError::InvalidRule(slice, error);
|
||||||
iter.parser.context.log_css_error(&iter.parser.error_context,
|
iter.parser.context.log_css_error(&iter.parser.error_context,
|
||||||
err.location, error);
|
location, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,17 +4,17 @@
|
||||||
|
|
||||||
//! [@supports rules](https://drafts.csswg.org/css-conditional-3/#at-supports)
|
//! [@supports rules](https://drafts.csswg.org/css-conditional-3/#at-supports)
|
||||||
|
|
||||||
use cssparser::{BasicParseError, ParseError as CssParseError, ParserInput};
|
|
||||||
use cssparser::{Delimiter, parse_important, Parser, SourceLocation, Token};
|
use cssparser::{Delimiter, parse_important, Parser, SourceLocation, Token};
|
||||||
|
use cssparser::{ParseError as CssParseError, ParserInput};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
|
use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
|
||||||
use parser::ParserContext;
|
use parser::ParserContext;
|
||||||
use properties::{PropertyId, PropertyDeclaration, PropertyParserContext, SourcePropertyDeclaration};
|
use properties::{PropertyId, PropertyDeclaration, PropertyParserContext, SourcePropertyDeclaration};
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
|
use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{ToCss, ParseError, StyleParseError};
|
use style_traits::{ToCss, ParseError};
|
||||||
use stylesheets::{CssRuleType, CssRules};
|
use stylesheets::{CssRuleType, CssRules};
|
||||||
|
|
||||||
/// An [`@supports`][supports] rule.
|
/// An [`@supports`][supports] rule.
|
||||||
|
@ -104,6 +104,7 @@ impl SupportsCondition {
|
||||||
|
|
||||||
let in_parens = SupportsCondition::parse_in_parens(input)?;
|
let in_parens = SupportsCondition::parse_in_parens(input)?;
|
||||||
|
|
||||||
|
let location = input.current_source_location();
|
||||||
let (keyword, wrapper) = match input.next() {
|
let (keyword, wrapper) = match input.next() {
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
// End of input
|
// End of input
|
||||||
|
@ -113,10 +114,10 @@ impl SupportsCondition {
|
||||||
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(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(t) => return Err(CssParseError::Basic(BasicParseError::UnexpectedToken(t.clone())))
|
Ok(t) => return Err(location.new_unexpected_token_error(t.clone()))
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut conditions = Vec::with_capacity(2);
|
let mut conditions = Vec::with_capacity(2);
|
||||||
|
@ -138,6 +139,7 @@ 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();
|
||||||
|
let location = input.current_source_location();
|
||||||
// FIXME: remove clone() when lifetimes are non-lexical
|
// FIXME: remove clone() when lifetimes are non-lexical
|
||||||
match input.next()?.clone() {
|
match input.next()?.clone() {
|
||||||
Token::ParenthesisBlock => {
|
Token::ParenthesisBlock => {
|
||||||
|
@ -149,7 +151,7 @@ impl SupportsCondition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Token::Function(_) => {}
|
Token::Function(_) => {}
|
||||||
t => return Err(CssParseError::Basic(BasicParseError::UnexpectedToken(t))),
|
t => return Err(location.new_unexpected_token_error(t)),
|
||||||
}
|
}
|
||||||
input.parse_nested_block(|i| consume_any_value(i))?;
|
input.parse_nested_block(|i| consume_any_value(i))?;
|
||||||
Ok(SupportsCondition::FutureSyntax(input.slice_from(pos).to_owned()))
|
Ok(SupportsCondition::FutureSyntax(input.slice_from(pos).to_owned()))
|
||||||
|
@ -258,18 +260,18 @@ 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| -> Result<(), CssParseError<()>> {
|
||||||
let prop = input.expect_ident().unwrap().as_ref().to_owned();
|
let prop = input.expect_ident().unwrap().as_ref().to_owned();
|
||||||
input.expect_colon().unwrap();
|
input.expect_colon().unwrap();
|
||||||
|
|
||||||
let property_context = PropertyParserContext::new(&context);
|
let property_context = PropertyParserContext::new(&context);
|
||||||
let id = PropertyId::parse(&prop, Some(&property_context))
|
let id = PropertyId::parse(&prop, Some(&property_context))
|
||||||
.map_err(|_| StyleParseError::UnspecifiedError)?;
|
.map_err(|()| input.new_custom_error(()))?;
|
||||||
|
|
||||||
let mut declarations = SourcePropertyDeclaration::new();
|
let mut declarations = SourcePropertyDeclaration::new();
|
||||||
input.parse_until_before(Delimiter::Bang, |input| {
|
input.parse_until_before(Delimiter::Bang, |input| {
|
||||||
PropertyDeclaration::parse_into(&mut declarations, id, prop.into(), &context, input)
|
PropertyDeclaration::parse_into(&mut declarations, id, prop.into(), &context, input)
|
||||||
.map_err(|e| StyleParseError::PropertyDeclaration(e).into())
|
.map_err(|_| input.new_custom_error(()))
|
||||||
})?;
|
})?;
|
||||||
let _ = input.try(parse_important);
|
let _ = input.try(parse_important);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -18,7 +18,7 @@ use media_queries::Device;
|
||||||
use parser::{ParserContext, ParserErrorContext};
|
use parser::{ParserContext, ParserErrorContext};
|
||||||
use properties::StyleBuilder;
|
use properties::StyleBuilder;
|
||||||
use rule_cache::RuleCacheConditions;
|
use rule_cache::RuleCacheConditions;
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use shared_lock::{SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard};
|
use shared_lock::{SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard};
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
@ -26,7 +26,7 @@ use std::cell::RefCell;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::iter::Enumerate;
|
use std::iter::Enumerate;
|
||||||
use std::str::Chars;
|
use std::str::Chars;
|
||||||
use style_traits::{PinchZoomFactor, ToCss, ParseError, StyleParseError};
|
use style_traits::{PinchZoomFactor, ToCss, ParseError, StyleParseErrorKind};
|
||||||
use style_traits::viewport::{Orientation, UserZoom, ViewportConstraints, Zoom};
|
use style_traits::viewport::{Orientation, UserZoom, ViewportConstraints, Zoom};
|
||||||
use stylesheets::{StylesheetInDocument, Origin};
|
use stylesheets::{StylesheetInDocument, Origin};
|
||||||
use values::computed::{Context, ToComputedValue};
|
use values::computed::{Context, ToComputedValue};
|
||||||
|
@ -276,12 +276,12 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for ViewportRuleParser<'a, 'b> {
|
||||||
type PreludeNoBlock = ();
|
type PreludeNoBlock = ();
|
||||||
type PreludeBlock = ();
|
type PreludeBlock = ();
|
||||||
type AtRule = Vec<ViewportDescriptorDeclaration>;
|
type AtRule = Vec<ViewportDescriptorDeclaration>;
|
||||||
type Error = SelectorParseError<'i, StyleParseError<'i>>;
|
type Error = StyleParseErrorKind<'i>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, 'i> DeclarationParser<'i> for ViewportRuleParser<'a, 'b> {
|
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 = StyleParseErrorKind<'i>;
|
||||||
|
|
||||||
fn parse_value<'t>(&mut self, name: CowRcStr<'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>> {
|
||||||
|
@ -323,7 +323,7 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for ViewportRuleParser<'a, 'b> {
|
||||||
"max-zoom" => ok!(MaxZoom(Zoom::parse)),
|
"max-zoom" => ok!(MaxZoom(Zoom::parse)),
|
||||||
"user-zoom" => ok!(UserZoom(UserZoom::parse)),
|
"user-zoom" => ok!(UserZoom(UserZoom::parse)),
|
||||||
"orientation" => ok!(Orientation(Orientation::parse)),
|
"orientation" => ok!(Orientation(Orientation::parse)),
|
||||||
_ => Err(SelectorParseError::UnexpectedIdent(name.clone()).into()),
|
_ => Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -368,9 +368,10 @@ impl ViewportRule {
|
||||||
cascade.add(Cow::Owned(declarations))
|
cascade.add(Cow::Owned(declarations))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err((error, slice)) => {
|
||||||
let error = ContextualParseError::UnsupportedViewportDescriptorDeclaration(err.slice, err.error);
|
let location = error.location;
|
||||||
context.log_css_error(error_context, err.location, error);
|
let error = ContextualParseError::UnsupportedViewportDescriptorDeclaration(slice, error);
|
||||||
|
context.log_css_error(error_context, location, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
use cssparser::Parser;
|
use cssparser::Parser;
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use std::{fmt, mem, usize};
|
use std::{fmt, mem, usize};
|
||||||
use style_traits::{ToCss, ParseError, StyleParseError};
|
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
|
||||||
use values::{CSSFloat, CustomIdent, serialize_dimension};
|
use values::{CSSFloat, CustomIdent, serialize_dimension};
|
||||||
use values::computed::{Context, ToComputedValue};
|
use values::computed::{Context, ToComputedValue};
|
||||||
use values::specified;
|
use values::specified;
|
||||||
|
@ -88,9 +88,10 @@ impl Parse for GridLine<specified::Integer> {
|
||||||
let mut val_before_span = false;
|
let mut val_before_span = false;
|
||||||
|
|
||||||
for _ in 0..3 { // Maximum possible entities for <grid-line>
|
for _ in 0..3 { // Maximum possible entities for <grid-line>
|
||||||
|
let location = input.current_source_location();
|
||||||
if input.try(|i| i.expect_ident_matching("span")).is_ok() {
|
if input.try(|i| i.expect_ident_matching("span")).is_ok() {
|
||||||
if grid_line.is_span {
|
if grid_line.is_span {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
||||||
if grid_line.line_num.is_some() || grid_line.ident.is_some() {
|
if grid_line.line_num.is_some() || grid_line.ident.is_some() {
|
||||||
|
@ -101,31 +102,31 @@ impl Parse for GridLine<specified::Integer> {
|
||||||
} else if let Ok(i) = input.try(|i| specified::Integer::parse(context, i)) {
|
} else if let Ok(i) = input.try(|i| specified::Integer::parse(context, i)) {
|
||||||
// FIXME(emilio): Probably shouldn't reject if it's calc()...
|
// FIXME(emilio): Probably shouldn't reject if it's calc()...
|
||||||
if i.value() == 0 || val_before_span || grid_line.line_num.is_some() {
|
if i.value() == 0 || val_before_span || grid_line.line_num.is_some() {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
||||||
grid_line.line_num = Some(i);
|
grid_line.line_num = Some(i);
|
||||||
} else if let Ok(name) = input.try(|i| i.expect_ident_cloned()) {
|
} 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(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
grid_line.ident = Some(CustomIdent::from_ident(&name, &[])?);
|
grid_line.ident = Some(CustomIdent::from_ident(location, &name, &[])?);
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if grid_line.is_auto() {
|
if grid_line.is_auto() {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
||||||
if grid_line.is_span {
|
if grid_line.is_span {
|
||||||
if let Some(i) = grid_line.line_num {
|
if let Some(i) = grid_line.line_num {
|
||||||
if i.value() <= 0 { // disallow negative integers for grid spans
|
if i.value() <= 0 { // disallow negative integers for grid spans
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
} else if grid_line.ident.is_none() { // integer could be omitted
|
} else if grid_line.ident.is_none() { // integer could be omitted
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,7 +370,7 @@ impl Parse for RepeatCount<specified::Integer> {
|
||||||
}
|
}
|
||||||
Ok(RepeatCount::Number(i))
|
Ok(RepeatCount::Number(i))
|
||||||
} else {
|
} else {
|
||||||
try_match_ident_ignore_ascii_case! { input.expect_ident()?,
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
"auto-fill" => Ok(RepeatCount::AutoFill),
|
"auto-fill" => Ok(RepeatCount::AutoFill),
|
||||||
"auto-fit" => Ok(RepeatCount::AutoFit),
|
"auto-fit" => Ok(RepeatCount::AutoFit),
|
||||||
}
|
}
|
||||||
|
@ -612,14 +613,14 @@ impl Parse for LineNameList {
|
||||||
RepeatCount::AutoFill if fill_idx.is_none() => {
|
RepeatCount::AutoFill if fill_idx.is_none() => {
|
||||||
// `repeat(autof-fill, ..)` should have just one line name.
|
// `repeat(autof-fill, ..)` should have just one line name.
|
||||||
if names_list.len() != 1 {
|
if names_list.len() != 1 {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
let names = names_list.pop().unwrap();
|
let names = names_list.pop().unwrap();
|
||||||
|
|
||||||
line_names.push(names);
|
line_names.push(names);
|
||||||
fill_idx = Some(line_names.len() as u32 - 1);
|
fill_idx = Some(line_names.len() as u32 - 1);
|
||||||
},
|
},
|
||||||
_ => return Err(StyleParseError::UnspecifiedError.into()),
|
_ => return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
|
||||||
}
|
}
|
||||||
} else if let Ok(names) = input.try(parse_line_names) {
|
} else if let Ok(names) = input.try(parse_line_names) {
|
||||||
line_names.push(names);
|
line_names.push(names);
|
||||||
|
|
|
@ -9,7 +9,7 @@ use counter_style::{Symbols, parse_counter_style_name};
|
||||||
use cssparser::Parser;
|
use cssparser::Parser;
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseError, ToCss};
|
use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseErrorKind, ToCss};
|
||||||
use super::CustomIdent;
|
use super::CustomIdent;
|
||||||
|
|
||||||
pub mod background;
|
pub mod background;
|
||||||
|
@ -114,16 +114,16 @@ impl Parse for CounterStyleOrNone {
|
||||||
// numeric system.
|
// numeric system.
|
||||||
if (symbols_type == SymbolsType::Alphabetic ||
|
if (symbols_type == SymbolsType::Alphabetic ||
|
||||||
symbols_type == SymbolsType::Numeric) && symbols.0.len() < 2 {
|
symbols_type == SymbolsType::Numeric) && symbols.0.len() < 2 {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
// Identifier is not allowed in symbols() function.
|
// Identifier is not allowed in symbols() function.
|
||||||
if symbols.0.iter().any(|sym| !sym.is_allowed_in_symbols()) {
|
if symbols.0.iter().any(|sym| !sym.is_allowed_in_symbols()) {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
Ok(CounterStyleOrNone::Symbols(symbols_type, symbols))
|
Ok(CounterStyleOrNone::Symbols(symbols_type, symbols))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,13 +170,14 @@ impl<T: Parse> Parse for FontSettingTag<T> {
|
||||||
|
|
||||||
let u_tag;
|
let u_tag;
|
||||||
{
|
{
|
||||||
|
let location = input.current_source_location();
|
||||||
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>
|
||||||
if tag.len() != 4 ||
|
if tag.len() != 4 ||
|
||||||
tag.chars().any(|c| c < ' ' || c > '~')
|
tag.chars().any(|c| c < ' ' || c > '~')
|
||||||
{
|
{
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut raw = Cursor::new(tag.as_bytes());
|
let mut raw = Cursor::new(tag.as_bytes());
|
||||||
|
@ -248,7 +249,7 @@ impl Parse for FontSettingTagInt {
|
||||||
if value >= 0 {
|
if value >= 0 {
|
||||||
Ok(FontSettingTagInt(value as u32))
|
Ok(FontSettingTagInt(value as u32))
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
} else if let Ok(_) = input.try(|input| input.expect_ident_matching("on")) {
|
} else if let Ok(_) = input.try(|input| input.expect_ident_matching("on")) {
|
||||||
// on is an alias for '1'
|
// on is an alias for '1'
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
use cssparser::Parser;
|
use cssparser::Parser;
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{ParseError, StyleParseError, ToCss};
|
use style_traits::{ParseError, StyleParseErrorKind, ToCss};
|
||||||
use values::{Either, None_};
|
use values::{Either, None_};
|
||||||
use values::computed::NumberOrPercentage;
|
use values::computed::NumberOrPercentage;
|
||||||
use values::computed::length::LengthOrPercentage;
|
use values::computed::length::LengthOrPercentage;
|
||||||
|
@ -54,7 +54,7 @@ pub enum SVGPaintKind<ColorType, UrlPaintServer> {
|
||||||
impl<ColorType, UrlPaintServer> SVGPaintKind<ColorType, UrlPaintServer> {
|
impl<ColorType, UrlPaintServer> SVGPaintKind<ColorType, UrlPaintServer> {
|
||||||
/// Parse a keyword value only
|
/// Parse a keyword value only
|
||||||
fn parse_ident<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
fn parse_ident<'i, 't>(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,
|
||||||
"none" => Ok(SVGPaintKind::None),
|
"none" => Ok(SVGPaintKind::None),
|
||||||
"context-fill" => Ok(SVGPaintKind::ContextFill),
|
"context-fill" => Ok(SVGPaintKind::ContextFill),
|
||||||
"context-stroke" => Ok(SVGPaintKind::ContextStroke),
|
"context-stroke" => Ok(SVGPaintKind::ContextStroke),
|
||||||
|
@ -104,7 +104,7 @@ impl<ColorType: Parse, UrlPaintServer: Parse> Parse for SVGPaint<ColorType, UrlP
|
||||||
fallback: None,
|
fallback: None,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -189,7 +189,7 @@ impl <LengthOrPercentageType: Parse, NumberType: Parse> Parse for
|
||||||
if let Ok(lop) = input.try(|i| LengthOrPercentageType::parse(context, i)) {
|
if let Ok(lop) = input.try(|i| LengthOrPercentageType::parse(context, i)) {
|
||||||
return Ok(SvgLengthOrPercentageOrNumber::LengthOrPercentage(lop));
|
return Ok(SvgLengthOrPercentageOrNumber::LengthOrPercentage(lop));
|
||||||
}
|
}
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,13 +9,13 @@
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
use Atom;
|
use Atom;
|
||||||
pub use cssparser::{RGBA, Token, Parser, serialize_identifier, BasicParseError, CowRcStr};
|
pub use cssparser::{RGBA, Token, Parser, serialize_identifier, CowRcStr, SourceLocation};
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
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, StyleParseErrorKind};
|
||||||
|
|
||||||
pub mod animated;
|
pub mod animated;
|
||||||
pub mod computed;
|
pub mod computed;
|
||||||
|
@ -57,9 +57,9 @@ pub enum Impossible {}
|
||||||
impl Parse for Impossible {
|
impl Parse for Impossible {
|
||||||
fn parse<'i, 't>(
|
fn parse<'i, 't>(
|
||||||
_context: &ParserContext,
|
_context: &ParserContext,
|
||||||
_input: &mut Parser<'i, 't>)
|
input: &mut Parser<'i, 't>)
|
||||||
-> Result<Self, ParseError<'i>> {
|
-> Result<Self, ParseError<'i>> {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,16 +103,17 @@ 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: &CowRcStr<'i>, excluding: &[&str]) -> Result<Self, ParseError<'i>> {
|
pub fn from_ident<'i>(location: SourceLocation, 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.clone()).into());
|
return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone())));
|
||||||
}
|
}
|
||||||
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(location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
} else {
|
} else {
|
||||||
Ok(CustomIdent(Atom::from(ident.as_ref())))
|
Ok(CustomIdent(Atom::from(ident.as_ref())))
|
||||||
}
|
}
|
||||||
|
@ -139,7 +140,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: &str) -> Self {
|
pub fn from_ident(value: &str) -> Self {
|
||||||
let custom_ident = CustomIdent::from_ident(&value.into(), &["none"]).ok();
|
let location = SourceLocation { line: 0, column: 0 };
|
||||||
|
let custom_ident = CustomIdent::from_ident(location, &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()),
|
||||||
|
@ -182,10 +184,11 @@ 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>> {
|
||||||
|
let location = input.current_source_location();
|
||||||
match input.next() {
|
match input.next() {
|
||||||
Ok(&Token::Ident(ref s)) => Ok(KeyframesName::Ident(CustomIdent::from_ident(s, &["none"])?)),
|
Ok(&Token::Ident(ref s)) => Ok(KeyframesName::Ident(CustomIdent::from_ident(location, s, &["none"])?)),
|
||||||
Ok(&Token::QuotedString(ref s)) => Ok(KeyframesName::QuotedString(Atom::from(s.as_ref()))),
|
Ok(&Token::QuotedString(ref s)) => Ok(KeyframesName::QuotedString(Atom::from(s.as_ref()))),
|
||||||
Ok(t) => Err(BasicParseError::UnexpectedToken(t.clone()).into()),
|
Ok(t) => Err(location.new_unexpected_token_error(t.clone())),
|
||||||
Err(e) => Err(e.into()),
|
Err(e) => Err(e.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
use cssparser::Parser;
|
use cssparser::Parser;
|
||||||
use gecko_bindings::structs;
|
use gecko_bindings::structs;
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{ToCss, ParseError, StyleParseError};
|
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Constants shared by multiple CSS Box Alignment properties
|
/// Constants shared by multiple CSS Box Alignment properties
|
||||||
|
@ -201,7 +201,7 @@ impl Parse for AlignJustifyContent {
|
||||||
}
|
}
|
||||||
return Ok(AlignJustifyContent::new(fallback))
|
return Ok(AlignJustifyContent::new(fallback))
|
||||||
}
|
}
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +239,7 @@ impl Parse for AlignJustifySelf {
|
||||||
if let Ok(value) = input.try(parse_overflow_self_position) {
|
if let Ok(value) = input.try(parse_overflow_self_position) {
|
||||||
return Ok(AlignJustifySelf(value))
|
return Ok(AlignJustifySelf(value))
|
||||||
}
|
}
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,7 +277,7 @@ impl Parse for AlignItems {
|
||||||
if let Ok(value) = input.try(parse_overflow_self_position) {
|
if let Ok(value) = input.try(parse_overflow_self_position) {
|
||||||
return Ok(AlignItems(value))
|
return Ok(AlignItems(value))
|
||||||
}
|
}
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,7 +326,7 @@ impl Parse for JustifyItems {
|
||||||
if let Ok(value) = parse_overflow_self_position(input) {
|
if let Ok(value) = parse_overflow_self_position(input) {
|
||||||
return Ok(JustifyItems(value))
|
return Ok(JustifyItems(value))
|
||||||
}
|
}
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,7 +351,7 @@ fn parse_auto_normal_stretch_baseline<'i, 't>(input: &mut Parser<'i, 't>)
|
||||||
return Ok(baseline);
|
return Ok(baseline);
|
||||||
}
|
}
|
||||||
|
|
||||||
try_match_ident_ignore_ascii_case! { input.expect_ident()?,
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
"auto" => Ok(ALIGN_AUTO),
|
"auto" => Ok(ALIGN_AUTO),
|
||||||
"normal" => Ok(ALIGN_NORMAL),
|
"normal" => Ok(ALIGN_NORMAL),
|
||||||
"stretch" => Ok(ALIGN_STRETCH),
|
"stretch" => Ok(ALIGN_STRETCH),
|
||||||
|
@ -364,7 +364,7 @@ fn parse_normal_stretch_baseline<'i, 't>(input: &mut Parser<'i, 't>) -> Result<A
|
||||||
return Ok(baseline);
|
return Ok(baseline);
|
||||||
}
|
}
|
||||||
|
|
||||||
try_match_ident_ignore_ascii_case! { input.expect_ident()?,
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
"normal" => Ok(ALIGN_NORMAL),
|
"normal" => Ok(ALIGN_NORMAL),
|
||||||
"stretch" => Ok(ALIGN_STRETCH),
|
"stretch" => Ok(ALIGN_STRETCH),
|
||||||
}
|
}
|
||||||
|
@ -383,7 +383,7 @@ 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>> {
|
||||||
// FIXME: remove clone() when lifetimes are non-lexical
|
// FIXME: remove clone() when lifetimes are non-lexical
|
||||||
try_match_ident_ignore_ascii_case! { input.expect_ident()?.clone(),
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
"baseline" => Ok(ALIGN_BASELINE),
|
"baseline" => Ok(ALIGN_BASELINE),
|
||||||
"first" => {
|
"first" => {
|
||||||
input.expect_ident_matching("baseline")?;
|
input.expect_ident_matching("baseline")?;
|
||||||
|
@ -398,7 +398,7 @@ fn parse_baseline<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, Pars
|
||||||
|
|
||||||
// <content-distribution>
|
// <content-distribution>
|
||||||
fn parse_content_distribution<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseError<'i>> {
|
fn parse_content_distribution<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseError<'i>> {
|
||||||
try_match_ident_ignore_ascii_case! { input.expect_ident()?,
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
"stretch" => Ok(ALIGN_STRETCH),
|
"stretch" => Ok(ALIGN_STRETCH),
|
||||||
"space-between" => Ok(ALIGN_SPACE_BETWEEN),
|
"space-between" => Ok(ALIGN_SPACE_BETWEEN),
|
||||||
"space-around" => Ok(ALIGN_SPACE_AROUND),
|
"space-around" => Ok(ALIGN_SPACE_AROUND),
|
||||||
|
@ -421,12 +421,12 @@ fn parse_overflow_content_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result
|
||||||
return Ok(overflow | content)
|
return Ok(overflow | content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
||||||
// <content-position>
|
// <content-position>
|
||||||
fn parse_content_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseError<'i>> {
|
fn parse_content_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseError<'i>> {
|
||||||
try_match_ident_ignore_ascii_case! { input.expect_ident()?,
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
"start" => Ok(ALIGN_START),
|
"start" => Ok(ALIGN_START),
|
||||||
"end" => Ok(ALIGN_END),
|
"end" => Ok(ALIGN_END),
|
||||||
"flex-start" => Ok(ALIGN_FLEX_START),
|
"flex-start" => Ok(ALIGN_FLEX_START),
|
||||||
|
@ -439,7 +439,7 @@ fn parse_content_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFla
|
||||||
|
|
||||||
// <overflow-position>
|
// <overflow-position>
|
||||||
fn parse_overflow_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseError<'i>> {
|
fn parse_overflow_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseError<'i>> {
|
||||||
try_match_ident_ignore_ascii_case! { input.expect_ident()?,
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
"safe" => Ok(ALIGN_SAFE),
|
"safe" => Ok(ALIGN_SAFE),
|
||||||
"unsafe" => Ok(ALIGN_UNSAFE),
|
"unsafe" => Ok(ALIGN_UNSAFE),
|
||||||
}
|
}
|
||||||
|
@ -460,12 +460,12 @@ fn parse_overflow_self_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Al
|
||||||
return Ok(overflow | self_position)
|
return Ok(overflow | self_position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
||||||
// <self-position>
|
// <self-position>
|
||||||
fn parse_self_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseError<'i>> {
|
fn parse_self_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseError<'i>> {
|
||||||
try_match_ident_ignore_ascii_case! { input.expect_ident()?,
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
"start" => Ok(ALIGN_START),
|
"start" => Ok(ALIGN_START),
|
||||||
"end" => Ok(ALIGN_END),
|
"end" => Ok(ALIGN_END),
|
||||||
"flex-start" => Ok(ALIGN_FLEX_START),
|
"flex-start" => Ok(ALIGN_FLEX_START),
|
||||||
|
@ -480,7 +480,9 @@ 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_location = input.current_source_location();
|
||||||
let a = input.expect_ident()?.clone();
|
let a = input.expect_ident()?.clone();
|
||||||
|
let b_location = input.current_source_location();
|
||||||
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,
|
||||||
|
@ -488,15 +490,15 @@ 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.clone()).into())
|
}).map_err(|()| b_location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(b.clone())))
|
||||||
} 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),
|
||||||
"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(a).into())
|
}).map_err(|()| a_location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(a)))
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(a_location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
//! Specified angles.
|
//! Specified angles.
|
||||||
|
|
||||||
use cssparser::{Parser, Token, BasicParseError};
|
use cssparser::{Parser, Token};
|
||||||
use parser::{ParserContext, Parse};
|
use parser::{ParserContext, Parse};
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -112,7 +112,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.clone()).into())
|
}.map_err(|()| input.new_unexpected_token_error(token.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,6 +155,6 @@ 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.clone()).into())
|
}.map_err(|()| input.new_unexpected_token_error(token.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
use cssparser::Parser;
|
use cssparser::Parser;
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use style_traits::ParseError;
|
use style_traits::ParseError;
|
||||||
use values::generics::background::BackgroundSize as GenericBackgroundSize;
|
use values::generics::background::BackgroundSize as GenericBackgroundSize;
|
||||||
use values::specified::length::LengthOrPercentageOrAuto;
|
use values::specified::length::LengthOrPercentageOrAuto;
|
||||||
|
@ -22,12 +22,13 @@ impl Parse for BackgroundSize {
|
||||||
.unwrap_or(LengthOrPercentageOrAuto::Auto);
|
.unwrap_or(LengthOrPercentageOrAuto::Auto);
|
||||||
return Ok(GenericBackgroundSize::Explicit { width, height });
|
return Ok(GenericBackgroundSize::Explicit { width, height });
|
||||||
}
|
}
|
||||||
|
let location = input.current_source_location();
|
||||||
let ident = input.expect_ident()?;
|
let ident = input.expect_ident()?;
|
||||||
(match_ignore_ascii_case! { &ident,
|
(match_ignore_ascii_case! { &ident,
|
||||||
"cover" => Ok(GenericBackgroundSize::Cover),
|
"cover" => Ok(GenericBackgroundSize::Cover),
|
||||||
"contain" => Ok(GenericBackgroundSize::Contain),
|
"contain" => Ok(GenericBackgroundSize::Contain),
|
||||||
_ => Err(()),
|
_ => Err(()),
|
||||||
}).map_err(|()| SelectorParseError::UnexpectedIdent(ident.clone()).into())
|
}).map_err(|()| location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ use cssparser::Parser;
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{ToCss, ParseError, StyleParseError};
|
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
|
||||||
use values::computed::Percentage;
|
use values::computed::Percentage;
|
||||||
use values::generics::basic_shape::{Circle as GenericCircle};
|
use values::generics::basic_shape::{Circle as GenericCircle};
|
||||||
use values::generics::basic_shape::{ClippingShape as GenericClippingShape, Ellipse as GenericEllipse};
|
use values::generics::basic_shape::{ClippingShape as GenericClippingShape, Ellipse as GenericEllipse};
|
||||||
|
@ -81,7 +81,7 @@ impl<ReferenceBox: Parse> Parse for ShapeSource<BasicShape, ReferenceBox, Specif
|
||||||
return Ok(ShapeSource::Shape(shp, ref_box))
|
return Ok(ShapeSource::Shape(shp, ref_box))
|
||||||
}
|
}
|
||||||
|
|
||||||
ref_box.map(|v| ShapeSource::Box(v)).ok_or(StyleParseError::UnspecifiedError.into())
|
ref_box.map(|v| ShapeSource::Box(v)).ok_or(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ impl Parse for GeometryBox {
|
||||||
return Ok(GeometryBox::ShapeBox(shape_box))
|
return Ok(GeometryBox::ShapeBox(shape_box))
|
||||||
}
|
}
|
||||||
|
|
||||||
try_match_ident_ignore_ascii_case! { input.expect_ident()?,
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
"fill-box" => Ok(GeometryBox::FillBox),
|
"fill-box" => Ok(GeometryBox::FillBox),
|
||||||
"stroke-box" => Ok(GeometryBox::StrokeBox),
|
"stroke-box" => Ok(GeometryBox::StrokeBox),
|
||||||
"view-box" => Ok(GeometryBox::ViewBox),
|
"view-box" => Ok(GeometryBox::ViewBox),
|
||||||
|
@ -101,6 +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 location = input.current_source_location();
|
||||||
let function = input.expect_function()?.clone();
|
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,
|
||||||
|
@ -109,7 +110,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.clone()).into())
|
}).map_err(|()| location.new_custom_error(StyleParseErrorKind::UnexpectedFunction(function.clone())))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -229,7 +230,7 @@ impl Parse for ShapeRadius {
|
||||||
return Ok(GenericShapeRadius::Length(lop))
|
return Ok(GenericShapeRadius::Length(lop))
|
||||||
}
|
}
|
||||||
|
|
||||||
try_match_ident_ignore_ascii_case! { input.expect_ident()?,
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
"closest-side" => Ok(GenericShapeRadius::ClosestSide),
|
"closest-side" => Ok(GenericShapeRadius::ClosestSide),
|
||||||
"farthest-side" => Ok(GenericShapeRadius::FarthestSide),
|
"farthest-side" => Ok(GenericShapeRadius::FarthestSide),
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ impl BorderSideWidth {
|
||||||
if let Ok(length) = input.try(|i| Length::parse_non_negative_quirky(context, i, allow_quirks)) {
|
if let Ok(length) = input.try(|i| Length::parse_non_negative_quirky(context, i, allow_quirks)) {
|
||||||
return Ok(BorderSideWidth::Length(length));
|
return Ok(BorderSideWidth::Length(length));
|
||||||
}
|
}
|
||||||
try_match_ident_ignore_ascii_case! { input.expect_ident()?,
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
"thin" => Ok(BorderSideWidth::Thin),
|
"thin" => Ok(BorderSideWidth::Thin),
|
||||||
"medium" => Ok(BorderSideWidth::Medium),
|
"medium" => Ok(BorderSideWidth::Medium),
|
||||||
"thick" => Ok(BorderSideWidth::Thick),
|
"thick" => Ok(BorderSideWidth::Thick),
|
||||||
|
|
|
@ -23,7 +23,7 @@ impl Parse for VerticalAlign {
|
||||||
return Ok(GenericVerticalAlign::Length(lop));
|
return Ok(GenericVerticalAlign::Length(lop));
|
||||||
}
|
}
|
||||||
|
|
||||||
try_match_ident_ignore_ascii_case! { input.expect_ident()?,
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
"baseline" => Ok(GenericVerticalAlign::Baseline),
|
"baseline" => Ok(GenericVerticalAlign::Baseline),
|
||||||
"sub" => Ok(GenericVerticalAlign::Sub),
|
"sub" => Ok(GenericVerticalAlign::Sub),
|
||||||
"super" => Ok(GenericVerticalAlign::Super),
|
"super" => Ok(GenericVerticalAlign::Super),
|
||||||
|
|
|
@ -6,11 +6,11 @@
|
||||||
//!
|
//!
|
||||||
//! [calc]: https://drafts.csswg.org/css-values/#calc-notation
|
//! [calc]: https://drafts.csswg.org/css-values/#calc-notation
|
||||||
|
|
||||||
use cssparser::{Parser, Token, BasicParseError};
|
use cssparser::{Parser, Token};
|
||||||
use parser::ParserContext;
|
use parser::ParserContext;
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{ToCss, ParseError, StyleParseError};
|
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
|
||||||
use style_traits::values::specified::AllowedNumericType;
|
use style_traits::values::specified::AllowedNumericType;
|
||||||
use values::{CSSInteger, CSSFloat};
|
use values::{CSSInteger, CSSFloat};
|
||||||
use values::computed;
|
use values::computed;
|
||||||
|
@ -170,6 +170,7 @@ 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>> {
|
||||||
|
let location = input.current_source_location();
|
||||||
// FIXME: remove early returns when lifetimes are non-lexical
|
// FIXME: remove early returns when lifetimes are non-lexical
|
||||||
match (input.next()?, expected_unit) {
|
match (input.next()?, expected_unit) {
|
||||||
(&Token::Number { value, .. }, _) => return Ok(CalcNode::Number(value)),
|
(&Token::Number { value, .. }, _) => return Ok(CalcNode::Number(value)),
|
||||||
|
@ -177,17 +178,17 @@ impl CalcNode {
|
||||||
(&Token::Dimension { value, ref unit, .. }, CalcUnit::LengthOrPercentage) => {
|
(&Token::Dimension { value, ref unit, .. }, CalcUnit::LengthOrPercentage) => {
|
||||||
return 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(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
(&Token::Dimension { value, ref unit, .. }, CalcUnit::Angle) => {
|
(&Token::Dimension { value, ref unit, .. }, CalcUnit::Angle) => {
|
||||||
return 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(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
(&Token::Dimension { value, ref unit, .. }, CalcUnit::Time) => {
|
(&Token::Dimension { value, ref unit, .. }, CalcUnit::Time) => {
|
||||||
return 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(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
(&Token::Percentage { unit_value, .. }, CalcUnit::LengthOrPercentage) |
|
(&Token::Percentage { unit_value, .. }, CalcUnit::LengthOrPercentage) |
|
||||||
(&Token::Percentage { unit_value, .. }, CalcUnit::Percentage) => {
|
(&Token::Percentage { unit_value, .. }, CalcUnit::Percentage) => {
|
||||||
|
@ -195,7 +196,7 @@ impl CalcNode {
|
||||||
}
|
}
|
||||||
(&Token::ParenthesisBlock, _) => {}
|
(&Token::ParenthesisBlock, _) => {}
|
||||||
(&Token::Function(ref name), _) if name.eq_ignore_ascii_case("calc") => {}
|
(&Token::Function(ref name), _) if name.eq_ignore_ascii_case("calc") => {}
|
||||||
(t, _) => return Err(BasicParseError::UnexpectedToken(t.clone()).into())
|
(t, _) => return Err(location.new_unexpected_token_error(t.clone()))
|
||||||
}
|
}
|
||||||
input.parse_nested_block(|i| {
|
input.parse_nested_block(|i| {
|
||||||
CalcNode::parse(context, i, expected_unit)
|
CalcNode::parse(context, i, expected_unit)
|
||||||
|
@ -236,7 +237,7 @@ impl CalcNode {
|
||||||
CalcNode::Sub(Box::new(root), Box::new(rhs));
|
CalcNode::Sub(Box::new(root), Box::new(rhs));
|
||||||
root = new_root;
|
root = new_root;
|
||||||
}
|
}
|
||||||
t => return Err(BasicParseError::UnexpectedToken(t).into()),
|
t => return Err(input.new_unexpected_token_error(t)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -559,7 +560,7 @@ impl CalcNode {
|
||||||
Self::parse(context, input, CalcUnit::Integer)?
|
Self::parse(context, input, CalcUnit::Integer)?
|
||||||
.to_number()
|
.to_number()
|
||||||
.map(|n| n as CSSInteger)
|
.map(|n| n as CSSInteger)
|
||||||
.map_err(|()| StyleParseError::UnspecifiedError.into())
|
.map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience parsing function for `<length> | <percentage>`.
|
/// Convenience parsing function for `<length> | <percentage>`.
|
||||||
|
@ -570,7 +571,7 @@ impl CalcNode {
|
||||||
) -> Result<CalcLengthOrPercentage, ParseError<'i>> {
|
) -> Result<CalcLengthOrPercentage, ParseError<'i>> {
|
||||||
Self::parse(context, input, CalcUnit::LengthOrPercentage)?
|
Self::parse(context, input, CalcUnit::LengthOrPercentage)?
|
||||||
.to_length_or_percentage(clamping_mode)
|
.to_length_or_percentage(clamping_mode)
|
||||||
.map_err(|()| StyleParseError::UnspecifiedError.into())
|
.map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience parsing function for percentages.
|
/// Convenience parsing function for percentages.
|
||||||
|
@ -580,7 +581,7 @@ impl CalcNode {
|
||||||
) -> Result<CSSFloat, ParseError<'i>> {
|
) -> Result<CSSFloat, ParseError<'i>> {
|
||||||
Self::parse(context, input, CalcUnit::Percentage)?
|
Self::parse(context, input, CalcUnit::Percentage)?
|
||||||
.to_percentage()
|
.to_percentage()
|
||||||
.map_err(|()| StyleParseError::UnspecifiedError.into())
|
.map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience parsing function for `<length>`.
|
/// Convenience parsing function for `<length>`.
|
||||||
|
@ -591,7 +592,7 @@ impl CalcNode {
|
||||||
) -> Result<CalcLengthOrPercentage, ParseError<'i>> {
|
) -> Result<CalcLengthOrPercentage, ParseError<'i>> {
|
||||||
Self::parse(context, input, CalcUnit::Length)?
|
Self::parse(context, input, CalcUnit::Length)?
|
||||||
.to_length_or_percentage(clamping_mode)
|
.to_length_or_percentage(clamping_mode)
|
||||||
.map_err(|()| StyleParseError::UnspecifiedError.into())
|
.map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience parsing function for `<number>`.
|
/// Convenience parsing function for `<number>`.
|
||||||
|
@ -601,7 +602,7 @@ impl CalcNode {
|
||||||
) -> Result<CSSFloat, ParseError<'i>> {
|
) -> Result<CSSFloat, ParseError<'i>> {
|
||||||
Self::parse(context, input, CalcUnit::Number)?
|
Self::parse(context, input, CalcUnit::Number)?
|
||||||
.to_number()
|
.to_number()
|
||||||
.map_err(|()| StyleParseError::UnspecifiedError.into())
|
.map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience parsing function for `<angle>`.
|
/// Convenience parsing function for `<angle>`.
|
||||||
|
@ -611,7 +612,7 @@ impl CalcNode {
|
||||||
) -> Result<Angle, ParseError<'i>> {
|
) -> Result<Angle, ParseError<'i>> {
|
||||||
Self::parse(context, input, CalcUnit::Angle)?
|
Self::parse(context, input, CalcUnit::Angle)?
|
||||||
.to_angle()
|
.to_angle()
|
||||||
.map_err(|()| StyleParseError::UnspecifiedError.into())
|
.map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience parsing function for `<time>`.
|
/// Convenience parsing function for `<time>`.
|
||||||
|
@ -621,6 +622,6 @@ impl CalcNode {
|
||||||
) -> Result<Time, ParseError<'i>> {
|
) -> Result<Time, ParseError<'i>> {
|
||||||
Self::parse(context, input, CalcUnit::Time)?
|
Self::parse(context, input, CalcUnit::Time)?
|
||||||
.to_time()
|
.to_time()
|
||||||
.map_err(|()| StyleParseError::UnspecifiedError.into())
|
.map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
//! Specified color values.
|
//! Specified color values.
|
||||||
|
|
||||||
use cssparser::{Color as CSSParserColor, Parser, RGBA, Token, BasicParseError};
|
use cssparser::{Color as CSSParserColor, Parser, RGBA, Token, BasicParseError, BasicParseErrorKind};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use gecko_bindings::structs::nscolor;
|
use gecko_bindings::structs::nscolor;
|
||||||
use itoa;
|
use itoa;
|
||||||
|
@ -13,7 +13,7 @@ use parser::{ParserContext, Parse};
|
||||||
use properties::longhands::system_colors::SystemColor;
|
use properties::longhands::system_colors::SystemColor;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use style_traits::{ToCss, ParseError, StyleParseError, ValueParseError};
|
use style_traits::{ToCss, ParseError, StyleParseErrorKind, ValueParseErrorKind};
|
||||||
use super::AllowQuirks;
|
use super::AllowQuirks;
|
||||||
use values::computed::{Color as ComputedColor, Context, ToComputedValue};
|
use values::computed::{Color as ComputedColor, Context, ToComputedValue};
|
||||||
|
|
||||||
|
@ -94,8 +94,11 @@ impl Parse for Color {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match e {
|
match e {
|
||||||
BasicParseError::UnexpectedToken(t) =>
|
BasicParseError { kind: BasicParseErrorKind::UnexpectedToken(t), location } => {
|
||||||
Err(StyleParseError::ValueError(ValueParseError::InvalidColor(t)).into()),
|
Err(location.new_custom_error(
|
||||||
|
StyleParseErrorKind::ValueError(ValueParseErrorKind::InvalidColor(t))
|
||||||
|
))
|
||||||
|
}
|
||||||
e => Err(e.into())
|
e => Err(e.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,6 +182,7 @@ 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 location = input.current_source_location();
|
||||||
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)
|
||||||
|
@ -188,17 +192,17 @@ impl Color {
|
||||||
},
|
},
|
||||||
Token::Ident(ref 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(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
return parse_hash_color(ident.as_bytes())
|
return parse_hash_color(ident.as_bytes())
|
||||||
.map_err(|()| StyleParseError::UnspecifiedError.into());
|
.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
ref t => {
|
ref t => {
|
||||||
return Err(BasicParseError::UnexpectedToken(t.clone()).into());
|
return Err(location.new_unexpected_token_error(t.clone()));
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
if value < 0 {
|
if value < 0 {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
let length = if value <= 9 {
|
let length = if value <= 9 {
|
||||||
1
|
1
|
||||||
|
@ -213,11 +217,11 @@ impl Color {
|
||||||
} else if value <= 999999 {
|
} else if value <= 999999 {
|
||||||
6
|
6
|
||||||
} else {
|
} else {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
};
|
};
|
||||||
let total = length + unit.as_ref().map_or(0, |d| d.len());
|
let total = length + unit.as_ref().map_or(0, |d| d.len());
|
||||||
if total > 6 {
|
if total > 6 {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
let mut serialization = [b'0'; 6];
|
let mut serialization = [b'0'; 6];
|
||||||
let space_padding = 6 - total;
|
let space_padding = 6 - total;
|
||||||
|
@ -227,7 +231,9 @@ impl Color {
|
||||||
written += (&mut serialization[written..]).write(unit.as_bytes()).unwrap();
|
written += (&mut serialization[written..]).write(unit.as_bytes()).unwrap();
|
||||||
}
|
}
|
||||||
debug_assert!(written == 6);
|
debug_assert!(written == 6);
|
||||||
parse_hash_color(&serialization).map_err(|()| StyleParseError::UnspecifiedError.into())
|
parse_hash_color(&serialization).map_err(|()| {
|
||||||
|
location.new_custom_error(StyleParseErrorKind::UnspecifiedError)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns false if the color is completely transparent, and
|
/// Returns false if the color is completely transparent, and
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
|
|
||||||
//! Specified types for CSS values related to effects.
|
//! Specified types for CSS values related to effects.
|
||||||
|
|
||||||
use cssparser::{Parser, Token, BasicParseError};
|
use cssparser::{self, Parser, Token, BasicParseErrorKind};
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use style_traits::{ParseError, StyleParseError, ValueParseError};
|
use style_traits::{ParseError, StyleParseErrorKind, ValueParseErrorKind};
|
||||||
#[cfg(not(feature = "gecko"))]
|
#[cfg(not(feature = "gecko"))]
|
||||||
use values::Impossible;
|
use values::Impossible;
|
||||||
use values::computed::{Context, NonNegativeNumber as ComputedNonNegativeNumber, ToComputedValue};
|
use values::computed::{Context, NonNegativeNumber as ComputedNonNegativeNumber, ToComputedValue};
|
||||||
|
@ -138,7 +138,7 @@ impl Parse for BoxShadow {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let lengths = lengths.ok_or(StyleParseError::UnspecifiedError)?;
|
let lengths = lengths.ok_or(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))?;
|
||||||
Ok(BoxShadow {
|
Ok(BoxShadow {
|
||||||
base: SimpleShadow {
|
base: SimpleShadow {
|
||||||
color: color,
|
color: color,
|
||||||
|
@ -186,10 +186,15 @@ impl Parse for Filter {
|
||||||
return Ok(GenericFilter::Url(url));
|
return Ok(GenericFilter::Url(url));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let location = input.current_source_location();
|
||||||
let function = match input.expect_function() {
|
let function = match input.expect_function() {
|
||||||
Ok(f) => f.clone(),
|
Ok(f) => f.clone(),
|
||||||
Err(BasicParseError::UnexpectedToken(t)) =>
|
Err(cssparser::BasicParseError {
|
||||||
return Err(ValueParseError::InvalidFilter(t.clone()).into()),
|
kind: BasicParseErrorKind::UnexpectedToken(t),
|
||||||
|
location,
|
||||||
|
}) => {
|
||||||
|
return Err(location.new_custom_error(ValueParseErrorKind::InvalidFilter(t)))
|
||||||
|
}
|
||||||
Err(e) => return Err(e.into()),
|
Err(e) => return Err(e.into()),
|
||||||
};
|
};
|
||||||
input.parse_nested_block(|i| {
|
input.parse_nested_block(|i| {
|
||||||
|
@ -220,7 +225,9 @@ impl Parse for Filter {
|
||||||
Ok(GenericFilter::Sepia(Factor::parse_with_clamping_to_one(context, i)?))
|
Ok(GenericFilter::Sepia(Factor::parse_with_clamping_to_one(context, i)?))
|
||||||
},
|
},
|
||||||
"drop-shadow" => Ok(GenericFilter::DropShadow(Parse::parse(context, i)?)),
|
"drop-shadow" => Ok(GenericFilter::DropShadow(Parse::parse(context, i)?)),
|
||||||
_ => Err(ValueParseError::InvalidFilter(Token::Function(function.clone())).into()),
|
_ => Err(location.new_custom_error(
|
||||||
|
ValueParseErrorKind::InvalidFilter(Token::Function(function.clone()))
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ impl Parse for FlexBasis {
|
||||||
if let Ok(length) = input.try(|i| LengthOrPercentage::parse_non_negative(context, i)) {
|
if let Ok(length) = input.try(|i| LengthOrPercentage::parse_non_negative(context, i)) {
|
||||||
return Ok(GenericFlexBasis::Length(length));
|
return Ok(GenericFlexBasis::Length(length));
|
||||||
}
|
}
|
||||||
try_match_ident_ignore_ascii_case! { input.expect_ident()?,
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
"auto" => Ok(GenericFlexBasis::Auto),
|
"auto" => Ok(GenericFlexBasis::Auto),
|
||||||
"content" => Ok(GenericFlexBasis::Content),
|
"content" => Ok(GenericFlexBasis::Content),
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ pub enum KeywordSize {
|
||||||
impl KeywordSize {
|
impl KeywordSize {
|
||||||
/// Parse a keyword size
|
/// Parse a keyword size
|
||||||
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>> {
|
||||||
try_match_ident_ignore_ascii_case! { input.expect_ident()?,
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
"xx-small" => Ok(KeywordSize::XXSmall),
|
"xx-small" => Ok(KeywordSize::XXSmall),
|
||||||
"x-small" => Ok(KeywordSize::XSmall),
|
"x-small" => Ok(KeywordSize::XSmall),
|
||||||
"small" => Ok(KeywordSize::Small),
|
"small" => Ok(KeywordSize::Small),
|
||||||
|
|
|
@ -5,11 +5,11 @@
|
||||||
//! CSS handling for the computed value of
|
//! CSS handling for the computed value of
|
||||||
//! [grids](https://drafts.csswg.org/css-grid/)
|
//! [grids](https://drafts.csswg.org/css-grid/)
|
||||||
|
|
||||||
use cssparser::{Parser, Token, BasicParseError};
|
use cssparser::{Parser, Token, ParseError as CssParseError};
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use style_traits::{ParseError, StyleParseError};
|
use style_traits::{ParseError, StyleParseErrorKind};
|
||||||
use values::{CSSFloat, CustomIdent};
|
use values::{CSSFloat, CustomIdent};
|
||||||
use values::computed::{self, Context, ToComputedValue};
|
use values::computed::{self, Context, ToComputedValue};
|
||||||
use values::generics::grid::{GridTemplateComponent, RepeatCount, TrackBreadth, TrackKeyword, TrackRepeat};
|
use values::generics::grid::{GridTemplateComponent, RepeatCount, TrackBreadth, TrackKeyword, TrackRepeat};
|
||||||
|
@ -18,10 +18,11 @@ use values::specified::{LengthOrPercentage, Integer};
|
||||||
|
|
||||||
/// 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>> {
|
||||||
|
let location = input.current_source_location();
|
||||||
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),
|
||||||
ref t => Err(BasicParseError::UnexpectedToken(t.clone()).into()),
|
ref t => Err(location.new_unexpected_token_error(t.clone())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,8 +75,10 @@ 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_cloned()) {
|
while let Ok((loc, ident)) = input.try(|i| -> Result<_, CssParseError<()>> {
|
||||||
let ident = CustomIdent::from_ident(&ident, &["span"])?;
|
Ok((i.current_source_location(), i.expect_ident_cloned()?))
|
||||||
|
}) {
|
||||||
|
let ident = CustomIdent::from_ident(loc, &ident, &["span"])?;
|
||||||
values.push(ident);
|
values.push(ident);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +127,7 @@ impl TrackRepeat<LengthOrPercentage, Integer> {
|
||||||
if !track_size.is_fixed() {
|
if !track_size.is_fixed() {
|
||||||
if is_auto {
|
if is_auto {
|
||||||
// should be <fixed-size> for <auto-repeat>
|
// should be <fixed-size> for <auto-repeat>
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
||||||
if repeat_type == RepeatType::Fixed {
|
if repeat_type == RepeatType::Fixed {
|
||||||
|
@ -147,7 +150,7 @@ impl TrackRepeat<LengthOrPercentage, Integer> {
|
||||||
} else {
|
} else {
|
||||||
if values.is_empty() {
|
if values.is_empty() {
|
||||||
// expecting at least one <track-size>
|
// expecting at least one <track-size>
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
||||||
names.push(current_names); // final `<line-names>`
|
names.push(current_names); // final `<line-names>`
|
||||||
|
@ -191,7 +194,7 @@ impl Parse for TrackList<LengthOrPercentage, Integer> {
|
||||||
atleast_one_not_fixed = true;
|
atleast_one_not_fixed = true;
|
||||||
if auto_repeat.is_some() {
|
if auto_repeat.is_some() {
|
||||||
// <auto-track-list> only accepts <fixed-size> and <fixed-repeat>
|
// <auto-track-list> only accepts <fixed-size> and <fixed-repeat>
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,13 +210,13 @@ impl Parse for TrackList<LengthOrPercentage, Integer> {
|
||||||
RepeatType::Normal => {
|
RepeatType::Normal => {
|
||||||
atleast_one_not_fixed = true;
|
atleast_one_not_fixed = true;
|
||||||
if auto_repeat.is_some() { // only <fixed-repeat>
|
if auto_repeat.is_some() { // only <fixed-repeat>
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
RepeatType::Auto => {
|
RepeatType::Auto => {
|
||||||
if auto_repeat.is_some() || atleast_one_not_fixed {
|
if auto_repeat.is_some() || atleast_one_not_fixed {
|
||||||
// We've either seen <auto-repeat> earlier, or there's at least one non-fixed value
|
// We've either seen <auto-repeat> earlier, or there's at least one non-fixed value
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
||||||
list_type = TrackListType::Auto(values.len() as u16 + auto_offset);
|
list_type = TrackListType::Auto(values.len() as u16 + auto_offset);
|
||||||
|
@ -233,7 +236,7 @@ impl Parse for TrackList<LengthOrPercentage, Integer> {
|
||||||
values.push(TrackListValue::TrackRepeat(repeat));
|
values.push(TrackListValue::TrackRepeat(repeat));
|
||||||
} else {
|
} else {
|
||||||
if values.is_empty() && auto_repeat.is_none() {
|
if values.is_empty() && auto_repeat.is_none() {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
||||||
names.push(current_names.into_boxed_slice());
|
names.push(current_names.into_boxed_slice());
|
||||||
|
|
|
@ -8,16 +8,16 @@
|
||||||
//! [image]: https://drafts.csswg.org/css-images/#image-values
|
//! [image]: https://drafts.csswg.org/css-images/#image-values
|
||||||
|
|
||||||
use Atom;
|
use Atom;
|
||||||
use cssparser::{Parser, Token, BasicParseError};
|
use cssparser::{Parser, Token};
|
||||||
use custom_properties::SpecifiedValue;
|
use custom_properties::SpecifiedValue;
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::f32::consts::PI;
|
use std::f32::consts::PI;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{ToCss, ParseError, StyleParseError};
|
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
|
||||||
use values::{Either, None_};
|
use values::{Either, None_};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use values::computed::{Context, Position as ComputedPosition, ToComputedValue};
|
use values::computed::{Context, Position as ComputedPosition, ToComputedValue};
|
||||||
|
@ -169,10 +169,11 @@ impl Image {
|
||||||
/// Parses a `-moz-element(# <element-id>)`.
|
/// Parses a `-moz-element(# <element-id>)`.
|
||||||
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"))?;
|
||||||
|
let location = input.current_source_location();
|
||||||
input.parse_nested_block(|i| {
|
input.parse_nested_block(|i| {
|
||||||
match *i.next()? {
|
match *i.next()? {
|
||||||
Token::IDHash(ref id) => Ok(Atom::from(id.as_ref())),
|
Token::IDHash(ref id) => Ok(Atom::from(id.as_ref())),
|
||||||
ref t => Err(BasicParseError::UnexpectedToken(t.clone()).into()),
|
ref t => Err(location.new_unexpected_token_error(t.clone())),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -236,7 +237,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.clone()).into()),
|
None => return Err(input.new_custom_error(StyleParseErrorKind::UnexpectedFunction(func.clone()))),
|
||||||
};
|
};
|
||||||
|
|
||||||
let (kind, items) = input.parse_nested_block(|i| {
|
let (kind, items) = input.parse_nested_block(|i| {
|
||||||
|
@ -249,7 +250,7 @@ impl Parse for Gradient {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if items.len() < 2 {
|
if items.len() < 2 {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Gradient {
|
Ok(Gradient {
|
||||||
|
@ -435,7 +436,7 @@ impl Gradient {
|
||||||
(kind, reverse_stops)
|
(kind, reverse_stops)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => return Err(SelectorParseError::UnexpectedIdent(ident.clone()).into()),
|
_ => return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut items = input.try(|i| {
|
let mut items = input.try(|i| {
|
||||||
|
@ -454,11 +455,11 @@ impl Gradient {
|
||||||
},
|
},
|
||||||
"from" => Percentage::zero(),
|
"from" => Percentage::zero(),
|
||||||
"to" => Percentage::hundred(),
|
"to" => Percentage::hundred(),
|
||||||
_ => return Err(StyleParseError::UnexpectedFunction(function.clone()).into()),
|
_ => return Err(i.new_custom_error(StyleParseErrorKind::UnexpectedFunction(function.clone()))),
|
||||||
};
|
};
|
||||||
let color = Color::parse(context, i)?;
|
let color = Color::parse(context, i)?;
|
||||||
if color == Color::CurrentColor {
|
if color == Color::CurrentColor {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(i.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
Ok((color.into(), p))
|
Ok((color.into(), p))
|
||||||
})?;
|
})?;
|
||||||
|
@ -728,7 +729,7 @@ impl LineDirection {
|
||||||
// There is no `to` keyword in webkit prefixed syntax. If it's consumed,
|
// There is no `to` keyword in webkit prefixed syntax. If it's consumed,
|
||||||
// parsing should throw an error.
|
// parsing should throw an error.
|
||||||
CompatMode::WebKit if to_ident.is_ok() => {
|
CompatMode::WebKit if to_ident.is_ok() => {
|
||||||
return Err(SelectorParseError::UnexpectedIdent("to".into()).into())
|
return Err(i.new_custom_error(SelectorParseErrorKind::UnexpectedIdent("to".into())))
|
||||||
},
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
|
@ -743,7 +744,7 @@ impl LineDirection {
|
||||||
};
|
};
|
||||||
|
|
||||||
if _angle.is_none() && position.is_none() {
|
if _angle.is_none() && position.is_none() {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(i.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
return Ok(LineDirection::MozPosition(position, _angle));
|
return Ok(LineDirection::MozPosition(position, _angle));
|
||||||
}
|
}
|
||||||
|
@ -867,7 +868,7 @@ impl ShapeExtent {
|
||||||
-> Result<Self, ParseError<'i>> {
|
-> Result<Self, ParseError<'i>> {
|
||||||
match Self::parse(input)? {
|
match Self::parse(input)? {
|
||||||
ShapeExtent::Contain | ShapeExtent::Cover if compat_mode == CompatMode::Modern => {
|
ShapeExtent::Contain | ShapeExtent::Cover if compat_mode == CompatMode::Modern => {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
},
|
},
|
||||||
ShapeExtent::Contain => Ok(ShapeExtent::ClosestSide),
|
ShapeExtent::Contain => Ok(ShapeExtent::ClosestSide),
|
||||||
ShapeExtent::Cover => Ok(ShapeExtent::FarthestCorner),
|
ShapeExtent::Cover => Ok(ShapeExtent::FarthestCorner),
|
||||||
|
@ -891,7 +892,7 @@ impl GradientItem {
|
||||||
ColorStop::parse(context, input).map(GenericGradientItem::ColorStop)
|
ColorStop::parse(context, input).map(GenericGradientItem::ColorStop)
|
||||||
})?;
|
})?;
|
||||||
if !seen_stop || items.len() < 2 {
|
if !seen_stop || items.len() < 2 {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
Ok(items)
|
Ok(items)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,14 +7,14 @@
|
||||||
//! [length]: https://drafts.csswg.org/css-values/#lengths
|
//! [length]: https://drafts.csswg.org/css-values/#lengths
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use cssparser::{Parser, Token, BasicParseError};
|
use cssparser::{Parser, Token};
|
||||||
use euclid::Size2D;
|
use euclid::Size2D;
|
||||||
use font_metrics::FontMetricsQueryResult;
|
use font_metrics::FontMetricsQueryResult;
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use std::{cmp, fmt, mem};
|
use std::{cmp, fmt, mem};
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::ops::{Add, Mul};
|
use std::ops::{Add, Mul};
|
||||||
use style_traits::{ToCss, ParseError, StyleParseError};
|
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
|
||||||
use style_traits::values::specified::AllowedNumericType;
|
use style_traits::values::specified::AllowedNumericType;
|
||||||
use stylesheets::CssRuleType;
|
use stylesheets::CssRuleType;
|
||||||
use super::{AllowQuirks, Number, ToComputedValue, Percentage};
|
use super::{AllowQuirks, Number, ToComputedValue, Percentage};
|
||||||
|
@ -662,22 +662,23 @@ impl Length {
|
||||||
-> Result<Length, ParseError<'i>> {
|
-> Result<Length, ParseError<'i>> {
|
||||||
// FIXME: remove early returns when lifetimes are non-lexical
|
// FIXME: remove early returns when lifetimes are non-lexical
|
||||||
{
|
{
|
||||||
|
let location = input.current_source_location();
|
||||||
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) => {
|
||||||
return Length::parse_dimension(context, value, unit)
|
return Length::parse_dimension(context, value, unit)
|
||||||
.map_err(|()| BasicParseError::UnexpectedToken(token.clone()).into())
|
.map_err(|()| location.new_unexpected_token_error(token.clone()))
|
||||||
}
|
}
|
||||||
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. &&
|
||||||
!context.parsing_mode.allows_unitless_lengths() &&
|
!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(location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
return 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") => {}
|
||||||
ref token => return Err(BasicParseError::UnexpectedToken(token.clone()).into())
|
ref token => return Err(location.new_unexpected_token_error(token.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
input.parse_nested_block(|input| {
|
input.parse_nested_block(|input| {
|
||||||
|
@ -858,12 +859,13 @@ impl LengthOrPercentage {
|
||||||
{
|
{
|
||||||
// FIXME: remove early returns when lifetimes are non-lexical
|
// FIXME: remove early returns when lifetimes are non-lexical
|
||||||
{
|
{
|
||||||
|
let location = input.current_source_location();
|
||||||
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) => {
|
||||||
return NoCalcLength::parse_dimension(context, value, unit)
|
return NoCalcLength::parse_dimension(context, value, unit)
|
||||||
.map(LengthOrPercentage::Length)
|
.map(LengthOrPercentage::Length)
|
||||||
.map_err(|()| BasicParseError::UnexpectedToken(token.clone()).into())
|
.map_err(|()| location.new_unexpected_token_error(token.clone()))
|
||||||
}
|
}
|
||||||
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)))
|
||||||
|
@ -872,13 +874,13 @@ 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) {
|
||||||
return Err(BasicParseError::UnexpectedToken(token.clone()).into())
|
return Err(location.new_unexpected_token_error(token.clone()))
|
||||||
} 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())
|
_ => return Err(location.new_unexpected_token_error(token.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -935,7 +937,7 @@ impl LengthOrPercentage {
|
||||||
if num >= 0. {
|
if num >= 0. {
|
||||||
Ok(LengthOrPercentage::Length(NoCalcLength::Absolute(AbsoluteLength::Px(num))))
|
Ok(LengthOrPercentage::Length(NoCalcLength::Absolute(AbsoluteLength::Px(num))))
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1000,12 +1002,13 @@ impl LengthOrPercentageOrAuto {
|
||||||
-> Result<Self, ParseError<'i>> {
|
-> Result<Self, ParseError<'i>> {
|
||||||
// FIXME: remove early returns when lifetimes are non-lexical
|
// FIXME: remove early returns when lifetimes are non-lexical
|
||||||
{
|
{
|
||||||
|
let location = input.current_source_location();
|
||||||
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) => {
|
||||||
return NoCalcLength::parse_dimension(context, value, unit)
|
return NoCalcLength::parse_dimension(context, value, unit)
|
||||||
.map(LengthOrPercentageOrAuto::Length)
|
.map(LengthOrPercentageOrAuto::Length)
|
||||||
.map_err(|()| BasicParseError::UnexpectedToken(token.clone()).into())
|
.map_err(|()| location.new_unexpected_token_error(token.clone()))
|
||||||
}
|
}
|
||||||
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(LengthOrPercentageOrAuto::Percentage(computed::Percentage(unit_value)))
|
return Ok(LengthOrPercentageOrAuto::Percentage(computed::Percentage(unit_value)))
|
||||||
|
@ -1014,7 +1017,7 @@ impl LengthOrPercentageOrAuto {
|
||||||
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) {
|
||||||
return Err(StyleParseError::UnspecifiedError.into())
|
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
return Ok(LengthOrPercentageOrAuto::Length(
|
return Ok(LengthOrPercentageOrAuto::Length(
|
||||||
NoCalcLength::Absolute(AbsoluteLength::Px(value))
|
NoCalcLength::Absolute(AbsoluteLength::Px(value))
|
||||||
|
@ -1024,7 +1027,7 @@ impl LengthOrPercentageOrAuto {
|
||||||
return 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())
|
_ => return Err(location.new_unexpected_token_error(token.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1105,12 +1108,13 @@ impl LengthOrPercentageOrNone {
|
||||||
{
|
{
|
||||||
// FIXME: remove early returns when lifetimes are non-lexical
|
// FIXME: remove early returns when lifetimes are non-lexical
|
||||||
{
|
{
|
||||||
|
let location = input.current_source_location();
|
||||||
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) => {
|
||||||
return NoCalcLength::parse_dimension(context, value, unit)
|
return NoCalcLength::parse_dimension(context, value, unit)
|
||||||
.map(LengthOrPercentageOrNone::Length)
|
.map(LengthOrPercentageOrNone::Length)
|
||||||
.map_err(|()| BasicParseError::UnexpectedToken(token.clone()).into())
|
.map_err(|()| location.new_unexpected_token_error(token.clone()))
|
||||||
}
|
}
|
||||||
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(LengthOrPercentageOrNone::Percentage(computed::Percentage(unit_value)))
|
return Ok(LengthOrPercentageOrNone::Percentage(computed::Percentage(unit_value)))
|
||||||
|
@ -1118,7 +1122,7 @@ impl LengthOrPercentageOrNone {
|
||||||
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(location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
return Ok(LengthOrPercentageOrNone::Length(
|
return Ok(LengthOrPercentageOrNone::Length(
|
||||||
NoCalcLength::Absolute(AbsoluteLength::Px(value))
|
NoCalcLength::Absolute(AbsoluteLength::Px(value))
|
||||||
|
@ -1128,7 +1132,7 @@ impl LengthOrPercentageOrNone {
|
||||||
Token::Ident(ref value) if value.eq_ignore_ascii_case("none") => {
|
Token::Ident(ref value) if value.eq_ignore_ascii_case("none") => {
|
||||||
return Ok(LengthOrPercentageOrNone::None)
|
return Ok(LengthOrPercentageOrNone::None)
|
||||||
}
|
}
|
||||||
_ => return Err(BasicParseError::UnexpectedToken(token.clone()).into())
|
_ => return Err(location.new_unexpected_token_error(token.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,13 +8,13 @@
|
||||||
|
|
||||||
use Namespace;
|
use Namespace;
|
||||||
use context::QuirksMode;
|
use context::QuirksMode;
|
||||||
use cssparser::{Parser, Token, serialize_identifier, BasicParseError};
|
use cssparser::{Parser, Token, serialize_identifier};
|
||||||
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::f32;
|
use std::f32;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{ToCss, ParseError, StyleParseError};
|
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
|
||||||
use style_traits::values::specified::AllowedNumericType;
|
use style_traits::values::specified::AllowedNumericType;
|
||||||
use super::{Auto, CSSFloat, CSSInteger, Either, None_};
|
use super::{Auto, CSSFloat, CSSInteger, Either, None_};
|
||||||
use super::computed::{Context, ToComputedValue};
|
use super::computed::{Context, ToComputedValue};
|
||||||
|
@ -103,11 +103,12 @@ impl Eq for 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>> {
|
||||||
|
let location = input.current_source_location();
|
||||||
// FIXME: remove early returns when lifetimes are non-lexical
|
// FIXME: remove early returns when lifetimes are non-lexical
|
||||||
match *input.next()? {
|
match *input.next()? {
|
||||||
Token::Number { int_value: Some(v), .. } => return Ok(Integer::new(v)),
|
Token::Number { int_value: Some(v), .. } => return Ok(Integer::new(v)),
|
||||||
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())
|
ref t => return Err(location.new_unexpected_token_error(t.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = input.parse_nested_block(|i| {
|
let result = input.parse_nested_block(|i| {
|
||||||
|
@ -129,6 +130,7 @@ 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>> {
|
||||||
|
let location = input.current_source_location();
|
||||||
// FIXME: remove early returns when lifetimes are non-lexical
|
// FIXME: remove early returns when lifetimes are non-lexical
|
||||||
match *input.next()? {
|
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) => {
|
||||||
|
@ -138,7 +140,7 @@ pub fn parse_number_with_clamping_mode<'i, 't>(context: &ParserContext,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
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())
|
ref t => return Err(location.new_unexpected_token_error(t.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = input.parse_nested_block(|i| {
|
let result = input.parse_nested_block(|i| {
|
||||||
|
@ -415,7 +417,7 @@ impl Integer {
|
||||||
// It's not totally clear it's worth it though, and no other browser
|
// It's not totally clear it's worth it though, and no other browser
|
||||||
// does this.
|
// does this.
|
||||||
Ok(value) if value.value() >= min => Ok(value),
|
Ok(value) if value.value() >= min => Ok(value),
|
||||||
Ok(_value) => Err(StyleParseError::UnspecifiedError.into()),
|
Ok(_value) => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -473,7 +475,9 @@ impl IntegerOrAuto {
|
||||||
input: &mut Parser<'i, 't>)
|
input: &mut Parser<'i, 't>)
|
||||||
-> Result<IntegerOrAuto, ParseError<'i>> {
|
-> Result<IntegerOrAuto, ParseError<'i>> {
|
||||||
match IntegerOrAuto::parse(context, input) {
|
match IntegerOrAuto::parse(context, input) {
|
||||||
Ok(Either::First(integer)) if integer.value() <= 0 => Err(StyleParseError::UnspecifiedError.into()),
|
Ok(Either::First(integer)) if integer.value() <= 0 => {
|
||||||
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
|
}
|
||||||
result => result,
|
result => result,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -741,17 +745,18 @@ impl Attr {
|
||||||
if let Ok(token) = input.try(|i| i.next_including_whitespace().map(|t| t.clone())) {
|
if let Ok(token) = input.try(|i| i.next_including_whitespace().map(|t| t.clone())) {
|
||||||
match token {
|
match token {
|
||||||
Token::Delim('|') => {
|
Token::Delim('|') => {
|
||||||
|
let location = input.current_source_location();
|
||||||
// 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(ref second) => second,
|
Token::Ident(ref second) => second,
|
||||||
ref t => return Err(BasicParseError::UnexpectedToken(t.clone()).into()),
|
ref t => return Err(location.new_unexpected_token_error(t.clone())),
|
||||||
};
|
};
|
||||||
|
|
||||||
let ns_with_id = if let Some(ns) = first {
|
let ns_with_id = if let Some(ns) = first {
|
||||||
let ns = Namespace::from(ns.as_ref());
|
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(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
Some((ns, id?))
|
Some((ns, id?))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -764,7 +769,7 @@ impl Attr {
|
||||||
// In the case of attr(foobar ) we don't want to error out
|
// In the case of attr(foobar ) we don't want to error out
|
||||||
// because of the trailing whitespace
|
// because of the trailing whitespace
|
||||||
Token::WhiteSpace(_) => (),
|
Token::WhiteSpace(_) => (),
|
||||||
ref t => return Err(BasicParseError::UnexpectedToken(t.clone()).into()),
|
ref t => return Err(input.new_unexpected_token_error(t.clone())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -774,7 +779,7 @@ impl Attr {
|
||||||
attribute: first.as_ref().to_owned(),
|
attribute: first.as_ref().to_owned(),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
//! Specified percentages.
|
//! Specified percentages.
|
||||||
|
|
||||||
use cssparser::{BasicParseError, Parser, Token};
|
use cssparser::{Parser, Token};
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -97,13 +97,14 @@ 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>> {
|
||||||
|
let location = input.current_source_location();
|
||||||
// FIXME: remove early returns when lifetimes are non-lexical
|
// FIXME: remove early returns when lifetimes are non-lexical
|
||||||
match *input.next()? {
|
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) => {
|
||||||
return 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()),
|
ref t => return Err(location.new_unexpected_token_error(t.clone())),
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = input.parse_nested_block(|i| {
|
let result = input.parse_nested_block(|i| {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
use cssparser::Parser;
|
use cssparser::Parser;
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use style_traits::{CommaWithSpace, ParseError, Separator, StyleParseError};
|
use style_traits::{CommaWithSpace, ParseError, Separator, StyleParseErrorKind};
|
||||||
use values::generics::svg as generic;
|
use values::generics::svg as generic;
|
||||||
use values::specified::{LengthOrPercentage, NonNegativeLengthOrPercentage, NonNegativeNumber};
|
use values::specified::{LengthOrPercentage, NonNegativeLengthOrPercentage, NonNegativeNumber};
|
||||||
use values::specified::{Number, Opacity, SpecifiedUrl};
|
use values::specified::{Number, Opacity, SpecifiedUrl};
|
||||||
|
@ -39,7 +39,7 @@ fn parse_context_value<'i, 't, T>(input: &mut Parser<'i, 't>, value: T)
|
||||||
return Ok(value);
|
return Ok(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A value of <length> | <percentage> | <number> for stroke-dashoffset.
|
/// A value of <length> | <percentage> | <number> for stroke-dashoffset.
|
||||||
|
@ -115,12 +115,12 @@ impl Parse for SVGOpacity {
|
||||||
if let Ok(opacity) = input.try(|i| Opacity::parse(context, i)) {
|
if let Ok(opacity) = input.try(|i| Opacity::parse(context, i)) {
|
||||||
Ok(generic::SVGOpacity::Opacity(opacity))
|
Ok(generic::SVGOpacity::Opacity(opacity))
|
||||||
} else if is_context_value_enabled() {
|
} else if is_context_value_enabled() {
|
||||||
try_match_ident_ignore_ascii_case! { input.expect_ident()?,
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
"context-fill-opacity" => Ok(generic::SVGOpacity::ContextFillOpacity),
|
"context-fill-opacity" => Ok(generic::SVGOpacity::ContextFillOpacity),
|
||||||
"context-stroke-opacity" => Ok(generic::SVGOpacity::ContextStrokeOpacity),
|
"context-stroke-opacity" => Ok(generic::SVGOpacity::ContextStrokeOpacity),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseError::UnspecifiedError.into())
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
use cssparser::Parser;
|
use cssparser::Parser;
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use style_traits::ParseError;
|
use style_traits::ParseError;
|
||||||
use values::computed::{Context, ToComputedValue};
|
use values::computed::{Context, ToComputedValue};
|
||||||
|
@ -65,6 +65,7 @@ impl Parse for LineHeight {
|
||||||
if let Ok(nlop) = input.try(|i| NonNegativeLengthOrPercentage::parse(context, i)) {
|
if let Ok(nlop) = input.try(|i| NonNegativeLengthOrPercentage::parse(context, i)) {
|
||||||
return Ok(GenericLineHeight::Length(nlop))
|
return Ok(GenericLineHeight::Length(nlop))
|
||||||
}
|
}
|
||||||
|
let location = input.current_source_location();
|
||||||
let ident = input.expect_ident()?;
|
let ident = input.expect_ident()?;
|
||||||
match ident {
|
match ident {
|
||||||
ref ident if ident.eq_ignore_ascii_case("normal") => {
|
ref ident if ident.eq_ignore_ascii_case("normal") => {
|
||||||
|
@ -74,7 +75,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.clone()).into()),
|
ident => Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,11 @@
|
||||||
|
|
||||||
//! Specified time values.
|
//! Specified time values.
|
||||||
|
|
||||||
use cssparser::{Parser, Token, BasicParseError};
|
use cssparser::{Parser, Token};
|
||||||
use parser::{ParserContext, Parse};
|
use parser::{ParserContext, Parse};
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{ToCss, ParseError, StyleParseError};
|
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
|
||||||
use style_traits::values::specified::AllowedNumericType;
|
use style_traits::values::specified::AllowedNumericType;
|
||||||
use values::CSSFloat;
|
use values::CSSFloat;
|
||||||
use values::computed::{Context, ToComputedValue};
|
use values::computed::{Context, ToComputedValue};
|
||||||
|
@ -83,6 +83,7 @@ impl Time {
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
use style_traits::PARSING_MODE_DEFAULT;
|
use style_traits::PARSING_MODE_DEFAULT;
|
||||||
|
|
||||||
|
let location = input.current_source_location();
|
||||||
// FIXME: remove early returns when lifetimes are non-lexical
|
// 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
|
||||||
|
@ -92,15 +93,15 @@ impl Time {
|
||||||
// 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) => {
|
||||||
return Time::parse_dimension(value, unit, /* from_calc = */ false)
|
return Time::parse_dimension(value, unit, /* from_calc = */ false)
|
||||||
.map_err(|()| StyleParseError::UnspecifiedError.into())
|
.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
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()),
|
Ok(t) => return Err(location.new_unexpected_token_error(t.clone())),
|
||||||
Err(e) => return Err(e.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(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
|
|
||||||
use cssparser::Parser;
|
use cssparser::Parser;
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use style_traits::{ParseError, StyleParseError};
|
use style_traits::{ParseError, StyleParseErrorKind};
|
||||||
use values::computed::{Context, LengthOrPercentage as ComputedLengthOrPercentage};
|
use values::computed::{Context, LengthOrPercentage as ComputedLengthOrPercentage};
|
||||||
use values::computed::{Percentage as ComputedPercentage, ToComputedValue};
|
use values::computed::{Percentage as ComputedPercentage, ToComputedValue};
|
||||||
use values::computed::transform::TimingFunction as ComputedTimingFunction;
|
use values::computed::transform::TimingFunction as ComputedTimingFunction;
|
||||||
|
@ -152,10 +152,11 @@ impl Parse for TimingFunction {
|
||||||
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,
|
||||||
_ => return Err(SelectorParseError::UnexpectedIdent(ident.clone()).into()),
|
_ => return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))),
|
||||||
};
|
};
|
||||||
return Ok(GenericTimingFunction::Steps(Integer::new(1), position));
|
return Ok(GenericTimingFunction::Steps(Integer::new(1), position));
|
||||||
}
|
}
|
||||||
|
let location = input.current_source_location();
|
||||||
let function = input.expect_function()?.clone();
|
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,
|
||||||
|
@ -169,7 +170,7 @@ impl Parse for TimingFunction {
|
||||||
let y2 = Number::parse(context, i)?;
|
let y2 = Number::parse(context, i)?;
|
||||||
|
|
||||||
if x1.get() < 0.0 || x1.get() > 1.0 || x2.get() < 0.0 || x2.get() > 1.0 {
|
if x1.get() < 0.0 || x1.get() > 1.0 || x2.get() < 0.0 || x2.get() > 1.0 {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(i.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(GenericTimingFunction::CubicBezier { x1, y1, x2, y2 })
|
Ok(GenericTimingFunction::CubicBezier { x1, y1, x2, y2 })
|
||||||
|
@ -191,7 +192,7 @@ impl Parse for TimingFunction {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => Err(()),
|
_ => Err(()),
|
||||||
}).map_err(|()| StyleParseError::UnexpectedFunction(function.clone()).into())
|
}).map_err(|()| location.new_custom_error(StyleParseErrorKind::UnexpectedFunction(function.clone())))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ gecko = []
|
||||||
[dependencies]
|
[dependencies]
|
||||||
app_units = "0.5"
|
app_units = "0.5"
|
||||||
bitflags = "0.7"
|
bitflags = "0.7"
|
||||||
cssparser = "0.21.1"
|
cssparser = "0.22.0"
|
||||||
euclid = "0.15"
|
euclid = "0.15"
|
||||||
heapsize = {version = "0.4", optional = true}
|
heapsize = {version = "0.4", optional = true}
|
||||||
heapsize_derive = {version = "0.1", optional = true}
|
heapsize_derive = {version = "0.1", optional = true}
|
||||||
|
|
|
@ -30,7 +30,7 @@ extern crate servo_arc;
|
||||||
#[cfg(feature = "servo")] pub use webrender_api::DevicePixel;
|
#[cfg(feature = "servo")] pub use webrender_api::DevicePixel;
|
||||||
|
|
||||||
use cssparser::{CowRcStr, Token};
|
use cssparser::{CowRcStr, Token};
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
#[cfg(feature = "servo")] use servo_atoms::Atom;
|
#[cfg(feature = "servo")] use servo_atoms::Atom;
|
||||||
|
|
||||||
/// One hardware pixel.
|
/// One hardware pixel.
|
||||||
|
@ -85,11 +85,14 @@ pub mod viewport;
|
||||||
pub use values::{Comma, CommaWithSpace, OneOrMoreSeparated, Separator, Space, ToCss};
|
pub use values::{Comma, CommaWithSpace, OneOrMoreSeparated, Separator, Space, ToCss};
|
||||||
|
|
||||||
/// The error type for all CSS parsing routines.
|
/// The error type for all CSS parsing routines.
|
||||||
pub type ParseError<'i> = cssparser::ParseError<'i, SelectorParseError<'i, StyleParseError<'i>>>;
|
pub type ParseError<'i> = cssparser::ParseError<'i, StyleParseErrorKind<'i>>;
|
||||||
|
|
||||||
|
/// Error in property value parsing
|
||||||
|
pub type ValueParseError<'i> = cssparser::ParseError<'i, ValueParseErrorKind<'i>>;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
/// Errors that can be encountered while parsing CSS values.
|
/// Errors that can be encountered while parsing CSS values.
|
||||||
pub enum StyleParseError<'i> {
|
pub enum StyleParseErrorKind<'i> {
|
||||||
/// A bad URL token in a DVB.
|
/// A bad URL token in a DVB.
|
||||||
BadUrlInDeclarationValueBlock(CowRcStr<'i>),
|
BadUrlInDeclarationValueBlock(CowRcStr<'i>),
|
||||||
/// A bad string token in a DVB.
|
/// A bad string token in a DVB.
|
||||||
|
@ -100,8 +103,6 @@ pub enum StyleParseError<'i> {
|
||||||
UnbalancedCloseSquareBracketInDeclarationValueBlock,
|
UnbalancedCloseSquareBracketInDeclarationValueBlock,
|
||||||
/// Unexpected closing curly bracket in a DVB.
|
/// Unexpected closing curly bracket in a DVB.
|
||||||
UnbalancedCloseCurlyBracketInDeclarationValueBlock,
|
UnbalancedCloseCurlyBracketInDeclarationValueBlock,
|
||||||
/// A property declaration parsing error.
|
|
||||||
PropertyDeclaration(PropertyDeclarationParseError<'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.
|
||||||
|
@ -129,47 +130,22 @@ pub enum StyleParseError<'i> {
|
||||||
/// An unexpected token was found within a namespace rule.
|
/// An unexpected token was found within a namespace rule.
|
||||||
UnexpectedTokenWithinNamespace(Token<'i>),
|
UnexpectedTokenWithinNamespace(Token<'i>),
|
||||||
/// An error was encountered while parsing a property value.
|
/// An error was encountered while parsing a property value.
|
||||||
ValueError(ValueParseError<'i>),
|
ValueError(ValueParseErrorKind<'i>),
|
||||||
}
|
/// An error was encountered while parsing a selector
|
||||||
|
SelectorError(SelectorParseErrorKind<'i>),
|
||||||
|
|
||||||
/// Specific errors that can be encountered while parsing property values.
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub enum ValueParseError<'i> {
|
|
||||||
/// An invalid token was encountered while parsing a color value.
|
|
||||||
InvalidColor(Token<'i>),
|
|
||||||
/// An invalid filter value was encountered.
|
|
||||||
InvalidFilter(Token<'i>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> From<ValueParseError<'a>> for ParseError<'a> {
|
|
||||||
fn from(this: ValueParseError<'a>) -> Self {
|
|
||||||
StyleParseError::ValueError(this).into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'i> ValueParseError<'i> {
|
|
||||||
/// Attempt to extract a ValueParseError value from a ParseError.
|
|
||||||
pub fn from_parse_error(this: ParseError<'i>) -> Option<ValueParseError<'i>> {
|
|
||||||
match this {
|
|
||||||
cssparser::ParseError::Custom(
|
|
||||||
SelectorParseError::Custom(
|
|
||||||
StyleParseError::ValueError(e))) => Some(e),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The result of parsing a property declaration.
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub enum PropertyDeclarationParseError<'i> {
|
|
||||||
/// The property declaration was for an unknown property.
|
/// The property declaration was for an unknown property.
|
||||||
UnknownProperty(CowRcStr<'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 color value.
|
||||||
|
InvalidColor(CowRcStr<'i>, Token<'i>),
|
||||||
|
/// The property declaration contained an invalid filter value.
|
||||||
|
InvalidFilter(CowRcStr<'i>, Token<'i>),
|
||||||
/// The property declaration contained an invalid value.
|
/// The property declaration contained an invalid value.
|
||||||
InvalidValue(CowRcStr<'i>, Option<ValueParseError<'i>>),
|
OtherInvalidValue(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).
|
||||||
///
|
///
|
||||||
|
@ -179,15 +155,47 @@ pub enum PropertyDeclarationParseError<'i> {
|
||||||
NotAllowedInPageRule,
|
NotAllowedInPageRule,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<StyleParseError<'a>> for ParseError<'a> {
|
impl<'i> From<ValueParseErrorKind<'i>> for StyleParseErrorKind<'i> {
|
||||||
fn from(this: StyleParseError<'a>) -> Self {
|
fn from(this: ValueParseErrorKind<'i>) -> Self {
|
||||||
cssparser::ParseError::Custom(SelectorParseError::Custom(this))
|
StyleParseErrorKind::ValueError(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<PropertyDeclarationParseError<'a>> for ParseError<'a> {
|
impl<'i> From<SelectorParseErrorKind<'i>> for StyleParseErrorKind<'i> {
|
||||||
fn from(this: PropertyDeclarationParseError<'a>) -> Self {
|
fn from(this: SelectorParseErrorKind<'i>) -> Self {
|
||||||
cssparser::ParseError::Custom(SelectorParseError::Custom(StyleParseError::PropertyDeclaration(this)))
|
StyleParseErrorKind::SelectorError(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Specific errors that can be encountered while parsing property values.
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub enum ValueParseErrorKind<'i> {
|
||||||
|
/// An invalid token was encountered while parsing a color value.
|
||||||
|
InvalidColor(Token<'i>),
|
||||||
|
/// An invalid filter value was encountered.
|
||||||
|
InvalidFilter(Token<'i>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'i> StyleParseErrorKind<'i> {
|
||||||
|
/// Create an InvalidValue parse error
|
||||||
|
pub fn new_invalid(name: CowRcStr<'i>, value_error: ParseError<'i>) -> ParseError<'i> {
|
||||||
|
let variant = match value_error.kind {
|
||||||
|
cssparser::ParseErrorKind::Custom(StyleParseErrorKind::ValueError(e)) => {
|
||||||
|
match e {
|
||||||
|
ValueParseErrorKind::InvalidColor(token) => {
|
||||||
|
StyleParseErrorKind::InvalidColor(name, token)
|
||||||
|
}
|
||||||
|
ValueParseErrorKind::InvalidFilter(token) => {
|
||||||
|
StyleParseErrorKind::InvalidFilter(name, token)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => StyleParseErrorKind::OtherInvalidValue(name),
|
||||||
|
};
|
||||||
|
cssparser::ParseError {
|
||||||
|
kind: cssparser::ParseErrorKind::Custom(variant),
|
||||||
|
location: value_error.location,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
//! Helper types and traits for the handling of CSS values.
|
//! Helper types and traits for the handling of CSS values.
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use cssparser::{BasicParseError, ParseError, Parser, Token, UnicodeRange, serialize_string};
|
use cssparser::{ParseError, Parser, Token, UnicodeRange, serialize_string};
|
||||||
use cssparser::ToCss as CssparserToCss;
|
use cssparser::ToCss as CssparserToCss;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
|
@ -299,12 +299,13 @@ impl Separator for CommaWithSpace {
|
||||||
let mut results = vec![parse_one(input)?];
|
let mut results = vec![parse_one(input)?];
|
||||||
loop {
|
loop {
|
||||||
input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less.
|
input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less.
|
||||||
|
let comma_location = input.current_source_location();
|
||||||
let comma = input.try(|i| i.expect_comma()).is_ok();
|
let comma = input.try(|i| i.expect_comma()).is_ok();
|
||||||
input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less.
|
input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less.
|
||||||
if let Ok(item) = input.try(&mut parse_one) {
|
if let Ok(item) = input.try(&mut parse_one) {
|
||||||
results.push(item);
|
results.push(item);
|
||||||
} else if comma {
|
} else if comma {
|
||||||
return Err(BasicParseError::UnexpectedToken(Token::Comma).into());
|
return Err(comma_location.new_unexpected_token_error(Token::Comma));
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -449,11 +450,16 @@ macro_rules! __define_css_keyword_enum__actual {
|
||||||
/// Parse this property from a CSS input stream.
|
/// Parse this property from a CSS input stream.
|
||||||
pub fn parse<'i, 't>(input: &mut ::cssparser::Parser<'i, 't>)
|
pub fn parse<'i, 't>(input: &mut ::cssparser::Parser<'i, 't>)
|
||||||
-> Result<$name, $crate::ParseError<'i>> {
|
-> Result<$name, $crate::ParseError<'i>> {
|
||||||
let ident = input.expect_ident()?;
|
use cssparser::Token;
|
||||||
Self::from_ident(&ident)
|
let location = input.current_source_location();
|
||||||
.map_err(|()| ::cssparser::ParseError::Basic(
|
match *input.next()? {
|
||||||
::cssparser::BasicParseError::UnexpectedToken(
|
Token::Ident(ref ident) => {
|
||||||
::cssparser::Token::Ident(ident.clone()))))
|
Self::from_ident(ident).map_err(|()| {
|
||||||
|
location.new_unexpected_token_error(Token::Ident(ident.clone()))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
ref token => Err(location.new_unexpected_token_error(token.clone()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse this property from an already-tokenized identifier.
|
/// Parse this property from an already-tokenized identifier.
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
//! Helper types for the `@viewport` rule.
|
//! Helper types for the `@viewport` rule.
|
||||||
|
|
||||||
use {CSSPixel, PinchZoomFactor, ParseError};
|
use {CSSPixel, PinchZoomFactor, ParseError};
|
||||||
use cssparser::{Parser, ToCss, ParseError as CssParseError, BasicParseError};
|
use cssparser::{Parser, ToCss};
|
||||||
use euclid::TypedSize2D;
|
use euclid::TypedSize2D;
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -109,6 +109,7 @@ impl Zoom {
|
||||||
use cssparser::Token;
|
use cssparser::Token;
|
||||||
use values::specified::AllowedNumericType::NonNegative;
|
use values::specified::AllowedNumericType::NonNegative;
|
||||||
|
|
||||||
|
let location = input.current_source_location();
|
||||||
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
|
||||||
|
@ -123,7 +124,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)
|
||||||
}
|
}
|
||||||
ref t => Err(CssParseError::Basic(BasicParseError::UnexpectedToken(t.clone())))
|
ref t => Err(location.new_unexpected_token_error(t.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ gecko_debug = ["style/gecko_debug"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
atomic_refcell = "0.1"
|
atomic_refcell = "0.1"
|
||||||
cssparser = "0.21.1"
|
cssparser = "0.22.0"
|
||||||
env_logger = {version = "0.4", default-features = false} # disable `regex` to reduce code size
|
env_logger = {version = "0.4", default-features = false} # disable `regex` to reduce code size
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
log = {version = "0.3.5", features = ["release_max_level_info"]}
|
log = {version = "0.3.5", features = ["release_max_level_info"]}
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
#![allow(unsafe_code)]
|
#![allow(unsafe_code)]
|
||||||
|
|
||||||
use cssparser::{CowRcStr, serialize_identifier, ToCss};
|
use cssparser::{CowRcStr, serialize_identifier, ToCss};
|
||||||
use cssparser::{SourceLocation, ParseError as CssParseError, Token, BasicParseError};
|
use cssparser::{SourceLocation, ParseError, ParseErrorKind, Token, BasicParseErrorKind};
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
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};
|
||||||
|
@ -18,7 +18,9 @@ use style::gecko_bindings::structs::ErrorReporter as GeckoErrorReporter;
|
||||||
use style::gecko_bindings::structs::URLExtraData as RawUrlExtraData;
|
use style::gecko_bindings::structs::URLExtraData as RawUrlExtraData;
|
||||||
use style::gecko_bindings::sugar::refptr::RefPtr;
|
use style::gecko_bindings::sugar::refptr::RefPtr;
|
||||||
use style::stylesheets::UrlExtraData;
|
use style::stylesheets::UrlExtraData;
|
||||||
use style_traits::{ParseError, StyleParseError, PropertyDeclarationParseError, ValueParseError};
|
use style_traits::StyleParseErrorKind;
|
||||||
|
|
||||||
|
pub type ErrorKind<'i> = ParseErrorKind<'i, StyleParseErrorKind<'i>>;
|
||||||
|
|
||||||
/// Wrapper around an instance of Gecko's CSS error reporter.
|
/// Wrapper around an instance of Gecko's CSS error reporter.
|
||||||
pub struct ErrorReporter(*mut GeckoErrorReporter);
|
pub struct ErrorReporter(*mut GeckoErrorReporter);
|
||||||
|
@ -70,49 +72,43 @@ enum Action {
|
||||||
}
|
}
|
||||||
|
|
||||||
trait ErrorHelpers<'a> {
|
trait ErrorHelpers<'a> {
|
||||||
fn error_data(self) -> (CowRcStr<'a>, ParseError<'a>);
|
fn error_data(self) -> (CowRcStr<'a>, ErrorKind<'a>);
|
||||||
fn error_params(self) -> ErrorParams<'a>;
|
fn error_params(self) -> ErrorParams<'a>;
|
||||||
fn to_gecko_message(&self) -> (Option<&'static [u8]>, &'static [u8], Action);
|
fn to_gecko_message(&self) -> (Option<&'static [u8]>, &'static [u8], Action);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_error_param<'a>(err: ParseError<'a>) -> Option<ErrorString<'a>> {
|
fn extract_error_param<'a>(err: ErrorKind<'a>) -> Option<ErrorString<'a>> {
|
||||||
Some(match err {
|
Some(match err {
|
||||||
CssParseError::Basic(BasicParseError::UnexpectedToken(t)) => {
|
ParseErrorKind::Basic(BasicParseErrorKind::UnexpectedToken(t)) => {
|
||||||
ErrorString::UnexpectedToken(t)
|
ErrorString::UnexpectedToken(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
CssParseError::Basic(BasicParseError::AtRuleInvalid(i)) |
|
ParseErrorKind::Basic(BasicParseErrorKind::AtRuleInvalid(i)) |
|
||||||
CssParseError::Custom(SelectorParseError::Custom(
|
ParseErrorKind::Custom(StyleParseErrorKind::UnsupportedAtRule(i)) => {
|
||||||
StyleParseError::UnsupportedAtRule(i)
|
|
||||||
)) => {
|
|
||||||
let mut s = String::from("@");
|
let mut s = String::from("@");
|
||||||
serialize_identifier(&i, &mut s).unwrap();
|
serialize_identifier(&i, &mut s).unwrap();
|
||||||
ErrorString::Snippet(s.into())
|
ErrorString::Snippet(s.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
CssParseError::Custom(SelectorParseError::Custom(
|
ParseErrorKind::Custom(StyleParseErrorKind::OtherInvalidValue(property)) => {
|
||||||
StyleParseError::PropertyDeclaration(
|
|
||||||
PropertyDeclarationParseError::InvalidValue(property, None)
|
|
||||||
)
|
|
||||||
)) => {
|
|
||||||
ErrorString::Snippet(property)
|
ErrorString::Snippet(property)
|
||||||
}
|
}
|
||||||
|
|
||||||
CssParseError::Custom(SelectorParseError::UnexpectedIdent(ident)) => {
|
ParseErrorKind::Custom(
|
||||||
|
StyleParseErrorKind::SelectorError(
|
||||||
|
SelectorParseErrorKind::UnexpectedIdent(ident)
|
||||||
|
)
|
||||||
|
) => {
|
||||||
ErrorString::Ident(ident)
|
ErrorString::Ident(ident)
|
||||||
}
|
}
|
||||||
|
|
||||||
CssParseError::Custom(SelectorParseError::Custom(
|
ParseErrorKind::Custom(StyleParseErrorKind::UnknownProperty(property)) => {
|
||||||
StyleParseError::PropertyDeclaration(
|
|
||||||
PropertyDeclarationParseError::UnknownProperty(property)
|
|
||||||
)
|
|
||||||
)) => {
|
|
||||||
ErrorString::Ident(property)
|
ErrorString::Ident(property)
|
||||||
}
|
}
|
||||||
|
|
||||||
CssParseError::Custom(SelectorParseError::Custom(
|
ParseErrorKind::Custom(
|
||||||
StyleParseError::UnexpectedTokenWithinNamespace(token)
|
StyleParseErrorKind::UnexpectedTokenWithinNamespace(token)
|
||||||
)) => {
|
) => {
|
||||||
ErrorString::UnexpectedToken(token)
|
ErrorString::UnexpectedToken(token)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,13 +116,6 @@ fn extract_error_param<'a>(err: ParseError<'a>) -> Option<ErrorString<'a>> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_value_error_param<'a>(err: ValueParseError<'a>) -> ErrorString<'a> {
|
|
||||||
match err {
|
|
||||||
ValueParseError::InvalidColor(t) |
|
|
||||||
ValueParseError::InvalidFilter(t) => ErrorString::UnexpectedToken(t),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ErrorParams<'a> {
|
struct ErrorParams<'a> {
|
||||||
prefix_param: Option<ErrorString<'a>>,
|
prefix_param: Option<ErrorString<'a>>,
|
||||||
main_param: Option<ErrorString<'a>>,
|
main_param: Option<ErrorString<'a>>,
|
||||||
|
@ -134,46 +123,56 @@ struct ErrorParams<'a> {
|
||||||
|
|
||||||
/// If an error parameter is present in the given error, return it. Additionally return
|
/// If an error parameter is present in the given error, return it. Additionally return
|
||||||
/// a second parameter if it exists, for use in the prefix for the eventual error message.
|
/// a second parameter if it exists, for use in the prefix for the eventual error message.
|
||||||
fn extract_error_params<'a>(err: ParseError<'a>) -> Option<ErrorParams<'a>> {
|
fn extract_error_params<'a>(err: ErrorKind<'a>) -> Option<ErrorParams<'a>> {
|
||||||
let (main, prefix) = match err {
|
let (main, prefix) = match err {
|
||||||
CssParseError::Custom(SelectorParseError::Custom(
|
ParseErrorKind::Custom(StyleParseErrorKind::InvalidColor(property, token)) |
|
||||||
StyleParseError::PropertyDeclaration(
|
ParseErrorKind::Custom(StyleParseErrorKind::InvalidFilter(property, token)) => {
|
||||||
PropertyDeclarationParseError::InvalidValue(property, Some(e))))) =>
|
(Some(ErrorString::Snippet(property.into())), Some(ErrorString::UnexpectedToken(token)))
|
||||||
(Some(ErrorString::Snippet(property.into())), Some(extract_value_error_param(e))),
|
}
|
||||||
|
|
||||||
CssParseError::Custom(SelectorParseError::Custom(
|
ParseErrorKind::Custom(
|
||||||
StyleParseError::MediaQueryExpectedFeatureName(ident))) =>
|
StyleParseErrorKind::MediaQueryExpectedFeatureName(ident)
|
||||||
(Some(ErrorString::Ident(ident)), None),
|
) => {
|
||||||
|
(Some(ErrorString::Ident(ident)), None)
|
||||||
|
}
|
||||||
|
|
||||||
CssParseError::Custom(SelectorParseError::Custom(
|
ParseErrorKind::Custom(
|
||||||
StyleParseError::ExpectedIdentifier(token))) =>
|
StyleParseErrorKind::ExpectedIdentifier(token)
|
||||||
(Some(ErrorString::UnexpectedToken(token)), None),
|
) => {
|
||||||
|
(Some(ErrorString::UnexpectedToken(token)), None)
|
||||||
CssParseError::Custom(SelectorParseError::UnexpectedTokenInAttributeSelector(t)) |
|
}
|
||||||
CssParseError::Custom(SelectorParseError::BadValueInAttr(t)) |
|
|
||||||
CssParseError::Custom(SelectorParseError::ExpectedBarInAttr(t)) |
|
|
||||||
CssParseError::Custom(SelectorParseError::NoQualifiedNameInAttributeSelector(t)) |
|
|
||||||
CssParseError::Custom(SelectorParseError::InvalidQualNameInAttr(t)) |
|
|
||||||
CssParseError::Custom(SelectorParseError::ExplicitNamespaceUnexpectedToken(t)) |
|
|
||||||
CssParseError::Custom(SelectorParseError::PseudoElementExpectedIdent(t)) |
|
|
||||||
CssParseError::Custom(SelectorParseError::NoIdentForPseudo(t)) |
|
|
||||||
CssParseError::Custom(SelectorParseError::ClassNeedsIdent(t)) |
|
|
||||||
CssParseError::Custom(SelectorParseError::PseudoElementExpectedColon(t)) =>
|
|
||||||
(None, Some(ErrorString::UnexpectedToken(t))),
|
|
||||||
|
|
||||||
CssParseError::Custom(SelectorParseError::ExpectedNamespace(namespace)) =>
|
|
||||||
(None, Some(ErrorString::Ident(namespace))),
|
|
||||||
|
|
||||||
CssParseError::Custom(SelectorParseError::UnsupportedPseudoClassOrElement(p)) =>
|
|
||||||
(None, Some(ErrorString::Ident(p))),
|
|
||||||
|
|
||||||
CssParseError::Custom(SelectorParseError::EmptySelector) |
|
|
||||||
CssParseError::Custom(SelectorParseError::DanglingCombinator) =>
|
|
||||||
(None, None),
|
|
||||||
|
|
||||||
CssParseError::Custom(SelectorParseError::EmptyNegation) =>
|
|
||||||
(None, Some(ErrorString::Snippet(")".into()))),
|
|
||||||
|
|
||||||
|
ParseErrorKind::Custom(StyleParseErrorKind::SelectorError(err)) => match err {
|
||||||
|
SelectorParseErrorKind::UnexpectedTokenInAttributeSelector(t) |
|
||||||
|
SelectorParseErrorKind::BadValueInAttr(t) |
|
||||||
|
SelectorParseErrorKind::ExpectedBarInAttr(t) |
|
||||||
|
SelectorParseErrorKind::NoQualifiedNameInAttributeSelector(t) |
|
||||||
|
SelectorParseErrorKind::InvalidQualNameInAttr(t) |
|
||||||
|
SelectorParseErrorKind::ExplicitNamespaceUnexpectedToken(t) |
|
||||||
|
SelectorParseErrorKind::PseudoElementExpectedIdent(t) |
|
||||||
|
SelectorParseErrorKind::NoIdentForPseudo(t) |
|
||||||
|
SelectorParseErrorKind::ClassNeedsIdent(t) |
|
||||||
|
SelectorParseErrorKind::PseudoElementExpectedColon(t) => {
|
||||||
|
(None, Some(ErrorString::UnexpectedToken(t)))
|
||||||
|
}
|
||||||
|
SelectorParseErrorKind::ExpectedNamespace(namespace) => {
|
||||||
|
(None, Some(ErrorString::Ident(namespace)))
|
||||||
|
}
|
||||||
|
SelectorParseErrorKind::UnsupportedPseudoClassOrElement(p) => {
|
||||||
|
(None, Some(ErrorString::Ident(p)))
|
||||||
|
}
|
||||||
|
SelectorParseErrorKind::EmptySelector |
|
||||||
|
SelectorParseErrorKind::DanglingCombinator => {
|
||||||
|
(None, None)
|
||||||
|
}
|
||||||
|
SelectorParseErrorKind::EmptyNegation => {
|
||||||
|
(None, Some(ErrorString::Snippet(")".into())))
|
||||||
|
}
|
||||||
|
err => match extract_error_param(ParseErrorKind::Custom(StyleParseErrorKind::SelectorError(err))) {
|
||||||
|
Some(e) => (Some(e), None),
|
||||||
|
None => return None,
|
||||||
|
}
|
||||||
|
},
|
||||||
err => match extract_error_param(err) {
|
err => match extract_error_param(err) {
|
||||||
Some(e) => (Some(e), None),
|
Some(e) => (Some(e), None),
|
||||||
None => return None,
|
None => return None,
|
||||||
|
@ -186,7 +185,7 @@ fn extract_error_params<'a>(err: ParseError<'a>) -> Option<ErrorParams<'a>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ErrorHelpers<'a> for ContextualParseError<'a> {
|
impl<'a> ErrorHelpers<'a> for ContextualParseError<'a> {
|
||||||
fn error_data(self) -> (CowRcStr<'a>, ParseError<'a>) {
|
fn error_data(self) -> (CowRcStr<'a>, ErrorKind<'a>) {
|
||||||
match self {
|
match self {
|
||||||
ContextualParseError::UnsupportedPropertyDeclaration(s, err) |
|
ContextualParseError::UnsupportedPropertyDeclaration(s, err) |
|
||||||
ContextualParseError::UnsupportedFontFaceDescriptor(s, err) |
|
ContextualParseError::UnsupportedFontFaceDescriptor(s, err) |
|
||||||
|
@ -198,15 +197,18 @@ impl<'a> ErrorHelpers<'a> for ContextualParseError<'a> {
|
||||||
ContextualParseError::UnsupportedRule(s, err) |
|
ContextualParseError::UnsupportedRule(s, err) |
|
||||||
ContextualParseError::UnsupportedViewportDescriptorDeclaration(s, err) |
|
ContextualParseError::UnsupportedViewportDescriptorDeclaration(s, err) |
|
||||||
ContextualParseError::UnsupportedCounterStyleDescriptorDeclaration(s, err) |
|
ContextualParseError::UnsupportedCounterStyleDescriptorDeclaration(s, err) |
|
||||||
ContextualParseError::InvalidMediaRule(s, err) =>
|
ContextualParseError::InvalidMediaRule(s, err) => {
|
||||||
(s.into(), err),
|
(s.into(), err.kind)
|
||||||
|
}
|
||||||
ContextualParseError::InvalidCounterStyleWithoutSymbols(s) |
|
ContextualParseError::InvalidCounterStyleWithoutSymbols(s) |
|
||||||
ContextualParseError::InvalidCounterStyleNotEnoughSymbols(s) =>
|
ContextualParseError::InvalidCounterStyleNotEnoughSymbols(s) => {
|
||||||
(s.into(), StyleParseError::UnspecifiedError.into()),
|
(s.into(), ParseErrorKind::Custom(StyleParseErrorKind::UnspecifiedError.into()))
|
||||||
|
}
|
||||||
ContextualParseError::InvalidCounterStyleWithoutAdditiveSymbols |
|
ContextualParseError::InvalidCounterStyleWithoutAdditiveSymbols |
|
||||||
ContextualParseError::InvalidCounterStyleExtendsWithSymbols |
|
ContextualParseError::InvalidCounterStyleExtendsWithSymbols |
|
||||||
ContextualParseError::InvalidCounterStyleExtendsWithAdditiveSymbols =>
|
ContextualParseError::InvalidCounterStyleExtendsWithAdditiveSymbols => {
|
||||||
("".into(), StyleParseError::UnspecifiedError.into())
|
("".into(), ParseErrorKind::Custom(StyleParseErrorKind::UnspecifiedError.into()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,20 +223,30 @@ impl<'a> ErrorHelpers<'a> for ContextualParseError<'a> {
|
||||||
fn to_gecko_message(&self) -> (Option<&'static [u8]>, &'static [u8], Action) {
|
fn to_gecko_message(&self) -> (Option<&'static [u8]>, &'static [u8], Action) {
|
||||||
let (msg, action): (&[u8], Action) = match *self {
|
let (msg, action): (&[u8], Action) = match *self {
|
||||||
ContextualParseError::UnsupportedPropertyDeclaration(
|
ContextualParseError::UnsupportedPropertyDeclaration(
|
||||||
_, CssParseError::Basic(BasicParseError::UnexpectedToken(_))) |
|
_, ParseError { kind: ParseErrorKind::Basic(BasicParseErrorKind::UnexpectedToken(_)), .. }
|
||||||
|
) |
|
||||||
ContextualParseError::UnsupportedPropertyDeclaration(
|
ContextualParseError::UnsupportedPropertyDeclaration(
|
||||||
_, CssParseError::Basic(BasicParseError::AtRuleInvalid(_))) =>
|
_, ParseError { kind: ParseErrorKind::Basic(BasicParseErrorKind::AtRuleInvalid(_)), .. }
|
||||||
(b"PEParseDeclarationDeclExpected\0", Action::Skip),
|
) => {
|
||||||
|
(b"PEParseDeclarationDeclExpected\0", Action::Skip)
|
||||||
|
}
|
||||||
ContextualParseError::UnsupportedPropertyDeclaration(
|
ContextualParseError::UnsupportedPropertyDeclaration(
|
||||||
_, CssParseError::Custom(SelectorParseError::Custom(
|
_, ParseError { kind: ParseErrorKind::Custom(ref err), .. }
|
||||||
StyleParseError::PropertyDeclaration(
|
) => {
|
||||||
PropertyDeclarationParseError::InvalidValue(_, ref err))))) => {
|
match *err {
|
||||||
let prefix = match *err {
|
StyleParseErrorKind::InvalidColor(_, _) => {
|
||||||
Some(ValueParseError::InvalidColor(_)) => Some(&b"PEColorNotColor\0"[..]),
|
return (Some(b"PEColorNotColor\0"),
|
||||||
Some(ValueParseError::InvalidFilter(_)) => Some(&b"PEExpectedNoneOrURLOrFilterFunction\0"[..]),
|
b"PEValueParsingError\0", Action::Drop)
|
||||||
_ => None,
|
}
|
||||||
};
|
StyleParseErrorKind::InvalidFilter(_, _) => {
|
||||||
return (prefix, b"PEValueParsingError\0", Action::Drop);
|
return (Some(b"PEExpectedNoneOrURLOrFilterFunction\0"),
|
||||||
|
b"PEValueParsingError\0", Action::Drop)
|
||||||
|
}
|
||||||
|
StyleParseErrorKind::OtherInvalidValue(_) => {
|
||||||
|
(b"PEValueParsingError\0", Action::Drop)
|
||||||
|
}
|
||||||
|
_ => (b"PEUnknownProperty\0", Action::Drop)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ContextualParseError::UnsupportedPropertyDeclaration(..) =>
|
ContextualParseError::UnsupportedPropertyDeclaration(..) =>
|
||||||
(b"PEUnknownProperty\0", Action::Drop),
|
(b"PEUnknownProperty\0", Action::Drop),
|
||||||
|
@ -245,67 +257,88 @@ impl<'a> ErrorHelpers<'a> for ContextualParseError<'a> {
|
||||||
ContextualParseError::UnsupportedKeyframePropertyDeclaration(..) =>
|
ContextualParseError::UnsupportedKeyframePropertyDeclaration(..) =>
|
||||||
(b"PEBadSelectorKeyframeRuleIgnored\0", Action::Nothing),
|
(b"PEBadSelectorKeyframeRuleIgnored\0", Action::Nothing),
|
||||||
ContextualParseError::InvalidRule(
|
ContextualParseError::InvalidRule(
|
||||||
_, CssParseError::Custom(SelectorParseError::Custom(
|
_, ParseError { kind: ParseErrorKind::Custom(
|
||||||
StyleParseError::UnexpectedTokenWithinNamespace(_)))) =>
|
StyleParseErrorKind::UnexpectedTokenWithinNamespace(_)
|
||||||
(b"PEAtNSUnexpected\0", Action::Nothing),
|
), .. }
|
||||||
|
) => {
|
||||||
|
(b"PEAtNSUnexpected\0", Action::Nothing)
|
||||||
|
}
|
||||||
ContextualParseError::InvalidRule(
|
ContextualParseError::InvalidRule(
|
||||||
_, CssParseError::Basic(BasicParseError::AtRuleInvalid(_))) |
|
_, ParseError { kind: ParseErrorKind::Basic(BasicParseErrorKind::AtRuleInvalid(_)), .. }
|
||||||
|
) |
|
||||||
ContextualParseError::InvalidRule(
|
ContextualParseError::InvalidRule(
|
||||||
_, CssParseError::Custom(SelectorParseError::Custom(
|
_, ParseError { kind: ParseErrorKind::Custom(
|
||||||
StyleParseError::UnsupportedAtRule(_)))) =>
|
StyleParseErrorKind::UnsupportedAtRule(_)
|
||||||
(b"PEUnknownAtRule\0", Action::Nothing),
|
), .. }
|
||||||
|
) => {
|
||||||
|
(b"PEUnknownAtRule\0", Action::Nothing)
|
||||||
|
}
|
||||||
ContextualParseError::InvalidRule(_, ref err) => {
|
ContextualParseError::InvalidRule(_, ref err) => {
|
||||||
let prefix = match *err {
|
let prefix = match err.kind {
|
||||||
CssParseError::Custom(SelectorParseError::UnexpectedTokenInAttributeSelector(_)) =>
|
ParseErrorKind::Custom(StyleParseErrorKind::SelectorError(ref err)) => match *err {
|
||||||
Some(&b"PEAttSelUnexpected\0"[..]),
|
SelectorParseErrorKind::UnexpectedTokenInAttributeSelector(_) => {
|
||||||
CssParseError::Custom(SelectorParseError::ExpectedBarInAttr(_)) =>
|
Some(&b"PEAttSelUnexpected\0"[..])
|
||||||
Some(&b"PEAttSelNoBar\0"[..]),
|
}
|
||||||
CssParseError::Custom(SelectorParseError::BadValueInAttr(_)) =>
|
SelectorParseErrorKind::ExpectedBarInAttr(_) => {
|
||||||
Some(&b"PEAttSelBadValue\0"[..]),
|
Some(&b"PEAttSelNoBar\0"[..])
|
||||||
CssParseError::Custom(SelectorParseError::NoQualifiedNameInAttributeSelector(_)) =>
|
}
|
||||||
Some(&b"PEAttributeNameOrNamespaceExpected\0"[..]),
|
SelectorParseErrorKind::BadValueInAttr(_) => {
|
||||||
CssParseError::Custom(SelectorParseError::InvalidQualNameInAttr(_)) =>
|
Some(&b"PEAttSelBadValue\0"[..])
|
||||||
Some(&b"PEAttributeNameExpected\0"[..]),
|
}
|
||||||
CssParseError::Custom(SelectorParseError::ExplicitNamespaceUnexpectedToken(_)) =>
|
SelectorParseErrorKind::NoQualifiedNameInAttributeSelector(_) => {
|
||||||
Some(&b"PETypeSelNotType\0"[..]),
|
Some(&b"PEAttributeNameOrNamespaceExpected\0"[..])
|
||||||
CssParseError::Custom(SelectorParseError::ExpectedNamespace(_)) =>
|
}
|
||||||
Some(&b"PEUnknownNamespacePrefix\0"[..]),
|
SelectorParseErrorKind::InvalidQualNameInAttr(_) => {
|
||||||
CssParseError::Custom(SelectorParseError::EmptySelector) =>
|
Some(&b"PEAttributeNameExpected\0"[..])
|
||||||
Some(&b"PESelectorGroupNoSelector\0"[..]),
|
}
|
||||||
CssParseError::Custom(SelectorParseError::DanglingCombinator) =>
|
SelectorParseErrorKind::ExplicitNamespaceUnexpectedToken(_) => {
|
||||||
Some(&b"PESelectorGroupExtraCombinator\0"[..]),
|
Some(&b"PETypeSelNotType\0"[..])
|
||||||
CssParseError::Custom(SelectorParseError::UnsupportedPseudoClassOrElement(_)) =>
|
}
|
||||||
Some(&b"PEPseudoSelUnknown\0"[..]),
|
SelectorParseErrorKind::ExpectedNamespace(_) => {
|
||||||
CssParseError::Custom(SelectorParseError::PseudoElementExpectedColon(_)) =>
|
Some(&b"PEUnknownNamespacePrefix\0"[..])
|
||||||
Some(&b"PEPseudoSelEndOrUserActionPC\0"[..]),
|
}
|
||||||
CssParseError::Custom(SelectorParseError::NoIdentForPseudo(_)) =>
|
SelectorParseErrorKind::EmptySelector => {
|
||||||
Some(&b"PEPseudoClassArgNotIdent\0"[..]),
|
Some(&b"PESelectorGroupNoSelector\0"[..])
|
||||||
CssParseError::Custom(SelectorParseError::PseudoElementExpectedIdent(_)) =>
|
}
|
||||||
Some(&b"PEPseudoSelBadName\0"[..]),
|
SelectorParseErrorKind::DanglingCombinator => {
|
||||||
CssParseError::Custom(SelectorParseError::ClassNeedsIdent(_)) =>
|
Some(&b"PESelectorGroupExtraCombinator\0"[..])
|
||||||
Some(&b"PEClassSelNotIdent\0"[..]),
|
}
|
||||||
CssParseError::Custom(SelectorParseError::EmptyNegation) =>
|
SelectorParseErrorKind::UnsupportedPseudoClassOrElement(_) => {
|
||||||
Some(&b"PENegationBadArg\0"[..]),
|
Some(&b"PEPseudoSelUnknown\0"[..])
|
||||||
|
}
|
||||||
|
SelectorParseErrorKind::PseudoElementExpectedColon(_) => {
|
||||||
|
Some(&b"PEPseudoSelEndOrUserActionPC\0"[..])
|
||||||
|
}
|
||||||
|
SelectorParseErrorKind::NoIdentForPseudo(_) => {
|
||||||
|
Some(&b"PEPseudoClassArgNotIdent\0"[..])
|
||||||
|
}
|
||||||
|
SelectorParseErrorKind::PseudoElementExpectedIdent(_) => {
|
||||||
|
Some(&b"PEPseudoSelBadName\0"[..])
|
||||||
|
}
|
||||||
|
SelectorParseErrorKind::ClassNeedsIdent(_) => {
|
||||||
|
Some(&b"PEClassSelNotIdent\0"[..])
|
||||||
|
}
|
||||||
|
SelectorParseErrorKind::EmptyNegation => {
|
||||||
|
Some(&b"PENegationBadArg\0"[..])
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
return (prefix, b"PEBadSelectorRSIgnored\0", Action::Nothing);
|
return (prefix, b"PEBadSelectorRSIgnored\0", Action::Nothing);
|
||||||
}
|
}
|
||||||
ContextualParseError::InvalidMediaRule(_, ref err) => {
|
ContextualParseError::InvalidMediaRule(_, ref err) => {
|
||||||
let err: &[u8] = match *err {
|
let err: &[u8] = match err.kind {
|
||||||
CssParseError::Custom(SelectorParseError::Custom(
|
ParseErrorKind::Custom(StyleParseErrorKind::ExpectedIdentifier(..)) => {
|
||||||
StyleParseError::ExpectedIdentifier(..))) => {
|
|
||||||
b"PEGatherMediaNotIdent\0"
|
b"PEGatherMediaNotIdent\0"
|
||||||
},
|
},
|
||||||
CssParseError::Custom(SelectorParseError::Custom(
|
ParseErrorKind::Custom(StyleParseErrorKind::MediaQueryExpectedFeatureName(..)) => {
|
||||||
StyleParseError::MediaQueryExpectedFeatureName(..))) => {
|
|
||||||
b"PEMQExpectedFeatureName\0"
|
b"PEMQExpectedFeatureName\0"
|
||||||
},
|
},
|
||||||
CssParseError::Custom(SelectorParseError::Custom(
|
ParseErrorKind::Custom(StyleParseErrorKind::MediaQueryExpectedFeatureValue) => {
|
||||||
StyleParseError::MediaQueryExpectedFeatureValue)) => {
|
|
||||||
b"PEMQExpectedFeatureValue\0"
|
b"PEMQExpectedFeatureValue\0"
|
||||||
},
|
},
|
||||||
CssParseError::Custom(SelectorParseError::Custom(
|
ParseErrorKind::Custom(StyleParseErrorKind::RangedExpressionWithNoValue) => {
|
||||||
StyleParseError::RangedExpressionWithNoValue)) => {
|
|
||||||
b"PEMQNoMinMaxWithoutValue\0"
|
b"PEMQNoMinMaxWithoutValue\0"
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
|
|
|
@ -10,7 +10,7 @@ path = "lib.rs"
|
||||||
doctest = false
|
doctest = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cssparser = "0.21.1"
|
cssparser = "0.22.0"
|
||||||
gfx = {path = "../../../components/gfx"}
|
gfx = {path = "../../../components/gfx"}
|
||||||
ipc-channel = "0.8"
|
ipc-channel = "0.8"
|
||||||
style = {path = "../../../components/style"}
|
style = {path = "../../../components/style"}
|
||||||
|
|
|
@ -12,7 +12,7 @@ doctest = false
|
||||||
[dependencies]
|
[dependencies]
|
||||||
byteorder = "1.0"
|
byteorder = "1.0"
|
||||||
app_units = "0.5"
|
app_units = "0.5"
|
||||||
cssparser = "0.21.1"
|
cssparser = "0.22.0"
|
||||||
euclid = "0.15"
|
euclid = "0.15"
|
||||||
html5ever = "0.20"
|
html5ever = "0.20"
|
||||||
parking_lot = "0.4"
|
parking_lot = "0.4"
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use selectors::parser::{SelectorParseError, SelectorParseErrorKind};
|
||||||
use style::invalidation::element::invalidation_map::Dependency;
|
use style::invalidation::element::invalidation_map::Dependency;
|
||||||
use style::properties;
|
use style::properties;
|
||||||
|
|
||||||
|
@ -12,3 +13,11 @@ size_of_test!(test_size_of_property_declaration, properties::PropertyDeclaration
|
||||||
// This is huge, but we allocate it on the stack and then never move it,
|
// This is huge, but we allocate it on the stack and then never move it,
|
||||||
// we only pass `&mut SourcePropertyDeclaration` references around.
|
// we only pass `&mut SourcePropertyDeclaration` references around.
|
||||||
size_of_test!(test_size_of_parsed_declaration, properties::SourcePropertyDeclaration, 576);
|
size_of_test!(test_size_of_parsed_declaration, properties::SourcePropertyDeclaration, 576);
|
||||||
|
|
||||||
|
size_of_test!(test_size_of_selector_parse_error_kind, SelectorParseErrorKind, 40);
|
||||||
|
size_of_test!(test_size_of_style_parse_error_kind, ::style_traits::StyleParseErrorKind, 56);
|
||||||
|
size_of_test!(test_size_of_value_parse_error_kind, ::style_traits::ValueParseErrorKind, 40);
|
||||||
|
|
||||||
|
size_of_test!(test_size_of_selector_parse_error, SelectorParseError, 56);
|
||||||
|
size_of_test!(test_size_of_style_traits_parse_error, ::style_traits::ParseError, 72);
|
||||||
|
size_of_test!(test_size_of_value_parse_error, ::style_traits::ValueParseError, 56);
|
||||||
|
|
|
@ -10,9 +10,10 @@ use selectors::attr::*;
|
||||||
use selectors::parser::*;
|
use selectors::parser::*;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use servo_atoms::Atom;
|
use servo_atoms::Atom;
|
||||||
|
use servo_config::prefs::{PREFS, PrefValue};
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::sync::Mutex;
|
use std::cell::RefCell;
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
use style::context::QuirksMode;
|
use style::context::QuirksMode;
|
||||||
use style::error_reporting::{ParseErrorReporter, ContextualParseError};
|
use style::error_reporting::{ParseErrorReporter, ContextualParseError};
|
||||||
|
@ -259,6 +260,7 @@ fn test_parse_stylesheet() {
|
||||||
assert_eq!(format!("{:#?}", stylesheet), format!("{:#?}", expected));
|
assert_eq!(format!("{:#?}", stylesheet), format!("{:#?}", expected));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct CSSError {
|
struct CSSError {
|
||||||
pub url : ServoUrl,
|
pub url : ServoUrl,
|
||||||
pub line: u32,
|
pub line: u32,
|
||||||
|
@ -266,71 +268,103 @@ struct CSSError {
|
||||||
pub message: String
|
pub message: String
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CSSInvalidErrorReporterTest {
|
struct TestingErrorReporter {
|
||||||
pub errors: Arc<Mutex<Vec<CSSError>>>
|
errors: RefCell<Vec<CSSError>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CSSInvalidErrorReporterTest {
|
impl TestingErrorReporter {
|
||||||
pub fn new() -> CSSInvalidErrorReporterTest {
|
pub fn new() -> Self {
|
||||||
return CSSInvalidErrorReporterTest{
|
TestingErrorReporter {
|
||||||
errors: Arc::new(Mutex::new(Vec::new()))
|
errors: RefCell::new(Vec::new()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assert_messages_contain(&self, expected_errors: &[(u32, u32, &str)]) {
|
||||||
|
let errors = self.errors.borrow();
|
||||||
|
for (i, (error, &(line, column, message))) in errors.iter().zip(expected_errors).enumerate() {
|
||||||
|
assert_eq!((error.line, error.column), (line, column),
|
||||||
|
"line/column numbers of the {}th error: {:?}", i + 1, error.message);
|
||||||
|
assert!(error.message.contains(message),
|
||||||
|
"{:?} does not contain {:?}", error.message, message);
|
||||||
|
}
|
||||||
|
if errors.len() < expected_errors.len() {
|
||||||
|
panic!("Missing errors: {:#?}", &expected_errors[errors.len()..]);
|
||||||
|
}
|
||||||
|
if errors.len() > expected_errors.len() {
|
||||||
|
panic!("Extra errors: {:#?}", &errors[expected_errors.len()..]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParseErrorReporter for CSSInvalidErrorReporterTest {
|
impl ParseErrorReporter for TestingErrorReporter {
|
||||||
fn report_error(&self,
|
fn report_error(&self,
|
||||||
url: &ServoUrl,
|
url: &ServoUrl,
|
||||||
location: SourceLocation,
|
location: SourceLocation,
|
||||||
error: ContextualParseError) {
|
error: ContextualParseError) {
|
||||||
let mut errors = self.errors.lock().unwrap();
|
self.errors.borrow_mut().push(
|
||||||
errors.push(
|
|
||||||
CSSError{
|
CSSError{
|
||||||
url: url.clone(),
|
url: url.clone(),
|
||||||
line: location.line,
|
line: location.line,
|
||||||
column: location.column,
|
column: location.column,
|
||||||
message: error.to_string(),
|
message: error.to_string(),
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_report_error_stylesheet() {
|
fn test_report_error_stylesheet() {
|
||||||
|
PREFS.set("layout.viewport.enabled", PrefValue::Boolean(true));
|
||||||
let css = r"
|
let css = r"
|
||||||
div {
|
div {
|
||||||
background-color: red;
|
background-color: red;
|
||||||
display: invalid;
|
display: invalid;
|
||||||
|
background-image: linear-gradient(0deg, black, invalid, transparent);
|
||||||
invalid: true;
|
invalid: true;
|
||||||
}
|
}
|
||||||
|
@media (min-width: 10px invalid 1000px) {}
|
||||||
|
@font-face { src: url(), invalid, url(); }
|
||||||
|
@counter-style foo { symbols: a 0invalid b }
|
||||||
|
@font-feature-values Sans Sans { @foo {} @swash { foo: 1 invalid 2 } }
|
||||||
|
@invalid;
|
||||||
|
@media screen { @invalid; }
|
||||||
|
@supports (color: green) and invalid and (margin: 0) {}
|
||||||
|
@keyframes foo { from invalid {} to { margin: 0 invalid 0; } }
|
||||||
|
@viewport { width: 320px invalid auto; }
|
||||||
";
|
";
|
||||||
let url = ServoUrl::parse("about::test").unwrap();
|
let url = ServoUrl::parse("about::test").unwrap();
|
||||||
let error_reporter = CSSInvalidErrorReporterTest::new();
|
let error_reporter = TestingErrorReporter::new();
|
||||||
|
|
||||||
let errors = error_reporter.errors.clone();
|
|
||||||
|
|
||||||
let lock = SharedRwLock::new();
|
let lock = SharedRwLock::new();
|
||||||
let media = Arc::new(lock.wrap(MediaList::empty()));
|
let media = Arc::new(lock.wrap(MediaList::empty()));
|
||||||
Stylesheet::from_str(css, url.clone(), Origin::UserAgent, media, lock,
|
Stylesheet::from_str(css, url.clone(), Origin::UserAgent, media, lock,
|
||||||
None, &error_reporter, QuirksMode::NoQuirks, 5);
|
None, &error_reporter, QuirksMode::NoQuirks, 5);
|
||||||
|
|
||||||
let mut errors = errors.lock().unwrap();
|
error_reporter.assert_messages_contain(&[
|
||||||
|
(8, 18, "Unsupported property declaration: 'display: invalid;'"),
|
||||||
|
(9, 27, "Unsupported property declaration: 'background-image:"), // FIXME: column should be around 56
|
||||||
|
(10, 17, "Unsupported property declaration: 'invalid: true;'"),
|
||||||
|
(12, 28, "Invalid media rule"),
|
||||||
|
(13, 30, "Unsupported @font-face descriptor declaration"),
|
||||||
|
|
||||||
let error = errors.pop().unwrap();
|
// When @counter-style is supported, this should be replaced with two errors
|
||||||
assert_eq!("Unsupported property declaration: 'invalid: true;', \
|
(14, 19, "Invalid rule: '@counter-style "),
|
||||||
Custom(PropertyDeclaration(UnknownProperty(\"invalid\")))", error.message);
|
|
||||||
assert_eq!(9, error.line);
|
|
||||||
assert_eq!(9, error.column);
|
|
||||||
|
|
||||||
let error = errors.pop().unwrap();
|
// When @font-feature-values is supported, this should be replaced with two errors
|
||||||
assert_eq!("Unsupported property declaration: 'display: invalid;', \
|
(15, 25, "Invalid rule: '@font-feature-values "),
|
||||||
Custom(PropertyDeclaration(InvalidValue(\"display\", None)))", error.message);
|
|
||||||
assert_eq!(8, error.line);
|
|
||||||
assert_eq!(9, error.column);
|
|
||||||
|
|
||||||
// testing for the url
|
// FIXME: the message of these two should be consistent
|
||||||
assert_eq!(url, error.url);
|
(16, 13, "Invalid rule: '@invalid'"),
|
||||||
|
(17, 29, "Unsupported rule: '@invalid'"),
|
||||||
|
|
||||||
|
(18, 34, "Invalid rule: '@supports "),
|
||||||
|
(19, 26, "Invalid keyframe rule: 'from invalid '"),
|
||||||
|
(19, 52, "Unsupported keyframe property declaration: 'margin: 0 invalid 0;'"),
|
||||||
|
(20, 29, "Unsupported @viewport descriptor declaration: 'width: 320px invalid auto;'"),
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert_eq!(error_reporter.errors.borrow()[0].url, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -343,21 +377,16 @@ fn test_no_report_unrecognized_vendor_properties() {
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
let url = ServoUrl::parse("about::test").unwrap();
|
let url = ServoUrl::parse("about::test").unwrap();
|
||||||
let error_reporter = CSSInvalidErrorReporterTest::new();
|
let error_reporter = TestingErrorReporter::new();
|
||||||
|
|
||||||
let errors = error_reporter.errors.clone();
|
|
||||||
|
|
||||||
let lock = SharedRwLock::new();
|
let lock = SharedRwLock::new();
|
||||||
let media = Arc::new(lock.wrap(MediaList::empty()));
|
let media = Arc::new(lock.wrap(MediaList::empty()));
|
||||||
Stylesheet::from_str(css, url, Origin::UserAgent, media, lock,
|
Stylesheet::from_str(css, url, Origin::UserAgent, media, lock,
|
||||||
None, &error_reporter, QuirksMode::NoQuirks, 0);
|
None, &error_reporter, QuirksMode::NoQuirks, 0);
|
||||||
|
|
||||||
let mut errors = errors.lock().unwrap();
|
error_reporter.assert_messages_contain(&[
|
||||||
let error = errors.pop().unwrap();
|
(4, 31, "Unsupported property declaration: '-moz-background-color: red;'"),
|
||||||
assert_eq!("Unsupported property declaration: '-moz-background-color: red;', \
|
]);
|
||||||
Custom(PropertyDeclaration(UnknownProperty(\"-moz-background-color\")))",
|
|
||||||
error.message);
|
|
||||||
assert!(errors.is_empty());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -13,7 +13,7 @@ doctest = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
atomic_refcell = "0.1"
|
atomic_refcell = "0.1"
|
||||||
cssparser = "0.21.1"
|
cssparser = "0.22.0"
|
||||||
env_logger = "0.4"
|
env_logger = "0.4"
|
||||||
euclid = "0.15"
|
euclid = "0.15"
|
||||||
geckoservo = {path = "../../../ports/geckolib"}
|
geckoservo = {path = "../../../ports/geckolib"}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue