mirror of
https://github.com/servo/servo.git
synced 2025-08-07 06:25:32 +01:00
Auto merge of #21036 - emilio:gecko-sync, r=emilio
style: Sync changes from mozilla-central. See each individual commit for details. <!-- 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/21036) <!-- Reviewable:end -->
This commit is contained in:
commit
cad2b164dc
43 changed files with 934 additions and 717 deletions
86
Cargo.lock
generated
86
Cargo.lock
generated
|
@ -271,7 +271,7 @@ dependencies = [
|
||||||
"azure 0.29.0 (git+https://github.com/servo/rust-azure)",
|
"azure 0.29.0 (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.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.23.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.17.2 (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.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gleam 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -289,7 +289,7 @@ dependencies = [
|
||||||
name = "canvas_traits"
|
name = "canvas_traits"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.23.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gleam 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gleam 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -563,30 +563,32 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cssparser"
|
name = "cssparser"
|
||||||
version = "0.23.2"
|
version = "0.23.10"
|
||||||
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.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"dtoa-short 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"dtoa-short 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"procedural-masquerade 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"procedural-masquerade 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cssparser-macros"
|
name = "cssparser-macros"
|
||||||
version = "0.3.0"
|
version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"procedural-masquerade 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"procedural-masquerade 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1319,11 +1321,6 @@ dependencies = [
|
||||||
"either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "itoa"
|
|
||||||
version = "0.3.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
|
@ -1615,7 +1612,7 @@ name = "malloc_size_of"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.23.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hashglobe 0.1.0",
|
"hashglobe 0.1.0",
|
||||||
"hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1625,7 +1622,7 @@ dependencies = [
|
||||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"servo_arc 0.1.1",
|
"servo_arc 0.1.1",
|
||||||
"smallbitvec 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallbitvec 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2280,11 +2277,6 @@ name = "quick-error"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "quote"
|
|
||||||
version = "0.3.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
|
@ -2472,7 +2464,7 @@ dependencies = [
|
||||||
"chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.23.10 (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",
|
||||||
|
@ -2549,7 +2541,7 @@ dependencies = [
|
||||||
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"app_units 0.6.1 (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.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.23.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gfx_traits 0.0.1",
|
"gfx_traits 0.0.1",
|
||||||
"html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2631,7 +2623,7 @@ name = "selectors"
|
||||||
version = "0.19.0"
|
version = "0.19.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.23.10 (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.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2921,7 +2913,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallbitvec"
|
name = "smallbitvec"
|
||||||
version = "2.1.0"
|
version = "2.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2981,7 +2973,7 @@ dependencies = [
|
||||||
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.2.1 (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.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.23.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"fallible 0.0.1",
|
"fallible 0.0.1",
|
||||||
|
@ -3012,7 +3004,7 @@ dependencies = [
|
||||||
"servo_atoms 0.0.1",
|
"servo_atoms 0.0.1",
|
||||||
"servo_config 0.0.1",
|
"servo_config 0.0.1",
|
||||||
"servo_url 0.0.1",
|
"servo_url 0.0.1",
|
||||||
"smallbitvec 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallbitvec 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"style_derive 0.0.1",
|
"style_derive 0.0.1",
|
||||||
|
@ -3042,7 +3034,7 @@ version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.23.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -3064,7 +3056,7 @@ version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.23.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"malloc_size_of 0.0.1",
|
"malloc_size_of 0.0.1",
|
||||||
"malloc_size_of_derive 0.0.1",
|
"malloc_size_of_derive 0.0.1",
|
||||||
|
@ -3081,16 +3073,6 @@ name = "swapper"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "syn"
|
|
||||||
version = "0.11.11"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "0.13.1"
|
version = "0.13.1"
|
||||||
|
@ -3101,14 +3083,6 @@ dependencies = [
|
||||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "synom"
|
|
||||||
version = "0.11.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "synstructure"
|
name = "synstructure"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
|
@ -3296,11 +3270,6 @@ name = "unicode-width"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-xid"
|
|
||||||
version = "0.0.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -3787,8 +3756,8 @@ dependencies = [
|
||||||
"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
|
"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
|
||||||
"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
|
"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
|
||||||
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
|
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
|
||||||
"checksum cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8a807ac3ab7a217829c2a3b65732b926b2befe6a35f33b4bf8b503692430f223"
|
"checksum cssparser 0.23.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1c74d99b0f489cc546336b911452562ebfd4aec034b0c526cb77a3a02d3790"
|
||||||
"checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df"
|
"checksum cssparser-macros 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f3a5383ae18dbfdeb569ed62019f5bddb2a95cd2d3833313c475a0d014777805"
|
||||||
"checksum darling 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2a78af487e4eb8f4421a1770687b328af6bb4494ca93435210678c6eea875c11"
|
"checksum darling 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2a78af487e4eb8f4421a1770687b328af6bb4494ca93435210678c6eea875c11"
|
||||||
"checksum darling_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b315f49c7b6db3708bca6e6913c194581a44ec619b7a39e131d4dd63733a3698"
|
"checksum darling_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b315f49c7b6db3708bca6e6913c194581a44ec619b7a39e131d4dd63733a3698"
|
||||||
"checksum darling_macro 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eb69a38fdeaeaf3db712e1df170de67ee9dfc24fb88ca3e9d21e703ec25a4d8e"
|
"checksum darling_macro 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eb69a38fdeaeaf3db712e1df170de67ee9dfc24fb88ca3e9d21e703ec25a4d8e"
|
||||||
|
@ -3853,7 +3822,6 @@ dependencies = [
|
||||||
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
|
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
|
||||||
"checksum ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db9daf099728ac5390c73f54e6e3708f0c514d2b51f24373830f568702eadfca"
|
"checksum ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db9daf099728ac5390c73f54e6e3708f0c514d2b51f24373830f568702eadfca"
|
||||||
"checksum itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b07332223953b5051bceb67e8c4700aa65291535568e1f12408c43c4a42c0394"
|
"checksum itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b07332223953b5051bceb67e8c4700aa65291535568e1f12408c43c4a42c0394"
|
||||||
"checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c"
|
|
||||||
"checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682"
|
"checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682"
|
||||||
"checksum jemalloc-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "479294d130502fada93c7a957e8d059b632b03d6204aca37af557dee947f30a9"
|
"checksum jemalloc-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "479294d130502fada93c7a957e8d059b632b03d6204aca37af557dee947f30a9"
|
||||||
"checksum jpeg-decoder 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "0dfe27a6c0dabd772d0f9b9f8701c4ca12c4d1eebcadf2be1f6f70396f6a1434"
|
"checksum jpeg-decoder 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "0dfe27a6c0dabd772d0f9b9f8701c4ca12c4d1eebcadf2be1f6f70396f6a1434"
|
||||||
|
@ -3927,7 +3895,6 @@ dependencies = [
|
||||||
"checksum proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "77997c53ae6edd6d187fec07ec41b207063b5ee6f33680e9fa86d405cdd313d4"
|
"checksum proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "77997c53ae6edd6d187fec07ec41b207063b5ee6f33680e9fa86d405cdd313d4"
|
||||||
"checksum procedural-masquerade 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c93cdc1fb30af9ddf3debc4afbdb0f35126cbd99daa229dd76cdd5349b41d989"
|
"checksum procedural-masquerade 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c93cdc1fb30af9ddf3debc4afbdb0f35126cbd99daa229dd76cdd5349b41d989"
|
||||||
"checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4"
|
"checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4"
|
||||||
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
|
|
||||||
"checksum quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0ff51282f28dc1b53fd154298feaa2e77c5ea0dba68e1fd8b03b72fbe13d2a"
|
"checksum quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0ff51282f28dc1b53fd154298feaa2e77c5ea0dba68e1fd8b03b72fbe13d2a"
|
||||||
"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1"
|
"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1"
|
||||||
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
|
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
|
||||||
|
@ -3967,7 +3934,7 @@ dependencies = [
|
||||||
"checksum signpost 0.1.0 (git+https://github.com/pcwalton/signpost.git)" = "<none>"
|
"checksum signpost 0.1.0 (git+https://github.com/pcwalton/signpost.git)" = "<none>"
|
||||||
"checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537"
|
"checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537"
|
||||||
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
|
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
|
||||||
"checksum smallbitvec 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "665fbc8384f961eb55c548daa2a4b1efff1f9d03b7a10f162ac6ad6a781ca966"
|
"checksum smallbitvec 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c63726029f0069f88467873e47f392575f28f9f16b72ac65465263db4b3a13c"
|
||||||
"checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9"
|
"checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9"
|
||||||
"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
|
"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
|
||||||
"checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423"
|
"checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423"
|
||||||
|
@ -3975,9 +3942,7 @@ dependencies = [
|
||||||
"checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
|
"checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
|
||||||
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
|
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
|
||||||
"checksum swapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e454d048db5527d000bfddb77bd072bbf3a1e2ae785f16d9bd116e07c2ab45eb"
|
"checksum swapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e454d048db5527d000bfddb77bd072bbf3a1e2ae785f16d9bd116e07c2ab45eb"
|
||||||
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
|
|
||||||
"checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59"
|
"checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59"
|
||||||
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
|
|
||||||
"checksum synstructure 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "98cad891cd238c98e1f0aec9f7c0f620aa696e4e5f7daba56ac67b5e86a6b049"
|
"checksum synstructure 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "98cad891cd238c98e1f0aec9f7c0f620aa696e4e5f7daba56ac67b5e86a6b049"
|
||||||
"checksum tempfile 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "11ce2fe9db64b842314052e2421ac61a73ce41b898dc8e3750398b219c5fc1e0"
|
"checksum tempfile 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "11ce2fe9db64b842314052e2421ac61a73ce41b898dc8e3750398b219c5fc1e0"
|
||||||
"checksum tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508"
|
"checksum tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508"
|
||||||
|
@ -4002,7 +3967,6 @@ dependencies = [
|
||||||
"checksum unicode-script 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e8bd7bbf020b2885113e6304f68bcc33881c5552657c58d4e9699cd1b6606e81"
|
"checksum unicode-script 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e8bd7bbf020b2885113e6304f68bcc33881c5552657c58d4e9699cd1b6606e81"
|
||||||
"checksum unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8083c594e02b8ae1654ae26f0ade5158b119bd88ad0e8227a5d8fcd72407946"
|
"checksum unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8083c594e02b8ae1654ae26f0ade5158b119bd88ad0e8227a5d8fcd72407946"
|
||||||
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
|
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
|
||||||
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
|
|
||||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||||
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
|
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
|
||||||
"checksum url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa35e768d4daf1d85733418a49fb42e10d7f633e394fccab4ab7aba897053fe2"
|
"checksum url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa35e768d4daf1d85733418a49fb42e10d7f633e394fccab4ab7aba897053fe2"
|
||||||
|
|
|
@ -253,7 +253,7 @@ impl CSSStyleDeclaration {
|
||||||
self.owner.mutate_associated_block(|pdb, changed| {
|
self.owner.mutate_associated_block(|pdb, changed| {
|
||||||
if value.is_empty() {
|
if value.is_empty() {
|
||||||
// Step 3
|
// Step 3
|
||||||
*changed = pdb.remove_property(&id);
|
*changed = pdb.remove_property(&id, |_| {});
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,7 +365,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
||||||
let mut string = String::new();
|
let mut string = String::new();
|
||||||
self.owner.mutate_associated_block(|pdb, changed| {
|
self.owner.mutate_associated_block(|pdb, changed| {
|
||||||
pdb.property_value_to_css(&id, &mut string).unwrap();
|
pdb.property_value_to_css(&id, &mut string).unwrap();
|
||||||
*changed = pdb.remove_property(&id);
|
*changed = pdb.remove_property(&id, |_| {});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Step 6
|
// Step 6
|
||||||
|
|
|
@ -36,6 +36,7 @@ use std::slice;
|
||||||
/// (from left to right). Once the process is complete, callers should invoke
|
/// (from left to right). Once the process is complete, callers should invoke
|
||||||
/// build(), which transforms the contents of the SelectorBuilder into a heap-
|
/// build(), which transforms the contents of the SelectorBuilder into a heap-
|
||||||
/// allocated Selector and leaves the builder in a drained state.
|
/// allocated Selector and leaves the builder in a drained state.
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct SelectorBuilder<Impl: SelectorImpl> {
|
pub struct SelectorBuilder<Impl: SelectorImpl> {
|
||||||
/// The entire sequence of simple selectors, from left to right, without combinators.
|
/// The entire sequence of simple selectors, from left to right, without combinators.
|
||||||
///
|
///
|
||||||
|
@ -104,7 +105,7 @@ impl<Impl: SelectorImpl> SelectorBuilder<Impl> {
|
||||||
parsed_slotted: bool,
|
parsed_slotted: bool,
|
||||||
) -> ThinArc<SpecificityAndFlags, Component<Impl>> {
|
) -> ThinArc<SpecificityAndFlags, Component<Impl>> {
|
||||||
// Compute the specificity and flags.
|
// Compute the specificity and flags.
|
||||||
let mut spec = SpecificityAndFlags(specificity(self.simple_selectors.iter()));
|
let mut spec = SpecificityAndFlags(specificity(&*self, self.simple_selectors.iter()));
|
||||||
if parsed_pseudo {
|
if parsed_pseudo {
|
||||||
spec.0 |= HAS_PSEUDO_BIT;
|
spec.0 |= HAS_PSEUDO_BIT;
|
||||||
}
|
}
|
||||||
|
@ -268,25 +269,35 @@ impl From<Specificity> for u32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn specificity<Impl>(iter: slice::Iter<Component<Impl>>) -> u32
|
fn specificity<Impl>(builder: &SelectorBuilder<Impl>, iter: slice::Iter<Component<Impl>>) -> u32
|
||||||
where
|
where
|
||||||
Impl: SelectorImpl,
|
Impl: SelectorImpl,
|
||||||
{
|
{
|
||||||
complex_selector_specificity(iter).into()
|
complex_selector_specificity(builder, iter).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn complex_selector_specificity<Impl>(mut iter: slice::Iter<Component<Impl>>) -> Specificity
|
fn complex_selector_specificity<Impl>(
|
||||||
|
builder: &SelectorBuilder<Impl>,
|
||||||
|
mut iter: slice::Iter<Component<Impl>>,
|
||||||
|
) -> Specificity
|
||||||
where
|
where
|
||||||
Impl: SelectorImpl,
|
Impl: SelectorImpl,
|
||||||
{
|
{
|
||||||
fn simple_selector_specificity<Impl>(
|
fn simple_selector_specificity<Impl>(
|
||||||
|
builder: &SelectorBuilder<Impl>,
|
||||||
simple_selector: &Component<Impl>,
|
simple_selector: &Component<Impl>,
|
||||||
specificity: &mut Specificity,
|
specificity: &mut Specificity,
|
||||||
) where
|
) where
|
||||||
Impl: SelectorImpl,
|
Impl: SelectorImpl,
|
||||||
{
|
{
|
||||||
match *simple_selector {
|
match *simple_selector {
|
||||||
Component::Combinator(..) => unreachable!(),
|
Component::Combinator(ref combinator) => {
|
||||||
|
unreachable!(
|
||||||
|
"Found combinator {:?} in simple selectors vector? {:?}",
|
||||||
|
combinator,
|
||||||
|
builder,
|
||||||
|
);
|
||||||
|
}
|
||||||
// FIXME(emilio): Spec doesn't define any particular specificity for
|
// FIXME(emilio): Spec doesn't define any particular specificity for
|
||||||
// ::slotted(), so apply the general rule for pseudos per:
|
// ::slotted(), so apply the general rule for pseudos per:
|
||||||
//
|
//
|
||||||
|
@ -326,7 +337,7 @@ where
|
||||||
},
|
},
|
||||||
Component::Negation(ref negated) => {
|
Component::Negation(ref negated) => {
|
||||||
for ss in negated.iter() {
|
for ss in negated.iter() {
|
||||||
simple_selector_specificity(&ss, specificity);
|
simple_selector_specificity(builder, &ss, specificity);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -334,7 +345,7 @@ where
|
||||||
|
|
||||||
let mut specificity = Default::default();
|
let mut specificity = Default::default();
|
||||||
for simple_selector in &mut iter {
|
for simple_selector in &mut iter {
|
||||||
simple_selector_specificity(&simple_selector, &mut specificity);
|
simple_selector_specificity(builder, &simple_selector, &mut specificity);
|
||||||
}
|
}
|
||||||
specificity
|
specificity
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@ macro_rules! with_all_bounds {
|
||||||
/// NB: We need Clone so that we can derive(Clone) on struct with that
|
/// NB: We need Clone so that we can derive(Clone) on struct with that
|
||||||
/// are parameterized on SelectorImpl. See
|
/// are parameterized on SelectorImpl. See
|
||||||
/// <https://github.com/rust-lang/rust/issues/26925>
|
/// <https://github.com/rust-lang/rust/issues/26925>
|
||||||
pub trait SelectorImpl: Clone + Sized + 'static {
|
pub trait SelectorImpl: Clone + Debug + Sized + 'static {
|
||||||
type ExtraMatchingData: Sized + Default + 'static;
|
type ExtraMatchingData: Sized + Default + 'static;
|
||||||
type AttrValue: $($InSelector)*;
|
type AttrValue: $($InSelector)*;
|
||||||
type Identifier: $($InSelector)*;
|
type Identifier: $($InSelector)*;
|
||||||
|
@ -544,10 +544,26 @@ impl<Impl: SelectorImpl> Selector<Impl> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether this selector is a featureless :host selector, with no
|
/// Whether this selector is a featureless :host selector, with no
|
||||||
/// combinators to the left.
|
/// combinators to the left, and optionally has a pseudo-element to the
|
||||||
|
/// right.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_featureless_host_selector(&self) -> bool {
|
pub fn is_featureless_host_selector_or_pseudo_element(&self) -> bool {
|
||||||
self.iter().is_featureless_host_selector()
|
let mut iter = self.iter();
|
||||||
|
if !self.has_pseudo_element() {
|
||||||
|
return iter.is_featureless_host_selector();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip the pseudo-element.
|
||||||
|
for _ in &mut iter { }
|
||||||
|
|
||||||
|
match iter.next_sequence() {
|
||||||
|
None => return false,
|
||||||
|
Some(combinator) => {
|
||||||
|
debug_assert_eq!(combinator, Combinator::PseudoElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iter.is_featureless_host_selector()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator over this selector in matching order (right-to-left),
|
/// Returns an iterator over this selector in matching order (right-to-left),
|
||||||
|
|
|
@ -59,7 +59,7 @@ serde = {version = "1.0", optional = true, features = ["derive"]}
|
||||||
servo_arc = { path = "../servo_arc" }
|
servo_arc = { path = "../servo_arc" }
|
||||||
servo_atoms = {path = "../atoms", optional = true}
|
servo_atoms = {path = "../atoms", optional = true}
|
||||||
servo_config = {path = "../config", optional = true}
|
servo_config = {path = "../config", optional = true}
|
||||||
smallbitvec = "2.1.0"
|
smallbitvec = "2.1.1"
|
||||||
smallvec = "0.6"
|
smallvec = "0.6"
|
||||||
string_cache = { version = "0.7", optional = true }
|
string_cache = { version = "0.7", optional = true }
|
||||||
style_derive = {path = "../style_derive"}
|
style_derive = {path = "../style_derive"}
|
||||||
|
|
|
@ -10,7 +10,7 @@ use context::SharedStyleContext;
|
||||||
use dom::{OpaqueNode, TElement};
|
use dom::{OpaqueNode, TElement};
|
||||||
use font_metrics::FontMetricsProvider;
|
use font_metrics::FontMetricsProvider;
|
||||||
use properties::{self, CascadeFlags, ComputedValues, LonghandId};
|
use properties::{self, CascadeFlags, ComputedValues, LonghandId};
|
||||||
use properties::animated_properties::{AnimatedProperty, TransitionProperty};
|
use properties::animated_properties::AnimatedProperty;
|
||||||
use properties::longhands::animation_direction::computed_value::single_value::T as AnimationDirection;
|
use properties::longhands::animation_direction::computed_value::single_value::T as AnimationDirection;
|
||||||
use properties::longhands::animation_play_state::computed_value::single_value::T as AnimationPlayState;
|
use properties::longhands::animation_play_state::computed_value::single_value::T as AnimationPlayState;
|
||||||
use rule_tree::CascadeLevel;
|
use rule_tree::CascadeLevel;
|
||||||
|
@ -20,6 +20,7 @@ use std::sync::mpsc::Sender;
|
||||||
use stylesheets::keyframes_rule::{KeyframesAnimation, KeyframesStep, KeyframesStepValue};
|
use stylesheets::keyframes_rule::{KeyframesAnimation, KeyframesStep, KeyframesStepValue};
|
||||||
use timer::Timer;
|
use timer::Timer;
|
||||||
use values::computed::Time;
|
use values::computed::Time;
|
||||||
|
use values::computed::box_::TransitionProperty;
|
||||||
use values::computed::transform::TimingFunction;
|
use values::computed::transform::TimingFunction;
|
||||||
use values::generics::box_::AnimationIterationCount;
|
use values::generics::box_::AnimationIterationCount;
|
||||||
use values::generics::transform::{StepPosition, TimingFunction as GenericTimingFunction};
|
use values::generics::transform::{StepPosition, TimingFunction as GenericTimingFunction};
|
||||||
|
@ -303,7 +304,8 @@ impl PropertyAnimation {
|
||||||
let duration = box_style.transition_duration_mod(transition_index);
|
let duration = box_style.transition_duration_mod(transition_index);
|
||||||
|
|
||||||
match transition_property {
|
match transition_property {
|
||||||
TransitionProperty::Unsupported(_) => result,
|
TransitionProperty::Custom(..) |
|
||||||
|
TransitionProperty::Unsupported(..) => result,
|
||||||
TransitionProperty::Shorthand(ref shorthand_id) => shorthand_id
|
TransitionProperty::Shorthand(ref shorthand_id) => shorthand_id
|
||||||
.longhands()
|
.longhands()
|
||||||
.filter_map(|longhand| {
|
.filter_map(|longhand| {
|
||||||
|
|
|
@ -323,7 +323,7 @@ macro_rules! is_descriptor_enabled {
|
||||||
("font-variation-settings") => {
|
("font-variation-settings") => {
|
||||||
unsafe {
|
unsafe {
|
||||||
use gecko_bindings::structs::mozilla;
|
use gecko_bindings::structs::mozilla;
|
||||||
mozilla::StaticPrefs_sVarCache_layout_css_font_variations_enabled
|
mozilla::StaticPrefs_sVarCache_layout_css_font_variations_enabled != 0
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
($name:tt) => {
|
($name:tt) => {
|
||||||
|
|
|
@ -67,7 +67,6 @@ use media_queries::Device;
|
||||||
use properties::{ComputedValues, LonghandId};
|
use properties::{ComputedValues, LonghandId};
|
||||||
use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock};
|
use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock};
|
||||||
use properties::animated_properties::{AnimationValue, AnimationValueMap};
|
use properties::animated_properties::{AnimationValue, AnimationValueMap};
|
||||||
use properties::animated_properties::TransitionProperty;
|
|
||||||
use properties::style_structs::Font;
|
use properties::style_structs::Font;
|
||||||
use rule_tree::CascadeLevel as ServoCascadeLevel;
|
use rule_tree::CascadeLevel as ServoCascadeLevel;
|
||||||
use selector_parser::{AttrValue, Direction, PseudoClassStringArg};
|
use selector_parser::{AttrValue, Direction, PseudoClassStringArg};
|
||||||
|
@ -181,7 +180,6 @@ impl<'lr> TShadowRoot for GeckoShadowRoot<'lr> {
|
||||||
|
|
||||||
let author_styles = AuthorStyles::<GeckoStyleSheet>::from_ffi(author_styles);
|
let author_styles = AuthorStyles::<GeckoStyleSheet>::from_ffi(author_styles);
|
||||||
|
|
||||||
debug_assert!(!author_styles.stylesheets.dirty());
|
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
author_styles.quirks_mode == self.as_node().owner_doc().quirks_mode() ||
|
author_styles.quirks_mode == self.as_node().owner_doc().quirks_mode() ||
|
||||||
author_styles.stylesheets.is_empty()
|
author_styles.stylesheets.is_empty()
|
||||||
|
@ -617,31 +615,37 @@ impl<'le> GeckoElement<'le> {
|
||||||
// GeckoNode is a raw reference.
|
// GeckoNode is a raw reference.
|
||||||
//
|
//
|
||||||
// We can use a Cell<T>, but that's a bit of a pain.
|
// We can use a Cell<T>, but that's a bit of a pain.
|
||||||
|
#[inline]
|
||||||
fn set_flags(&self, flags: u32) {
|
fn set_flags(&self, flags: u32) {
|
||||||
unsafe { Gecko_SetNodeFlags(self.as_node().0, flags) }
|
unsafe { Gecko_SetNodeFlags(self.as_node().0, flags) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
unsafe fn unset_flags(&self, flags: u32) {
|
unsafe fn unset_flags(&self, flags: u32) {
|
||||||
Gecko_UnsetNodeFlags(self.as_node().0, flags)
|
Gecko_UnsetNodeFlags(self.as_node().0, flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if this element has descendants for lazy frame construction.
|
/// Returns true if this element has descendants for lazy frame construction.
|
||||||
|
#[inline]
|
||||||
pub fn descendants_need_frames(&self) -> bool {
|
pub fn descendants_need_frames(&self) -> bool {
|
||||||
self.flags() & (NODE_DESCENDANTS_NEED_FRAMES as u32) != 0
|
self.flags() & (NODE_DESCENDANTS_NEED_FRAMES as u32) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if this element needs lazy frame construction.
|
/// Returns true if this element needs lazy frame construction.
|
||||||
|
#[inline]
|
||||||
pub fn needs_frame(&self) -> bool {
|
pub fn needs_frame(&self) -> bool {
|
||||||
self.flags() & (NODE_NEEDS_FRAME as u32) != 0
|
self.flags() & (NODE_NEEDS_FRAME as u32) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reference to the DOM slots for this Element, if they exist.
|
/// Returns a reference to the DOM slots for this Element, if they exist.
|
||||||
|
#[inline]
|
||||||
fn dom_slots(&self) -> Option<&structs::FragmentOrElement_nsDOMSlots> {
|
fn dom_slots(&self) -> Option<&structs::FragmentOrElement_nsDOMSlots> {
|
||||||
let slots = self.as_node().0.mSlots as *const structs::FragmentOrElement_nsDOMSlots;
|
let slots = self.as_node().0.mSlots as *const structs::FragmentOrElement_nsDOMSlots;
|
||||||
unsafe { slots.as_ref() }
|
unsafe { slots.as_ref() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reference to the extended DOM slots for this Element.
|
/// Returns a reference to the extended DOM slots for this Element.
|
||||||
|
#[inline]
|
||||||
fn extended_slots(&self) -> Option<&structs::FragmentOrElement_nsExtendedDOMSlots> {
|
fn extended_slots(&self) -> Option<&structs::FragmentOrElement_nsExtendedDOMSlots> {
|
||||||
self.dom_slots().and_then(|s| unsafe {
|
self.dom_slots().and_then(|s| unsafe {
|
||||||
(s._base.mExtendedSlots.mPtr as *const structs::FragmentOrElement_nsExtendedDOMSlots)
|
(s._base.mExtendedSlots.mPtr as *const structs::FragmentOrElement_nsExtendedDOMSlots)
|
||||||
|
@ -699,6 +703,7 @@ impl<'le> GeckoElement<'le> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn non_xul_xbl_binding_parent_raw_content(&self) -> *mut nsIContent {
|
fn non_xul_xbl_binding_parent_raw_content(&self) -> *mut nsIContent {
|
||||||
debug_assert!(!self.is_xul_element());
|
debug_assert!(!self.is_xul_element());
|
||||||
self.extended_slots()
|
self.extended_slots()
|
||||||
|
@ -1113,7 +1118,23 @@ impl<'le> TElement for GeckoElement<'le> {
|
||||||
assert_eq!(base as *const _, self.0 as *const _, "Bad cast");
|
assert_eq!(base as *const _, self.0 as *const _, "Bad cast");
|
||||||
}
|
}
|
||||||
|
|
||||||
let assigned_nodes: &[structs::RefPtr<structs::nsINode>] = &*slot.mAssignedNodes;
|
// FIXME(emilio): Workaround a bindgen bug on Android that causes
|
||||||
|
// mAssignedNodes to be at the wrong offset. See bug 1466406.
|
||||||
|
//
|
||||||
|
// Bug 1466580 tracks running the Android layout tests on automation.
|
||||||
|
//
|
||||||
|
// The actual bindgen bug still needs reduction.
|
||||||
|
let assigned_nodes: &[structs::RefPtr<structs::nsINode>] =
|
||||||
|
if !cfg!(target_os = "android") {
|
||||||
|
debug_assert_eq!(
|
||||||
|
unsafe { bindings::Gecko_GetAssignedNodes(self.0) },
|
||||||
|
&slot.mAssignedNodes as *const _,
|
||||||
|
);
|
||||||
|
|
||||||
|
&*slot.mAssignedNodes
|
||||||
|
} else {
|
||||||
|
unsafe { &**bindings::Gecko_GetAssignedNodes(self.0) }
|
||||||
|
};
|
||||||
|
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
mem::size_of::<structs::RefPtr<structs::nsINode>>(),
|
mem::size_of::<structs::RefPtr<structs::nsINode>>(),
|
||||||
|
@ -1351,6 +1372,7 @@ impl<'le> TElement for GeckoElement<'le> {
|
||||||
!self.is_in_native_anonymous_subtree()
|
!self.is_in_native_anonymous_subtree()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn implemented_pseudo_element(&self) -> Option<PseudoElement> {
|
fn implemented_pseudo_element(&self) -> Option<PseudoElement> {
|
||||||
if !self.is_in_native_anonymous_subtree() {
|
if !self.is_in_native_anonymous_subtree() {
|
||||||
return None;
|
return None;
|
||||||
|
@ -1364,6 +1386,7 @@ impl<'le> TElement for GeckoElement<'le> {
|
||||||
PseudoElement::from_pseudo_type(pseudo_type)
|
PseudoElement::from_pseudo_type(pseudo_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn store_children_to_process(&self, _: isize) {
|
fn store_children_to_process(&self, _: isize) {
|
||||||
// This is only used for bottom-up traversal, and is thus a no-op for Gecko.
|
// This is only used for bottom-up traversal, and is thus a no-op for Gecko.
|
||||||
}
|
}
|
||||||
|
@ -1587,6 +1610,7 @@ impl<'le> TElement for GeckoElement<'le> {
|
||||||
) -> bool {
|
) -> bool {
|
||||||
use gecko_bindings::structs::nsCSSPropertyID;
|
use gecko_bindings::structs::nsCSSPropertyID;
|
||||||
use properties::LonghandIdSet;
|
use properties::LonghandIdSet;
|
||||||
|
use values::computed::TransitionProperty;
|
||||||
|
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
self.might_need_transitions_update(Some(before_change_style), after_change_style),
|
self.might_need_transitions_update(Some(before_change_style), after_change_style),
|
||||||
|
@ -1630,6 +1654,7 @@ impl<'le> TElement for GeckoElement<'le> {
|
||||||
};
|
};
|
||||||
|
|
||||||
match transition_property {
|
match transition_property {
|
||||||
|
TransitionProperty::Custom(..) |
|
||||||
TransitionProperty::Unsupported(..) => {},
|
TransitionProperty::Unsupported(..) => {},
|
||||||
TransitionProperty::Shorthand(ref shorthand) => {
|
TransitionProperty::Shorthand(ref shorthand) => {
|
||||||
if shorthand.longhands().any(property_check_helper) {
|
if shorthand.longhands().any(property_check_helper) {
|
||||||
|
|
|
@ -8,6 +8,7 @@ use context::QuirksMode;
|
||||||
use gecko_bindings::structs::nsCompatibility;
|
use gecko_bindings::structs::nsCompatibility;
|
||||||
|
|
||||||
impl From<nsCompatibility> for QuirksMode {
|
impl From<nsCompatibility> for QuirksMode {
|
||||||
|
#[inline]
|
||||||
fn from(mode: nsCompatibility) -> QuirksMode {
|
fn from(mode: nsCompatibility) -> QuirksMode {
|
||||||
match mode {
|
match mode {
|
||||||
nsCompatibility::eCompatibility_FullStandards => QuirksMode::NoQuirks,
|
nsCompatibility::eCompatibility_FullStandards => QuirksMode::NoQuirks,
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
|
|
||||||
//! A rust helper to ease the use of Gecko's refcounted types.
|
//! A rust helper to ease the use of Gecko's refcounted types.
|
||||||
|
|
||||||
use gecko_bindings::structs;
|
use Atom;
|
||||||
|
use gecko_bindings::{structs, bindings};
|
||||||
use gecko_bindings::sugar::ownership::HasArcFFI;
|
use gecko_bindings::sugar::ownership::HasArcFFI;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use std::{fmt, mem, ptr};
|
use std::{fmt, mem, ptr};
|
||||||
|
@ -255,13 +256,16 @@ unsafe impl<T: ThreadSafeRefCounted> Send for RefPtr<T> {}
|
||||||
unsafe impl<T: ThreadSafeRefCounted> Sync for RefPtr<T> {}
|
unsafe impl<T: ThreadSafeRefCounted> Sync for RefPtr<T> {}
|
||||||
|
|
||||||
macro_rules! impl_refcount {
|
macro_rules! impl_refcount {
|
||||||
($t:ty, $addref:ident, $release:ident) => {
|
($t:ty, $addref:path, $release:path) => {
|
||||||
unsafe impl RefCounted for $t {
|
unsafe impl RefCounted for $t {
|
||||||
|
#[inline]
|
||||||
fn addref(&self) {
|
fn addref(&self) {
|
||||||
unsafe { ::gecko_bindings::bindings::$addref(self as *const _ as *mut _) }
|
unsafe { $addref(self as *const _ as *mut _) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
unsafe fn release(&self) {
|
unsafe fn release(&self) {
|
||||||
::gecko_bindings::bindings::$release(self as *const _ as *mut _)
|
$release(self as *const _ as *mut _)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -271,50 +275,63 @@ macro_rules! impl_refcount {
|
||||||
//
|
//
|
||||||
// Gets you a free RefCounted impl implemented via FFI.
|
// Gets you a free RefCounted impl implemented via FFI.
|
||||||
macro_rules! impl_threadsafe_refcount {
|
macro_rules! impl_threadsafe_refcount {
|
||||||
($t:ty, $addref:ident, $release:ident) => {
|
($t:ty, $addref:path, $release:path) => {
|
||||||
impl_refcount!($t, $addref, $release);
|
impl_refcount!($t, $addref, $release);
|
||||||
unsafe impl ThreadSafeRefCounted for $t {}
|
unsafe impl ThreadSafeRefCounted for $t {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_threadsafe_refcount!(
|
impl_threadsafe_refcount!(
|
||||||
::gecko_bindings::structs::RawGeckoURLExtraData,
|
structs::RawGeckoURLExtraData,
|
||||||
Gecko_AddRefURLExtraDataArbitraryThread,
|
bindings::Gecko_AddRefURLExtraDataArbitraryThread,
|
||||||
Gecko_ReleaseURLExtraDataArbitraryThread
|
bindings::Gecko_ReleaseURLExtraDataArbitraryThread
|
||||||
);
|
);
|
||||||
impl_threadsafe_refcount!(
|
impl_threadsafe_refcount!(
|
||||||
::gecko_bindings::structs::nsStyleQuoteValues,
|
structs::nsStyleQuoteValues,
|
||||||
Gecko_AddRefQuoteValuesArbitraryThread,
|
bindings::Gecko_AddRefQuoteValuesArbitraryThread,
|
||||||
Gecko_ReleaseQuoteValuesArbitraryThread
|
bindings::Gecko_ReleaseQuoteValuesArbitraryThread
|
||||||
);
|
);
|
||||||
impl_threadsafe_refcount!(
|
impl_threadsafe_refcount!(
|
||||||
::gecko_bindings::structs::nsCSSValueSharedList,
|
structs::nsCSSValueSharedList,
|
||||||
Gecko_AddRefCSSValueSharedListArbitraryThread,
|
bindings::Gecko_AddRefCSSValueSharedListArbitraryThread,
|
||||||
Gecko_ReleaseCSSValueSharedListArbitraryThread
|
bindings::Gecko_ReleaseCSSValueSharedListArbitraryThread
|
||||||
);
|
);
|
||||||
impl_threadsafe_refcount!(
|
impl_threadsafe_refcount!(
|
||||||
::gecko_bindings::structs::mozilla::css::URLValue,
|
structs::mozilla::css::URLValue,
|
||||||
Gecko_AddRefCSSURLValueArbitraryThread,
|
bindings::Gecko_AddRefCSSURLValueArbitraryThread,
|
||||||
Gecko_ReleaseCSSURLValueArbitraryThread
|
bindings::Gecko_ReleaseCSSURLValueArbitraryThread
|
||||||
);
|
);
|
||||||
impl_threadsafe_refcount!(
|
impl_threadsafe_refcount!(
|
||||||
::gecko_bindings::structs::mozilla::css::GridTemplateAreasValue,
|
structs::mozilla::css::GridTemplateAreasValue,
|
||||||
Gecko_AddRefGridTemplateAreasValueArbitraryThread,
|
bindings::Gecko_AddRefGridTemplateAreasValueArbitraryThread,
|
||||||
Gecko_ReleaseGridTemplateAreasValueArbitraryThread
|
bindings::Gecko_ReleaseGridTemplateAreasValueArbitraryThread
|
||||||
);
|
);
|
||||||
impl_threadsafe_refcount!(
|
impl_threadsafe_refcount!(
|
||||||
::gecko_bindings::structs::ImageValue,
|
structs::ImageValue,
|
||||||
Gecko_AddRefImageValueArbitraryThread,
|
bindings::Gecko_AddRefImageValueArbitraryThread,
|
||||||
Gecko_ReleaseImageValueArbitraryThread
|
bindings::Gecko_ReleaseImageValueArbitraryThread
|
||||||
);
|
);
|
||||||
impl_threadsafe_refcount!(
|
impl_threadsafe_refcount!(
|
||||||
::gecko_bindings::structs::SharedFontList,
|
structs::SharedFontList,
|
||||||
Gecko_AddRefSharedFontListArbitraryThread,
|
bindings::Gecko_AddRefSharedFontListArbitraryThread,
|
||||||
Gecko_ReleaseSharedFontListArbitraryThread
|
bindings::Gecko_ReleaseSharedFontListArbitraryThread
|
||||||
|
);
|
||||||
|
impl_threadsafe_refcount!(
|
||||||
|
structs::SheetLoadDataHolder,
|
||||||
|
bindings::Gecko_AddRefSheetLoadDataHolderArbitraryThread,
|
||||||
|
bindings::Gecko_ReleaseSheetLoadDataHolderArbitraryThread
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
unsafe fn addref_atom(atom: *mut structs::nsAtom) {
|
||||||
|
mem::forget(Atom::from_raw(atom));
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
unsafe fn release_atom(atom: *mut structs::nsAtom) {
|
||||||
|
let _ = Atom::from_addrefed(atom);
|
||||||
|
}
|
||||||
impl_threadsafe_refcount!(
|
impl_threadsafe_refcount!(
|
||||||
::gecko_bindings::structs::SheetLoadDataHolder,
|
structs::nsAtom,
|
||||||
Gecko_AddRefSheetLoadDataHolderArbitraryThread,
|
addref_atom,
|
||||||
Gecko_ReleaseSheetLoadDataHolderArbitraryThread
|
release_atom
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,28 +5,21 @@
|
||||||
//! Rust helpers to interact with Gecko's StyleComplexColor.
|
//! Rust helpers to interact with Gecko's StyleComplexColor.
|
||||||
|
|
||||||
use gecko::values::{convert_nscolor_to_rgba, convert_rgba_to_nscolor};
|
use gecko::values::{convert_nscolor_to_rgba, convert_rgba_to_nscolor};
|
||||||
use gecko_bindings::structs::{nscolor, StyleComplexColor};
|
use gecko_bindings::structs::StyleComplexColor;
|
||||||
|
use gecko_bindings::structs::StyleComplexColor_Tag as Tag;
|
||||||
use values::{Auto, Either};
|
use values::{Auto, Either};
|
||||||
use values::computed::Color as ComputedColor;
|
use values::computed::{Color as ComputedColor, RGBAColor as ComputedRGBA};
|
||||||
use values::computed::ui::ColorOrAuto;
|
use values::computed::ui::ColorOrAuto;
|
||||||
|
use values::generics::color::{Color as GenericColor, ComplexColorRatios};
|
||||||
impl From<nscolor> for StyleComplexColor {
|
|
||||||
fn from(other: nscolor) -> Self {
|
|
||||||
StyleComplexColor {
|
|
||||||
mColor: other,
|
|
||||||
mForegroundRatio: 0,
|
|
||||||
mIsAuto: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StyleComplexColor {
|
impl StyleComplexColor {
|
||||||
/// Create a `StyleComplexColor` value that represents `currentColor`.
|
/// Create a `StyleComplexColor` value that represents `currentColor`.
|
||||||
pub fn current_color() -> Self {
|
pub fn current_color() -> Self {
|
||||||
StyleComplexColor {
|
StyleComplexColor {
|
||||||
mColor: 0,
|
mColor: 0,
|
||||||
mForegroundRatio: 255,
|
mBgRatio: 0.,
|
||||||
mIsAuto: false,
|
mFgRatio: 1.,
|
||||||
|
mTag: Tag::eForeground,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,28 +27,66 @@ impl StyleComplexColor {
|
||||||
pub fn auto() -> Self {
|
pub fn auto() -> Self {
|
||||||
StyleComplexColor {
|
StyleComplexColor {
|
||||||
mColor: 0,
|
mColor: 0,
|
||||||
mForegroundRatio: 255,
|
mBgRatio: 0.,
|
||||||
mIsAuto: true,
|
mFgRatio: 1.,
|
||||||
|
mTag: Tag::eAuto,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ComputedRGBA> for StyleComplexColor {
|
||||||
|
fn from(other: ComputedRGBA) -> Self {
|
||||||
|
StyleComplexColor {
|
||||||
|
mColor: convert_rgba_to_nscolor(&other),
|
||||||
|
mBgRatio: 1.,
|
||||||
|
mFgRatio: 0.,
|
||||||
|
mTag: Tag::eNumeric,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ComputedColor> for StyleComplexColor {
|
impl From<ComputedColor> for StyleComplexColor {
|
||||||
fn from(other: ComputedColor) -> Self {
|
fn from(other: ComputedColor) -> Self {
|
||||||
StyleComplexColor {
|
match other {
|
||||||
mColor: convert_rgba_to_nscolor(&other.color).into(),
|
GenericColor::Numeric(color) => color.into(),
|
||||||
mForegroundRatio: other.foreground_ratio,
|
GenericColor::Foreground => Self::current_color(),
|
||||||
mIsAuto: false,
|
GenericColor::Complex(color, ratios) => {
|
||||||
|
debug_assert!(ratios != ComplexColorRatios::NUMERIC);
|
||||||
|
debug_assert!(ratios != ComplexColorRatios::FOREGROUND);
|
||||||
|
StyleComplexColor {
|
||||||
|
mColor: convert_rgba_to_nscolor(&color).into(),
|
||||||
|
mBgRatio: ratios.bg,
|
||||||
|
mFgRatio: ratios.fg,
|
||||||
|
mTag: Tag::eComplex,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<StyleComplexColor> for ComputedColor {
|
impl From<StyleComplexColor> for ComputedColor {
|
||||||
fn from(other: StyleComplexColor) -> Self {
|
fn from(other: StyleComplexColor) -> Self {
|
||||||
debug_assert!(!other.mIsAuto);
|
match other.mTag {
|
||||||
ComputedColor {
|
Tag::eNumeric => {
|
||||||
color: convert_nscolor_to_rgba(other.mColor),
|
debug_assert!(other.mBgRatio == 1. && other.mFgRatio == 0.);
|
||||||
foreground_ratio: other.mForegroundRatio,
|
GenericColor::Numeric(convert_nscolor_to_rgba(other.mColor))
|
||||||
|
}
|
||||||
|
Tag::eForeground => {
|
||||||
|
debug_assert!(other.mBgRatio == 0. && other.mFgRatio == 1.);
|
||||||
|
GenericColor::Foreground
|
||||||
|
}
|
||||||
|
Tag::eComplex => {
|
||||||
|
debug_assert!(other.mBgRatio != 1. || other.mFgRatio != 0.);
|
||||||
|
debug_assert!(other.mBgRatio != 0. || other.mFgRatio != 1.);
|
||||||
|
GenericColor::Complex(
|
||||||
|
convert_nscolor_to_rgba(other.mColor),
|
||||||
|
ComplexColorRatios {
|
||||||
|
bg: other.mBgRatio,
|
||||||
|
fg: other.mFgRatio,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Tag::eAuto => unreachable!("Unsupport StyleComplexColor with tag eAuto"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +102,7 @@ impl From<ColorOrAuto> for StyleComplexColor {
|
||||||
|
|
||||||
impl From<StyleComplexColor> for ColorOrAuto {
|
impl From<StyleComplexColor> for ColorOrAuto {
|
||||||
fn from(other: StyleComplexColor) -> Self {
|
fn from(other: StyleComplexColor) -> Self {
|
||||||
if !other.mIsAuto {
|
if other.mTag != Tag::eAuto {
|
||||||
Either::First(other.into())
|
Either::First(other.into())
|
||||||
} else {
|
} else {
|
||||||
Either::Second(Auto)
|
Either::Second(Auto)
|
||||||
|
|
|
@ -150,10 +150,19 @@ impl<'a> ParserContext<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXXManishearth Replace all specified value parse impls with impls of this
|
|
||||||
// trait. This will make it easy to write more generic values in the future.
|
|
||||||
/// A trait to abstract parsing of a specified value given a `ParserContext` and
|
/// A trait to abstract parsing of a specified value given a `ParserContext` and
|
||||||
/// CSS input.
|
/// CSS input.
|
||||||
|
///
|
||||||
|
/// This can be derived on keywords with `#[derive(Parse)]`.
|
||||||
|
///
|
||||||
|
/// The derive code understands the following attributes on each of the variants:
|
||||||
|
///
|
||||||
|
/// * `#[parse(aliases = "foo,bar")]` can be used to alias a value with another
|
||||||
|
/// at parse-time.
|
||||||
|
///
|
||||||
|
/// * `#[parse(condition = "function")]` can be used to make the parsing of the
|
||||||
|
/// value conditional on `function`, which needs to fulfill
|
||||||
|
/// `fn(&ParserContext) -> bool`.
|
||||||
pub trait Parse: Sized {
|
pub trait Parse: Sized {
|
||||||
/// Parse a value of this type.
|
/// Parse a value of this type.
|
||||||
///
|
///
|
||||||
|
|
|
@ -226,6 +226,10 @@ class Longhand(object):
|
||||||
# See compute_damage for the various values this can take
|
# See compute_damage for the various values this can take
|
||||||
self.servo_restyle_damage = servo_restyle_damage
|
self.servo_restyle_damage = servo_restyle_damage
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def type():
|
||||||
|
return "longhand"
|
||||||
|
|
||||||
def experimental(self, product):
|
def experimental(self, product):
|
||||||
if product == "gecko":
|
if product == "gecko":
|
||||||
return bool(self.gecko_pref)
|
return bool(self.gecko_pref)
|
||||||
|
@ -361,6 +365,10 @@ class Shorthand(object):
|
||||||
animatable = property(get_animatable)
|
animatable = property(get_animatable)
|
||||||
transitionable = property(get_transitionable)
|
transitionable = property(get_transitionable)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def type():
|
||||||
|
return "shorthand"
|
||||||
|
|
||||||
def experimental(self, product):
|
def experimental(self, product):
|
||||||
if product == "gecko":
|
if product == "gecko":
|
||||||
return bool(self.gecko_pref)
|
return bool(self.gecko_pref)
|
||||||
|
@ -392,6 +400,10 @@ class Alias(object):
|
||||||
self.allowed_in_page_rule = original.allowed_in_page_rule
|
self.allowed_in_page_rule = original.allowed_in_page_rule
|
||||||
self.allowed_in_keyframe_block = original.allowed_in_keyframe_block
|
self.allowed_in_keyframe_block = original.allowed_in_keyframe_block
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def type():
|
||||||
|
return "alias"
|
||||||
|
|
||||||
def experimental(self, product):
|
def experimental(self, product):
|
||||||
if product == "gecko":
|
if product == "gecko":
|
||||||
return bool(self.gecko_pref)
|
return bool(self.gecko_pref)
|
||||||
|
|
|
@ -492,9 +492,9 @@ impl PropertyDeclarationBlock {
|
||||||
/// declaration with more importance, and will ensure that, if inserted,
|
/// declaration with more importance, and will ensure that, if inserted,
|
||||||
/// it's inserted at the end of the declaration block.
|
/// it's inserted at the end of the declaration block.
|
||||||
///
|
///
|
||||||
/// * For `DeclarationSource::CssOm`, this will override importance and
|
/// * For `DeclarationSource::CssOm`, this will override importance.
|
||||||
/// will preserve the original position on the block.
|
|
||||||
///
|
///
|
||||||
|
/// Returns whether the declaration has changed.
|
||||||
pub fn push(
|
pub fn push(
|
||||||
&mut self,
|
&mut self,
|
||||||
declaration: PropertyDeclaration,
|
declaration: PropertyDeclaration,
|
||||||
|
@ -517,15 +517,15 @@ impl PropertyDeclarationBlock {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let important = self.declarations_importance[i];
|
|
||||||
// For declarations from parsing, non-important declarations
|
|
||||||
// shouldn't override existing important one.
|
|
||||||
if important && !importance.important() &&
|
|
||||||
matches!(source, DeclarationSource::Parsing) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if matches!(source, DeclarationSource::Parsing) {
|
if matches!(source, DeclarationSource::Parsing) {
|
||||||
|
let important = self.declarations_importance[i];
|
||||||
|
|
||||||
|
// For declarations from parsing, non-important declarations
|
||||||
|
// shouldn't override existing important one.
|
||||||
|
if important && !importance.important() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// As a compatibility hack, specially on Android,
|
// As a compatibility hack, specially on Android,
|
||||||
// don't allow to override a prefixed webkit display
|
// don't allow to override a prefixed webkit display
|
||||||
// value with an unprefixed version from parsing
|
// value with an unprefixed version from parsing
|
||||||
|
@ -564,27 +564,17 @@ impl PropertyDeclarationBlock {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the declaration importance for a given property, if found.
|
|
||||||
///
|
|
||||||
/// Returns whether any declaration was updated.
|
|
||||||
pub fn set_importance(&mut self, property: &PropertyId, new_importance: Importance) -> bool {
|
|
||||||
let mut updated_at_least_one = false;
|
|
||||||
for (i, declaration) in self.declarations.iter().enumerate() {
|
|
||||||
if declaration.id().is_or_is_longhand_of(property) {
|
|
||||||
let is_important = new_importance.important();
|
|
||||||
if self.declarations_importance[i] != is_important {
|
|
||||||
self.declarations_importance.set(i, is_important);
|
|
||||||
updated_at_least_one = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
updated_at_least_one
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-removeproperty>
|
/// <https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-removeproperty>
|
||||||
///
|
///
|
||||||
/// Returns whether any declaration was actually removed.
|
/// Returns whether any declaration was actually removed.
|
||||||
pub fn remove_property(&mut self, property: &PropertyId) -> bool {
|
pub fn remove_property<C>(
|
||||||
|
&mut self,
|
||||||
|
property: &PropertyId,
|
||||||
|
mut before_change_callback: C,
|
||||||
|
) -> bool
|
||||||
|
where
|
||||||
|
C: FnMut(&Self),
|
||||||
|
{
|
||||||
let longhand_id = property.longhand_id();
|
let longhand_id = property.longhand_id();
|
||||||
if let Some(id) = longhand_id {
|
if let Some(id) = longhand_id {
|
||||||
if !self.longhands.contains(id) {
|
if !self.longhands.contains(id) {
|
||||||
|
@ -592,23 +582,28 @@ impl PropertyDeclarationBlock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut removed_at_least_one = false;
|
let mut removed_at_least_one = false;
|
||||||
let longhands = &mut self.longhands;
|
|
||||||
let declarations_importance = &mut self.declarations_importance;
|
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
self.declarations.retain(|declaration| {
|
let mut len = self.len();
|
||||||
let id = declaration.id();
|
while i < len {
|
||||||
let remove = id.is_or_is_longhand_of(property);
|
{
|
||||||
if remove {
|
let id = self.declarations[i].id();
|
||||||
|
if !id.is_or_is_longhand_of(property) {
|
||||||
|
i += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !removed_at_least_one {
|
||||||
|
before_change_callback(&*self);
|
||||||
|
}
|
||||||
removed_at_least_one = true;
|
removed_at_least_one = true;
|
||||||
if let PropertyDeclarationId::Longhand(id) = id {
|
if let PropertyDeclarationId::Longhand(id) = id {
|
||||||
longhands.remove(id);
|
self.longhands.remove(id);
|
||||||
}
|
}
|
||||||
declarations_importance.remove(i);
|
self.declarations_importance.remove(i);
|
||||||
} else {
|
|
||||||
i += 1;
|
|
||||||
}
|
}
|
||||||
!remove
|
self.declarations.remove(i);
|
||||||
});
|
len -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
if longhand_id.is_some() {
|
if longhand_id.is_some() {
|
||||||
debug_assert!(removed_at_least_one);
|
debug_assert!(removed_at_least_one);
|
||||||
|
@ -1116,9 +1111,7 @@ where
|
||||||
let mut parser = Parser::new(&mut input);
|
let mut parser = Parser::new(&mut input);
|
||||||
let start_position = parser.position();
|
let start_position = parser.position();
|
||||||
parser.parse_entirely(|parser| {
|
parser.parse_entirely(|parser| {
|
||||||
let name = id.name().into();
|
PropertyDeclaration::parse_into(declarations, id, &context, parser)
|
||||||
PropertyDeclaration::parse_into(declarations, id, name, &context, parser)
|
|
||||||
.map_err(|e| e.into())
|
|
||||||
}).map_err(|err| {
|
}).map_err(|err| {
|
||||||
let location = err.location;
|
let location = err.location;
|
||||||
let error = ContextualParseError::UnsupportedPropertyDeclaration(
|
let error = ContextualParseError::UnsupportedPropertyDeclaration(
|
||||||
|
@ -1169,7 +1162,7 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for PropertyDeclarationParser<'a, 'b> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
input.parse_until_before(Delimiter::Bang, |input| {
|
input.parse_until_before(Delimiter::Bang, |input| {
|
||||||
PropertyDeclaration::parse_into(self.declarations, id, name, self.context, input)
|
PropertyDeclaration::parse_into(self.declarations, id, self.context, input)
|
||||||
})?;
|
})?;
|
||||||
let importance = match input.try(parse_important) {
|
let importance = match input.try(parse_important) {
|
||||||
Ok(()) => Importance::Important,
|
Ok(()) => Importance::Important,
|
||||||
|
|
|
@ -28,7 +28,6 @@ use gecko_bindings::bindings::Gecko_CopyListStyleImageFrom;
|
||||||
use gecko_bindings::bindings::Gecko_EnsureImageLayersLength;
|
use gecko_bindings::bindings::Gecko_EnsureImageLayersLength;
|
||||||
use gecko_bindings::bindings::Gecko_SetCursorArrayLength;
|
use gecko_bindings::bindings::Gecko_SetCursorArrayLength;
|
||||||
use gecko_bindings::bindings::Gecko_SetCursorImageValue;
|
use gecko_bindings::bindings::Gecko_SetCursorImageValue;
|
||||||
use gecko_bindings::bindings::Gecko_StyleTransition_SetUnsupportedProperty;
|
|
||||||
use gecko_bindings::bindings::Gecko_NewCSSShadowArray;
|
use gecko_bindings::bindings::Gecko_NewCSSShadowArray;
|
||||||
use gecko_bindings::bindings::Gecko_nsStyleFont_SetLang;
|
use gecko_bindings::bindings::Gecko_nsStyleFont_SetLang;
|
||||||
use gecko_bindings::bindings::Gecko_nsStyleFont_CopyLangFrom;
|
use gecko_bindings::bindings::Gecko_nsStyleFont_CopyLangFrom;
|
||||||
|
@ -49,7 +48,6 @@ use gecko::values::GeckoStyleCoordConvertible;
|
||||||
use gecko::values::round_border_to_device_pixels;
|
use gecko::values::round_border_to_device_pixels;
|
||||||
use logical_geometry::WritingMode;
|
use logical_geometry::WritingMode;
|
||||||
use media_queries::Device;
|
use media_queries::Device;
|
||||||
use properties::animated_properties::TransitionProperty;
|
|
||||||
use properties::computed_value_flags::*;
|
use properties::computed_value_flags::*;
|
||||||
use properties::{longhands, Importance, LonghandId};
|
use properties::{longhands, Importance, LonghandId};
|
||||||
use properties::{PropertyDeclaration, PropertyDeclarationBlock, PropertyDeclarationId};
|
use properties::{PropertyDeclaration, PropertyDeclarationBlock, PropertyDeclarationId};
|
||||||
|
@ -60,7 +58,7 @@ use std::marker::PhantomData;
|
||||||
use std::mem::{forget, uninitialized, transmute, zeroed};
|
use std::mem::{forget, uninitialized, transmute, zeroed};
|
||||||
use std::{cmp, ops, ptr};
|
use std::{cmp, ops, ptr};
|
||||||
use values::{self, CustomIdent, Either, KeyframesName, None_};
|
use values::{self, CustomIdent, Either, KeyframesName, None_};
|
||||||
use values::computed::{NonNegativeLength, ToComputedValue, Percentage};
|
use values::computed::{NonNegativeLength, ToComputedValue, Percentage, TransitionProperty};
|
||||||
use values::computed::font::FontSize;
|
use values::computed::font::FontSize;
|
||||||
use values::computed::effects::{BoxShadow, Filter, SimpleShadow};
|
use values::computed::effects::{BoxShadow, Filter, SimpleShadow};
|
||||||
use values::computed::outline::OutlineStyle;
|
use values::computed::outline::OutlineStyle;
|
||||||
|
@ -390,17 +388,9 @@ impl ${style_struct.gecko_struct_name} {
|
||||||
|
|
||||||
<%!
|
<%!
|
||||||
def get_gecko_property(ffi_name, self_param = "self"):
|
def get_gecko_property(ffi_name, self_param = "self"):
|
||||||
if "mBorderColor" in ffi_name:
|
|
||||||
return ffi_name.replace("mBorderColor",
|
|
||||||
"unsafe { *%s.gecko.__bindgen_anon_1.mBorderColor.as_ref() }"
|
|
||||||
% self_param)
|
|
||||||
return "%s.gecko.%s" % (self_param, ffi_name)
|
return "%s.gecko.%s" % (self_param, ffi_name)
|
||||||
|
|
||||||
def set_gecko_property(ffi_name, expr):
|
def set_gecko_property(ffi_name, expr):
|
||||||
if "mBorderColor" in ffi_name:
|
|
||||||
ffi_name = ffi_name.replace("mBorderColor",
|
|
||||||
"*self.gecko.__bindgen_anon_1.mBorderColor.as_mut()")
|
|
||||||
return "unsafe { %s = %s };" % (ffi_name, expr)
|
|
||||||
return "self.gecko.%s = %s;" % (ffi_name, expr)
|
return "self.gecko.%s = %s;" % (ffi_name, expr)
|
||||||
%>
|
%>
|
||||||
|
|
||||||
|
@ -1596,7 +1586,7 @@ fn static_assert() {
|
||||||
self.gecko.mComputedBorder.${side.ident} = self.gecko.mBorder.${side.ident};
|
self.gecko.mComputedBorder.${side.ident} = self.gecko.mBorder.${side.ident};
|
||||||
}
|
}
|
||||||
|
|
||||||
<% impl_color("border_%s_color" % side.ident, "(mBorderColor)[%s]" % side.index) %>
|
<% impl_color("border_%s_color" % side.ident, "mBorder%sColor" % side.name) %>
|
||||||
|
|
||||||
<% impl_non_negative_length("border_%s_width" % side.ident,
|
<% impl_non_negative_length("border_%s_width" % side.ident,
|
||||||
"mComputedBorder.%s" % side.ident,
|
"mComputedBorder.%s" % side.ident,
|
||||||
|
@ -3267,6 +3257,8 @@ fn static_assert() {
|
||||||
I::IntoIter: ExactSizeIterator
|
I::IntoIter: ExactSizeIterator
|
||||||
{
|
{
|
||||||
use gecko_bindings::structs::nsCSSPropertyID::eCSSPropertyExtra_no_properties;
|
use gecko_bindings::structs::nsCSSPropertyID::eCSSPropertyExtra_no_properties;
|
||||||
|
use gecko_bindings::structs::nsCSSPropertyID::eCSSPropertyExtra_variable;
|
||||||
|
use gecko_bindings::structs::nsCSSPropertyID::eCSSProperty_UNKNOWN;
|
||||||
|
|
||||||
let v = v.into_iter();
|
let v = v.into_iter();
|
||||||
|
|
||||||
|
@ -3274,10 +3266,17 @@ fn static_assert() {
|
||||||
self.gecko.mTransitions.ensure_len(v.len());
|
self.gecko.mTransitions.ensure_len(v.len());
|
||||||
self.gecko.mTransitionPropertyCount = v.len() as u32;
|
self.gecko.mTransitionPropertyCount = v.len() as u32;
|
||||||
for (servo, gecko) in v.zip(self.gecko.mTransitions.iter_mut()) {
|
for (servo, gecko) in v.zip(self.gecko.mTransitions.iter_mut()) {
|
||||||
|
unsafe { gecko.mUnknownProperty.clear() };
|
||||||
|
|
||||||
match servo {
|
match servo {
|
||||||
TransitionProperty::Unsupported(ref ident) => unsafe {
|
TransitionProperty::Unsupported(ident) => {
|
||||||
Gecko_StyleTransition_SetUnsupportedProperty(gecko, ident.0.as_ptr())
|
gecko.mProperty = eCSSProperty_UNKNOWN;
|
||||||
|
gecko.mUnknownProperty.mRawPtr = ident.0.into_addrefed();
|
||||||
},
|
},
|
||||||
|
TransitionProperty::Custom(name) => {
|
||||||
|
gecko.mProperty = eCSSPropertyExtra_variable;
|
||||||
|
gecko.mUnknownProperty.mRawPtr = name.into_addrefed();
|
||||||
|
}
|
||||||
_ => gecko.mProperty = servo.to_nscsspropertyid().unwrap(),
|
_ => gecko.mProperty = servo.to_nscsspropertyid().unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3307,15 +3306,24 @@ fn static_assert() {
|
||||||
use gecko_bindings::structs::nsCSSPropertyID::eCSSProperty_UNKNOWN;
|
use gecko_bindings::structs::nsCSSPropertyID::eCSSProperty_UNKNOWN;
|
||||||
|
|
||||||
let property = self.gecko.mTransitions[index].mProperty;
|
let property = self.gecko.mTransitions[index].mProperty;
|
||||||
if property == eCSSProperty_UNKNOWN || property == eCSSPropertyExtra_variable {
|
if property == eCSSProperty_UNKNOWN {
|
||||||
let atom = self.gecko.mTransitions[index].mUnknownProperty.mRawPtr;
|
let atom = self.gecko.mTransitions[index].mUnknownProperty.mRawPtr;
|
||||||
debug_assert!(!atom.is_null());
|
debug_assert!(!atom.is_null());
|
||||||
TransitionProperty::Unsupported(CustomIdent(unsafe{
|
TransitionProperty::Unsupported(CustomIdent(unsafe{
|
||||||
Atom::from_raw(atom)
|
Atom::from_raw(atom)
|
||||||
}))
|
}))
|
||||||
|
} else if property == eCSSPropertyExtra_variable {
|
||||||
|
let atom = self.gecko.mTransitions[index].mUnknownProperty.mRawPtr;
|
||||||
|
debug_assert!(!atom.is_null());
|
||||||
|
TransitionProperty::Custom(unsafe{
|
||||||
|
Atom::from_raw(atom)
|
||||||
|
})
|
||||||
} else if property == eCSSPropertyExtra_no_properties {
|
} else if property == eCSSPropertyExtra_no_properties {
|
||||||
// Actually, we don't expect TransitionProperty::Unsupported also represents "none",
|
// Actually, we don't expect TransitionProperty::Unsupported also
|
||||||
// but if the caller wants to convert it, it is fine. Please use it carefully.
|
// represents "none", but if the caller wants to convert it, it is
|
||||||
|
// fine. Please use it carefully.
|
||||||
|
//
|
||||||
|
// FIXME(emilio): This is a hack, is this reachable?
|
||||||
TransitionProperty::Unsupported(CustomIdent(atom!("none")))
|
TransitionProperty::Unsupported(CustomIdent(atom!("none")))
|
||||||
} else {
|
} else {
|
||||||
property.into()
|
property.into()
|
||||||
|
@ -3336,11 +3344,12 @@ fn static_assert() {
|
||||||
|
|
||||||
for (index, transition) in self.gecko.mTransitions.iter_mut().enumerate().take(count as usize) {
|
for (index, transition) in self.gecko.mTransitions.iter_mut().enumerate().take(count as usize) {
|
||||||
transition.mProperty = other.gecko.mTransitions[index].mProperty;
|
transition.mProperty = other.gecko.mTransitions[index].mProperty;
|
||||||
|
unsafe { transition.mUnknownProperty.clear() };
|
||||||
if transition.mProperty == eCSSProperty_UNKNOWN ||
|
if transition.mProperty == eCSSProperty_UNKNOWN ||
|
||||||
transition.mProperty == eCSSPropertyExtra_variable {
|
transition.mProperty == eCSSPropertyExtra_variable {
|
||||||
let atom = other.gecko.mTransitions[index].mUnknownProperty.mRawPtr;
|
let atom = other.gecko.mTransitions[index].mUnknownProperty.mRawPtr;
|
||||||
debug_assert!(!atom.is_null());
|
debug_assert!(!atom.is_null());
|
||||||
unsafe { Gecko_StyleTransition_SetUnsupportedProperty(transition, atom) };
|
transition.mUnknownProperty.mRawPtr = unsafe { Atom::from_raw(atom) }.into_addrefed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -594,7 +594,7 @@
|
||||||
aliases.append(alias)
|
aliases.append(alias)
|
||||||
%>
|
%>
|
||||||
% if aliases:
|
% if aliases:
|
||||||
#[css(aliases = "${','.join(aliases)}")]
|
#[parse(aliases = "${','.join(aliases)}")]
|
||||||
% endif
|
% endif
|
||||||
% endif
|
% endif
|
||||||
${to_camel_case(variant)},
|
${to_camel_case(variant)},
|
||||||
|
@ -809,8 +809,10 @@
|
||||||
use values::generics::rect::Rect;
|
use values::generics::rect::Rect;
|
||||||
use values::specified;
|
use values::specified;
|
||||||
|
|
||||||
pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
pub fn parse_value<'i, 't>(
|
||||||
-> Result<Longhands, ParseError<'i>> {
|
context: &ParserContext,
|
||||||
|
input: &mut Parser<'i, 't>,
|
||||||
|
) -> Result<Longhands, ParseError<'i>> {
|
||||||
let rect = Rect::parse_with(context, input, |_c, i| {
|
let rect = Rect::parse_with(context, input, |_c, i| {
|
||||||
% if allow_quirks:
|
% if allow_quirks:
|
||||||
${parser_function}_quirky(_c, i, specified::AllowQuirks::Yes)
|
${parser_function}_quirky(_c, i, specified::AllowQuirks::Yes)
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
from itertools import groupby
|
from itertools import groupby
|
||||||
%>
|
%>
|
||||||
|
|
||||||
use cssparser::Parser;
|
|
||||||
#[cfg(feature = "gecko")] use gecko_bindings::bindings::RawServoAnimationValueMap;
|
#[cfg(feature = "gecko")] use gecko_bindings::bindings::RawServoAnimationValueMap;
|
||||||
#[cfg(feature = "gecko")] use gecko_bindings::structs::RawGeckoGfxMatrix4x4;
|
#[cfg(feature = "gecko")] use gecko_bindings::structs::RawGeckoGfxMatrix4x4;
|
||||||
#[cfg(feature = "gecko")] use gecko_bindings::structs::nsCSSPropertyID;
|
#[cfg(feature = "gecko")] use gecko_bindings::structs::nsCSSPropertyID;
|
||||||
|
@ -27,12 +26,12 @@ use smallvec::SmallVec;
|
||||||
use std::{cmp, ptr};
|
use std::{cmp, ptr};
|
||||||
use std::mem::{self, ManuallyDrop};
|
use std::mem::{self, ManuallyDrop};
|
||||||
#[cfg(feature = "gecko")] use hash::FnvHashMap;
|
#[cfg(feature = "gecko")] use hash::FnvHashMap;
|
||||||
use style_traits::{KeywordsCollectFn, ParseError, SpecifiedValueInfo};
|
|
||||||
use super::ComputedValues;
|
use super::ComputedValues;
|
||||||
use values::{CSSFloat, CustomIdent};
|
use values::CSSFloat;
|
||||||
use values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero};
|
use values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero};
|
||||||
use values::animated::color::RGBA as AnimatedRGBA;
|
use values::animated::color::RGBA as AnimatedRGBA;
|
||||||
use values::animated::effects::Filter as AnimatedFilter;
|
use values::animated::effects::Filter as AnimatedFilter;
|
||||||
|
#[cfg(feature = "gecko")] use values::computed::TransitionProperty;
|
||||||
use values::computed::{Angle, CalcLengthOrPercentage};
|
use values::computed::{Angle, CalcLengthOrPercentage};
|
||||||
use values::computed::{ClipRect, Context};
|
use values::computed::{ClipRect, Context};
|
||||||
use values::computed::{Length, LengthOrPercentage, LengthOrPercentageOrAuto};
|
use values::computed::{Length, LengthOrPercentage, LengthOrPercentageOrAuto};
|
||||||
|
@ -70,78 +69,6 @@ pub fn nscsspropertyid_is_animatable(property: nsCSSPropertyID) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A given transition property, that is either `All`, a transitionable longhand property,
|
|
||||||
/// a shorthand with at least one transitionable longhand component, or an unsupported property.
|
|
||||||
// NB: This needs to be here because it needs all the longhands generated
|
|
||||||
// beforehand.
|
|
||||||
#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue, ToCss)]
|
|
||||||
pub enum TransitionProperty {
|
|
||||||
/// A shorthand.
|
|
||||||
Shorthand(ShorthandId),
|
|
||||||
/// A longhand transitionable property.
|
|
||||||
Longhand(LonghandId),
|
|
||||||
/// Unrecognized property which could be any non-transitionable, custom property, or
|
|
||||||
/// unknown property.
|
|
||||||
Unsupported(CustomIdent),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TransitionProperty {
|
|
||||||
/// Returns `all`.
|
|
||||||
#[inline]
|
|
||||||
pub fn all() -> Self {
|
|
||||||
TransitionProperty::Shorthand(ShorthandId::All)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parse a transition-property value.
|
|
||||||
pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
|
||||||
// FIXME(https://github.com/rust-lang/rust/issues/33156): remove this
|
|
||||||
// enum and use PropertyId when stable Rust allows destructors in
|
|
||||||
// statics.
|
|
||||||
//
|
|
||||||
// FIXME: This should handle aliases too.
|
|
||||||
pub enum StaticId {
|
|
||||||
Longhand(LonghandId),
|
|
||||||
Shorthand(ShorthandId),
|
|
||||||
}
|
|
||||||
ascii_case_insensitive_phf_map! {
|
|
||||||
static_id -> StaticId = {
|
|
||||||
% for prop in data.shorthands:
|
|
||||||
"${prop.name}" => StaticId::Shorthand(ShorthandId::${prop.camel_case}),
|
|
||||||
% endfor
|
|
||||||
% for prop in data.longhands:
|
|
||||||
"${prop.name}" => StaticId::Longhand(LonghandId::${prop.camel_case}),
|
|
||||||
% endfor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let location = input.current_source_location();
|
|
||||||
let ident = input.expect_ident()?;
|
|
||||||
|
|
||||||
Ok(match static_id(&ident) {
|
|
||||||
Some(&StaticId::Longhand(id)) => TransitionProperty::Longhand(id),
|
|
||||||
Some(&StaticId::Shorthand(id)) => TransitionProperty::Shorthand(id),
|
|
||||||
None => {
|
|
||||||
TransitionProperty::Unsupported(
|
|
||||||
CustomIdent::from_ident(location, ident, &["none"])?,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert TransitionProperty to nsCSSPropertyID.
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
pub fn to_nscsspropertyid(&self) -> Result<nsCSSPropertyID, ()> {
|
|
||||||
Ok(match *self {
|
|
||||||
TransitionProperty::Shorthand(ShorthandId::All) => {
|
|
||||||
nsCSSPropertyID::eCSSPropertyExtra_all_properties
|
|
||||||
}
|
|
||||||
TransitionProperty::Shorthand(ref id) => id.to_nscsspropertyid(),
|
|
||||||
TransitionProperty::Longhand(ref id) => id.to_nscsspropertyid(),
|
|
||||||
TransitionProperty::Unsupported(..) => return Err(()),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert nsCSSPropertyID to TransitionProperty
|
/// Convert nsCSSPropertyID to TransitionProperty
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
#[allow(non_upper_case_globals)]
|
#[allow(non_upper_case_globals)]
|
||||||
|
@ -168,15 +95,6 @@ impl From<nsCSSPropertyID> for TransitionProperty {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SpecifiedValueInfo for TransitionProperty {
|
|
||||||
fn collect_completion_keywords(f: KeywordsCollectFn) {
|
|
||||||
// `transition-property` can actually accept all properties and
|
|
||||||
// arbitrary identifiers, but `all` is a special one we'd like
|
|
||||||
// to list.
|
|
||||||
f(&["all"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if this nsCSSPropertyID is one of the transitionable properties.
|
/// Returns true if this nsCSSPropertyID is one of the transitionable properties.
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub fn nscsspropertyid_is_transitionable(property: nsCSSPropertyID) -> bool {
|
pub fn nscsspropertyid_is_transitionable(property: nsCSSPropertyID) -> bool {
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
inherited=False,
|
inherited=False,
|
||||||
gecko_name="Display") %>
|
gecko_name="Display") %>
|
||||||
|
|
||||||
// TODO(SimonSapin): don't parse `inline-table`, since we don't support it
|
|
||||||
//
|
|
||||||
// We allow "display" to apply to placeholders because we need to make the
|
// We allow "display" to apply to placeholders because we need to make the
|
||||||
// placeholder pseudo-element an inline-block in the UA stylesheet in Gecko.
|
// placeholder pseudo-element an inline-block in the UA stylesheet in Gecko.
|
||||||
${helpers.predefined_type(
|
${helpers.predefined_type(
|
||||||
|
@ -19,10 +17,10 @@ ${helpers.predefined_type(
|
||||||
"computed::Display::inline()",
|
"computed::Display::inline()",
|
||||||
initial_specified_value="specified::Display::inline()",
|
initial_specified_value="specified::Display::inline()",
|
||||||
animation_value_type="discrete",
|
animation_value_type="discrete",
|
||||||
needs_context=False,
|
|
||||||
flags="APPLIES_TO_PLACEHOLDER",
|
flags="APPLIES_TO_PLACEHOLDER",
|
||||||
spec="https://drafts.csswg.org/css-display/#propdef-display",
|
spec="https://drafts.csswg.org/css-display/#propdef-display",
|
||||||
servo_restyle_damage="rebuild_and_reflow"
|
servo_restyle_damage="rebuild_and_reflow",
|
||||||
|
needs_context=product == "gecko"
|
||||||
)}
|
)}
|
||||||
|
|
||||||
// FIXME(emilio): Listing all the display values here is very unfortunate, we should teach C++ to use the
|
// FIXME(emilio): Listing all the display values here is very unfortunate, we should teach C++ to use the
|
||||||
|
@ -257,7 +255,6 @@ ${helpers.predefined_type(
|
||||||
vector=True,
|
vector=True,
|
||||||
allow_empty="NotInitial",
|
allow_empty="NotInitial",
|
||||||
need_index=True,
|
need_index=True,
|
||||||
needs_context=False,
|
|
||||||
animation_value_type="none",
|
animation_value_type="none",
|
||||||
extra_prefixes=transition_extra_prefixes,
|
extra_prefixes=transition_extra_prefixes,
|
||||||
spec="https://drafts.csswg.org/css-transitions/#propdef-transition-property",
|
spec="https://drafts.csswg.org/css-transitions/#propdef-transition-property",
|
||||||
|
|
|
@ -41,13 +41,17 @@ ${helpers.single_keyword("-moz-window-shadow", "none default menu tooltip sheet"
|
||||||
enabled_in="chrome",
|
enabled_in="chrome",
|
||||||
spec="None (Nonstandard internal property)")}
|
spec="None (Nonstandard internal property)")}
|
||||||
|
|
||||||
// TODO(bug 1419695) This should be hidden from content.
|
${helpers.predefined_type(
|
||||||
${helpers.predefined_type("-moz-window-opacity", "Opacity", "1.0", products="gecko",
|
"-moz-window-opacity",
|
||||||
gecko_ffi_name="mWindowOpacity",
|
"Opacity",
|
||||||
animation_value_type="ComputedValue",
|
"1.0",
|
||||||
spec="None (Nonstandard internal property)")}
|
products="gecko",
|
||||||
|
gecko_ffi_name="mWindowOpacity",
|
||||||
|
animation_value_type="ComputedValue",
|
||||||
|
spec="None (Nonstandard internal property)",
|
||||||
|
enabled_in="chrome",
|
||||||
|
)}
|
||||||
|
|
||||||
// TODO(bug 1419695) This should be hidden from content.
|
|
||||||
${helpers.predefined_type(
|
${helpers.predefined_type(
|
||||||
"-moz-window-transform",
|
"-moz-window-transform",
|
||||||
"Transform",
|
"Transform",
|
||||||
|
@ -56,10 +60,10 @@ ${helpers.predefined_type(
|
||||||
gecko_ffi_name="mSpecifiedWindowTransform",
|
gecko_ffi_name="mSpecifiedWindowTransform",
|
||||||
flags="GETCS_NEEDS_LAYOUT_FLUSH",
|
flags="GETCS_NEEDS_LAYOUT_FLUSH",
|
||||||
animation_value_type="ComputedValue",
|
animation_value_type="ComputedValue",
|
||||||
spec="None (Nonstandard internal property)"
|
spec="None (Nonstandard internal property)",
|
||||||
|
enabled_in="chrome",
|
||||||
)}
|
)}
|
||||||
|
|
||||||
// TODO(bug 1419695) This should be hidden from content.
|
|
||||||
${helpers.predefined_type(
|
${helpers.predefined_type(
|
||||||
"-moz-window-transform-origin",
|
"-moz-window-transform-origin",
|
||||||
"TransformOrigin",
|
"TransformOrigin",
|
||||||
|
@ -69,7 +73,8 @@ ${helpers.predefined_type(
|
||||||
products="gecko",
|
products="gecko",
|
||||||
boxed=True,
|
boxed=True,
|
||||||
flags="GETCS_NEEDS_LAYOUT_FLUSH",
|
flags="GETCS_NEEDS_LAYOUT_FLUSH",
|
||||||
spec="None (Nonstandard internal property)"
|
spec="None (Nonstandard internal property)",
|
||||||
|
enabled_in="chrome",
|
||||||
)}
|
)}
|
||||||
|
|
||||||
// TODO(emilio): Probably also should be hidden from content.
|
// TODO(emilio): Probably also should be hidden from content.
|
||||||
|
|
|
@ -22,8 +22,7 @@ use std::cell::RefCell;
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
use std::mem::{self, ManuallyDrop};
|
use std::mem::{self, ManuallyDrop};
|
||||||
|
|
||||||
#[cfg(feature = "servo")] use cssparser::RGBA;
|
use cssparser::{Parser, RGBA, TokenSerializationType};
|
||||||
use cssparser::{CowRcStr, Parser, TokenSerializationType, serialize_identifier};
|
|
||||||
use cssparser::ParserInput;
|
use cssparser::ParserInput;
|
||||||
#[cfg(feature = "servo")] use euclid::SideOffsets2D;
|
#[cfg(feature = "servo")] use euclid::SideOffsets2D;
|
||||||
use context::QuirksMode;
|
use context::QuirksMode;
|
||||||
|
@ -45,10 +44,10 @@ use shared_lock::StylesheetGuards;
|
||||||
use style_traits::{CssWriter, KeywordsCollectFn, ParseError, ParsingMode};
|
use style_traits::{CssWriter, KeywordsCollectFn, ParseError, ParsingMode};
|
||||||
use style_traits::{SpecifiedValueInfo, StyleParseErrorKind, ToCss};
|
use style_traits::{SpecifiedValueInfo, StyleParseErrorKind, ToCss};
|
||||||
use stylesheets::{CssRuleType, Origin, UrlExtraData};
|
use stylesheets::{CssRuleType, Origin, UrlExtraData};
|
||||||
#[cfg(feature = "servo")] use values::Either;
|
|
||||||
use values::generics::text::LineHeight;
|
use values::generics::text::LineHeight;
|
||||||
use values::computed;
|
use values::computed;
|
||||||
use values::computed::NonNegativeLength;
|
use values::computed::NonNegativeLength;
|
||||||
|
use values::serialize_atom_name;
|
||||||
use rule_tree::{CascadeLevel, StrongRuleNode};
|
use rule_tree::{CascadeLevel, StrongRuleNode};
|
||||||
use self::computed_value_flags::*;
|
use self::computed_value_flags::*;
|
||||||
use str::{CssString, CssStringBorrow, CssStringWriter};
|
use str::{CssString, CssStringBorrow, CssStringWriter};
|
||||||
|
@ -427,6 +426,17 @@ impl NonCustomPropertyId {
|
||||||
MAP[self.0]
|
MAP[self.0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the property name.
|
||||||
|
#[inline]
|
||||||
|
fn name(self) -> &'static str {
|
||||||
|
static MAP: [&'static str; ${len(data.longhands) + len(data.shorthands) + len(data.all_aliases())}] = [
|
||||||
|
% for property in data.longhands + data.shorthands + data.all_aliases():
|
||||||
|
"${property.name}",
|
||||||
|
% endfor
|
||||||
|
];
|
||||||
|
MAP[self.0]
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn enabled_for_all_content(self) -> bool {
|
fn enabled_for_all_content(self) -> bool {
|
||||||
${static_non_custom_property_id_set(
|
${static_non_custom_property_id_set(
|
||||||
|
@ -499,6 +509,11 @@ impl NonCustomPropertyId {
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.allowed_in_ignoring_rule_type(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn allowed_in_ignoring_rule_type(self, context: &ParserContext) -> bool {
|
||||||
// The semantics of these are kinda hard to reason about, what follows
|
// The semantics of these are kinda hard to reason about, what follows
|
||||||
// is a description of the different combinations that can happen with
|
// is a description of the different combinations that can happen with
|
||||||
// these three sets.
|
// these three sets.
|
||||||
|
@ -576,18 +591,21 @@ impl NonCustomPropertyId {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<LonghandId> for NonCustomPropertyId {
|
impl From<LonghandId> for NonCustomPropertyId {
|
||||||
|
#[inline]
|
||||||
fn from(id: LonghandId) -> Self {
|
fn from(id: LonghandId) -> Self {
|
||||||
NonCustomPropertyId(id as usize)
|
NonCustomPropertyId(id as usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ShorthandId> for NonCustomPropertyId {
|
impl From<ShorthandId> for NonCustomPropertyId {
|
||||||
|
#[inline]
|
||||||
fn from(id: ShorthandId) -> Self {
|
fn from(id: ShorthandId) -> Self {
|
||||||
NonCustomPropertyId((id as usize) + ${len(data.longhands)})
|
NonCustomPropertyId((id as usize) + ${len(data.longhands)})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<AliasId> for NonCustomPropertyId {
|
impl From<AliasId> for NonCustomPropertyId {
|
||||||
|
#[inline]
|
||||||
fn from(id: AliasId) -> Self {
|
fn from(id: AliasId) -> Self {
|
||||||
NonCustomPropertyId(id as usize + ${len(data.longhands) + len(data.shorthands)})
|
NonCustomPropertyId(id as usize + ${len(data.longhands) + len(data.shorthands)})
|
||||||
}
|
}
|
||||||
|
@ -814,13 +832,13 @@ bitflags! {
|
||||||
const APPLIES_TO_FIRST_LINE = 1 << 4;
|
const APPLIES_TO_FIRST_LINE = 1 << 4;
|
||||||
/// This longhand property applies to ::placeholder.
|
/// This longhand property applies to ::placeholder.
|
||||||
const APPLIES_TO_PLACEHOLDER = 1 << 5;
|
const APPLIES_TO_PLACEHOLDER = 1 << 5;
|
||||||
|
/// This property's getComputedStyle implementation requires layout
|
||||||
|
/// to be flushed.
|
||||||
|
const GETCS_NEEDS_LAYOUT_FLUSH = 1 << 6;
|
||||||
|
|
||||||
/* The following flags are currently not used in Rust code, they
|
/* The following flags are currently not used in Rust code, they
|
||||||
* only need to be listed in corresponding properties so that
|
* only need to be listed in corresponding properties so that
|
||||||
* they can be checked in the C++ side via ServoCSSPropList.h. */
|
* they can be checked in the C++ side via ServoCSSPropList.h. */
|
||||||
/// This property's getComputedStyle implementation requires layout
|
|
||||||
/// to be flushed.
|
|
||||||
const GETCS_NEEDS_LAYOUT_FLUSH = 0;
|
|
||||||
/// This property can be animated on the compositor.
|
/// This property can be animated on the compositor.
|
||||||
const CAN_ANIMATE_ON_COMPOSITOR = 0;
|
const CAN_ANIMATE_ON_COMPOSITOR = 0;
|
||||||
}
|
}
|
||||||
|
@ -854,12 +872,9 @@ impl fmt::Debug for LonghandId {
|
||||||
|
|
||||||
impl LonghandId {
|
impl LonghandId {
|
||||||
/// Get the name of this longhand property.
|
/// Get the name of this longhand property.
|
||||||
|
#[inline]
|
||||||
pub fn name(&self) -> &'static str {
|
pub fn name(&self) -> &'static str {
|
||||||
match *self {
|
NonCustomPropertyId::from(*self).name()
|
||||||
% for property in data.longhands:
|
|
||||||
LonghandId::${property.camel_case} => "${property.name}",
|
|
||||||
% endfor
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether the longhand property is inherited by default.
|
/// Returns whether the longhand property is inherited by default.
|
||||||
|
@ -1197,12 +1212,9 @@ impl ToCss for ShorthandId {
|
||||||
|
|
||||||
impl ShorthandId {
|
impl ShorthandId {
|
||||||
/// Get the name for this shorthand property.
|
/// Get the name for this shorthand property.
|
||||||
|
#[inline]
|
||||||
pub fn name(&self) -> &'static str {
|
pub fn name(&self) -> &'static str {
|
||||||
match *self {
|
NonCustomPropertyId::from(*self).name()
|
||||||
% for property in data.shorthands:
|
|
||||||
ShorthandId::${property.camel_case} => "${property.name}",
|
|
||||||
% endfor
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts from a ShorthandId to an adequate nsCSSPropertyID.
|
/// Converts from a ShorthandId to an adequate nsCSSPropertyID.
|
||||||
|
@ -1423,11 +1435,17 @@ impl UnparsedValue {
|
||||||
// As of this writing, only the base URL is used for property
|
// As of this writing, only the base URL is used for property
|
||||||
// values.
|
// values.
|
||||||
//
|
//
|
||||||
// FIXME(emilio): These bits are slightly fishy.
|
// NOTE(emilio): we intentionally pase `None` as the rule type here.
|
||||||
|
// If something starts depending on it, it's probably a bug, since
|
||||||
|
// it'd change how values are parsed depending on whether we're in a
|
||||||
|
// @keyframes rule or not, for example... So think twice about
|
||||||
|
// whether you want to do this!
|
||||||
|
//
|
||||||
|
// FIXME(emilio): ParsingMode is slightly fishy...
|
||||||
let context = ParserContext::new(
|
let context = ParserContext::new(
|
||||||
Origin::Author,
|
Origin::Author,
|
||||||
&self.url_data,
|
&self.url_data,
|
||||||
Some(CssRuleType::Style),
|
None,
|
||||||
ParsingMode::DEFAULT,
|
ParsingMode::DEFAULT,
|
||||||
quirks_mode,
|
quirks_mode,
|
||||||
);
|
);
|
||||||
|
@ -1495,8 +1513,9 @@ impl<'a> ToCss for PropertyDeclarationId<'a> {
|
||||||
{
|
{
|
||||||
match *self {
|
match *self {
|
||||||
PropertyDeclarationId::Longhand(id) => dest.write_str(id.name()),
|
PropertyDeclarationId::Longhand(id) => dest.write_str(id.name()),
|
||||||
PropertyDeclarationId::Custom(_) => {
|
PropertyDeclarationId::Custom(ref name) => {
|
||||||
serialize_identifier(&self.name(), dest)
|
dest.write_str("--")?;
|
||||||
|
serialize_atom_name(name, dest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1576,8 +1595,9 @@ impl ToCss for PropertyId {
|
||||||
PropertyId::Shorthand(id) => dest.write_str(id.name()),
|
PropertyId::Shorthand(id) => dest.write_str(id.name()),
|
||||||
PropertyId::LonghandAlias(id, _) => dest.write_str(id.name()),
|
PropertyId::LonghandAlias(id, _) => dest.write_str(id.name()),
|
||||||
PropertyId::ShorthandAlias(id, _) => dest.write_str(id.name()),
|
PropertyId::ShorthandAlias(id, _) => dest.write_str(id.name()),
|
||||||
PropertyId::Custom(_) => {
|
PropertyId::Custom(ref name) => {
|
||||||
serialize_identifier(&self.name(), dest)
|
dest.write_str("--")?;
|
||||||
|
serialize_atom_name(name, dest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1674,6 +1694,24 @@ impl PropertyId {
|
||||||
Ok(id)
|
Ok(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parses a property name, and returns an error if it's unknown or isn't
|
||||||
|
/// allowed in this context, ignoring the rule_type checks.
|
||||||
|
///
|
||||||
|
/// This is useful for parsing stuff from CSS values, for example.
|
||||||
|
#[inline]
|
||||||
|
pub fn parse_ignoring_rule_type(
|
||||||
|
name: &str,
|
||||||
|
context: &ParserContext,
|
||||||
|
) -> Result<Self, ()> {
|
||||||
|
let id = Self::parse_unchecked(name)?;
|
||||||
|
|
||||||
|
if !id.allowed_in_ignoring_rule_type(context) {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(id)
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a property id from Gecko's nsCSSPropertyID.
|
/// Returns a property id from Gecko's nsCSSPropertyID.
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
#[allow(non_upper_case_globals)]
|
#[allow(non_upper_case_globals)]
|
||||||
|
@ -1728,21 +1766,6 @@ impl PropertyId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the name of the property without CSS escaping.
|
|
||||||
pub fn name(&self) -> Cow<'static, str> {
|
|
||||||
match *self {
|
|
||||||
PropertyId::ShorthandAlias(id, _) |
|
|
||||||
PropertyId::Shorthand(id) => id.name().into(),
|
|
||||||
PropertyId::LonghandAlias(id, _) |
|
|
||||||
PropertyId::Longhand(id) => id.name().into(),
|
|
||||||
PropertyId::Custom(ref name) => {
|
|
||||||
let mut s = String::new();
|
|
||||||
write!(&mut s, "--{}", name).unwrap();
|
|
||||||
s.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn non_custom_id(&self) -> Option<NonCustomPropertyId> {
|
fn non_custom_id(&self) -> Option<NonCustomPropertyId> {
|
||||||
Some(match *self {
|
Some(match *self {
|
||||||
PropertyId::Custom(_) => return None,
|
PropertyId::Custom(_) => return None,
|
||||||
|
@ -1787,6 +1810,16 @@ impl PropertyId {
|
||||||
id.allowed_in(context)
|
id.allowed_in(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn allowed_in_ignoring_rule_type(&self, context: &ParserContext) -> bool {
|
||||||
|
let id = match self.non_custom_id() {
|
||||||
|
// Custom properties are allowed everywhere
|
||||||
|
None => return true,
|
||||||
|
Some(id) => id,
|
||||||
|
};
|
||||||
|
id.allowed_in_ignoring_rule_type(context)
|
||||||
|
}
|
||||||
|
|
||||||
/// Whether the property supports the given CSS type.
|
/// Whether the property supports the given CSS type.
|
||||||
/// `ty` should a bitflags of constants in style_traits::CssType.
|
/// `ty` should a bitflags of constants in style_traits::CssType.
|
||||||
pub fn supports_type(&self, ty: u8) -> bool {
|
pub fn supports_type(&self, ty: u8) -> bool {
|
||||||
|
@ -1995,13 +2028,13 @@ impl PropertyDeclaration {
|
||||||
pub fn parse_into<'i, 't>(
|
pub fn parse_into<'i, 't>(
|
||||||
declarations: &mut SourcePropertyDeclaration,
|
declarations: &mut SourcePropertyDeclaration,
|
||||||
id: PropertyId,
|
id: PropertyId,
|
||||||
name: CowRcStr<'i>,
|
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<(), ParseError<'i>> {
|
) -> Result<(), ParseError<'i>> {
|
||||||
assert!(declarations.is_empty());
|
assert!(declarations.is_empty());
|
||||||
debug_assert!(id.allowed_in(context), "{:?}", id);
|
debug_assert!(id.allowed_in(context), "{:?}", id);
|
||||||
|
|
||||||
|
let non_custom_id = id.non_custom_id();
|
||||||
let start = input.state();
|
let start = input.state();
|
||||||
match id {
|
match id {
|
||||||
PropertyId::Custom(property_name) => {
|
PropertyId::Custom(property_name) => {
|
||||||
|
@ -2012,7 +2045,10 @@ 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(StyleParseErrorKind::new_invalid(name, e)),
|
Err(e) => return Err(StyleParseErrorKind::new_invalid(
|
||||||
|
format!("--{}", property_name),
|
||||||
|
e,
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
declarations.push(PropertyDeclaration::Custom(CustomDeclaration {
|
declarations.push(PropertyDeclaration::Custom(CustomDeclaration {
|
||||||
|
@ -2037,7 +2073,10 @@ 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| {
|
||||||
StyleParseErrorKind::new_invalid(name, e)
|
StyleParseErrorKind::new_invalid(
|
||||||
|
non_custom_id.unwrap().name(),
|
||||||
|
e,
|
||||||
|
)
|
||||||
})?;
|
})?;
|
||||||
Ok(PropertyDeclaration::WithVariables(VariableDeclaration {
|
Ok(PropertyDeclaration::WithVariables(VariableDeclaration {
|
||||||
id,
|
id,
|
||||||
|
@ -2049,7 +2088,10 @@ impl PropertyDeclaration {
|
||||||
}),
|
}),
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseErrorKind::new_invalid(name, err))
|
Err(StyleParseErrorKind::new_invalid(
|
||||||
|
non_custom_id.unwrap().name(),
|
||||||
|
err,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}).map(|declaration| {
|
}).map(|declaration| {
|
||||||
|
@ -2083,7 +2125,10 @@ 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| {
|
||||||
StyleParseErrorKind::new_invalid(name, e)
|
StyleParseErrorKind::new_invalid(
|
||||||
|
non_custom_id.unwrap().name(),
|
||||||
|
e,
|
||||||
|
)
|
||||||
})?;
|
})?;
|
||||||
let unparsed = Arc::new(UnparsedValue {
|
let unparsed = Arc::new(UnparsedValue {
|
||||||
css: css.into_owned(),
|
css: css.into_owned(),
|
||||||
|
@ -2105,7 +2150,10 @@ impl PropertyDeclaration {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(StyleParseErrorKind::new_invalid(name, err))
|
Err(StyleParseErrorKind::new_invalid(
|
||||||
|
non_custom_id.unwrap().name(),
|
||||||
|
err,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -2453,6 +2501,7 @@ pub mod style_structs {
|
||||||
/// Whether this is a multicol style.
|
/// Whether this is a multicol style.
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
pub fn is_multicol(&self) -> bool {
|
pub fn is_multicol(&self) -> bool {
|
||||||
|
use values::Either;
|
||||||
match self.column_width {
|
match self.column_width {
|
||||||
Either::First(_width) => true,
|
Either::First(_width) => true,
|
||||||
Either::Second(_auto) => !self.column_count.is_auto(),
|
Either::Second(_auto) => !self.column_count.is_auto(),
|
||||||
|
@ -2564,6 +2613,59 @@ impl ComputedValues {
|
||||||
pub fn custom_properties(&self) -> Option<<&Arc<::custom_properties::CustomPropertiesMap>> {
|
pub fn custom_properties(&self) -> Option<<&Arc<::custom_properties::CustomPropertiesMap>> {
|
||||||
self.custom_properties.as_ref()
|
self.custom_properties.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Writes the value of the given longhand as a string in `dest`.
|
||||||
|
///
|
||||||
|
/// Note that the value will usually be the computed value, except for
|
||||||
|
/// colors, where it's resolved.
|
||||||
|
pub fn get_longhand_property_value<W>(
|
||||||
|
&self,
|
||||||
|
property_id: LonghandId,
|
||||||
|
dest: &mut CssWriter<W>
|
||||||
|
) -> fmt::Result
|
||||||
|
where
|
||||||
|
W: Write,
|
||||||
|
{
|
||||||
|
// TODO(emilio): Is it worth to merge branches here just like
|
||||||
|
// PropertyDeclaration::to_css does?
|
||||||
|
//
|
||||||
|
// We'd need to get a concept of ~resolved value, which may not be worth
|
||||||
|
// it.
|
||||||
|
match property_id {
|
||||||
|
% for prop in data.longhands:
|
||||||
|
LonghandId::${prop.camel_case} => {
|
||||||
|
let style_struct =
|
||||||
|
self.get_${prop.style_struct.ident.strip("_")}();
|
||||||
|
let value =
|
||||||
|
style_struct
|
||||||
|
% if prop.logical:
|
||||||
|
.clone_${prop.ident}(self.writing_mode);
|
||||||
|
% else:
|
||||||
|
.clone_${prop.ident}();
|
||||||
|
% endif
|
||||||
|
|
||||||
|
% if prop.predefined_type == "Color":
|
||||||
|
let value = self.resolve_color(value);
|
||||||
|
% endif
|
||||||
|
|
||||||
|
value.to_css(dest)
|
||||||
|
}
|
||||||
|
% endfor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Resolves the currentColor keyword.
|
||||||
|
///
|
||||||
|
/// Any color value from computed values (except for the 'color' property
|
||||||
|
/// itself) should go through this method.
|
||||||
|
///
|
||||||
|
/// Usage example:
|
||||||
|
/// let top_color =
|
||||||
|
/// style.resolve_color(style.get_border().clone_border_top_color());
|
||||||
|
#[inline]
|
||||||
|
pub fn resolve_color(&self, color: computed::Color) -> RGBA {
|
||||||
|
color.to_rgba(self.get_color().clone_color())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
|
@ -2598,6 +2700,26 @@ impl ComputedValues {
|
||||||
|
|
||||||
/// Get the initial computed values.
|
/// Get the initial computed values.
|
||||||
pub fn initial_values() -> &'static Self { &*INITIAL_SERVO_VALUES }
|
pub fn initial_values() -> &'static Self { &*INITIAL_SERVO_VALUES }
|
||||||
|
|
||||||
|
/// Serializes the computed value of this property as a string.
|
||||||
|
pub fn computed_value_to_string(&self, property: PropertyDeclarationId) -> String {
|
||||||
|
match property {
|
||||||
|
PropertyDeclarationId::Longhand(id) => {
|
||||||
|
let mut s = String::new();
|
||||||
|
self.get_longhand_property_value(
|
||||||
|
id,
|
||||||
|
&mut CssWriter::new(&mut s)
|
||||||
|
).unwrap();
|
||||||
|
s
|
||||||
|
}
|
||||||
|
PropertyDeclarationId::Custom(name) => {
|
||||||
|
self.custom_properties
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|map| map.get(name))
|
||||||
|
.map_or(String::new(), |value| value.to_css_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
|
@ -2676,18 +2798,6 @@ impl ComputedValuesInner {
|
||||||
self.get_column().is_multicol()
|
self.get_column().is_multicol()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolves the currentColor keyword.
|
|
||||||
///
|
|
||||||
/// Any color value from computed values (except for the 'color' property
|
|
||||||
/// itself) should go through this method.
|
|
||||||
///
|
|
||||||
/// Usage example:
|
|
||||||
/// let top_color = style.resolve_color(style.Border.border_top_color);
|
|
||||||
#[inline]
|
|
||||||
pub fn resolve_color(&self, color: computed::Color) -> RGBA {
|
|
||||||
color.to_rgba(self.get_color().color)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the logical computed inline size.
|
/// Get the logical computed inline size.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn content_inline_size(&self) -> computed::LengthOrPercentageOrAuto {
|
pub fn content_inline_size(&self) -> computed::LengthOrPercentageOrAuto {
|
||||||
|
@ -2848,26 +2958,6 @@ impl ComputedValuesInner {
|
||||||
// Neither perspective nor transform present
|
// Neither perspective nor transform present
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Serializes the computed value of this property as a string.
|
|
||||||
pub fn computed_value_to_string(&self, property: PropertyDeclarationId) -> String {
|
|
||||||
match property {
|
|
||||||
% for style_struct in data.active_style_structs():
|
|
||||||
% for longhand in style_struct.longhands:
|
|
||||||
PropertyDeclarationId::Longhand(LonghandId::${longhand.camel_case}) => {
|
|
||||||
self.${style_struct.ident}.${longhand.ident}.to_css_string()
|
|
||||||
}
|
|
||||||
% endfor
|
|
||||||
% endfor
|
|
||||||
PropertyDeclarationId::Custom(name) => {
|
|
||||||
self.custom_properties
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|map| map.get(name))
|
|
||||||
.map(|value| value.to_css_string())
|
|
||||||
.unwrap_or(String::new())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
% if product == "gecko":
|
% if product == "gecko":
|
||||||
|
|
|
@ -123,9 +123,11 @@ macro_rules! try_parse_one {
|
||||||
transition-timing-function
|
transition-timing-function
|
||||||
transition-delay"
|
transition-delay"
|
||||||
spec="https://drafts.csswg.org/css-transitions/#propdef-transition">
|
spec="https://drafts.csswg.org/css-transitions/#propdef-transition">
|
||||||
|
use parser::Parse;
|
||||||
% for prop in "delay duration property timing_function".split():
|
% for prop in "delay duration property timing_function".split():
|
||||||
use properties::longhands::transition_${prop};
|
use properties::longhands::transition_${prop};
|
||||||
% endfor
|
% endfor
|
||||||
|
use values::specified::TransitionProperty;
|
||||||
|
|
||||||
pub fn parse_value<'i, 't>(
|
pub fn parse_value<'i, 't>(
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
|
@ -137,7 +139,7 @@ macro_rules! try_parse_one {
|
||||||
% endfor
|
% endfor
|
||||||
// Unlike other properties, transition-property uses an Option<> to
|
// Unlike other properties, transition-property uses an Option<> to
|
||||||
// represent 'none' as `None`.
|
// represent 'none' as `None`.
|
||||||
transition_property: Option<transition_property::SingleSpecifiedValue>,
|
transition_property: Option<TransitionProperty>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_one_transition<'i, 't>(
|
fn parse_one_transition<'i, 't>(
|
||||||
|
@ -158,10 +160,12 @@ macro_rules! try_parse_one {
|
||||||
// Must check 'transition-property' after 'transition-timing-function' since
|
// Must check 'transition-property' after 'transition-timing-function' since
|
||||||
// 'transition-property' accepts any keyword.
|
// 'transition-property' accepts any keyword.
|
||||||
if property.is_none() {
|
if property.is_none() {
|
||||||
if let Ok(value) = input.try(|i| transition_property::SingleSpecifiedValue::parse(i)) {
|
if let Ok(value) = input.try(|i| TransitionProperty::parse(context, i)) {
|
||||||
property = Some(Some(value));
|
property = Some(Some(value));
|
||||||
continue;
|
continue;
|
||||||
} else if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
}
|
||||||
|
|
||||||
|
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
||||||
// 'none' is not a valid value for <single-transition-property>,
|
// 'none' is not a valid value for <single-transition-property>,
|
||||||
// so it's not acceptable in the function above.
|
// so it's not acceptable in the function above.
|
||||||
property = Some(None);
|
property = Some(None);
|
||||||
|
|
|
@ -315,39 +315,6 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
fn adjust_for_contain(&mut self) {
|
|
||||||
use properties::longhands::contain::SpecifiedValue;
|
|
||||||
|
|
||||||
// An element with contain: paint needs to be a formatting context, and
|
|
||||||
// also implies overflow: clip.
|
|
||||||
//
|
|
||||||
// TODO(emilio): This mimics Gecko, but spec links are missing!
|
|
||||||
let contain = self.style.get_box().clone_contain();
|
|
||||||
if !contain.contains(SpecifiedValue::PAINT) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.style.get_box().clone_display() == Display::Inline {
|
|
||||||
self.style
|
|
||||||
.mutate_box()
|
|
||||||
.set_adjusted_display(Display::InlineBlock, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// When 'contain: paint', update overflow from 'visible' to 'clip'.
|
|
||||||
if self.style
|
|
||||||
.get_box()
|
|
||||||
.clone_contain()
|
|
||||||
.contains(SpecifiedValue::PAINT)
|
|
||||||
{
|
|
||||||
if self.style.get_box().clone_overflow_x() == Overflow::Visible {
|
|
||||||
let box_style = self.style.mutate_box();
|
|
||||||
box_style.set_overflow_x(Overflow::MozHiddenUnscrollable);
|
|
||||||
box_style.set_overflow_y(Overflow::MozHiddenUnscrollable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// When mathvariant is not "none", font-weight and font-style are
|
/// When mathvariant is not "none", font-weight and font-style are
|
||||||
/// both forced to "normal".
|
/// both forced to "normal".
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
@ -752,7 +719,6 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
{
|
{
|
||||||
self.adjust_for_table_text_align();
|
self.adjust_for_table_text_align();
|
||||||
self.adjust_for_contain();
|
|
||||||
self.adjust_for_mathvariant();
|
self.adjust_for_mathvariant();
|
||||||
self.adjust_for_justify_items();
|
self.adjust_for_justify_items();
|
||||||
}
|
}
|
||||||
|
|
|
@ -623,12 +623,12 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for KeyframeDeclarationParser<'a, 'b> {
|
||||||
let id = match PropertyId::parse(&name, self.context) {
|
let id = match PropertyId::parse(&name, self.context) {
|
||||||
Ok(id) => id,
|
Ok(id) => id,
|
||||||
Err(()) => return Err(input.new_custom_error(
|
Err(()) => return Err(input.new_custom_error(
|
||||||
StyleParseErrorKind::UnknownProperty(name.clone())
|
StyleParseErrorKind::UnknownProperty(name)
|
||||||
)),
|
)),
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO(emilio): Shouldn't this use parse_entirely?
|
// TODO(emilio): Shouldn't this use parse_entirely?
|
||||||
PropertyDeclaration::parse_into(self.declarations, id, name, self.context, input)?;
|
PropertyDeclaration::parse_into(self.declarations, id, self.context, input)?;
|
||||||
|
|
||||||
// In case there is still unparsed text in the declaration, we should
|
// In case there is still unparsed text in the declaration, we should
|
||||||
// roll back.
|
// roll back.
|
||||||
|
|
|
@ -316,20 +316,23 @@ 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| -> Result<(), CssParseError<()>> {
|
input.parse_entirely(|input| -> Result<(), CssParseError<()>> {
|
||||||
let prop = input.expect_ident_cloned().unwrap();
|
let prop = input.expect_ident_cloned().unwrap();
|
||||||
input.expect_colon().unwrap();
|
input.expect_colon().unwrap();
|
||||||
|
|
||||||
let id = PropertyId::parse(&prop, context)
|
let id = PropertyId::parse(&prop, context)
|
||||||
.map_err(|_| input.new_custom_error(()))?;
|
.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, &context, input)
|
PropertyDeclaration::parse_into(
|
||||||
.map_err(|_| input.new_custom_error(()))
|
&mut declarations,
|
||||||
})?;
|
id,
|
||||||
let _ = input.try(parse_important);
|
&context,
|
||||||
Ok(())
|
input,
|
||||||
})
|
).map_err(|_| input.new_custom_error(()))
|
||||||
.is_ok()
|
})?;
|
||||||
|
let _ = input.try(parse_important);
|
||||||
|
Ok(())
|
||||||
|
}).is_ok()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1951,14 +1951,9 @@ pub struct CascadeData {
|
||||||
/// cascade level.
|
/// cascade level.
|
||||||
normal_rules: ElementAndPseudoRules,
|
normal_rules: ElementAndPseudoRules,
|
||||||
|
|
||||||
/// The `:host` pseudo rules that are the rightmost selector.
|
/// The `:host` pseudo rules that are the rightmost selector (without
|
||||||
///
|
/// accounting for pseudo-elements).
|
||||||
/// Note that as of right now these can't affect invalidation in any way,
|
host_rules: Option<Box<ElementAndPseudoRules>>,
|
||||||
/// until we support the :host(<selector>) notation.
|
|
||||||
///
|
|
||||||
/// Also, note that other engines don't accept stuff like :host::before /
|
|
||||||
/// :host::after, so we don't need to store pseudo rules at all.
|
|
||||||
host_rules: Option<Box<SelectorMap<Rule>>>,
|
|
||||||
|
|
||||||
/// The data coming from ::slotted() pseudo-element rules.
|
/// The data coming from ::slotted() pseudo-element rules.
|
||||||
///
|
///
|
||||||
|
@ -2122,11 +2117,7 @@ impl CascadeData {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn host_rules(&self, pseudo: Option<&PseudoElement>) -> Option<&SelectorMap<Rule>> {
|
fn host_rules(&self, pseudo: Option<&PseudoElement>) -> Option<&SelectorMap<Rule>> {
|
||||||
if pseudo.is_some() {
|
self.host_rules.as_ref().and_then(|d| d.rules(pseudo))
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.host_rules.as_ref().map(|rules| &**rules)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -2258,20 +2249,20 @@ impl CascadeData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if selector.is_featureless_host_selector() {
|
// NOTE(emilio): It's fine to look at :host and then at
|
||||||
let host_rules = self.host_rules
|
// ::slotted(..), since :host::slotted(..) could never
|
||||||
.get_or_insert_with(|| Box::new(Default::default()));
|
// possibly match, as <slot> is not a valid shadow host.
|
||||||
host_rules.insert(rule, quirks_mode)?;
|
let rules = if selector.is_featureless_host_selector_or_pseudo_element() {
|
||||||
|
self.host_rules
|
||||||
|
.get_or_insert_with(|| Box::new(Default::default()))
|
||||||
|
} else if selector.is_slotted() {
|
||||||
|
self.slotted_rules
|
||||||
|
.get_or_insert_with(|| Box::new(Default::default()))
|
||||||
} else {
|
} else {
|
||||||
let rules = if selector.is_slotted() {
|
&mut self.normal_rules
|
||||||
self.slotted_rules
|
};
|
||||||
.get_or_insert_with(|| Box::new(Default::default()))
|
|
||||||
} else {
|
|
||||||
&mut self.normal_rules
|
|
||||||
};
|
|
||||||
|
|
||||||
rules.insert(rule, pseudo_element, quirks_mode)?;
|
rules.insert(rule, pseudo_element, quirks_mode)?;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
self.rules_source_order += 1;
|
self.rules_source_order += 1;
|
||||||
},
|
},
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
use values::animated::{Animate, Procedure, ToAnimatedZero};
|
use values::animated::{Animate, Procedure, ToAnimatedZero};
|
||||||
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||||
|
use values::generics::color::{Color as GenericColor, ComplexColorRatios};
|
||||||
|
|
||||||
/// An animated RGBA color.
|
/// An animated RGBA color.
|
||||||
///
|
///
|
||||||
|
@ -91,42 +92,26 @@ impl ComputeSquaredDistance for RGBA {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
/// An animated value for `<color>`.
|
||||||
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
|
pub type Color = GenericColor<RGBA>;
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
|
||||||
pub struct Color {
|
|
||||||
pub color: RGBA,
|
|
||||||
pub foreground_ratio: f32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Color {
|
impl Color {
|
||||||
fn currentcolor() -> Self {
|
|
||||||
Color {
|
|
||||||
color: RGBA::transparent(),
|
|
||||||
foreground_ratio: 1.,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a transparent intermediate color.
|
|
||||||
pub fn transparent() -> Self {
|
|
||||||
Color {
|
|
||||||
color: RGBA::transparent(),
|
|
||||||
foreground_ratio: 0.,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_currentcolor(&self) -> bool {
|
|
||||||
self.foreground_ratio >= 1.
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_numeric(&self) -> bool {
|
|
||||||
self.foreground_ratio <= 0.
|
|
||||||
}
|
|
||||||
|
|
||||||
fn effective_intermediate_rgba(&self) -> RGBA {
|
fn effective_intermediate_rgba(&self) -> RGBA {
|
||||||
RGBA {
|
match *self {
|
||||||
alpha: self.color.alpha * (1. - self.foreground_ratio),
|
GenericColor::Numeric(color) => color,
|
||||||
..self.color
|
GenericColor::Foreground => RGBA::transparent(),
|
||||||
|
GenericColor::Complex(color, ratios) => RGBA {
|
||||||
|
alpha: color.alpha * ratios.bg,
|
||||||
|
..color.clone()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn effective_ratios(&self) -> ComplexColorRatios {
|
||||||
|
match *self {
|
||||||
|
GenericColor::Numeric(..) => ComplexColorRatios::NUMERIC,
|
||||||
|
GenericColor::Foreground => ComplexColorRatios::FOREGROUND,
|
||||||
|
GenericColor::Complex(.., ratios) => ratios,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,80 +119,88 @@ impl Color {
|
||||||
impl Animate for Color {
|
impl Animate for Color {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
|
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
|
||||||
|
use self::GenericColor::*;
|
||||||
|
|
||||||
// Common cases are interpolating between two numeric colors,
|
// Common cases are interpolating between two numeric colors,
|
||||||
// two currentcolors, and a numeric color and a currentcolor.
|
// two currentcolors, and a numeric color and a currentcolor.
|
||||||
//
|
|
||||||
// Note: this algorithm assumes self_portion + other_portion
|
|
||||||
// equals to one, so it may be broken for additive operation.
|
|
||||||
// To properly support additive color interpolation, we would
|
|
||||||
// need two ratio fields in computed color types.
|
|
||||||
let (this_weight, other_weight) = procedure.weights();
|
let (this_weight, other_weight) = procedure.weights();
|
||||||
if self.foreground_ratio == other.foreground_ratio {
|
|
||||||
if self.is_currentcolor() {
|
Ok(match (*self, *other, procedure) {
|
||||||
Ok(Color::currentcolor())
|
// Any interpolation of currentColor with currentColor returns currentColor.
|
||||||
} else {
|
(Foreground, Foreground, Procedure::Interpolate { .. }) => Color::currentcolor(),
|
||||||
Ok(Color {
|
// Animating two numeric colors.
|
||||||
color: self.color.animate(&other.color, procedure)?,
|
(Numeric(c1), Numeric(c2), _) => Numeric(c1.animate(&c2, procedure)?),
|
||||||
foreground_ratio: self.foreground_ratio,
|
// Combinations of numeric color and currentColor
|
||||||
})
|
(Foreground, Numeric(color), _) => Self::with_ratios(
|
||||||
}
|
color,
|
||||||
} else if self.is_currentcolor() && other.is_numeric() {
|
ComplexColorRatios {
|
||||||
Ok(Color {
|
bg: other_weight as f32,
|
||||||
color: other.color,
|
fg: this_weight as f32,
|
||||||
foreground_ratio: this_weight as f32,
|
|
||||||
})
|
|
||||||
} else if self.is_numeric() && other.is_currentcolor() {
|
|
||||||
Ok(Color {
|
|
||||||
color: self.color,
|
|
||||||
foreground_ratio: other_weight as f32,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
// For interpolating between two complex colors, we need to
|
|
||||||
// generate colors with effective alpha value.
|
|
||||||
let self_color = self.effective_intermediate_rgba();
|
|
||||||
let other_color = other.effective_intermediate_rgba();
|
|
||||||
let color = self_color.animate(&other_color, procedure)?;
|
|
||||||
// Then we compute the final foreground ratio, and derive
|
|
||||||
// the final alpha value from the effective alpha value.
|
|
||||||
let foreground_ratio = self.foreground_ratio
|
|
||||||
.animate(&other.foreground_ratio, procedure)?;
|
|
||||||
let alpha = color.alpha / (1. - foreground_ratio);
|
|
||||||
Ok(Color {
|
|
||||||
color: RGBA {
|
|
||||||
alpha: alpha,
|
|
||||||
..color
|
|
||||||
},
|
},
|
||||||
foreground_ratio: foreground_ratio,
|
),
|
||||||
})
|
(Numeric(color), Foreground, _) => Self::with_ratios(
|
||||||
}
|
color,
|
||||||
|
ComplexColorRatios {
|
||||||
|
bg: this_weight as f32,
|
||||||
|
fg: other_weight as f32,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
// Any other animation of currentColor with currentColor.
|
||||||
|
(Foreground, Foreground, _) => Self::with_ratios(
|
||||||
|
RGBA::transparent(),
|
||||||
|
ComplexColorRatios {
|
||||||
|
bg: 0.,
|
||||||
|
fg: (this_weight + other_weight) as f32,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
// Defer to complex calculations
|
||||||
|
_ => {
|
||||||
|
// For interpolating between two complex colors, we need to
|
||||||
|
// generate colors with effective alpha value.
|
||||||
|
let self_color = self.effective_intermediate_rgba();
|
||||||
|
let other_color = other.effective_intermediate_rgba();
|
||||||
|
let color = self_color.animate(&other_color, procedure)?;
|
||||||
|
// Then we compute the final background ratio, and derive
|
||||||
|
// the final alpha value from the effective alpha value.
|
||||||
|
let self_ratios = self.effective_ratios();
|
||||||
|
let other_ratios = other.effective_ratios();
|
||||||
|
let ratios = self_ratios.animate(&other_ratios, procedure)?;
|
||||||
|
let alpha = color.alpha / ratios.bg;
|
||||||
|
let color = RGBA { alpha, ..color };
|
||||||
|
|
||||||
|
Self::with_ratios(color, ratios)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ComputeSquaredDistance for Color {
|
impl ComputeSquaredDistance for Color {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||||
|
use self::GenericColor::*;
|
||||||
|
|
||||||
// All comments from the Animate impl also applies here.
|
// All comments from the Animate impl also applies here.
|
||||||
if self.foreground_ratio == other.foreground_ratio {
|
Ok(match (*self, *other) {
|
||||||
if self.is_currentcolor() {
|
(Foreground, Foreground) => SquaredDistance::from_sqrt(0.),
|
||||||
Ok(SquaredDistance::from_sqrt(0.))
|
(Numeric(c1), Numeric(c2)) => c1.compute_squared_distance(&c2)?,
|
||||||
} else {
|
(Foreground, Numeric(color)) | (Numeric(color), Foreground) => {
|
||||||
self.color.compute_squared_distance(&other.color)
|
// `computed_squared_distance` is symmetic.
|
||||||
|
color.compute_squared_distance(&RGBA::transparent())?
|
||||||
|
+ SquaredDistance::from_sqrt(1.)
|
||||||
}
|
}
|
||||||
} else if self.is_currentcolor() && other.is_numeric() {
|
(_, _) => {
|
||||||
Ok(
|
let self_color = self.effective_intermediate_rgba();
|
||||||
RGBA::transparent().compute_squared_distance(&other.color)? +
|
let other_color = other.effective_intermediate_rgba();
|
||||||
SquaredDistance::from_sqrt(1.),
|
let self_ratios = self.effective_ratios();
|
||||||
)
|
let other_ratios = other.effective_ratios();
|
||||||
} else if self.is_numeric() && other.is_currentcolor() {
|
|
||||||
Ok(self.color.compute_squared_distance(&RGBA::transparent())? +
|
self_color.compute_squared_distance(&other_color)?
|
||||||
SquaredDistance::from_sqrt(1.))
|
+ self_ratios.bg.compute_squared_distance(&other_ratios.bg)?
|
||||||
} else {
|
+ self_ratios.fg.compute_squared_distance(&other_ratios.fg)?
|
||||||
let self_color = self.effective_intermediate_rgba();
|
}
|
||||||
let other_color = other.effective_intermediate_rgba();
|
})
|
||||||
Ok(self_color.compute_squared_distance(&other_color)? +
|
|
||||||
self.foreground_ratio
|
|
||||||
.compute_squared_distance(&other.foreground_ratio)?)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ use values::generics::box_::Perspective as GenericPerspective;
|
||||||
use values::generics::box_::VerticalAlign as GenericVerticalAlign;
|
use values::generics::box_::VerticalAlign as GenericVerticalAlign;
|
||||||
|
|
||||||
pub use values::specified::box_::{AnimationName, Contain, Display, OverflowClipBox};
|
pub use values::specified::box_::{AnimationName, Contain, Display, OverflowClipBox};
|
||||||
pub use values::specified::box_::{OverscrollBehavior, ScrollSnapType, TouchAction, WillChange};
|
pub use values::specified::box_::{OverscrollBehavior, ScrollSnapType, TouchAction, TransitionProperty, WillChange};
|
||||||
|
|
||||||
/// A computed value for the `vertical-align` property.
|
/// A computed value for the `vertical-align` property.
|
||||||
pub type VerticalAlign = GenericVerticalAlign<LengthOrPercentage>;
|
pub type VerticalAlign = GenericVerticalAlign<LengthOrPercentage>;
|
||||||
|
|
|
@ -8,20 +8,8 @@ use cssparser::{Color as CSSParserColor, RGBA};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{CssWriter, ToCss};
|
use style_traits::{CssWriter, ToCss};
|
||||||
use values::animated::ToAnimatedValue;
|
use values::animated::ToAnimatedValue;
|
||||||
use values::animated::color::{Color as AnimatedColor, RGBA as AnimatedRGBA};
|
use values::animated::color::RGBA as AnimatedRGBA;
|
||||||
|
use values::generics::color::Color as GenericColor;
|
||||||
/// This struct represents a combined color from a numeric color and
|
|
||||||
/// the current foreground color (currentcolor keyword).
|
|
||||||
/// Conceptually, the formula is "color * (1 - p) + currentcolor * p"
|
|
||||||
/// where p is foreground_ratio.
|
|
||||||
#[derive(Clone, Copy, Debug, MallocSizeOf)]
|
|
||||||
pub struct Color {
|
|
||||||
/// RGBA color.
|
|
||||||
pub color: RGBA,
|
|
||||||
|
|
||||||
/// The ratio of currentcolor in complex color.
|
|
||||||
pub foreground_ratio: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Computed value type for the specified RGBAColor.
|
/// Computed value type for the specified RGBAColor.
|
||||||
pub type RGBAColor = RGBA;
|
pub type RGBAColor = RGBA;
|
||||||
|
@ -29,89 +17,49 @@ pub type RGBAColor = RGBA;
|
||||||
/// The computed value of the `color` property.
|
/// The computed value of the `color` property.
|
||||||
pub type ColorPropertyValue = RGBA;
|
pub type ColorPropertyValue = RGBA;
|
||||||
|
|
||||||
impl Color {
|
/// A computed value for `<color>`.
|
||||||
/// Returns a numeric color representing the given RGBA value.
|
pub type Color = GenericColor<RGBAColor>;
|
||||||
pub fn rgba(rgba: RGBA) -> Color {
|
|
||||||
Color {
|
|
||||||
color: rgba,
|
|
||||||
foreground_ratio: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
impl Color {
|
||||||
/// Returns a complex color value representing transparent.
|
/// Returns a complex color value representing transparent.
|
||||||
pub fn transparent() -> Color {
|
pub fn transparent() -> Color {
|
||||||
Color::rgba(RGBA::transparent())
|
Color::rgba(RGBA::transparent())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a complex color value representing currentcolor.
|
|
||||||
pub fn currentcolor() -> Color {
|
|
||||||
Color {
|
|
||||||
color: RGBA::transparent(),
|
|
||||||
foreground_ratio: u8::max_value(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Whether it is a numeric color (no currentcolor component).
|
|
||||||
pub fn is_numeric(&self) -> bool {
|
|
||||||
self.foreground_ratio == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Whether it is a currentcolor value (no numeric color component).
|
|
||||||
pub fn is_currentcolor(&self) -> bool {
|
|
||||||
self.foreground_ratio == u8::max_value()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Combine this complex color with the given foreground color into
|
/// Combine this complex color with the given foreground color into
|
||||||
/// a numeric RGBA color. It currently uses linear blending.
|
/// a numeric RGBA color. It currently uses linear blending.
|
||||||
pub fn to_rgba(&self, fg_color: RGBA) -> RGBA {
|
pub fn to_rgba(&self, fg_color: RGBA) -> RGBA {
|
||||||
// Common cases that the complex color is either pure numeric
|
let (color, ratios) = match *self {
|
||||||
// color or pure currentcolor.
|
// Common cases that the complex color is either pure numeric
|
||||||
if self.is_numeric() {
|
// color or pure currentcolor.
|
||||||
return self.color;
|
GenericColor::Numeric(color) => return color,
|
||||||
}
|
GenericColor::Foreground => return fg_color,
|
||||||
if self.is_currentcolor() {
|
GenericColor::Complex(color, ratios) => (color, ratios),
|
||||||
return fg_color.clone();
|
};
|
||||||
}
|
|
||||||
|
|
||||||
fn blend_color_component(bg: u8, fg: u8, fg_alpha: u8) -> u8 {
|
|
||||||
let bg_ratio = (u8::max_value() - fg_alpha) as u32;
|
|
||||||
let fg_ratio = fg_alpha as u32;
|
|
||||||
let color = bg as u32 * bg_ratio + fg as u32 * fg_ratio;
|
|
||||||
// Rounding divide the number by 255
|
|
||||||
((color + 127) / 255) as u8
|
|
||||||
}
|
|
||||||
|
|
||||||
// Common case that alpha channel is equal (usually both are opaque).
|
|
||||||
let fg_ratio = self.foreground_ratio;
|
|
||||||
if self.color.alpha == fg_color.alpha {
|
|
||||||
let r = blend_color_component(self.color.red, fg_color.red, fg_ratio);
|
|
||||||
let g = blend_color_component(self.color.green, fg_color.green, fg_ratio);
|
|
||||||
let b = blend_color_component(self.color.blue, fg_color.blue, fg_ratio);
|
|
||||||
return RGBA::new(r, g, b, fg_color.alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
// For the more complicated case that the alpha value differs,
|
// For the more complicated case that the alpha value differs,
|
||||||
// we use the following formula to compute the components:
|
// we use the following formula to compute the components:
|
||||||
// alpha = self_alpha * (1 - fg_ratio) + fg_alpha * fg_ratio
|
// alpha = self_alpha * bg_ratio + fg_alpha * fg_ratio
|
||||||
// color = (self_color * self_alpha * (1 - fg_ratio) +
|
// color = (self_color * self_alpha * bg_ratio +
|
||||||
// fg_color * fg_alpha * fg_ratio) / alpha
|
// fg_color * fg_alpha * fg_ratio) / alpha
|
||||||
|
|
||||||
let p1 = (1. / 255.) * (255 - fg_ratio) as f32;
|
let p1 = ratios.bg;
|
||||||
let a1 = self.color.alpha_f32();
|
let a1 = color.alpha_f32();
|
||||||
let r1 = a1 * self.color.red_f32();
|
let r1 = a1 * color.red_f32();
|
||||||
let g1 = a1 * self.color.green_f32();
|
let g1 = a1 * color.green_f32();
|
||||||
let b1 = a1 * self.color.blue_f32();
|
let b1 = a1 * color.blue_f32();
|
||||||
|
|
||||||
let p2 = 1. - p1;
|
let p2 = ratios.fg;
|
||||||
let a2 = fg_color.alpha_f32();
|
let a2 = fg_color.alpha_f32();
|
||||||
let r2 = a2 * fg_color.red_f32();
|
let r2 = a2 * fg_color.red_f32();
|
||||||
let g2 = a2 * fg_color.green_f32();
|
let g2 = a2 * fg_color.green_f32();
|
||||||
let b2 = a2 * fg_color.blue_f32();
|
let b2 = a2 * fg_color.blue_f32();
|
||||||
|
|
||||||
let a = p1 * a1 + p2 * a2;
|
let a = p1 * a1 + p2 * a2;
|
||||||
if a == 0.0 {
|
if a <= 0. {
|
||||||
return RGBA::transparent();
|
return RGBA::transparent();
|
||||||
}
|
}
|
||||||
|
let a = f32::min(a, 1.);
|
||||||
|
|
||||||
let inverse_a = 1. / a;
|
let inverse_a = 1. / a;
|
||||||
let r = (p1 * r1 + p2 * r2) * inverse_a;
|
let r = (p1 * r1 + p2 * r2) * inverse_a;
|
||||||
|
@ -121,53 +69,15 @@ impl Color {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for Color {
|
|
||||||
fn eq(&self, other: &Color) -> bool {
|
|
||||||
self.foreground_ratio == other.foreground_ratio &&
|
|
||||||
(self.is_currentcolor() || self.color == other.color)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<RGBA> for Color {
|
|
||||||
fn from(color: RGBA) -> Color {
|
|
||||||
Color {
|
|
||||||
color: color,
|
|
||||||
foreground_ratio: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToCss for Color {
|
impl ToCss for Color {
|
||||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||||
where
|
where
|
||||||
W: fmt::Write,
|
W: fmt::Write,
|
||||||
{
|
{
|
||||||
if self.is_numeric() {
|
match *self {
|
||||||
self.color.to_css(dest)
|
GenericColor::Numeric(color) => color.to_css(dest),
|
||||||
} else if self.is_currentcolor() {
|
GenericColor::Foreground => CSSParserColor::CurrentColor.to_css(dest),
|
||||||
CSSParserColor::CurrentColor.to_css(dest)
|
_ => Ok(()),
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToAnimatedValue for Color {
|
|
||||||
type AnimatedValue = AnimatedColor;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn to_animated_value(self) -> Self::AnimatedValue {
|
|
||||||
AnimatedColor {
|
|
||||||
color: self.color.to_animated_value(),
|
|
||||||
foreground_ratio: self.foreground_ratio as f32 * (1. / 255.),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
|
|
||||||
Color {
|
|
||||||
color: RGBA::from_animated_value(animated.color),
|
|
||||||
foreground_ratio: (animated.foreground_ratio * 255.).round() as u8,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent
|
||||||
use super::specified;
|
use super::specified;
|
||||||
|
|
||||||
pub use app_units::Au;
|
pub use app_units::Au;
|
||||||
pub use properties::animated_properties::TransitionProperty;
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub use self::align::{AlignContent, AlignItems, JustifyContent, JustifyItems, SelfAlignment};
|
pub use self::align::{AlignContent, AlignItems, JustifyContent, JustifyItems, SelfAlignment};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
@ -43,7 +42,7 @@ pub use self::font::{FontSize, FontSizeAdjust, FontStretch, FontSynthesis, FontV
|
||||||
pub use self::font::{FontFamily, FontLanguageOverride, FontStyle, FontVariantEastAsian, FontVariationSettings};
|
pub use self::font::{FontFamily, FontLanguageOverride, FontStyle, FontVariantEastAsian, FontVariationSettings};
|
||||||
pub use self::font::{FontFeatureSettings, FontVariantLigatures, FontVariantNumeric};
|
pub use self::font::{FontFeatureSettings, FontVariantLigatures, FontVariantNumeric};
|
||||||
pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XLang, XTextZoom};
|
pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XLang, XTextZoom};
|
||||||
pub use self::box_::{AnimationIterationCount, AnimationName, Contain, Display};
|
pub use self::box_::{AnimationIterationCount, AnimationName, Contain, Display, TransitionProperty};
|
||||||
pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective};
|
pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective};
|
||||||
pub use self::box_::{ScrollSnapType, TouchAction, VerticalAlign, WillChange};
|
pub use self::box_::{ScrollSnapType, TouchAction, VerticalAlign, WillChange};
|
||||||
pub use self::color::{Color, ColorPropertyValue, RGBAColor};
|
pub use self::color::{Color, ColorPropertyValue, RGBAColor};
|
||||||
|
|
76
components/style/values/generics/color.rs
Normal file
76
components/style/values/generics/color.rs
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* 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/. */
|
||||||
|
|
||||||
|
//! Generic types for color properties.
|
||||||
|
|
||||||
|
/// Ratios representing the contribution of color and currentcolor to
|
||||||
|
/// the final color value.
|
||||||
|
#[derive(Animate, Clone, Copy, Debug, MallocSizeOf, PartialEq, ToAnimatedValue)]
|
||||||
|
pub struct ComplexColorRatios {
|
||||||
|
/// Numeric color contribution.
|
||||||
|
pub bg: f32,
|
||||||
|
/// Foreground color, aka currentcolor, contribution.
|
||||||
|
pub fg: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ComplexColorRatios {
|
||||||
|
/// Ratios representing a `Numeric` color.
|
||||||
|
pub const NUMERIC: ComplexColorRatios = ComplexColorRatios { bg: 1., fg: 0. };
|
||||||
|
/// Ratios representing the `Foreground` color.
|
||||||
|
pub const FOREGROUND: ComplexColorRatios = ComplexColorRatios { bg: 0., fg: 1. };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This enum represents a combined color from a numeric color and
|
||||||
|
/// the current foreground color (currentcolor keyword).
|
||||||
|
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToAnimatedValue)]
|
||||||
|
pub enum Color<RGBA> {
|
||||||
|
/// Numeric RGBA color.
|
||||||
|
Numeric(RGBA),
|
||||||
|
|
||||||
|
/// The current foreground color.
|
||||||
|
Foreground,
|
||||||
|
|
||||||
|
/// A linear combination of numeric color and currentcolor.
|
||||||
|
/// The formula is: `color * ratios.bg + currentcolor * ratios.fg`.
|
||||||
|
Complex(RGBA, ComplexColorRatios),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<RGBA> Color<RGBA> {
|
||||||
|
/// Create a color based upon the specified ratios.
|
||||||
|
pub fn with_ratios(color: RGBA, ratios: ComplexColorRatios) -> Self {
|
||||||
|
if ratios == ComplexColorRatios::NUMERIC {
|
||||||
|
Color::Numeric(color)
|
||||||
|
} else if ratios == ComplexColorRatios::FOREGROUND {
|
||||||
|
Color::Foreground
|
||||||
|
} else {
|
||||||
|
Color::Complex(color, ratios)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a numeric color representing the given RGBA value.
|
||||||
|
pub fn rgba(color: RGBA) -> Self {
|
||||||
|
Color::Numeric(color)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a complex color value representing currentcolor.
|
||||||
|
pub fn currentcolor() -> Self {
|
||||||
|
Color::Foreground
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether it is a numeric color (no currentcolor component).
|
||||||
|
pub fn is_numeric(&self) -> bool {
|
||||||
|
matches!(*self, Color::Numeric(..))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether it is a currentcolor value (no numeric color component).
|
||||||
|
pub fn is_currentcolor(&self) -> bool {
|
||||||
|
matches!(*self, Color::Foreground)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<RGBA> From<RGBA> for Color<RGBA> {
|
||||||
|
fn from(color: RGBA) -> Self {
|
||||||
|
Self::rgba(color)
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,7 @@ pub mod basic_shape;
|
||||||
pub mod border;
|
pub mod border;
|
||||||
#[path = "box.rs"]
|
#[path = "box.rs"]
|
||||||
pub mod box_;
|
pub mod box_;
|
||||||
|
pub mod color;
|
||||||
pub mod column;
|
pub mod column;
|
||||||
pub mod counters;
|
pub mod counters;
|
||||||
pub mod effects;
|
pub mod effects;
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
use Atom;
|
use Atom;
|
||||||
pub use cssparser::{serialize_identifier, CowRcStr, Parser, SourceLocation, Token, RGBA};
|
pub use cssparser::{serialize_identifier, serialize_name, CowRcStr, Parser, SourceLocation, Token, RGBA};
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use selectors::parser::SelectorParseErrorKind;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use std::fmt::{self, Debug, Write};
|
use std::fmt::{self, Debug, Write};
|
||||||
|
@ -60,6 +60,28 @@ where
|
||||||
serialize_identifier(&ident, dest)
|
serialize_identifier(&ident, dest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Serialize a name which is represented as an Atom.
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
pub fn serialize_atom_name<W>(ident: &Atom, dest: &mut W) -> fmt::Result
|
||||||
|
where
|
||||||
|
W: Write,
|
||||||
|
{
|
||||||
|
ident.with_str(|s| serialize_name(s, dest))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Serialize a name which is represented as an Atom.
|
||||||
|
#[cfg(feature = "servo")]
|
||||||
|
pub fn serialize_atom_name<Static, W>(
|
||||||
|
ident: &::string_cache::Atom<Static>,
|
||||||
|
dest: &mut W,
|
||||||
|
) -> fmt::Result
|
||||||
|
where
|
||||||
|
Static: ::string_cache::StaticAtomSet,
|
||||||
|
W: Write,
|
||||||
|
{
|
||||||
|
serialize_name(&ident, dest)
|
||||||
|
}
|
||||||
|
|
||||||
/// Serialize a normalized value into percentage.
|
/// Serialize a normalized value into percentage.
|
||||||
pub fn serialize_percentage<W>(value: CSSFloat, dest: &mut CssWriter<W>) -> fmt::Result
|
pub fn serialize_percentage<W>(value: CSSFloat, dest: &mut CssWriter<W>) -> fmt::Result
|
||||||
where
|
where
|
||||||
|
|
|
@ -6,11 +6,12 @@
|
||||||
|
|
||||||
use Atom;
|
use Atom;
|
||||||
use cssparser::Parser;
|
use cssparser::Parser;
|
||||||
|
use custom_properties::Name as CustomPropertyName;
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use properties::{LonghandId, PropertyId, PropertyFlags, PropertyDeclarationId};
|
use properties::{LonghandId, ShorthandId, PropertyId, PropertyFlags, PropertyDeclarationId};
|
||||||
use selectors::parser::SelectorParseErrorKind;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
|
use style_traits::{CssWriter, KeywordsCollectFn, ParseError, StyleParseErrorKind, SpecifiedValueInfo, ToCss};
|
||||||
use values::{CustomIdent, KeyframesName};
|
use values::{CustomIdent, KeyframesName};
|
||||||
use values::generics::box_::AnimationIterationCount as GenericAnimationIterationCount;
|
use values::generics::box_::AnimationIterationCount as GenericAnimationIterationCount;
|
||||||
use values::generics::box_::Perspective as GenericPerspective;
|
use values::generics::box_::Perspective as GenericPerspective;
|
||||||
|
@ -18,6 +19,17 @@ use values::generics::box_::VerticalAlign as GenericVerticalAlign;
|
||||||
use values::specified::{AllowQuirks, Number};
|
use values::specified::{AllowQuirks, Number};
|
||||||
use values::specified::length::{LengthOrPercentage, NonNegativeLength};
|
use values::specified::length::{LengthOrPercentage, NonNegativeLength};
|
||||||
|
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
fn moz_display_values_enabled(context: &ParserContext) -> bool {
|
||||||
|
use gecko_bindings::structs;
|
||||||
|
use stylesheets::Origin;
|
||||||
|
context.stylesheet_origin == Origin::UserAgent ||
|
||||||
|
context.chrome_rules_enabled() ||
|
||||||
|
unsafe {
|
||||||
|
structs::StaticPrefs_sVarCache_layout_css_xul_display_values_content_enabled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq,
|
#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq,
|
||||||
SpecifiedValueInfo, ToComputedValue, ToCss)]
|
SpecifiedValueInfo, ToComputedValue, ToCss)]
|
||||||
|
@ -41,9 +53,9 @@ pub enum Display {
|
||||||
TableCaption,
|
TableCaption,
|
||||||
ListItem,
|
ListItem,
|
||||||
None,
|
None,
|
||||||
#[css(aliases = "-webkit-flex")]
|
#[parse(aliases = "-webkit-flex")]
|
||||||
Flex,
|
Flex,
|
||||||
#[css(aliases = "-webkit-inline-flex")]
|
#[parse(aliases = "-webkit-inline-flex")]
|
||||||
InlineFlex,
|
InlineFlex,
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
Grid,
|
Grid,
|
||||||
|
@ -72,22 +84,31 @@ pub enum Display {
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
MozInlineBox,
|
MozInlineBox,
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
#[parse(condition = "moz_display_values_enabled")]
|
||||||
MozGrid,
|
MozGrid,
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
#[parse(condition = "moz_display_values_enabled")]
|
||||||
MozInlineGrid,
|
MozInlineGrid,
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
#[parse(condition = "moz_display_values_enabled")]
|
||||||
MozGridGroup,
|
MozGridGroup,
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
#[parse(condition = "moz_display_values_enabled")]
|
||||||
MozGridLine,
|
MozGridLine,
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
#[parse(condition = "moz_display_values_enabled")]
|
||||||
MozStack,
|
MozStack,
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
#[parse(condition = "moz_display_values_enabled")]
|
||||||
MozInlineStack,
|
MozInlineStack,
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
#[parse(condition = "moz_display_values_enabled")]
|
||||||
MozDeck,
|
MozDeck,
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
#[parse(condition = "moz_display_values_enabled")]
|
||||||
MozPopup,
|
MozPopup,
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
#[parse(condition = "moz_display_values_enabled")]
|
||||||
MozGroupbox,
|
MozGroupbox,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,7 +465,7 @@ fn change_bits_for_longhand(longhand: LonghandId) -> WillChangeBits {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn change_bits_for_maybe_property(ident: &str, context: &ParserContext) -> WillChangeBits {
|
fn change_bits_for_maybe_property(ident: &str, context: &ParserContext) -> WillChangeBits {
|
||||||
let id = match PropertyId::parse(ident, context) {
|
let id = match PropertyId::parse_ignoring_rule_type(ident, context) {
|
||||||
Ok(id) => id,
|
Ok(id) => id,
|
||||||
Err(..) => return WillChangeBits::empty(),
|
Err(..) => return WillChangeBits::empty(),
|
||||||
};
|
};
|
||||||
|
@ -714,3 +735,96 @@ impl Parse for Perspective {
|
||||||
)?))
|
)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A given transition property, that is either `All`, a longhand or shorthand
|
||||||
|
/// property, or an unsupported or custom property.
|
||||||
|
#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue)]
|
||||||
|
pub enum TransitionProperty {
|
||||||
|
/// A shorthand.
|
||||||
|
Shorthand(ShorthandId),
|
||||||
|
/// A longhand transitionable property.
|
||||||
|
Longhand(LonghandId),
|
||||||
|
/// A custom property.
|
||||||
|
Custom(CustomPropertyName),
|
||||||
|
/// Unrecognized property which could be any non-transitionable, custom property, or
|
||||||
|
/// unknown property.
|
||||||
|
Unsupported(CustomIdent),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for TransitionProperty {
|
||||||
|
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||||
|
where
|
||||||
|
W: Write,
|
||||||
|
{
|
||||||
|
use values::serialize_atom_name;
|
||||||
|
match *self {
|
||||||
|
TransitionProperty::Shorthand(ref s) => s.to_css(dest),
|
||||||
|
TransitionProperty::Longhand(ref l) => l.to_css(dest),
|
||||||
|
TransitionProperty::Custom(ref name) => {
|
||||||
|
dest.write_str("--")?;
|
||||||
|
serialize_atom_name(name, dest)
|
||||||
|
}
|
||||||
|
TransitionProperty::Unsupported(ref i) => i.to_css(dest),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Parse for TransitionProperty {
|
||||||
|
fn parse<'i, 't>(
|
||||||
|
context: &ParserContext,
|
||||||
|
input: &mut Parser<'i, 't>,
|
||||||
|
) -> Result<Self, ParseError<'i>> {
|
||||||
|
let location = input.current_source_location();
|
||||||
|
let ident = input.expect_ident()?;
|
||||||
|
|
||||||
|
let id = match PropertyId::parse_ignoring_rule_type(&ident, context) {
|
||||||
|
Ok(id) => id,
|
||||||
|
Err(..) => return Ok(TransitionProperty::Unsupported(
|
||||||
|
CustomIdent::from_ident(location, ident, &["none"])?,
|
||||||
|
)),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(match id.as_shorthand() {
|
||||||
|
Ok(s) => TransitionProperty::Shorthand(s),
|
||||||
|
Err(longhand_or_custom) => {
|
||||||
|
match longhand_or_custom {
|
||||||
|
PropertyDeclarationId::Longhand(id) => TransitionProperty::Longhand(id),
|
||||||
|
PropertyDeclarationId::Custom(custom) => {
|
||||||
|
TransitionProperty::Custom(custom.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SpecifiedValueInfo for TransitionProperty {
|
||||||
|
fn collect_completion_keywords(f: KeywordsCollectFn) {
|
||||||
|
// `transition-property` can actually accept all properties and
|
||||||
|
// arbitrary identifiers, but `all` is a special one we'd like
|
||||||
|
// to list.
|
||||||
|
f(&["all"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TransitionProperty {
|
||||||
|
/// Returns `all`.
|
||||||
|
#[inline]
|
||||||
|
pub fn all() -> Self {
|
||||||
|
TransitionProperty::Shorthand(ShorthandId::All)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert TransitionProperty to nsCSSPropertyID.
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
pub fn to_nscsspropertyid(&self) -> Result<::gecko_bindings::structs::nsCSSPropertyID, ()> {
|
||||||
|
Ok(match *self {
|
||||||
|
TransitionProperty::Shorthand(ShorthandId::All) => {
|
||||||
|
::gecko_bindings::structs::nsCSSPropertyID::eCSSPropertyExtra_all_properties
|
||||||
|
}
|
||||||
|
TransitionProperty::Shorthand(ref id) => id.to_nscsspropertyid(),
|
||||||
|
TransitionProperty::Longhand(ref id) => id.to_nscsspropertyid(),
|
||||||
|
TransitionProperty::Custom(..) |
|
||||||
|
TransitionProperty::Unsupported(..) => return Err(()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ use style_traits::{CssType, CssWriter, KeywordsCollectFn, ParseError, StyleParse
|
||||||
use style_traits::{SpecifiedValueInfo, ToCss, ValueParseErrorKind};
|
use style_traits::{SpecifiedValueInfo, ToCss, ValueParseErrorKind};
|
||||||
use super::AllowQuirks;
|
use super::AllowQuirks;
|
||||||
use values::computed::{Color as ComputedColor, Context, ToComputedValue};
|
use values::computed::{Color as ComputedColor, Context, ToComputedValue};
|
||||||
|
use values::generics::color::Color as GenericColor;
|
||||||
use values::specified::calc::CalcNode;
|
use values::specified::calc::CalcNode;
|
||||||
|
|
||||||
/// Specified color value
|
/// Specified color value
|
||||||
|
@ -88,11 +89,11 @@ impl<'a, 'b: 'a, 'i: 'a> ::cssparser::ColorComponentParser<'i> for ColorComponen
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(AngleOrNumber::Angle { degrees })
|
Ok(AngleOrNumber::Angle { degrees })
|
||||||
},
|
}
|
||||||
Token::Number { value, .. } => Ok(AngleOrNumber::Number { value }),
|
Token::Number { value, .. } => Ok(AngleOrNumber::Number { value }),
|
||||||
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
|
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
|
||||||
input.parse_nested_block(|i| CalcNode::parse_angle_or_number(self.0, i))
|
input.parse_nested_block(|i| CalcNode::parse_angle_or_number(self.0, i))
|
||||||
},
|
}
|
||||||
t => return Err(location.new_unexpected_token_error(t)),
|
t => return Err(location.new_unexpected_token_error(t)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,10 +120,10 @@ impl<'a, 'b: 'a, 'i: 'a> ::cssparser::ColorComponentParser<'i> for ColorComponen
|
||||||
Token::Number { value, .. } => Ok(NumberOrPercentage::Number { value }),
|
Token::Number { value, .. } => Ok(NumberOrPercentage::Number { value }),
|
||||||
Token::Percentage { unit_value, .. } => {
|
Token::Percentage { unit_value, .. } => {
|
||||||
Ok(NumberOrPercentage::Percentage { unit_value })
|
Ok(NumberOrPercentage::Percentage { unit_value })
|
||||||
},
|
}
|
||||||
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
|
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
|
||||||
input.parse_nested_block(|i| CalcNode::parse_number_or_percentage(self.0, i))
|
input.parse_nested_block(|i| CalcNode::parse_number_or_percentage(self.0, i))
|
||||||
},
|
}
|
||||||
t => return Err(location.new_unexpected_token_error(t)),
|
t => return Err(location.new_unexpected_token_error(t)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,10 +169,10 @@ impl Parse for Color {
|
||||||
Err(e.location.new_custom_error(StyleParseErrorKind::ValueError(
|
Err(e.location.new_custom_error(StyleParseErrorKind::ValueError(
|
||||||
ValueParseErrorKind::InvalidColor(t),
|
ValueParseErrorKind::InvalidColor(t),
|
||||||
)))
|
)))
|
||||||
},
|
}
|
||||||
_ => Err(e),
|
_ => Err(e),
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -275,10 +276,10 @@ impl Color {
|
||||||
}
|
}
|
||||||
return parse_hash_color(ident.as_bytes())
|
return parse_hash_color(ident.as_bytes())
|
||||||
.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
},
|
}
|
||||||
ref t => {
|
ref t => {
|
||||||
return Err(location.new_unexpected_token_error(t.clone()));
|
return Err(location.new_unexpected_token_error(t.clone()));
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
if value < 0 {
|
if value < 0 {
|
||||||
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
|
@ -358,11 +359,11 @@ impl Color {
|
||||||
Keyword::MozVisitedhyperlinktext => pres_context.mVisitedLinkColor,
|
Keyword::MozVisitedhyperlinktext => pres_context.mVisitedLinkColor,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
Color::InheritFromBodyQuirk => {
|
Color::InheritFromBodyQuirk => {
|
||||||
_context.map(|context| ComputedColor::rgba(context.device().body_text_color()))
|
_context.map(|context| ComputedColor::rgba(context.device().body_text_color()))
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -372,7 +373,7 @@ impl ToComputedValue for Color {
|
||||||
|
|
||||||
fn to_computed_value(&self, context: &Context) -> ComputedColor {
|
fn to_computed_value(&self, context: &Context) -> ComputedColor {
|
||||||
let result = self.to_computed_color(Some(context)).unwrap();
|
let result = self.to_computed_color(Some(context)).unwrap();
|
||||||
if result.foreground_ratio != 0 {
|
if !result.is_numeric() {
|
||||||
if let Some(longhand) = context.for_non_inherited_property {
|
if let Some(longhand) = context.for_non_inherited_property {
|
||||||
if longhand.stores_complex_colors_lossily() {
|
if longhand.stores_complex_colors_lossily() {
|
||||||
context.rule_cache_conditions.borrow_mut().set_uncacheable();
|
context.rule_cache_conditions.borrow_mut().set_uncacheable();
|
||||||
|
@ -383,12 +384,10 @@ impl ToComputedValue for Color {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_computed_value(computed: &ComputedColor) -> Self {
|
fn from_computed_value(computed: &ComputedColor) -> Self {
|
||||||
if computed.is_numeric() {
|
match *computed {
|
||||||
Color::rgba(computed.color)
|
GenericColor::Numeric(color) => Color::rgba(color),
|
||||||
} else if computed.is_currentcolor() {
|
GenericColor::Foreground => Color::currentcolor(),
|
||||||
Color::currentcolor()
|
GenericColor::Complex(..) => Color::Complex(*computed),
|
||||||
} else {
|
|
||||||
Color::Complex(*computed)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ use super::generics::grid::{TrackList as GenericTrackList, TrackSize as GenericT
|
||||||
use values::serialize_atom_identifier;
|
use values::serialize_atom_identifier;
|
||||||
use values::specified::calc::CalcNode;
|
use values::specified::calc::CalcNode;
|
||||||
|
|
||||||
pub use properties::animated_properties::TransitionProperty;
|
|
||||||
pub use self::angle::Angle;
|
pub use self::angle::Angle;
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub use self::align::{AlignContent, AlignItems, AlignSelf, ContentDistribution};
|
pub use self::align::{AlignContent, AlignItems, AlignSelf, ContentDistribution};
|
||||||
|
@ -40,7 +39,7 @@ pub use self::font::{FontFeatureSettings, FontVariantLigatures, FontVariantNumer
|
||||||
pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XLang, XTextZoom};
|
pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XLang, XTextZoom};
|
||||||
pub use self::box_::{AnimationIterationCount, AnimationName, Contain, Display};
|
pub use self::box_::{AnimationIterationCount, AnimationName, Contain, Display};
|
||||||
pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective};
|
pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective};
|
||||||
pub use self::box_::{ScrollSnapType, TouchAction, VerticalAlign, WillChange};
|
pub use self::box_::{ScrollSnapType, TouchAction, TransitionProperty, VerticalAlign, WillChange};
|
||||||
pub use self::color::{Color, ColorPropertyValue, RGBAColor};
|
pub use self::color::{Color, ColorPropertyValue, RGBAColor};
|
||||||
pub use self::counters::{Content, ContentItem, CounterIncrement, CounterReset};
|
pub use self::counters::{Content, ContentItem, CounterIncrement, CounterReset};
|
||||||
pub use self::effects::{BoxShadow, Filter, SimpleShadow};
|
pub use self::effects::{BoxShadow, Filter, SimpleShadow};
|
||||||
|
|
|
@ -40,7 +40,7 @@ pub fn derive_to_animated_value(stream: TokenStream) -> TokenStream {
|
||||||
to_animated_value::derive(input).into()
|
to_animated_value::derive(input).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[proc_macro_derive(Parse, attributes(css))]
|
#[proc_macro_derive(Parse, attributes(css, parse))]
|
||||||
pub fn derive_parse(stream: TokenStream) -> TokenStream {
|
pub fn derive_parse(stream: TokenStream) -> TokenStream {
|
||||||
let input = syn::parse(stream).unwrap();
|
let input = syn::parse(stream).unwrap();
|
||||||
parse::derive(input).into()
|
parse::derive(input).into()
|
||||||
|
@ -64,7 +64,7 @@ pub fn derive_to_css(stream: TokenStream) -> TokenStream {
|
||||||
to_css::derive(input).into()
|
to_css::derive(input).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[proc_macro_derive(SpecifiedValueInfo, attributes(css, value_info))]
|
#[proc_macro_derive(SpecifiedValueInfo, attributes(css, parse, value_info))]
|
||||||
pub fn derive_specified_value_info(stream: TokenStream) -> TokenStream {
|
pub fn derive_specified_value_info(stream: TokenStream) -> TokenStream {
|
||||||
let input = syn::parse(stream).unwrap();
|
let input = syn::parse(stream).unwrap();
|
||||||
specified_value_info::derive(input).into()
|
specified_value_info::derive(input).into()
|
||||||
|
|
|
@ -4,14 +4,22 @@
|
||||||
|
|
||||||
use cg;
|
use cg;
|
||||||
use quote::Tokens;
|
use quote::Tokens;
|
||||||
use syn::DeriveInput;
|
use syn::{DeriveInput, Path};
|
||||||
use synstructure;
|
use synstructure;
|
||||||
use to_css::CssVariantAttrs;
|
use to_css::CssVariantAttrs;
|
||||||
|
|
||||||
|
#[darling(attributes(parse), default)]
|
||||||
|
#[derive(Default, FromVariant)]
|
||||||
|
pub struct ParseVariantAttrs {
|
||||||
|
pub aliases: Option<String>,
|
||||||
|
pub condition: Option<Path>,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn derive(input: DeriveInput) -> Tokens {
|
pub fn derive(input: DeriveInput) -> Tokens {
|
||||||
let name = &input.ident;
|
let name = &input.ident;
|
||||||
let s = synstructure::Structure::new(&input);
|
let s = synstructure::Structure::new(&input);
|
||||||
|
|
||||||
|
let mut saw_condition = false;
|
||||||
let match_body = s.variants().iter().fold(quote!(), |match_body, variant| {
|
let match_body = s.variants().iter().fold(quote!(), |match_body, variant| {
|
||||||
let bindings = variant.bindings();
|
let bindings = variant.bindings();
|
||||||
assert!(
|
assert!(
|
||||||
|
@ -19,23 +27,31 @@ pub fn derive(input: DeriveInput) -> Tokens {
|
||||||
"Parse is only supported for single-variant enums for now"
|
"Parse is only supported for single-variant enums for now"
|
||||||
);
|
);
|
||||||
|
|
||||||
let variant_attrs = cg::parse_variant_attrs_from_ast::<CssVariantAttrs>(&variant.ast());
|
let css_variant_attrs =
|
||||||
if variant_attrs.skip {
|
cg::parse_variant_attrs_from_ast::<CssVariantAttrs>(&variant.ast());
|
||||||
|
let parse_attrs =
|
||||||
|
cg::parse_variant_attrs_from_ast::<ParseVariantAttrs>(&variant.ast());
|
||||||
|
if css_variant_attrs.skip {
|
||||||
return match_body;
|
return match_body;
|
||||||
}
|
}
|
||||||
|
|
||||||
let identifier = cg::to_css_identifier(
|
let identifier = cg::to_css_identifier(
|
||||||
&variant_attrs.keyword.unwrap_or(variant.ast().ident.as_ref().into()),
|
&css_variant_attrs.keyword.unwrap_or(variant.ast().ident.as_ref().into()),
|
||||||
);
|
);
|
||||||
let ident = &variant.ast().ident;
|
let ident = &variant.ast().ident;
|
||||||
|
|
||||||
let mut body = quote! {
|
saw_condition |= parse_attrs.condition.is_some();
|
||||||
#match_body
|
let condition = match parse_attrs.condition {
|
||||||
#identifier => Ok(#name::#ident),
|
Some(ref p) => quote! { if #p(context) },
|
||||||
|
None => quote! { },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut body = quote! {
|
||||||
|
#match_body
|
||||||
|
#identifier #condition => Ok(#name::#ident),
|
||||||
|
};
|
||||||
|
|
||||||
let aliases = match variant_attrs.aliases {
|
let aliases = match parse_attrs.aliases {
|
||||||
Some(aliases) => aliases,
|
Some(aliases) => aliases,
|
||||||
None => return body,
|
None => return body,
|
||||||
};
|
};
|
||||||
|
@ -43,25 +59,51 @@ pub fn derive(input: DeriveInput) -> Tokens {
|
||||||
for alias in aliases.split(",") {
|
for alias in aliases.split(",") {
|
||||||
body = quote! {
|
body = quote! {
|
||||||
#body
|
#body
|
||||||
#alias => Ok(#name::#ident),
|
#alias #condition => Ok(#name::#ident),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
body
|
body
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let context_ident = if saw_condition {
|
||||||
|
quote! { context }
|
||||||
|
} else {
|
||||||
|
quote! { _ }
|
||||||
|
};
|
||||||
|
|
||||||
|
let parse_body = if saw_condition {
|
||||||
|
quote! {
|
||||||
|
let location = input.current_source_location();
|
||||||
|
let ident = input.expect_ident()?;
|
||||||
|
match_ignore_ascii_case! { &ident,
|
||||||
|
#match_body
|
||||||
|
_ => Err(location.new_unexpected_token_error(
|
||||||
|
::cssparser::Token::Ident(ident.clone())
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! { Self::parse(input) }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
let parse_trait_impl = quote! {
|
let parse_trait_impl = quote! {
|
||||||
impl ::parser::Parse for #name {
|
impl ::parser::Parse for #name {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn parse<'i, 't>(
|
fn parse<'i, 't>(
|
||||||
_: &::parser::ParserContext,
|
#context_ident: &::parser::ParserContext,
|
||||||
input: &mut ::cssparser::Parser<'i, 't>,
|
input: &mut ::cssparser::Parser<'i, 't>,
|
||||||
) -> Result<Self, ::style_traits::ParseError<'i>> {
|
) -> Result<Self, ::style_traits::ParseError<'i>> {
|
||||||
Self::parse(input)
|
#parse_body
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if saw_condition {
|
||||||
|
return parse_trait_impl;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(emilio): It'd be nice to get rid of these, but that makes the
|
// TODO(emilio): It'd be nice to get rid of these, but that makes the
|
||||||
// conversion harder...
|
// conversion harder...
|
||||||
let methods_impl = quote! {
|
let methods_impl = quote! {
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* 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 cg;
|
use cg;
|
||||||
|
use parse::ParseVariantAttrs;
|
||||||
use quote::Tokens;
|
use quote::Tokens;
|
||||||
use syn::{Data, DeriveInput, Fields, Ident, Type};
|
use syn::{Data, DeriveInput, Fields, Ident, Type};
|
||||||
use to_css::{CssFieldAttrs, CssInputAttrs, CssVariantAttrs};
|
use to_css::{CssFieldAttrs, CssInputAttrs, CssVariantAttrs};
|
||||||
|
@ -33,10 +34,11 @@ pub fn derive(mut input: DeriveInput) -> Tokens {
|
||||||
for v in e.variants.iter() {
|
for v in e.variants.iter() {
|
||||||
let css_attrs = cg::parse_variant_attrs::<CssVariantAttrs>(&v);
|
let css_attrs = cg::parse_variant_attrs::<CssVariantAttrs>(&v);
|
||||||
let info_attrs = cg::parse_variant_attrs::<ValueInfoVariantAttrs>(&v);
|
let info_attrs = cg::parse_variant_attrs::<ValueInfoVariantAttrs>(&v);
|
||||||
|
let parse_attrs = cg::parse_variant_attrs::<ParseVariantAttrs>(&v);
|
||||||
if css_attrs.skip {
|
if css_attrs.skip {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if let Some(aliases) = css_attrs.aliases {
|
if let Some(aliases) = parse_attrs.aliases {
|
||||||
for alias in aliases.split(",") {
|
for alias in aliases.split(",") {
|
||||||
values.push(alias.to_string());
|
values.push(alias.to_string());
|
||||||
}
|
}
|
||||||
|
|
|
@ -234,7 +234,6 @@ pub struct CssVariantAttrs {
|
||||||
pub comma: bool,
|
pub comma: bool,
|
||||||
pub dimension: bool,
|
pub dimension: bool,
|
||||||
pub keyword: Option<String>,
|
pub keyword: Option<String>,
|
||||||
pub aliases: Option<String>,
|
|
||||||
pub skip: bool,
|
pub skip: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -177,7 +177,11 @@ pub enum ValueParseErrorKind<'i> {
|
||||||
|
|
||||||
impl<'i> StyleParseErrorKind<'i> {
|
impl<'i> StyleParseErrorKind<'i> {
|
||||||
/// Create an InvalidValue parse error
|
/// Create an InvalidValue parse error
|
||||||
pub fn new_invalid(name: CowRcStr<'i>, value_error: ParseError<'i>) -> ParseError<'i> {
|
pub fn new_invalid<S>(name: S, value_error: ParseError<'i>) -> ParseError<'i>
|
||||||
|
where
|
||||||
|
S: Into<CowRcStr<'i>>,
|
||||||
|
{
|
||||||
|
let name = name.into();
|
||||||
let variant = match value_error.kind {
|
let variant = match value_error.kind {
|
||||||
cssparser::ParseErrorKind::Custom(StyleParseErrorKind::ValueError(e)) => {
|
cssparser::ParseErrorKind::Custom(StyleParseErrorKind::ValueError(e)) => {
|
||||||
match e {
|
match e {
|
||||||
|
|
|
@ -43,7 +43,7 @@ pub type KeywordsCollectFn<'a> = &'a mut FnMut(&[&'static str]);
|
||||||
/// name is listed in `collect_completion_keywords`.
|
/// name is listed in `collect_completion_keywords`.
|
||||||
/// * If `#[css(skip)]` is found, the content inside the variant or
|
/// * If `#[css(skip)]` is found, the content inside the variant or
|
||||||
/// field is ignored.
|
/// field is ignored.
|
||||||
/// * Values listed in `#[css(if_empty)]`, `#[css(aliases)]`, and
|
/// * Values listed in `#[css(if_empty)]`, `#[parse(aliases)]`, and
|
||||||
/// `#[css(keyword)]` are added into `collect_completion_keywords`.
|
/// `#[css(keyword)]` are added into `collect_completion_keywords`.
|
||||||
///
|
///
|
||||||
/// In addition to `css` attributes, it also has `value_info` helper
|
/// In addition to `css` attributes, it also has `value_info` helper
|
||||||
|
|
|
@ -39,13 +39,9 @@ num = [
|
||||||
# Ignored packages with duplicated versions
|
# Ignored packages with duplicated versions
|
||||||
packages = [
|
packages = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"itoa",
|
|
||||||
"log",
|
"log",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"quote",
|
|
||||||
"rand",
|
"rand",
|
||||||
"syn",
|
|
||||||
"unicode-xid",
|
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
# Files that are ignored for all tidy and lint checks.
|
# Files that are ignored for all tidy and lint checks.
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[currentcolor-animation-001.html]
|
|
||||||
type: testharness
|
|
||||||
[currentcolortransition]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue