diff --git a/Cargo.lock b/Cargo.lock index edbc9cb1bdc..ee14093c660 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -454,6 +454,14 @@ dependencies = [ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cmake" version = "0.1.29" @@ -603,6 +611,18 @@ dependencies = [ "build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "crossbeam-channel" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crossbeam-deque" version = "0.2.0" @@ -626,6 +646,19 @@ dependencies = [ "scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "crossbeam-epoch" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayvec 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crossbeam-utils" version = "0.2.2" @@ -634,6 +667,11 @@ dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "crossbeam-utils" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "cssparser" version = "0.24.0" @@ -899,7 +937,7 @@ version = "0.3.0" source = "git+https://github.com/energymon/energymon-sys.git#f8d77ea2906b25f9c0fd358aa9d300a46dc3e97c" dependencies = [ "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -973,7 +1011,7 @@ version = "2.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1191,7 +1229,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1218,7 +1256,7 @@ dependencies = [ "wayland-client 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "winit 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", - "x11-dl 2.18.1 (registry+https://github.com/rust-lang/crates.io-index)", + "x11-dl 2.18.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1238,7 +1276,7 @@ dependencies = [ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1284,7 +1322,7 @@ dependencies = [ "gstreamer-base-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "gstreamer-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1313,7 +1351,7 @@ dependencies = [ "gstreamer-base-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "gstreamer-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1340,7 +1378,7 @@ dependencies = [ "gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "gstreamer-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1369,7 +1407,7 @@ dependencies = [ "gstreamer-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "gstreamer-video-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1381,7 +1419,7 @@ dependencies = [ "glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1412,7 +1450,7 @@ dependencies = [ "gstreamer-base-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "gstreamer-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1432,7 +1470,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "freetype 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1459,7 +1497,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1623,12 +1661,29 @@ dependencies = [ "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ipc-channel" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-channel 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "uuid 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "itertools" version = "0.7.6" @@ -1844,7 +1899,7 @@ name = "libdbus-sys" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1921,7 +1976,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2135,7 +2190,7 @@ dependencies = [ [[package]] name = "mio" -version = "0.6.12" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2144,10 +2199,10 @@ dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2157,7 +2212,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2285,14 +2340,12 @@ dependencies = [ [[package]] name = "net2" -version = "0.2.29" +version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2491,7 +2544,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2566,7 +2619,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "petgraph" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2610,7 +2663,7 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.12" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2752,6 +2805,23 @@ dependencies = [ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "range" version = "0.0.1" @@ -2780,7 +2850,7 @@ dependencies = [ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3182,7 +3252,7 @@ version = "4.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "expat-sys 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "servo-freetype-sys 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3192,13 +3262,13 @@ version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "servo-media" version = "0.1.0" -source = "git+https://github.com/servo/media#6ecac1c6259b3995e8d6a368e49777e5c2d398ae" +source = "git+https://github.com/servo/media#44ad355b020168e78ab32db2c6f5286e7db2ba77" dependencies = [ "servo-media-audio 0.1.0 (git+https://github.com/servo/media)", "servo-media-gstreamer 0.1.0 (git+https://github.com/servo/media)", @@ -3208,12 +3278,12 @@ dependencies = [ [[package]] name = "servo-media-audio" version = "0.1.0" -source = "git+https://github.com/servo/media#6ecac1c6259b3995e8d6a368e49777e5c2d398ae" +source = "git+https://github.com/servo/media#44ad355b020168e78ab32db2c6f5286e7db2ba77" dependencies = [ "byte-slice-cast 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", "servo_media_derive 0.1.0 (git+https://github.com/servo/media)", "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3221,7 +3291,7 @@ dependencies = [ [[package]] name = "servo-media-gstreamer" version = "0.1.0" -source = "git+https://github.com/servo/media#6ecac1c6259b3995e8d6a368e49777e5c2d398ae" +source = "git+https://github.com/servo/media#44ad355b020168e78ab32db2c6f5286e7db2ba77" dependencies = [ "byte-slice-cast 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "glib 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3229,7 +3299,7 @@ dependencies = [ "gstreamer-app 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)", "gstreamer-audio 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "gstreamer-player 0.11.3 (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.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "servo-media-audio 0.1.0 (git+https://github.com/servo/media)", "servo-media-player 0.1.0 (git+https://github.com/servo/media)", @@ -3239,9 +3309,9 @@ dependencies = [ [[package]] name = "servo-media-player" version = "0.1.0" -source = "git+https://github.com/servo/media#6ecac1c6259b3995e8d6a368e49777e5c2d398ae" +source = "git+https://github.com/servo/media#44ad355b020168e78ab32db2c6f5286e7db2ba77" dependencies = [ - "ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ipc-channel 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3325,7 +3395,7 @@ dependencies = [ [[package]] name = "servo_media_derive" version = "0.1.0" -source = "git+https://github.com/servo/media#6ecac1c6259b3995e8d6a368e49777e5c2d398ae" +source = "git+https://github.com/servo/media#44ad355b020168e78ab32db2c6f5286e7db2ba77" dependencies = [ "quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3400,6 +3470,11 @@ name = "slab" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "slab" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "smallbitvec" version = "2.1.1" @@ -4115,7 +4190,7 @@ dependencies = [ "smithay-client-toolkit 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "wayland-client 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "x11-dl 2.18.1 (registry+https://github.com/rust-lang/crates.io-index)", + "x11-dl 2.18.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4135,7 +4210,7 @@ dependencies = [ "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4158,7 +4233,7 @@ version = "2.17.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4172,12 +4247,12 @@ dependencies = [ [[package]] name = "x11-dl" -version = "2.18.1" +version = "2.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4276,6 +4351,7 @@ dependencies = [ "checksum clap 2.28.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dc34bf7d5d66268b466b9852bca925ec1d2650654dab4da081e63fd230145c2e" "checksum clipboard 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b9b4623b47d8637fc9d47564583d4cc01eb8c8e34e26b2bf348bf4b036acb657" "checksum clipboard-win 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "14cc3e6c075926b96490d5f90d4a5af7be8012a4d8a8698e619655085a7641a3" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "56d741ea7a69e577f6d06b36b7dff4738f680593dc27a701ffa8506b73ce28bb" "checksum cocoa 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5cd1afb83b2de9c41e5dfedb2bcccb779d433b958404876009ae4b01746ff23" "checksum color_quant 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a475fc4af42d83d28adf72968d9bcfaf035a1a9381642d8e85d8a04957767b0d" @@ -4286,9 +4362,12 @@ dependencies = [ "checksum core-graphics 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92801c908ea6301ae619ed842a72e01098085fc321b9c2f3f833dad555bba055" "checksum core-text 11.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "157ff38a92496dc676ce36d9124554e9ac66f1c1039f952690ac64f71cfa5968" "checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" +"checksum crossbeam-channel 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6c0a94250b0278d7fc5a894c3d276b11ea164edc8bf8feb10ca1ea517b44a649" "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.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30fecfcac6abfef8771151f8be4abc9e4edc112c2bcb233314cafde2680536e9" "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" +"checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015" "checksum cssparser 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)" = "495beddc39b1987b8e9f029354eccbd5ef88eb5f1cd24badb764dce338acf2e0" "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" @@ -4373,6 +4452,7 @@ dependencies = [ "checksum io-surface 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9a33981dff54baaff80f4decb487a65d148a3c00facc97820d0f09128f74dd" "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.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd75debad4ffd295c00c6e3634d254df30050b0837a85e5cd039ac424365f24a" "checksum itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b07332223953b5051bceb67e8c4700aa65291535568e1f12408c43c4a42c0394" "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" @@ -4406,7 +4486,7 @@ dependencies = [ "checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4" "checksum miniz_oxide 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9ba430291c9d6cedae28bcd2d49d1c32fc57d60cd49086646c5dd5673a870eb5" "checksum miniz_oxide_c_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5a5b8234d6103ebfba71e29786da4608540f862de5ce980a1c94f86a40ca0d51" -"checksum mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "75f72a93f046f1517e3cfddc0a096eb756a2ba727d36edc8227dee769a50a9b0" +"checksum mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)" = "4fcfcb32d63961fb6f367bfd5d21e4600b92cd310f71f9dca25acae196eb1560" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum mitochondria 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9de3eca27871df31c33b807f834b94ef7d000956f57aa25c5aed9c5f0aae8f6f" "checksum mozangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "45a8a18a41cfab0fde25cc2f43ea89064d211a0fbb33225b8ff93ab20406e0e7" @@ -4416,7 +4496,7 @@ dependencies = [ "checksum mp4parse 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7316728464443fe5793a805dde3257864e9690cf46374daff3ce93de1df2f254" "checksum msdos_time 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aad9dfe950c057b1bfe9c1f2aa51583a8468ef2a5baba2ebbe06d775efeb7729" "checksum muldiv 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1cbef5aa2e8cd82a18cc20e26434cc9843e1ef46e55bfabe5bddb022236c5b3e" -"checksum net2 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)" = "bc01404e7568680f1259aa5729539f221cb1e6d047a0d9053cab4be8a73b5d67" +"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum new-ordered-float 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8ccbebba6fb53a6d2bdcfaf79cb339bc136dee3bfff54dc337a334bafe36476a" "checksum new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cdc457076c78ab54d5e0d6fa7c47981757f1e34dc39ff92787f217dede586c4" "checksum nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37e713a259ff641624b6cb20e3b12b2952313ba36b6823c0f16e6cfd9e5de17" @@ -4446,12 +4526,12 @@ dependencies = [ "checksum parking_lot_core 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "538ef00b7317875071d5e00f603f24d16f0b474c1a5fc0ccb8b454ca72eafa79" "checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" "checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356" -"checksum petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "8b30dc85588cd02b9b76f5e386535db546d21dc68506cff2abebee0b6445e8e4" +"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" "checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc" "checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f" "checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03" "checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2" -"checksum pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)" = "6a52e4dbc8354505ee07e484ab07127e06d87ca6fa7f0a516a2b294e5ad5ad16" +"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" "checksum plane-split 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ff3a4fc9e31d70eb6828e9a2d7a401a824d9f281686a39a8fc06f08796edb1bb" "checksum png 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f54b9600d584d3b8a739e1662a595fab051329eff43f20e7d8cc22872962145b" "checksum podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "780fb4b6698bbf9cf2444ea5d22411cef2953f0824b98f33cf454ec5615645bd" @@ -4464,6 +4544,8 @@ dependencies = [ "checksum quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e44651a0dc4cdd99f71c83b561e221f714912d11af1a4dff0631f923d53af035" "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.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" +"checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2" "checksum rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "485541959c8ecc49865526fe6c4de9653dd6e60d829d6edf0be228167b60372d" "checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8" "checksum redox_syscall 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "29dbdfd4b9df8ab31dec47c6087b7b13cbf4a776f335e4de8efba8288dda075b" @@ -4504,6 +4586,7 @@ dependencies = [ "checksum signpost 0.1.0 (git+https://github.com/pcwalton/signpost.git)" = "" "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.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d" "checksum smallbitvec 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c63726029f0069f88467873e47f392575f28f9f16b72ac65465263db4b3a13c" "checksum smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "26df3bb03ca5eac2e64192b723d51f56c1b1e0860e7c766281f4598f181acdc8" "checksum smithay-client-toolkit 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2051bffc6cbf271176e8ba1527f801b6444567daee15951ff5152aaaf7777b2f" @@ -4573,7 +4656,7 @@ dependencies = [ "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum x11 2.17.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e5c4ac579b5d324dc4add02312b5d0e3e0218521e2d5779d526ac39ee4bb171" "checksum x11-clipboard 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2e7374c7699210cca7084ca61d57e09640fc744d1391808cb9ae2fe4ca9bd1df" -"checksum x11-dl 2.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "966f78e9291e51d573bd3dd9287b285c0265daa8aa9fbe74c370467baa360c4e" +"checksum x11-dl 2.18.3 (registry+https://github.com/rust-lang/crates.io-index)" = "940586acb859ea05c53971ac231685799a7ec1dee66ac0bccc0e6ad96e06b4e3" "checksum xcb 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5e917a3f24142e9ff8be2414e36c649d47d6cc2ba81f16201cdef96e533e02de" "checksum xi-unicode 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "12ea8eda4b1eb72f02d148402e23832d56a33f55d8c1b2d5bcdde91d79d47cb1" "checksum xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c1cb601d29fe2c2ac60a2b2e5e293994d87a1f6fa9687a31a15270f909be9c2" diff --git a/README.md b/README.md index e7d5671a54a..db98506d280 100644 --- a/README.md +++ b/README.md @@ -101,9 +101,10 @@ If `virtualenv` does not exist, try `python-virtualenv`. ``` sh sudo dnf install curl libtool gcc-c++ libXi-devel \ freetype-devel mesa-libGL-devel mesa-libEGL-devel glib2-devel libX11-devel libXrandr-devel gperf \ - fontconfig-devel cabextract ttmkfdir python python-virtualenv python-pip expat-devel \ + fontconfig-devel cabextract ttmkfdir python2 python2-virtualenv python2-pip expat-devel \ rpm-build openssl-devel cmake bzip2-devel libXcursor-devel libXmu-devel mesa-libOSMesa-devel \ - dbus-devel ncurses-devel harfbuzz-devel ccache mesa-libGLU-devel clang clang-libs gstreamer autoconf213 + dbus-devel ncurses-devel harfbuzz-devel ccache mesa-libGLU-devel clang clang-libs gstreamer1-devel \ + gstreamer1-plugins-base-devel gstreamer1-plugins-bad-free-devel autoconf213 ``` #### On CentOS @@ -132,13 +133,13 @@ export LIBCLANG_PATH=/opt/rh/llvm-toolset-7/root/usr/lib64 sudo zypper install libX11-devel libexpat-devel libbz2-devel Mesa-libEGL-devel Mesa-libGL-devel cabextract cmake \ dbus-1-devel fontconfig-devel freetype-devel gcc-c++ git glib2-devel gperf \ harfbuzz-devel libOSMesa-devel libXcursor-devel libXi-devel libXmu-devel libXrandr-devel libopenssl-devel \ - python-pip python-virtualenv rpm-build glu-devel ccache llvm-clang libclang + python-pip python-virtualenv rpm-build glu-devel ccache llvm-clang libclang ``` #### On Arch Linux ``` sh sudo pacman -S --needed base-devel git python2 python2-virtualenv python2-pip mesa cmake bzip2 libxmu glu \ - pkg-config ttf-fira-sans harfbuzz ccache clang + pkg-config ttf-fira-sans harfbuzz ccache clang autoconf2.13 ``` #### On Gentoo Linux diff --git a/appveyor.yml b/appveyor.yml index a1d34d8fe05..6be6ea70418 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -44,7 +44,7 @@ cache: - .ccache install: - - choco install pkgconfiglite + - appveyor-retry choco install pkgconfiglite - appveyor-retry appveyor DownloadFile https://gstreamer.freedesktop.org/data/pkg/windows/1.14.1/gstreamer-1.0-devel-x86_64-1.14.1.msi - appveyor-retry appveyor DownloadFile https://gstreamer.freedesktop.org/data/pkg/windows/1.14.1/gstreamer-1.0-x86_64-1.14.1.msi - msiexec /i gstreamer-1.0-devel-x86_64-1.14.1.msi /quiet /qn /norestart /log install-devel.log @@ -54,8 +54,6 @@ install: - rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain none - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin - set PKG_CONFIG_PATH=%PKG_CONFIG_PATH%;C:\gstreamer\1.0\x86_64\lib\pkgconfig - - set LIB=%LIB%;C:\gstreamer\1.0\x86_64\lib - - set LIBPATH=C:\gstreamer\1.0\x86_64\lib;%LIBPATH% - rustup -V - mach rustc --version - mach cargo --version diff --git a/components/atoms/static_atoms.txt b/components/atoms/static_atoms.txt index 0798179c151..7fbd043dc0f 100644 --- a/components/atoms/static_atoms.txt +++ b/components/atoms/static_atoms.txt @@ -36,6 +36,7 @@ invalid keydown keypress left +ltr load loadeddata loadedmetadata @@ -65,6 +66,7 @@ readystatechange reftest-wait reset right +rtl sans-serif scan screen diff --git a/components/canvas/webgl_mode/inprocess.rs b/components/canvas/webgl_mode/inprocess.rs index d8d4b4656f1..42a4a112cee 100644 --- a/components/canvas/webgl_mode/inprocess.rs +++ b/components/canvas/webgl_mode/inprocess.rs @@ -22,23 +22,38 @@ pub struct WebGLThreads(WebGLSender); impl WebGLThreads { /// Creates a new WebGLThreads object - pub fn new(gl_factory: GLContextFactory, - webrender_gl: Rc, - webrender_api_sender: webrender_api::RenderApiSender, - webvr_compositor: Option>) - -> (WebGLThreads, Box, Option>) { + pub fn new( + gl_factory: GLContextFactory, + webrender_gl: Rc, + webrender_api_sender: webrender_api::RenderApiSender, + webvr_compositor: Option>, + ) -> ( + WebGLThreads, + Box, + Option>, + ) { // This implementation creates a single `WebGLThread` for all the pipelines. - let channel = WebGLThread::start(gl_factory, - webrender_api_sender, - webvr_compositor.map(|c| WebVRRenderWrapper(c)), - PhantomData); + let channel = WebGLThread::start( + gl_factory, + webrender_api_sender, + webvr_compositor.map(|c| WebVRRenderWrapper(c)), + PhantomData, + ); let output_handler = if PREFS.is_dom_to_texture_enabled() { - Some(Box::new(OutputHandler::new(webrender_gl.clone(), channel.clone()))) + Some(Box::new(OutputHandler::new( + webrender_gl.clone(), + channel.clone(), + ))) } else { None }; - let external = WebGLExternalImageHandler::new(WebGLExternalImages::new(webrender_gl, channel.clone())); - (WebGLThreads(channel), Box::new(external), output_handler.map(|b| b as Box<_>)) + let external = + WebGLExternalImageHandler::new(WebGLExternalImages::new(webrender_gl, channel.clone())); + ( + WebGLThreads(channel), + Box::new(external), + output_handler.map(|b| b as Box<_>), + ) } /// Gets the WebGLThread handle for each script pipeline. @@ -49,7 +64,9 @@ impl WebGLThreads { /// Sends a exit message to close the WebGLThreads and release all WebGLContexts. pub fn exit(&self) -> Result<(), &'static str> { - self.0.send(WebGLMsg::Exit).map_err(|_| "Failed to send Exit message") + self.0 + .send(WebGLMsg::Exit) + .map_err(|_| "Failed to send Exit message") } } @@ -58,7 +75,10 @@ struct WebGLExternalImages { webrender_gl: Rc, webgl_channel: WebGLSender, // Used to avoid creating a new channel on each received WebRender request. - lock_channel: (WebGLSender<(u32, Size2D, usize)>, WebGLReceiver<(u32, Size2D, usize)>), + lock_channel: ( + WebGLSender<(u32, Size2D, usize)>, + WebGLReceiver<(u32, Size2D, usize)>, + ), } impl WebGLExternalImages { @@ -75,12 +95,15 @@ impl WebGLExternalImageApi for WebGLExternalImages { fn lock(&mut self, ctx_id: WebGLContextId) -> (u32, Size2D) { // WebGL Thread has it's own GL command queue that we need to synchronize with the WR GL command queue. // The WebGLMsg::Lock message inserts a fence in the WebGL command queue. - self.webgl_channel.send(WebGLMsg::Lock(ctx_id, self.lock_channel.0.clone())).unwrap(); + self.webgl_channel + .send(WebGLMsg::Lock(ctx_id, self.lock_channel.0.clone())) + .unwrap(); let (image_id, size, gl_sync) = self.lock_channel.1.recv().unwrap(); // The next glWaitSync call is run on the WR thread and it's used to synchronize the two // flows of OpenGL commands in order to avoid WR using a semi-ready WebGL texture. // glWaitSync doesn't block WR thread, it affects only internal OpenGL subsystem. - self.webrender_gl.wait_sync(gl_sync as gl::GLsync, 0, gl::TIMEOUT_IGNORED); + self.webrender_gl + .wait_sync(gl_sync as gl::GLsync, 0, gl::TIMEOUT_IGNORED); (image_id, size) } @@ -92,11 +115,17 @@ impl WebGLExternalImageApi for WebGLExternalImages { /// Custom observer used in a `WebGLThread`. impl WebGLThreadObserver for PhantomData<()> { fn on_context_create(&mut self, ctx_id: WebGLContextId, texture_id: u32, size: Size2D) { - debug!("WebGLContext created (ctx_id: {:?} texture_id: {:?} size: {:?}", ctx_id, texture_id, size); + debug!( + "WebGLContext created (ctx_id: {:?} texture_id: {:?} size: {:?}", + ctx_id, texture_id, size + ); } fn on_context_resize(&mut self, ctx_id: WebGLContextId, texture_id: u32, size: Size2D) { - debug!("WebGLContext resized (ctx_id: {:?} texture_id: {:?} size: {:?}", ctx_id, texture_id, size); + debug!( + "WebGLContext resized (ctx_id: {:?} texture_id: {:?} size: {:?}", + ctx_id, texture_id, size + ); } fn on_context_delete(&mut self, ctx_id: WebGLContextId) { @@ -104,7 +133,6 @@ impl WebGLThreadObserver for PhantomData<()> { } } - /// Wrapper to send WebVR commands used in `WebGLThread`. struct WebVRRenderWrapper(Box); @@ -120,7 +148,10 @@ struct OutputHandler { webrender_gl: Rc, webgl_channel: WebGLSender, // Used to avoid creating a new channel on each received WebRender request. - lock_channel: (WebGLSender, WebGLReceiver), + lock_channel: ( + WebGLSender, + WebGLReceiver, + ), sync_objects: FnvHashMap, } @@ -137,14 +168,24 @@ impl OutputHandler { /// Bridge between the WR frame outputs and WebGL to implement DOMToTexture synchronization. impl webrender::OutputImageHandler for OutputHandler { - fn lock(&mut self, id: webrender_api::PipelineId) -> Option<(u32, webrender_api::DeviceIntSize)> { + fn lock( + &mut self, + id: webrender_api::PipelineId, + ) -> Option<(u32, webrender_api::DeviceIntSize)> { // Insert a fence in the WR command queue - let gl_sync = self.webrender_gl.fence_sync(gl::SYNC_GPU_COMMANDS_COMPLETE, 0); + let gl_sync = self + .webrender_gl + .fence_sync(gl::SYNC_GPU_COMMANDS_COMPLETE, 0); // The lock command adds a WaitSync call on the WebGL command flow. let command = DOMToTextureCommand::Lock(id, gl_sync as usize, self.lock_channel.0.clone()); - self.webgl_channel.send(WebGLMsg::DOMToTextureCommand(command)).unwrap(); + self.webgl_channel + .send(WebGLMsg::DOMToTextureCommand(command)) + .unwrap(); self.lock_channel.1.recv().unwrap().map(|(tex_id, size)| { - (tex_id, webrender_api::DeviceIntSize::new(size.width, size.height)) + ( + tex_id, + webrender_api::DeviceIntSize::new(size.width, size.height), + ) }) } diff --git a/components/canvas/webgl_thread.rs b/components/canvas/webgl_thread.rs index 7430145e5ee..efbb4ca71c5 100644 --- a/components/canvas/webgl_thread.rs +++ b/components/canvas/webgl_thread.rs @@ -7,8 +7,8 @@ use canvas_traits::webgl::*; use euclid::Size2D; use fnv::FnvHashMap; use gleam::gl; +use ipc_channel::ipc::IpcBytesSender; use offscreen_gl_context::{GLContext, GLContextAttributes, GLLimits, NativeGLContextMethods}; -use serde_bytes::ByteBuf; use std::thread; use super::gl_context::{GLContextFactory, GLContextWrapper}; use webrender; @@ -659,10 +659,12 @@ impl WebGLImpl { ctx.gl().blend_func(src, dest), WebGLCommand::BlendFuncSeparate(src_rgb, dest_rgb, src_alpha, dest_alpha) => ctx.gl().blend_func_separate(src_rgb, dest_rgb, src_alpha, dest_alpha), - WebGLCommand::BufferData(buffer_type, ref data, usage) => - gl::buffer_data(ctx.gl(), buffer_type, data, usage), - WebGLCommand::BufferSubData(buffer_type, offset, ref data) => - gl::buffer_sub_data(ctx.gl(), buffer_type, offset, data), + WebGLCommand::BufferData(buffer_type, ref receiver, usage) => { + gl::buffer_data(ctx.gl(), buffer_type, &receiver.recv().unwrap(), usage) + }, + WebGLCommand::BufferSubData(buffer_type, offset, ref receiver) => { + gl::buffer_sub_data(ctx.gl(), buffer_type, offset, &receiver.recv().unwrap()) + }, WebGLCommand::Clear(mask) => ctx.gl().clear(mask), WebGLCommand::ClearColor(r, g, b, a) => @@ -711,8 +713,9 @@ impl WebGLImpl { ctx.gl().pixel_store_i(name, val), WebGLCommand::PolygonOffset(factor, units) => ctx.gl().polygon_offset(factor, units), - WebGLCommand::ReadPixels(x, y, width, height, format, pixel_type, ref chan) => - Self::read_pixels(ctx.gl(), x, y, width, height, format, pixel_type, chan), + WebGLCommand::ReadPixels(x, y, width, height, format, pixel_type, ref chan) => { + Self::read_pixels(ctx.gl(), x, y, width, height, format, pixel_type, chan) + } WebGLCommand::RenderbufferStorage(target, format, width, height) => ctx.gl().renderbuffer_storage(target, format, width, height), WebGLCommand::SampleCoverage(value, invert) => @@ -831,11 +834,32 @@ impl WebGLImpl { WebGLCommand::SetViewport(x, y, width, height) => { ctx.gl().viewport(x, y, width, height); } - WebGLCommand::TexImage2D(target, level, internal, width, height, format, data_type, ref data) => - ctx.gl().tex_image_2d(target, level, internal, width, height, - /*border*/0, format, data_type, Some(data)), - WebGLCommand::TexSubImage2D(target, level, xoffset, yoffset, x, y, width, height, ref data) => - ctx.gl().tex_sub_image_2d(target, level, xoffset, yoffset, x, y, width, height, data), + WebGLCommand::TexImage2D(target, level, internal, width, height, format, data_type, ref chan) => { + ctx.gl().tex_image_2d( + target, + level, + internal, + width, + height, + 0, + format, + data_type, + Some(&chan.recv().unwrap()), + ) + } + WebGLCommand::TexSubImage2D(target, level, xoffset, yoffset, x, y, width, height, ref chan) => { + ctx.gl().tex_sub_image_2d( + target, + level, + xoffset, + yoffset, + x, + y, + width, + height, + &chan.recv().unwrap(), + ) + } WebGLCommand::DrawingBufferWidth(ref sender) => sender.send(ctx.borrow_draw_buffer().unwrap().size().width).unwrap(), WebGLCommand::DrawingBufferHeight(ref sender) => @@ -1163,10 +1187,10 @@ impl WebGLImpl { height: i32, format: u32, pixel_type: u32, - chan: &WebGLSender, + chan: &IpcBytesSender, ) { let result = gl.read_pixels(x, y, width, height, format, pixel_type); - chan.send(result.into()).unwrap() + chan.send(&result).unwrap() } fn finish(gl: &gl::Gl, chan: &WebGLSender<()>) { diff --git a/components/canvas_traits/webgl.rs b/components/canvas_traits/webgl.rs index bdffd586287..57647204910 100644 --- a/components/canvas_traits/webgl.rs +++ b/components/canvas_traits/webgl.rs @@ -4,6 +4,7 @@ use euclid::Size2D; use gleam::gl; +use ipc_channel::ipc::{IpcBytesReceiver, IpcBytesSender}; use offscreen_gl_context::{GLContextAttributes, GLLimits}; use serde_bytes::ByteBuf; use std::borrow::Cow; @@ -24,7 +25,7 @@ pub use ::webgl_channel::WebGLPipeline; pub use ::webgl_channel::WebGLChan; /// WebGL Message API -#[derive(Clone, Deserialize, Serialize)] +#[derive(Deserialize, Serialize)] pub enum WebGLMsg { /// Creates a new WebGLContext. CreateContext(WebGLVersion, Size2D, GLContextAttributes, @@ -155,7 +156,7 @@ impl WebGLMsgSender { } /// WebGL Commands for a specific WebGLContext -#[derive(Clone, Debug, Deserialize, Serialize)] +#[derive(Debug, Deserialize, Serialize)] pub enum WebGLCommand { GetContextAttributes(WebGLSender), ActiveTexture(u32), @@ -167,8 +168,8 @@ pub enum WebGLCommand { AttachShader(WebGLProgramId, WebGLShaderId), DetachShader(WebGLProgramId, WebGLShaderId), BindAttribLocation(WebGLProgramId, u32, String), - BufferData(u32, ByteBuf, u32), - BufferSubData(u32, isize, ByteBuf), + BufferData(u32, IpcBytesReceiver, u32), + BufferSubData(u32, isize, IpcBytesReceiver), Clear(u32), ClearColor(f32, f32, f32, f32), ClearDepth(f32), @@ -213,7 +214,7 @@ pub enum WebGLCommand { GetRenderbufferParameter(u32, u32, WebGLSender), PolygonOffset(f32, f32), RenderbufferStorage(u32, u32, i32, i32), - ReadPixels(i32, i32, i32, i32, u32, u32, WebGLSender), + ReadPixels(i32, i32, i32, i32, u32, u32, IpcBytesSender), SampleCoverage(f32, bool), Scissor(i32, i32, i32, i32), StencilFunc(u32, i32, u32), @@ -251,8 +252,8 @@ pub enum WebGLCommand { VertexAttribPointer(u32, i32, u32, bool, i32, u32), VertexAttribPointer2f(u32, i32, bool, i32, u32), SetViewport(i32, i32, i32, i32), - TexImage2D(u32, i32, i32, i32, i32, u32, u32, ByteBuf), - TexSubImage2D(u32, i32, i32, i32, i32, i32, u32, u32, ByteBuf), + TexImage2D(u32, i32, i32, i32, i32, u32, u32, IpcBytesReceiver), + TexSubImage2D(u32, i32, i32, i32, i32, i32, u32, u32, IpcBytesReceiver), DrawingBufferWidth(WebGLSender), DrawingBufferHeight(WebGLSender), Finish(WebGLSender<()>), diff --git a/components/canvas_traits/webgl_channel/ipc.rs b/components/canvas_traits/webgl_channel/ipc.rs index ac3020bbc7a..a00ceda75ed 100644 --- a/components/canvas_traits/webgl_channel/ipc.rs +++ b/components/canvas_traits/webgl_channel/ipc.rs @@ -9,7 +9,7 @@ use std::io; pub type WebGLSender = ipc_channel::ipc::IpcSender; pub type WebGLReceiver = ipc_channel::ipc::IpcReceiver; -pub fn webgl_channel Deserialize<'de>>() - -> Result<(WebGLSender, WebGLReceiver), io::Error> { +pub fn webgl_channel Deserialize<'de>>( +) -> Result<(WebGLSender, WebGLReceiver), io::Error> { ipc_channel::ipc::channel() } diff --git a/components/canvas_traits/webgl_channel/mod.rs b/components/canvas_traits/webgl_channel/mod.rs index c7376501049..3c6bd1690b0 100644 --- a/components/canvas_traits/webgl_channel/mod.rs +++ b/components/canvas_traits/webgl_channel/mod.rs @@ -13,17 +13,27 @@ use servo_config::opts; use std::fmt; lazy_static! { - static ref IS_MULTIPROCESS: bool = { - opts::multiprocess() - }; + static ref IS_MULTIPROCESS: bool = { opts::multiprocess() }; } -#[derive(Clone, Deserialize, Serialize)] +#[derive(Deserialize, Serialize)] pub enum WebGLSender { Ipc(ipc::WebGLSender), Mpsc(mpsc::WebGLSender), } +impl Clone for WebGLSender +where + T: Serialize, +{ + fn clone(&self) -> Self { + match *self { + WebGLSender::Ipc(ref chan) => WebGLSender::Ipc(chan.clone()), + WebGLSender::Mpsc(ref chan) => WebGLSender::Mpsc(chan.clone()), + } + } +} + impl fmt::Debug for WebGLSender { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "WebGLSender(..)") @@ -34,41 +44,42 @@ impl WebGLSender { #[inline] pub fn send(&self, msg: T) -> WebGLSendResult { match *self { - WebGLSender::Ipc(ref sender) => { - sender.send(msg).map_err(|_| ()) - }, - WebGLSender::Mpsc(ref sender) => { - sender.send(msg).map_err(|_| ()) - } + WebGLSender::Ipc(ref sender) => sender.send(msg).map_err(|_| ()), + WebGLSender::Mpsc(ref sender) => sender.send(msg).map_err(|_| ()), } } } pub type WebGLSendResult = Result<(), ()>; -pub enum WebGLReceiver where T: for<'de> Deserialize<'de> + Serialize { +pub enum WebGLReceiver +where + T: for<'de> Deserialize<'de> + Serialize, +{ Ipc(ipc::WebGLReceiver), Mpsc(mpsc::WebGLReceiver), } -impl WebGLReceiver where T: for<'de> Deserialize<'de> + Serialize { +impl WebGLReceiver +where + T: for<'de> Deserialize<'de> + Serialize, +{ pub fn recv(&self) -> Result { match *self { - WebGLReceiver::Ipc(ref receiver) => { - receiver.recv().map_err(|_| ()) - }, - WebGLReceiver::Mpsc(ref receiver) => { - receiver.recv().map_err(|_| ()) - } + WebGLReceiver::Ipc(ref receiver) => receiver.recv().map_err(|_| ()), + WebGLReceiver::Mpsc(ref receiver) => receiver.recv().map_err(|_| ()), } } } pub fn webgl_channel() -> Result<(WebGLSender, WebGLReceiver), ()> - where T: for<'de> Deserialize<'de> + Serialize { +where + T: for<'de> Deserialize<'de> + Serialize, +{ if *IS_MULTIPROCESS { - ipc::webgl_channel().map(|(tx, rx)| (WebGLSender::Ipc(tx), WebGLReceiver::Ipc(rx))) - .map_err(|_| ()) + ipc::webgl_channel() + .map(|(tx, rx)| (WebGLSender::Ipc(tx), WebGLReceiver::Ipc(rx))) + .map_err(|_| ()) } else { mpsc::webgl_channel().map(|(tx, rx)| (WebGLSender::Mpsc(tx), WebGLReceiver::Mpsc(rx))) } diff --git a/components/canvas_traits/webgl_channel/mpsc.rs b/components/canvas_traits/webgl_channel/mpsc.rs index b0fe29241f3..92b83791d36 100644 --- a/components/canvas_traits/webgl_channel/mpsc.rs +++ b/components/canvas_traits/webgl_channel/mpsc.rs @@ -17,17 +17,24 @@ macro_rules! unreachable_serializable { impl<'a, T> Deserialize<'a> for $name { fn deserialize(_: D) -> Result<$name, D::Error> - where D: Deserializer<'a> { + where + D: Deserializer<'a>, + { unreachable!(); } } }; } -#[derive(Clone)] pub struct WebGLSender(mpsc::Sender); pub struct WebGLReceiver(mpsc::Receiver); +impl Clone for WebGLSender { + fn clone(&self) -> Self { + WebGLSender(self.0.clone()) + } +} + impl WebGLSender { #[inline] pub fn send(&self, data: T) -> Result<(), mpsc::SendError> { diff --git a/components/compositing/build.rs b/components/compositing/build.rs index db081f795ad..8a13f9632d7 100644 --- a/components/compositing/build.rs +++ b/components/compositing/build.rs @@ -10,24 +10,33 @@ use std::io::{Read, Write}; use std::path::Path; fn main() { - let lockfile_path = Path::new(&env::var("CARGO_MANIFEST_DIR").unwrap()).join("..").join("..").join("Cargo.lock"); - let revision_file_path = Path::new(&env::var_os("OUT_DIR").unwrap()).join("webrender_revision.rs"); + let lockfile_path = Path::new(&env::var("CARGO_MANIFEST_DIR").unwrap()) + .join("..") + .join("..") + .join("Cargo.lock"); + let revision_file_path = + Path::new(&env::var_os("OUT_DIR").unwrap()).join("webrender_revision.rs"); let mut lockfile = String::new(); - File::open(lockfile_path).expect("Cannot open lockfile") + File::open(lockfile_path) + .expect("Cannot open lockfile") .read_to_string(&mut lockfile) .expect("Failed to read lockfile"); match toml::from_str::(&lockfile) { Ok(result) => { - let packages = result.get("package").expect("Cargo lockfile should contain package list"); + let packages = result + .get("package") + .expect("Cargo lockfile should contain package list"); match *packages { toml::Value::Array(ref arr) => { let source = arr .iter() - .find(|pkg| pkg.get("name").and_then(|name| name.as_str()).unwrap_or("") == "webrender") - .and_then(|pkg| pkg.get("source").and_then(|source| source.as_str())) + .find(|pkg| { + pkg.get("name").and_then(|name| name.as_str()).unwrap_or("") == + "webrender" + }).and_then(|pkg| pkg.get("source").and_then(|source| source.as_str())) .unwrap_or("unknown"); let parsed: Vec<&str> = source.split("#").collect(); @@ -36,9 +45,9 @@ fn main() { let mut revision_module_file = File::create(&revision_file_path).unwrap(); write!(&mut revision_module_file, "{}", format!("\"{}\"", revision)).unwrap(); }, - _ => panic!("Cannot find package definitions in lockfile") + _ => panic!("Cannot find package definitions in lockfile"), } }, - Err(e) => panic!(e) + Err(e) => panic!(e), } } diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index fc775125d86..2a4845b6c2a 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -43,7 +43,6 @@ use webrender_api::{self, DeviceIntPoint, DevicePoint, HitTestFlags, HitTestResu use webrender_api::{LayoutVector2D, ScrollLocation}; use windowing::{self, EmbedderCoordinates, MouseWindowEvent, WebRenderDebugOption, WindowMethods}; - #[derive(Debug, PartialEq)] enum UnableToComposite { WindowUnprepared, @@ -251,7 +250,7 @@ enum CompositeTarget { WindowAndPng, /// Compose to a PNG, write it to disk, and then exit the browser (used for reftests) - PngFile + PngFile, } #[derive(Clone)] @@ -273,7 +272,8 @@ impl webrender_api::RenderNotifier for RenderNotifier { } fn wake_up(&self) { - self.compositor_proxy.recomposite(CompositingReason::NewWebRenderFrame); + self.compositor_proxy + .recomposite(CompositingReason::NewWebRenderFrame); } fn new_frame_ready( @@ -284,7 +284,8 @@ impl webrender_api::RenderNotifier for RenderNotifier { _render_time_ns: Option, ) { if scrolled { - self.compositor_proxy.send(Msg::NewScrollFrameReady(composite_needed)); + self.compositor_proxy + .send(Msg::NewScrollFrameReady(composite_needed)); } else { self.wake_up(); } @@ -295,7 +296,7 @@ impl IOCompositor { fn new(window: Rc, state: InitialCompositorState) -> Self { let composite_target = match opts::get().output_file { Some(_) => CompositeTarget::PngFile, - None => CompositeTarget::Window + None => CompositeTarget::Window, }; IOCompositor { @@ -372,7 +373,8 @@ impl IOCompositor { // Tell the profiler, memory profiler, and scrolling timer to shut down. if let Ok((sender, receiver)) = ipc::channel() { - self.time_profiler_chan.send(time::ProfilerMsg::Exit(sender)); + self.time_profiler_chan + .send(time::ProfilerMsg::Exit(sender)); let _ = receiver.recv(); } @@ -383,33 +385,33 @@ impl IOCompositor { match (msg, self.shutdown_state) { (_, ShutdownState::FinishedShuttingDown) => { error!("compositor shouldn't be handling messages after shutting down"); - return false - } + return false; + }, (Msg::ShutdownComplete, _) => { self.finish_shutting_down(); return false; - } + }, - (Msg::ChangeRunningAnimationsState(pipeline_id, animation_state), - ShutdownState::NotShuttingDown) => { + ( + Msg::ChangeRunningAnimationsState(pipeline_id, animation_state), + ShutdownState::NotShuttingDown, + ) => { self.change_running_animations_state(pipeline_id, animation_state); - } + }, - (Msg::SetFrameTree(frame_tree), - ShutdownState::NotShuttingDown) => { + (Msg::SetFrameTree(frame_tree), ShutdownState::NotShuttingDown) => { self.set_frame_tree(&frame_tree); self.send_viewport_rects(); - } + }, (Msg::Recomposite(reason), ShutdownState::NotShuttingDown) => { self.composition_request = CompositionRequest::CompositeNow(reason) - } - + }, (Msg::TouchEventProcessed(result), ShutdownState::NotShuttingDown) => { self.touch_handler.on_event_processed(result); - } + }, (Msg::CreatePng(reply), ShutdownState::NotShuttingDown) => { let res = self.composite_specific_target(CompositeTarget::WindowAndPng); @@ -420,15 +422,20 @@ impl IOCompositor { if let Err(e) = reply.send(img) { warn!("Sending reply to create png failed ({}).", e); } - } + }, - (Msg::ViewportConstrained(pipeline_id, constraints), - ShutdownState::NotShuttingDown) => { + ( + Msg::ViewportConstrained(pipeline_id, constraints), + ShutdownState::NotShuttingDown, + ) => { self.constrain_viewport(pipeline_id, constraints); - } + }, (Msg::IsReadyToSaveImageReply(is_ready), ShutdownState::NotShuttingDown) => { - assert_eq!(self.ready_to_save_state, ReadyState::WaitingForConstellationReply); + assert_eq!( + self.ready_to_save_state, + ReadyState::WaitingForConstellationReply + ); if is_ready { self.ready_to_save_state = ReadyState::ReadyToSaveImage; if opts::get().is_running_problem_test { @@ -441,34 +448,38 @@ impl IOCompositor { } } self.composite_if_necessary(CompositingReason::Headless); - } + }, - (Msg::PipelineVisibilityChanged(pipeline_id, visible), ShutdownState::NotShuttingDown) => { + ( + Msg::PipelineVisibilityChanged(pipeline_id, visible), + ShutdownState::NotShuttingDown, + ) => { self.pipeline_details(pipeline_id).visible = visible; if visible { self.process_animations(); } - } + }, (Msg::PipelineExited(pipeline_id, sender), _) => { debug!("Compositor got pipeline exited: {:?}", pipeline_id); self.remove_pipeline_root_layer(pipeline_id); let _ = sender.send(()); - } + }, (Msg::NewScrollFrameReady(recomposite_needed), ShutdownState::NotShuttingDown) => { self.waiting_for_results_of_scroll = false; if recomposite_needed { self.composition_request = CompositionRequest::CompositeNow( - CompositingReason::NewWebRenderScrollFrame); + CompositingReason::NewWebRenderScrollFrame, + ); } - } + }, (Msg::Dispatch(func), ShutdownState::NotShuttingDown) => { // The functions sent here right now are really dumb, so they can't panic. // But if we start running more complex code here, we should really catch panic here. func(); - } + }, (Msg::LoadComplete(_), ShutdownState::NotShuttingDown) => { // If we're painting in headless mode, schedule a recomposite. @@ -479,30 +490,30 @@ impl IOCompositor { (Msg::PendingPaintMetric(pipeline_id, epoch), _) => { self.pending_paint_metrics.insert(pipeline_id, epoch); - } + }, (Msg::GetClientWindow(req), ShutdownState::NotShuttingDown) => { if let Err(e) = req.send(self.embedder_coordinates.window) { warn!("Sending response to get client window failed ({}).", e); } - } + }, (Msg::GetScreenSize(req), ShutdownState::NotShuttingDown) => { if let Err(e) = req.send(self.embedder_coordinates.screen) { warn!("Sending response to get screen size failed ({}).", e); } - } + }, (Msg::GetScreenAvailSize(req), ShutdownState::NotShuttingDown) => { if let Err(e) = req.send(self.embedder_coordinates.screen_avail) { warn!("Sending response to get screen avail size failed ({}).", e); } - } + }, // When we are shutting_down, we need to avoid performing operations // such as Paint that may crash because we have begun tearing down // the rest of our resources. - (_, ShutdownState::ShuttingDown) => {} + (_, ShutdownState::ShuttingDown) => {}, } true @@ -522,42 +533,53 @@ impl IOCompositor { if visible { self.composite_if_necessary(CompositingReason::Animation); } - } + }, AnimationState::AnimationCallbacksPresent => { let visible = self.pipeline_details(pipeline_id).visible; - self.pipeline_details(pipeline_id).animation_callbacks_running = true; + self.pipeline_details(pipeline_id) + .animation_callbacks_running = true; if visible { self.tick_animations_for_pipeline(pipeline_id); } - } + }, AnimationState::NoAnimationsPresent => { self.pipeline_details(pipeline_id).animations_running = false; - } + }, AnimationState::NoAnimationCallbacksPresent => { - self.pipeline_details(pipeline_id).animation_callbacks_running = false; - } + self.pipeline_details(pipeline_id) + .animation_callbacks_running = false; + }, } } fn pipeline_details(&mut self, pipeline_id: PipelineId) -> &mut PipelineDetails { if !self.pipeline_details.contains_key(&pipeline_id) { - self.pipeline_details.insert(pipeline_id, PipelineDetails::new()); + self.pipeline_details + .insert(pipeline_id, PipelineDetails::new()); } - self.pipeline_details.get_mut(&pipeline_id).expect("Insert then get failed!") + self.pipeline_details + .get_mut(&pipeline_id) + .expect("Insert then get failed!") } pub fn pipeline(&self, pipeline_id: PipelineId) -> Option<&CompositionPipeline> { match self.pipeline_details.get(&pipeline_id) { Some(ref details) => details.pipeline.as_ref(), None => { - warn!("Compositor layer has an unknown pipeline ({:?}).", pipeline_id); + warn!( + "Compositor layer has an unknown pipeline ({:?}).", + pipeline_id + ); None - } + }, } } fn set_frame_tree(&mut self, frame_tree: &SendableFrameTree) { - debug!("Setting the frame tree for pipeline {}", frame_tree.pipeline.id); + debug!( + "Setting the frame tree for pipeline {}", + frame_tree.pipeline.id + ); self.root_pipeline = Some(frame_tree.pipeline.clone()); @@ -565,7 +587,8 @@ impl IOCompositor { let mut txn = webrender_api::Transaction::new(); txn.set_root_pipeline(pipeline_id); txn.generate_frame(); - self.webrender_api.send_transaction(self.webrender_document, txn); + self.webrender_api + .send_transaction(self.webrender_document, txn); self.create_pipeline_details_for_frame_tree(&frame_tree); @@ -589,10 +612,12 @@ impl IOCompositor { fn send_window_size(&self, size_type: WindowSizeType) { let dppx = self.page_zoom * self.embedder_coordinates.hidpi_factor; - self.webrender_api.set_window_parameters(self.webrender_document, - self.embedder_coordinates.framebuffer, - self.embedder_coordinates.viewport, - self.embedder_coordinates.hidpi_factor.get()); + self.webrender_api.set_window_parameters( + self.webrender_document, + self.embedder_coordinates.framebuffer, + self.embedder_coordinates.viewport, + self.embedder_coordinates.hidpi_factor.get(), + ); let initial_viewport = self.embedder_coordinates.viewport.size.to_f32() / dppx; @@ -601,9 +626,10 @@ impl IOCompositor { initial_viewport: initial_viewport, }; - let top_level_browsing_context_id = self.root_pipeline.as_ref().map(|pipeline| { - pipeline.top_level_browsing_context_id - }); + let top_level_browsing_context_id = self + .root_pipeline + .as_ref() + .map(|pipeline| pipeline.top_level_browsing_context_id); let msg = ConstellationMsg::WindowSize(top_level_browsing_context_id, data, size_type); @@ -624,7 +650,8 @@ impl IOCompositor { } if self.embedder_coordinates.viewport == old_coords.viewport && - self.embedder_coordinates.framebuffer == old_coords.framebuffer { + self.embedder_coordinates.framebuffer == old_coords.framebuffer + { return; } @@ -634,11 +661,11 @@ impl IOCompositor { pub fn on_mouse_window_event_class(&mut self, mouse_window_event: MouseWindowEvent) { if opts::get().convert_mouse_to_touch { match mouse_window_event { - MouseWindowEvent::Click(_, _) => {} + MouseWindowEvent::Click(_, _) => {}, MouseWindowEvent::MouseDown(_, p) => self.on_touch_down(TouchId(0), p), MouseWindowEvent::MouseUp(_, p) => self.on_touch_up(TouchId(0), p), } - return + return; } self.dispatch_mouse_window_event_class(mouse_window_event); @@ -687,15 +714,14 @@ impl IOCompositor { self.webrender_document, None, world_cursor, - HitTestFlags::empty() + HitTestFlags::empty(), ) - } pub fn on_mouse_window_move_event_class(&mut self, cursor: DevicePoint) { if opts::get().convert_mouse_to_touch { self.on_touch_move(TouchId(0), cursor); - return + return; } self.dispatch_mouse_window_move_event_class(cursor); @@ -720,7 +746,7 @@ impl IOCompositor { warn!("Sending event to constellation failed ({}).", e); } - if let Some(cursor) = CursorKind::from_u8(item.tag.1 as _).ok() { + if let Some(cursor) = CursorKind::from_u8(item.tag.1 as _).ok() { let msg = ConstellationMsg::SetCursor(cursor); if let Err(e) = self.constellation_chan.send(msg) { warn!("Sending event to constellation failed ({}).", e); @@ -733,8 +759,8 @@ impl IOCompositor { &self, event_type: TouchEventType, identifier: TouchId, - point: DevicePoint) - { + point: DevicePoint, + ) { let results = self.hit_test_at_point(point); if let Some(item) = results.items.first() { let event = TouchEvent( @@ -751,10 +777,12 @@ impl IOCompositor { } } - pub fn on_touch_event(&mut self, - event_type: TouchEventType, - identifier: TouchId, - location: DevicePoint) { + pub fn on_touch_event( + &mut self, + event_type: TouchEventType, + identifier: TouchId, + location: DevicePoint, + ) { match event_type { TouchEventType::Down => self.on_touch_down(identifier, location), TouchEventType::Move => self.on_touch_move(identifier, location), @@ -770,28 +798,25 @@ impl IOCompositor { fn on_touch_move(&mut self, identifier: TouchId, point: DevicePoint) { match self.touch_handler.on_touch_move(identifier, point) { - TouchAction::Scroll(delta) => { - self.on_scroll_window_event( - ScrollLocation::Delta( - LayoutVector2D::from_untyped(&delta.to_untyped()) - ), - point.cast() - ) - } + TouchAction::Scroll(delta) => self.on_scroll_window_event( + ScrollLocation::Delta(LayoutVector2D::from_untyped(&delta.to_untyped())), + point.cast(), + ), TouchAction::Zoom(magnification, scroll_delta) => { - let cursor = TypedPoint2D::new(-1, -1); // Make sure this hits the base layer. + let cursor = TypedPoint2D::new(-1, -1); // Make sure this hits the base layer. self.pending_scroll_zoom_events.push(ScrollZoomEvent { magnification: magnification, - scroll_location: ScrollLocation::Delta(webrender_api::LayoutVector2D::from_untyped( - &scroll_delta.to_untyped())), + scroll_location: ScrollLocation::Delta( + webrender_api::LayoutVector2D::from_untyped(&scroll_delta.to_untyped()), + ), cursor: cursor, event_count: 1, }); - } + }, TouchAction::DispatchEvent => { self.send_touch_event(TouchEventType::Move, identifier, point); - } - _ => {} + }, + _ => {}, } } @@ -818,24 +843,24 @@ impl IOCompositor { self.dispatch_mouse_window_event_class(MouseWindowEvent::Click(button, p)); } - pub fn on_scroll_event(&mut self, - delta: ScrollLocation, - cursor: DeviceIntPoint, - phase: TouchEventType) { + pub fn on_scroll_event( + &mut self, + delta: ScrollLocation, + cursor: DeviceIntPoint, + phase: TouchEventType, + ) { match phase { TouchEventType::Move => self.on_scroll_window_event(delta, cursor), TouchEventType::Up | TouchEventType::Cancel => { self.on_scroll_end_window_event(delta, cursor); - } + }, TouchEventType::Down => { self.on_scroll_start_window_event(delta, cursor); - } + }, } } - fn on_scroll_window_event(&mut self, - scroll_location: ScrollLocation, - cursor: DeviceIntPoint) { + fn on_scroll_window_event(&mut self, scroll_location: ScrollLocation, cursor: DeviceIntPoint) { self.in_scroll_transaction = Some(Instant::now()); self.pending_scroll_zoom_events.push(ScrollZoomEvent { magnification: 1.0, @@ -845,9 +870,11 @@ impl IOCompositor { }); } - fn on_scroll_start_window_event(&mut self, - scroll_location: ScrollLocation, - cursor: DeviceIntPoint) { + fn on_scroll_start_window_event( + &mut self, + scroll_location: ScrollLocation, + cursor: DeviceIntPoint, + ) { self.scroll_in_progress = true; self.pending_scroll_zoom_events.push(ScrollZoomEvent { magnification: 1.0, @@ -857,9 +884,11 @@ impl IOCompositor { }); } - fn on_scroll_end_window_event(&mut self, - scroll_location: ScrollLocation, - cursor: DeviceIntPoint) { + fn on_scroll_end_window_event( + &mut self, + scroll_location: ScrollLocation, + cursor: DeviceIntPoint, + ) { self.scroll_in_progress = false; self.pending_scroll_zoom_events.push(ScrollZoomEvent { magnification: 1.0, @@ -884,19 +913,20 @@ impl IOCompositor { // disregard other pending events and exit the loop. last_combined_event = Some(scroll_event); break; - } + }, }; match &mut last_combined_event { last_combined_event @ &mut None => { *last_combined_event = Some(ScrollZoomEvent { magnification: scroll_event.magnification, - scroll_location: ScrollLocation::Delta(webrender_api::LayoutVector2D::from_untyped( - &this_delta.to_untyped())), + scroll_location: ScrollLocation::Delta( + webrender_api::LayoutVector2D::from_untyped(&this_delta.to_untyped()), + ), cursor: this_cursor, event_count: 1, }) - } + }, &mut Some(ref mut last_combined_event) => { // Mac OS X sometimes delivers scroll events out of vsync during a // fling. This causes events to get bunched up occasionally, causing @@ -909,21 +939,23 @@ impl IOCompositor { let new_event_count = TypedScale::new(last_combined_event.event_count as f32); last_combined_event.scroll_location = ScrollLocation::Delta( - (delta * old_event_count + this_delta) / - new_event_count); + (delta * old_event_count + this_delta) / new_event_count, + ); } last_combined_event.magnification *= scroll_event.magnification; - } + }, } } if let Some(combined_event) = last_combined_event { let scroll_location = match combined_event.scroll_location { ScrollLocation::Delta(delta) => { - let scaled_delta = (TypedVector2D::from_untyped(&delta.to_untyped()) / self.scale) - .to_untyped(); - let calculated_delta = webrender_api::LayoutVector2D::from_untyped(&scaled_delta); - ScrollLocation::Delta(calculated_delta) + let scaled_delta = (TypedVector2D::from_untyped(&delta.to_untyped()) / + self.scale) + .to_untyped(); + let calculated_delta = + webrender_api::LayoutVector2D::from_untyped(&scaled_delta); + ScrollLocation::Delta(calculated_delta) }, // Leave ScrollLocation unchanged if it is Start or End location. sl @ ScrollLocation::Start | sl @ ScrollLocation::End => sl, @@ -938,7 +970,8 @@ impl IOCompositor { txn.set_pinch_zoom(webrender_api::ZoomFactor::new(self.pinch_zoom_level())); } txn.generate_frame(); - self.webrender_api.send_transaction(self.webrender_document, txn); + self.webrender_api + .send_transaction(self.webrender_document, txn); self.waiting_for_results_of_scroll = true } @@ -951,10 +984,10 @@ impl IOCompositor { fn process_animations(&mut self) { let mut pipeline_ids = vec![]; for (pipeline_id, pipeline_details) in &self.pipeline_details { - if (pipeline_details.animations_running || - pipeline_details.animation_callbacks_running) && - pipeline_details.visible { - pipeline_ids.push(*pipeline_id); + if (pipeline_details.animations_running || pipeline_details.animation_callbacks_running) && + pipeline_details.visible + { + pipeline_ids.push(*pipeline_id); } } let animation_state = if pipeline_ids.is_empty() { @@ -969,7 +1002,9 @@ impl IOCompositor { } fn tick_animations_for_pipeline(&mut self, pipeline_id: PipelineId) { - let animation_callbacks_running = self.pipeline_details(pipeline_id).animation_callbacks_running; + let animation_callbacks_running = self + .pipeline_details(pipeline_id) + .animation_callbacks_running; if animation_callbacks_running { let msg = ConstellationMsg::TickAnimation(pipeline_id, AnimationTickType::Script); if let Err(e) = self.constellation_chan.send(msg) { @@ -988,9 +1023,10 @@ impl IOCompositor { } fn constrain_viewport(&mut self, pipeline_id: PipelineId, constraints: ViewportConstraints) { - let is_root = self.root_pipeline.as_ref().map_or(false, |root_pipeline| { - root_pipeline.id == pipeline_id - }); + let is_root = self + .root_pipeline + .as_ref() + .map_or(false, |root_pipeline| root_pipeline.id == pipeline_id); if is_root { self.viewport_zoom = constraints.initial_zoom; @@ -1006,7 +1042,7 @@ impl IOCompositor { None => match opts::get().output_file { Some(_) => TypedScale::new(1.0), None => self.embedder_coordinates.hidpi_factor, - } + }, } } @@ -1027,8 +1063,11 @@ impl IOCompositor { } pub fn on_zoom_window_event(&mut self, magnification: f32) { - self.page_zoom = TypedScale::new((self.page_zoom.get() * magnification) - .max(MIN_ZOOM).min(MAX_ZOOM)); + self.page_zoom = TypedScale::new( + (self.page_zoom.get() * magnification) + .max(MIN_ZOOM) + .min(MAX_ZOOM), + ); self.update_zoom_transform(); self.send_window_size(WindowSizeType::Resize); self.update_page_zoom_for_webrender(); @@ -1039,7 +1078,8 @@ impl IOCompositor { let mut txn = webrender_api::Transaction::new(); txn.set_page_zoom(page_zoom); - self.webrender_api.send_transaction(self.webrender_document, txn); + self.webrender_api + .send_transaction(self.webrender_document, txn); } /// Simulate a pinch zoom @@ -1047,14 +1087,17 @@ impl IOCompositor { self.pending_scroll_zoom_events.push(ScrollZoomEvent { magnification: magnification, scroll_location: ScrollLocation::Delta(TypedVector2D::zero()), // TODO: Scroll to keep the center in view? - cursor: TypedPoint2D::new(-1, -1), // Make sure this hits the base layer. + cursor: TypedPoint2D::new(-1, -1), // Make sure this hits the base layer. event_count: 1, }); } fn send_viewport_rects(&self) { let mut scroll_states_per_pipeline = HashMap::new(); - for scroll_layer_state in self.webrender_api.get_scroll_node_state(self.webrender_document) { + for scroll_layer_state in self + .webrender_api + .get_scroll_node_state(self.webrender_document) + { let scroll_state = ScrollState { scroll_id: scroll_layer_state.id, scroll_offset: scroll_layer_state.scroll_offset.to_untyped(), @@ -1105,8 +1148,9 @@ impl IOCompositor { let mut pipeline_epochs = HashMap::new(); for (id, _) in &self.pipeline_details { let webrender_pipeline_id = id.to_webrender(); - if let Some(webrender_api::Epoch(epoch)) = self.webrender - .current_epoch(webrender_pipeline_id) { + if let Some(webrender_api::Epoch(epoch)) = + self.webrender.current_epoch(webrender_pipeline_id) + { let epoch = Epoch(epoch); pipeline_epochs.insert(*id, epoch); } @@ -1120,12 +1164,12 @@ impl IOCompositor { } self.ready_to_save_state = ReadyState::WaitingForConstellationReply; Err(NotReadyToPaint::JustNotifiedConstellation) - } + }, ReadyState::WaitingForConstellationReply => { // If waiting on a reply from the constellation to the last // query if the image is stable, then assume not ready yet. Err(NotReadyToPaint::WaitingOnConstellation) - } + }, ReadyState::ReadyToSaveImage => { // Constellation has replied at some point in the past // that the current output image is stable and ready @@ -1137,7 +1181,7 @@ impl IOCompositor { } self.ready_to_save_state = ReadyState::Unknown; Ok(()) - } + }, } } @@ -1149,7 +1193,9 @@ impl IOCompositor { self.start_shutting_down(); }, Err(e) => if opts::get().is_running_problem_test { - if e != UnableToComposite::NotReadyToPaintImage(NotReadyToPaint::WaitingOnConstellation) { + if e != UnableToComposite::NotReadyToPaintImage( + NotReadyToPaint::WaitingOnConstellation, + ) { println!("not ready to composite: {:?}", e); } }, @@ -1161,13 +1207,14 @@ impl IOCompositor { /// for some reason. If CompositeTarget is Window or Png no image data is returned; /// in the latter case the image is written directly to a file. If CompositeTarget /// is WindowAndPng Ok(Some(png::Image)) is returned. - fn composite_specific_target(&mut self, - target: CompositeTarget) - -> Result, UnableToComposite> { + fn composite_specific_target( + &mut self, + target: CompositeTarget, + ) -> Result, UnableToComposite> { let width = self.embedder_coordinates.framebuffer.width_typed(); let height = self.embedder_coordinates.framebuffer.height_typed(); if !self.window.prepare_for_composite(width, height) { - return Err(UnableToComposite::WindowUnprepared) + return Err(UnableToComposite::WindowUnprepared); } self.webrender.update(); @@ -1183,34 +1230,40 @@ impl IOCompositor { // all active animations to complete. if self.animations_active() { self.process_animations(); - return Err(UnableToComposite::NotReadyToPaintImage(NotReadyToPaint::AnimationsActive)); + return Err(UnableToComposite::NotReadyToPaintImage( + NotReadyToPaint::AnimationsActive, + )); } if let Err(result) = self.is_ready_to_paint_image_output() { - return Err(UnableToComposite::NotReadyToPaintImage(result)) + return Err(UnableToComposite::NotReadyToPaintImage(result)); } } let rt_info = match target { #[cfg(feature = "gleam")] - CompositeTarget::Window => { - gl::RenderTargetInfo::default() - } + CompositeTarget::Window => gl::RenderTargetInfo::default(), #[cfg(feature = "gleam")] - CompositeTarget::WindowAndPng | - CompositeTarget::PngFile => { + CompositeTarget::WindowAndPng | CompositeTarget::PngFile => { gl::initialize_png(&*self.window.gl(), width, height) - } + }, #[cfg(not(feature = "gleam"))] - _ => () + _ => (), }; - profile(ProfilerCategory::Compositing, None, self.time_profiler_chan.clone(), || { - debug!("compositor: compositing"); + profile( + ProfilerCategory::Compositing, + None, + self.time_profiler_chan.clone(), + || { + debug!("compositor: compositing"); - // Paint the scene. - // TODO(gw): Take notice of any errors the renderer returns! - self.webrender.render(self.embedder_coordinates.framebuffer).ok(); - }); + // Paint the scene. + // TODO(gw): Take notice of any errors the renderer returns! + self.webrender + .render(self.embedder_coordinates.framebuffer) + .ok(); + }, + ); // If there are pending paint metrics, we check if any of the painted epochs is // one of the ones that the paint metrics recorder is expecting . In that case, @@ -1222,7 +1275,9 @@ impl IOCompositor { // For each pending paint metrics pipeline id for (id, pending_epoch) in &self.pending_paint_metrics { // we get the last painted frame id from webrender - if let Some(webrender_api::Epoch(epoch)) = self.webrender.current_epoch(id.to_webrender()) { + if let Some(webrender_api::Epoch(epoch)) = + self.webrender.current_epoch(id.to_webrender()) + { // and check if it is the one the layout thread is expecting, let epoch = Epoch(epoch); if *pending_epoch != epoch { @@ -1233,7 +1288,7 @@ impl IOCompositor { if let Some(pipeline) = self.pipeline(*id) { // and inform the layout thread with the measured paint time. let msg = LayoutControlMsg::PaintMetric(epoch, paint_time); - if let Err(e) = pipeline.layout_chan.send(msg) { + if let Err(e) = pipeline.layout_chan.send(msg) { warn!("Sending PaintMetric message to layout failed ({}).", e); } } @@ -1256,27 +1311,31 @@ impl IOCompositor { bytes: ipc::IpcSharedMemory::from_bytes(&*img), id: None, }) - } + }, #[cfg(feature = "gleam")] CompositeTarget::PngFile => { let gl = &*self.window.gl(); - profile(ProfilerCategory::ImageSaving, None, self.time_profiler_chan.clone(), || { - match opts::get().output_file.as_ref() { + profile( + ProfilerCategory::ImageSaving, + None, + self.time_profiler_chan.clone(), + || match opts::get().output_file.as_ref() { Some(path) => match File::create(path) { Ok(mut file) => { let img = gl::draw_img(gl, rt_info, width, height); let dynamic_image = DynamicImage::ImageRgb8(img); - if let Err(e) = dynamic_image.write_to(&mut file, ImageFormat::PNG) { + if let Err(e) = dynamic_image.write_to(&mut file, ImageFormat::PNG) + { error!("Failed to save {} ({}).", path, e); } }, Err(e) => error!("Failed to create {} ({}).", path, e), }, None => error!("No file specified."), - } - }); + }, + ); None - } + }, #[cfg(not(feature = "gleam"))] _ => None, }; @@ -1301,7 +1360,10 @@ impl IOCompositor { } self.composition_request = CompositionRequest::CompositeNow(reason) } else if opts::get().is_running_problem_test { - println!("composition_request is already {:?}", self.composition_request); + println!( + "composition_request is already {:?}", + self.composition_request + ); } } @@ -1315,17 +1377,17 @@ impl IOCompositor { let mut found_recomposite_msg = false; while let Some(msg) = self.port.try_recv_compositor_msg() { match msg { - Msg::Recomposite(_) if found_recomposite_msg => {} + Msg::Recomposite(_) if found_recomposite_msg => {}, Msg::Recomposite(_) => { found_recomposite_msg = true; compositor_messages.push(msg) - } + }, _ => compositor_messages.push(msg), } } for msg in compositor_messages { if !self.handle_browser_message(msg) { - return false + return false; } } true @@ -1342,10 +1404,8 @@ impl IOCompositor { } match self.composition_request { - CompositionRequest::NoCompositingNecessary => {} - CompositionRequest::CompositeNow(_) => { - self.composite() - } + CompositionRequest::NoCompositingNecessary => {}, + CompositionRequest::CompositeNow(_) => self.composite(), } if !self.pending_scroll_zoom_events.is_empty() && !self.waiting_for_results_of_scroll { @@ -1368,10 +1428,10 @@ impl IOCompositor { let keep_going = self.handle_browser_message(msg); if need_recomposite { self.composite(); - break + break; } if !keep_going { - break + break; } } } @@ -1395,44 +1455,47 @@ impl IOCompositor { let flag = match option { WebRenderDebugOption::Profiler => { webrender::DebugFlags::PROFILER_DBG | - webrender::DebugFlags::GPU_TIME_QUERIES | - webrender::DebugFlags::GPU_SAMPLE_QUERIES - } - WebRenderDebugOption::TextureCacheDebug => { - webrender::DebugFlags::TEXTURE_CACHE_DBG - } - WebRenderDebugOption::RenderTargetDebug => { - webrender::DebugFlags::RENDER_TARGET_DBG - } + webrender::DebugFlags::GPU_TIME_QUERIES | + webrender::DebugFlags::GPU_SAMPLE_QUERIES + }, + WebRenderDebugOption::TextureCacheDebug => webrender::DebugFlags::TEXTURE_CACHE_DBG, + WebRenderDebugOption::RenderTargetDebug => webrender::DebugFlags::RENDER_TARGET_DBG, }; flags.toggle(flag); self.webrender.set_debug_flags(flags); let mut txn = webrender_api::Transaction::new(); txn.generate_frame(); - self.webrender_api.send_transaction(self.webrender_document, txn); + self.webrender_api + .send_transaction(self.webrender_document, txn); } pub fn capture_webrender(&mut self) { let capture_id = now().to_timespec().sec.to_string(); - let available_path = [env::current_dir(), Ok(env::temp_dir())].iter() - .filter_map(|val| val.as_ref().map(|dir| dir.join("capture_webrender").join(&capture_id)).ok()) - .find(|val| { - match create_dir_all(&val) { - Ok(_) => true, - Err(err) => { - eprintln!("Unable to create path '{:?}' for capture: {:?}", &val, err); - false - } - } + let available_path = [env::current_dir(), Ok(env::temp_dir())] + .iter() + .filter_map(|val| { + val.as_ref() + .map(|dir| dir.join("capture_webrender").join(&capture_id)) + .ok() + }).find(|val| match create_dir_all(&val) { + Ok(_) => true, + Err(err) => { + eprintln!("Unable to create path '{:?}' for capture: {:?}", &val, err); + false + }, }); match available_path { Some(capture_path) => { let revision_file_path = capture_path.join("wr.txt"); - debug!("Trying to save webrender capture under {:?}", &revision_file_path); - self.webrender_api.save_capture(capture_path, webrender_api::CaptureBits::all()); + debug!( + "Trying to save webrender capture under {:?}", + &revision_file_path + ); + self.webrender_api + .save_capture(capture_path, webrender_api::CaptureBits::all()); match File::create(revision_file_path) { Ok(mut file) => { @@ -1440,11 +1503,14 @@ impl IOCompositor { if let Err(err) = write!(&mut file, "{}", revision) { eprintln!("Unable to write webrender revision: {:?}", err) } - } - Err(err) => eprintln!("Capture triggered, creating webrender revision info skipped: {:?}", err) + }, + Err(err) => eprintln!( + "Capture triggered, creating webrender revision info skipped: {:?}", + err + ), } }, - None => eprintln!("Unable to locate path to save captures") + None => eprintln!("Unable to locate path to save captures"), } } } diff --git a/components/compositing/compositor_thread.rs b/components/compositing/compositor_thread.rs index 15fd4d31cd6..9ea2f73ab35 100644 --- a/components/compositing/compositor_thread.rs +++ b/components/compositing/compositor_thread.rs @@ -20,7 +20,6 @@ use style_traits::viewport::ViewportConstraints; use webrender; use webrender_api::{self, DeviceIntPoint, DeviceUintSize}; - /// Sends messages to the compositor. pub struct CompositorProxy { pub sender: Sender, @@ -48,7 +47,7 @@ impl Clone for CompositorProxy { /// The port that the compositor receives messages on. pub struct CompositorReceiver { - pub receiver: Receiver + pub receiver: Receiver, } impl CompositorReceiver { diff --git a/components/compositing/gl.rs b/components/compositing/gl.rs index 4c7f1261fbe..6637ef203ea 100644 --- a/components/compositing/gl.rs +++ b/components/compositing/gl.rs @@ -2,12 +2,10 @@ * 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/. */ - use gleam::gl; use image::RgbImage; use servo_geometry::DeviceUintLength; - #[derive(Default)] pub struct RenderTargetInfo { framebuffer_ids: Vec, @@ -16,7 +14,9 @@ pub struct RenderTargetInfo { } pub fn initialize_png( - gl: &gl::Gl, width: DeviceUintLength, height: DeviceUintLength + gl: &gl::Gl, + width: DeviceUintLength, + height: DeviceUintLength, ) -> RenderTargetInfo { let framebuffer_ids = gl.gen_framebuffers(1); gl.bind_framebuffer(gl::FRAMEBUFFER, framebuffer_ids[0]); @@ -24,27 +24,53 @@ pub fn initialize_png( let texture_ids = gl.gen_textures(1); gl.bind_texture(gl::TEXTURE_2D, texture_ids[0]); - gl.tex_image_2d(gl::TEXTURE_2D, 0, gl::RGB as gl::GLint, width.get() as gl::GLsizei, - height.get() as gl::GLsizei, 0, gl::RGB, gl::UNSIGNED_BYTE, None); - gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as gl::GLint); - gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as gl::GLint); + gl.tex_image_2d( + gl::TEXTURE_2D, + 0, + gl::RGB as gl::GLint, + width.get() as gl::GLsizei, + height.get() as gl::GLsizei, + 0, + gl::RGB, + gl::UNSIGNED_BYTE, + None, + ); + gl.tex_parameter_i( + gl::TEXTURE_2D, + gl::TEXTURE_MAG_FILTER, + gl::NEAREST as gl::GLint, + ); + gl.tex_parameter_i( + gl::TEXTURE_2D, + gl::TEXTURE_MIN_FILTER, + gl::NEAREST as gl::GLint, + ); - gl.framebuffer_texture_2d(gl::FRAMEBUFFER, gl::COLOR_ATTACHMENT0, gl::TEXTURE_2D, - texture_ids[0], 0); + gl.framebuffer_texture_2d( + gl::FRAMEBUFFER, + gl::COLOR_ATTACHMENT0, + gl::TEXTURE_2D, + texture_ids[0], + 0, + ); gl.bind_texture(gl::TEXTURE_2D, 0); let renderbuffer_ids = gl.gen_renderbuffers(1); let depth_rb = renderbuffer_ids[0]; gl.bind_renderbuffer(gl::RENDERBUFFER, depth_rb); - gl.renderbuffer_storage(gl::RENDERBUFFER, - gl::DEPTH_COMPONENT24, - width.get() as gl::GLsizei, - height.get() as gl::GLsizei); - gl.framebuffer_renderbuffer(gl::FRAMEBUFFER, - gl::DEPTH_ATTACHMENT, - gl::RENDERBUFFER, - depth_rb); + gl.renderbuffer_storage( + gl::RENDERBUFFER, + gl::DEPTH_COMPONENT24, + width.get() as gl::GLsizei, + height.get() as gl::GLsizei, + ); + gl.framebuffer_renderbuffer( + gl::FRAMEBUFFER, + gl::DEPTH_ATTACHMENT, + gl::RENDERBUFFER, + depth_rb, + ); RenderTargetInfo { framebuffer_ids, @@ -70,10 +96,12 @@ pub fn draw_img( gl.bind_vertex_array(0); let mut pixels = gl.read_pixels( - 0, 0, + 0, + 0, width as gl::GLsizei, height as gl::GLsizei, - gl::RGB, gl::UNSIGNED_BYTE, + gl::RGB, + gl::UNSIGNED_BYTE, ); gl.bind_framebuffer(gl::FRAMEBUFFER, 0); @@ -88,10 +116,9 @@ pub fn draw_img( for y in 0..height { let dst_start = y * stride; let src_start = (height - y - 1) * stride; - let src_slice = &orig_pixels[src_start .. src_start + stride]; - (&mut pixels[dst_start .. dst_start + stride]).clone_from_slice(&src_slice[..stride]); + let src_slice = &orig_pixels[src_start..src_start + stride]; + (&mut pixels[dst_start..dst_start + stride]).clone_from_slice(&src_slice[..stride]); } - RgbImage::from_raw(width as u32, height as u32, pixels) - .expect("Flipping image failed!") + RgbImage::from_raw(width as u32, height as u32, pixels).expect("Flipping image failed!") } diff --git a/components/compositing/touch.rs b/components/compositing/touch.rs index fd4877ead75..28a2588a91f 100644 --- a/components/compositing/touch.rs +++ b/components/compositing/touch.rs @@ -19,12 +19,15 @@ pub struct TouchHandler { #[derive(Clone, Copy, Debug)] pub struct TouchPoint { pub id: TouchId, - pub point: TypedPoint2D + pub point: TypedPoint2D, } impl TouchPoint { pub fn new(id: TouchId, point: TypedPoint2D) -> Self { - TouchPoint { id: id, point: point } + TouchPoint { + id: id, + point: point, + } } } @@ -79,22 +82,25 @@ impl TouchHandler { self.active_touch_points.push(point); self.state = match self.state { - Nothing => WaitingForScript, - Touching | Panning => Pinching, - WaitingForScript => WaitingForScript, - DefaultPrevented => DefaultPrevented, + Nothing => WaitingForScript, + Touching | Panning => Pinching, + WaitingForScript => WaitingForScript, + DefaultPrevented => DefaultPrevented, Pinching | MultiTouch => MultiTouch, }; } - pub fn on_touch_move(&mut self, id: TouchId, point: TypedPoint2D) - -> TouchAction { + pub fn on_touch_move( + &mut self, + id: TouchId, + point: TypedPoint2D, + ) -> TouchAction { let idx = match self.active_touch_points.iter_mut().position(|t| t.id == id) { Some(i) => i, None => { warn!("Got a touchmove event for a non-active touch point"); return TouchAction::NoAction; - } + }, }; let old_point = self.active_touch_points[idx].point; @@ -103,21 +109,19 @@ impl TouchHandler { let delta = point - old_point; if delta.x.abs() > TOUCH_PAN_MIN_SCREEN_PX || - delta.y.abs() > TOUCH_PAN_MIN_SCREEN_PX + delta.y.abs() > TOUCH_PAN_MIN_SCREEN_PX { self.state = Panning; TouchAction::Scroll(delta) } else { TouchAction::NoAction } - } + }, Panning => { let delta = point - old_point; TouchAction::Scroll(delta) - } - DefaultPrevented => { - TouchAction::DispatchEvent - } + }, + DefaultPrevented => TouchAction::DispatchEvent, Pinching => { let (d0, c0) = self.pinch_distance_and_center(); self.active_touch_points[idx].point = point; @@ -127,7 +131,7 @@ impl TouchHandler { let scroll_delta = c1 - c0 * TypedScale::new(magnification); TouchAction::Zoom(magnification, scroll_delta) - } + }, WaitingForScript => TouchAction::NoAction, MultiTouch => TouchAction::NoAction, Nothing => unreachable!(), @@ -141,15 +145,18 @@ impl TouchHandler { action } - pub fn on_touch_up(&mut self, id: TouchId, _point: TypedPoint2D) - -> TouchAction { + pub fn on_touch_up( + &mut self, + id: TouchId, + _point: TypedPoint2D, + ) -> TouchAction { match self.active_touch_points.iter().position(|t| t.id == id) { Some(i) => { self.active_touch_points.swap_remove(i); - } + }, None => { warn!("Got a touch up event for a non-active touch point"); - } + }, } match self.state { Touching => { @@ -157,21 +164,21 @@ impl TouchHandler { // FIXME: Don't send a click if preventDefault is called on the touchend event. self.state = Nothing; TouchAction::Click - } + }, Nothing | Panning => { self.state = Nothing; TouchAction::NoAction - } + }, Pinching => { self.state = Panning; TouchAction::NoAction - } + }, WaitingForScript | DefaultPrevented | MultiTouch => { if self.active_touch_points.is_empty() { self.state = Nothing; } TouchAction::NoAction - } + }, } } @@ -179,25 +186,25 @@ impl TouchHandler { match self.active_touch_points.iter().position(|t| t.id == id) { Some(i) => { self.active_touch_points.swap_remove(i); - } + }, None => { warn!("Got a touchcancel event for a non-active touch point"); return; - } + }, } match self.state { - Nothing => {} + Nothing => {}, Touching | Panning => { self.state = Nothing; - } + }, Pinching => { self.state = Panning; - } + }, WaitingForScript | DefaultPrevented | MultiTouch => { if self.active_touch_points.is_empty() { self.state = Nothing; } - } + }, } } @@ -209,7 +216,7 @@ impl TouchHandler { 1 => Touching, 2 => Pinching, _ => MultiTouch, - } + }, } } } diff --git a/components/config/basedir.rs b/components/config/basedir.rs index c0970ce9770..562f049bbd2 100644 --- a/components/config/basedir.rs +++ b/components/config/basedir.rs @@ -8,7 +8,12 @@ use std::path::PathBuf; -#[cfg(all(unix, not(target_os = "macos"), not(target_os = "ios"), not(target_os = "android")))] +#[cfg(all( + unix, + not(target_os = "macos"), + not(target_os = "ios"), + not(target_os = "android") +))] pub fn default_config_dir() -> Option { let mut config_dir = ::dirs::config_dir().unwrap(); config_dir.push("servo"); diff --git a/components/config/lib.rs b/components/config/lib.rs index c5aac6e9f70..d1a63520f11 100644 --- a/components/config/lib.rs +++ b/components/config/lib.rs @@ -9,17 +9,21 @@ extern crate dirs; extern crate embedder_traits; extern crate euclid; extern crate getopts; -#[macro_use] extern crate lazy_static; -#[macro_use] extern crate log; +#[macro_use] +extern crate lazy_static; +#[macro_use] +extern crate log; extern crate num_cpus; extern crate rustc_serialize; -#[macro_use] extern crate serde; +#[macro_use] +extern crate serde; extern crate servo_geometry; extern crate servo_url; extern crate url; pub mod basedir; -#[allow(unsafe_code)] pub mod opts; +#[allow(unsafe_code)] +pub mod opts; pub mod prefs; pub fn servo_version() -> String { diff --git a/components/config/opts.rs b/components/config/opts.rs index a93d39bdf73..293a5f64c10 100644 --- a/components/config/opts.rs +++ b/components/config/opts.rs @@ -22,7 +22,6 @@ use std::process; use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering}; use url::{self, Url}; - /// Global flags for Servo, currently set on the command line. #[derive(Clone, Deserialize, Serialize)] pub struct Opts { @@ -230,11 +229,13 @@ pub struct Opts { } fn print_usage(app: &str, opts: &Options) { - let message = format!("Usage: {} [ options ... ] [URL]\n\twhere options include", app); + let message = format!( + "Usage: {} [ options ... ] [URL]\n\twhere options include", + app + ); println!("{}", opts.usage(&message)); } - /// Debug options for Servo, currently set on the command line with -Z #[derive(Default)] pub struct DebugOptions { @@ -333,7 +334,6 @@ pub struct DebugOptions { pub signpost: bool, } - impl DebugOptions { pub fn extend(&mut self, debug_string: String) -> Result<(), String> { for option in debug_string.split(',') { @@ -371,50 +371,103 @@ impl DebugOptions { "" => {}, _ => return Err(String::from(option)), }; - }; + } Ok(()) } } - fn print_debug_usage(app: &str) -> ! { fn print_option(name: &str, description: &str) { println!("\t{:<35} {}", name, description); } - println!("Usage: {} debug option,[options,...]\n\twhere options include\n\nOptions:", app); + println!( + "Usage: {} debug option,[options,...]\n\twhere options include\n\nOptions:", + app + ); - print_option("bubble-widths", "Bubble intrinsic widths separately like other engines."); + print_option( + "bubble-widths", + "Bubble intrinsic widths separately like other engines.", + ); print_option("disable-text-aa", "Disable antialiasing of rendered text."); - print_option("disable-canvas-aa", "Disable antialiasing on the HTML canvas element."); - print_option("dump-style-tree", "Print the DOM with computed styles after each restyle."); + print_option( + "disable-canvas-aa", + "Disable antialiasing on the HTML canvas element.", + ); + print_option( + "dump-style-tree", + "Print the DOM with computed styles after each restyle.", + ); print_option("dump-flow-tree", "Print the flow tree after each layout."); - print_option("dump-display-list", "Print the display list after each layout."); - print_option("dump-display-list-json", "Print the display list in JSON form."); - print_option("relayout-event", "Print notifications when there is a relayout."); - print_option("profile-script-events", "Enable profiling of script-related events."); - print_option("profile-heartbeats", "Enable heartbeats for all thread categories."); - print_option("show-fragment-borders", "Paint borders along fragment boundaries."); - print_option("show-parallel-layout", "Mark which thread laid each flow out with colors."); - print_option("trace-layout", "Write layout trace to an external file for debugging."); - print_option("disable-share-style-cache", - "Disable the style sharing cache."); - print_option("parallel-display-list-building", "Build display lists in parallel."); - print_option("convert-mouse-to-touch", "Send touch events instead of mouse events"); - print_option("replace-surrogates", "Replace unpaires surrogates in DOM strings with U+FFFD. \ - See https://github.com/servo/servo/issues/6564"); + print_option( + "dump-display-list", + "Print the display list after each layout.", + ); + print_option( + "dump-display-list-json", + "Print the display list in JSON form.", + ); + print_option( + "relayout-event", + "Print notifications when there is a relayout.", + ); + print_option( + "profile-script-events", + "Enable profiling of script-related events.", + ); + print_option( + "profile-heartbeats", + "Enable heartbeats for all thread categories.", + ); + print_option( + "show-fragment-borders", + "Paint borders along fragment boundaries.", + ); + print_option( + "show-parallel-layout", + "Mark which thread laid each flow out with colors.", + ); + print_option( + "trace-layout", + "Write layout trace to an external file for debugging.", + ); + print_option( + "disable-share-style-cache", + "Disable the style sharing cache.", + ); + print_option( + "parallel-display-list-building", + "Build display lists in parallel.", + ); + print_option( + "convert-mouse-to-touch", + "Send touch events instead of mouse events", + ); + print_option( + "replace-surrogates", + "Replace unpaires surrogates in DOM strings with U+FFFD. \ + See https://github.com/servo/servo/issues/6564", + ); print_option("gc-profile", "Log GC passes and their durations."); - print_option("load-webfonts-synchronously", - "Load web fonts synchronously to avoid non-deterministic network-driven reflows"); - print_option("disable-vsync", - "Disable vsync mode in the compositor to allow profiling at more than monitor refresh rate"); + print_option( + "load-webfonts-synchronously", + "Load web fonts synchronously to avoid non-deterministic network-driven reflows", + ); + print_option( + "disable-vsync", + "Disable vsync mode in the compositor to allow profiling at more than monitor refresh rate", + ); print_option("wr-stats", "Show WebRender profiler on screen."); print_option("msaa", "Use multisample antialiasing in WebRender."); print_option("full-backtraces", "Print full backtraces for all errors"); print_option("wr-debug", "Display webrender tile borders."); print_option("wr-no-batch", "Disable webrender instanced batching."); print_option("precache-shaders", "Compile all shaders during init."); - print_option("signpost", "Emit native OS signposts for profile events (currently macOS only)"); + print_option( + "signpost", + "Emit native OS signposts for profile events (currently macOS only)", + ); println!(""); @@ -445,7 +498,7 @@ enum UserAgent { Desktop, Android, #[allow(non_camel_case_types)] - iOS + iOS, } fn default_user_agent_string(agent: UserAgent) -> &'static str { @@ -468,17 +521,12 @@ fn default_user_agent_string(agent: UserAgent) -> &'static str { const DESKTOP_UA_STRING: &'static str = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:55.0) Servo/1.0 Firefox/55.0"; - match agent { - UserAgent::Desktop => { - DESKTOP_UA_STRING - } - UserAgent::Android => { - "Mozilla/5.0 (Android; Mobile; rv:55.0) Servo/1.0 Firefox/55.0" - } + UserAgent::Desktop => DESKTOP_UA_STRING, + UserAgent::Android => "Mozilla/5.0 (Android; Mobile; rv:55.0) Servo/1.0 Firefox/55.0", UserAgent::iOS => { "Mozilla/5.0 (iPhone; CPU iPhone OS 8_3 like Mac OS X; rv:55.0) Servo/1.0 Firefox/55.0" - } + }, } } @@ -564,54 +612,146 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { opts.optopt("o", "output", "Output file", "output.png"); opts.optopt("s", "size", "Size of tiles", "512"); opts.optopt("", "device-pixel-ratio", "Device pixels per px", ""); - opts.optflagopt("p", "profile", "Time profiler flag and either a TSV output filename \ - OR an interval for output to Stdout (blank for Stdout with interval of 5s)", "10 \ - OR time.tsv"); - opts.optflagopt("", "profiler-trace-path", - "Path to dump a self-contained HTML timeline of profiler traces", - ""); - opts.optflagopt("m", "memory-profile", "Memory profiler flag and output interval", "10"); + opts.optflagopt( + "p", + "profile", + "Time profiler flag and either a TSV output filename \ + OR an interval for output to Stdout (blank for Stdout with interval of 5s)", + "10 \ + OR time.tsv", + ); + opts.optflagopt( + "", + "profiler-trace-path", + "Path to dump a self-contained HTML timeline of profiler traces", + "", + ); + opts.optflagopt( + "m", + "memory-profile", + "Memory profiler flag and output interval", + "10", + ); opts.optflag("x", "exit", "Exit after load flag"); - opts.optopt("y", "layout-threads", "Number of threads to use for layout", "1"); - opts.optflag("i", "nonincremental-layout", "Enable to turn off incremental layout."); - opts.optflagopt("", "userscripts", - "Uses userscripts in resources/user-agent-js, or a specified full path", ""); - opts.optmulti("", "user-stylesheet", - "A user stylesheet to be added to every document", "file.css"); - opts.optopt("", "shaders", - "Shaders will be loaded from the specified directory instead of using the builtin ones.", ""); + opts.optopt( + "y", + "layout-threads", + "Number of threads to use for layout", + "1", + ); + opts.optflag( + "i", + "nonincremental-layout", + "Enable to turn off incremental layout.", + ); + opts.optflagopt( + "", + "userscripts", + "Uses userscripts in resources/user-agent-js, or a specified full path", + "", + ); + opts.optmulti( + "", + "user-stylesheet", + "A user stylesheet to be added to every document", + "file.css", + ); + opts.optopt( + "", + "shaders", + "Shaders will be loaded from the specified directory instead of using the builtin ones.", + "", + ); opts.optflag("z", "headless", "Headless mode"); - opts.optflag("f", "hard-fail", "Exit on thread failure instead of displaying about:failure"); - opts.optflag("F", "soft-fail", "Display about:failure on thread failure instead of exiting"); - opts.optflagopt("", "remote-debugging-port", "Start remote debugger server on port", "2794"); - opts.optflagopt("", "devtools", "Start remote devtools server on port", "6000"); - opts.optflagopt("", "webdriver", "Start remote WebDriver server on port", "7000"); + opts.optflag( + "f", + "hard-fail", + "Exit on thread failure instead of displaying about:failure", + ); + opts.optflag( + "F", + "soft-fail", + "Display about:failure on thread failure instead of exiting", + ); + opts.optflagopt( + "", + "remote-debugging-port", + "Start remote debugger server on port", + "2794", + ); + opts.optflagopt( + "", + "devtools", + "Start remote devtools server on port", + "6000", + ); + opts.optflagopt( + "", + "webdriver", + "Start remote WebDriver server on port", + "7000", + ); opts.optopt("", "resolution", "Set window resolution.", "1024x740"); - opts.optopt("u", - "user-agent", - "Set custom user agent string (or ios / android / desktop for platform default)", - "NCSA Mosaic/1.0 (X11;SunOS 4.1.4 sun4m)"); + opts.optopt( + "u", + "user-agent", + "Set custom user agent string (or ios / android / desktop for platform default)", + "NCSA Mosaic/1.0 (X11;SunOS 4.1.4 sun4m)", + ); opts.optflag("M", "multiprocess", "Run in multiprocess mode"); opts.optflag("S", "sandbox", "Run in a sandbox if multiprocess"); - opts.optopt("", - "random-pipeline-closure-probability", - "Probability of randomly closing a pipeline (for testing constellation hardening).", - "0.0"); - opts.optopt("", "random-pipeline-closure-seed", "A fixed seed for repeatbility of random pipeline closure.", ""); - opts.optmulti("Z", "debug", - "A comma-separated string of debug options. Pass help to show available options.", ""); + opts.optopt( + "", + "random-pipeline-closure-probability", + "Probability of randomly closing a pipeline (for testing constellation hardening).", + "0.0", + ); + opts.optopt( + "", + "random-pipeline-closure-seed", + "A fixed seed for repeatbility of random pipeline closure.", + "", + ); + opts.optmulti( + "Z", + "debug", + "A comma-separated string of debug options. Pass help to show available options.", + "", + ); opts.optflag("h", "help", "Print this message"); - opts.optopt("", "resources-path", "Path to find static resources", "/home/servo/resources"); - opts.optopt("", "certificate-path", "Path to find SSL certificates", "/home/servo/resources/certs"); - opts.optopt("", "content-process" , "Run as a content process and connect to the given pipe", - "servo-ipc-channel.abcdefg"); - opts.optmulti("", "pref", - "A preference to set to enable", "dom.bluetooth.enabled"); + opts.optopt( + "", + "resources-path", + "Path to find static resources", + "/home/servo/resources", + ); + opts.optopt( + "", + "certificate-path", + "Path to find SSL certificates", + "/home/servo/resources/certs", + ); + opts.optopt( + "", + "content-process", + "Run as a content process and connect to the given pipe", + "servo-ipc-channel.abcdefg", + ); + opts.optmulti( + "", + "pref", + "A preference to set to enable", + "dom.bluetooth.enabled", + ); opts.optflag("b", "no-native-titlebar", "Do not use native titlebar"); opts.optflag("w", "webrender", "Use webrender backend"); opts.optopt("G", "graphics", "Select graphics backend (gl or es2)", "gl"); - opts.optopt("", "config-dir", - "config directory following xdg spec on linux platform", ""); + opts.optopt( + "", + "config-dir", + "config directory following xdg spec on linux platform", + "", + ); opts.optflag("v", "version", "Display servo version information"); opts.optflag("", "unminify-js", "Unminify Javascript"); opts.optopt("", "profiler-db-user", "Profiler database user", ""); @@ -654,44 +794,50 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { } else { None }; - let is_running_problem_test = - url_opt - .as_ref() - .map_or(false, |url| - url.starts_with("http://web-platform.test:8000/2dcontext/drawing-images-to-the-canvas/") || - url.starts_with("http://web-platform.test:8000/_mozilla/mozilla/canvas/") || - url.starts_with("http://web-platform.test:8000/_mozilla/css/canvas_over_area.html")); + let is_running_problem_test = url_opt.as_ref().map_or(false, |url| { + url.starts_with("http://web-platform.test:8000/2dcontext/drawing-images-to-the-canvas/") || + url.starts_with("http://web-platform.test:8000/_mozilla/mozilla/canvas/") || + url.starts_with("http://web-platform.test:8000/_mozilla/css/canvas_over_area.html") + }); - let url_opt = url_opt.and_then(|url_string| parse_url_or_filename(&cwd, url_string) - .or_else(|error| { - warn!("URL parsing failed ({:?}).", error); - Err(error) - }).ok()); + let url_opt = url_opt.and_then(|url_string| { + parse_url_or_filename(&cwd, url_string) + .or_else(|error| { + warn!("URL parsing failed ({:?}).", error); + Err(error) + }).ok() + }); let tile_size: usize = match opt_match.opt_str("s") { - Some(tile_size_str) => tile_size_str.parse() + Some(tile_size_str) => tile_size_str + .parse() .unwrap_or_else(|err| args_fail(&format!("Error parsing option: -s ({})", err))), None => 512, }; - let device_pixels_per_px = opt_match.opt_str("device-pixel-ratio").map(|dppx_str| - dppx_str.parse() - .unwrap_or_else(|err| args_fail(&format!("Error parsing option: --device-pixel-ratio ({})", err))) - ); + let device_pixels_per_px = opt_match.opt_str("device-pixel-ratio").map(|dppx_str| { + dppx_str.parse().unwrap_or_else(|err| { + args_fail(&format!( + "Error parsing option: --device-pixel-ratio ({})", + err + )) + }) + }); // If only the flag is present, default to a 5 second period for both profilers let time_profiling = if opt_match.opt_present("p") { match opt_match.opt_str("p") { Some(argument) => match argument.parse::() { - Ok(interval) => Some(OutputOptions::Stdout(interval)) , - Err(_) => { - match ServoUrl::parse(&argument) { - Ok(url) => Some(OutputOptions::DB(url, opt_match.opt_str("profiler-db-name"), - opt_match.opt_str("profiler-db-user"), - opt_match.opt_str("profiler-db-pass"))), - Err(_) => Some(OutputOptions::FileName(argument)), - } - } + Ok(interval) => Some(OutputOptions::Stdout(interval)), + Err(_) => match ServoUrl::parse(&argument) { + Ok(url) => Some(OutputOptions::DB( + url, + opt_match.opt_str("profiler-db-name"), + opt_match.opt_str("profiler-db-user"), + opt_match.opt_str("profiler-db-pass"), + )), + Err(_) => Some(OutputOptions::FileName(argument)), + }, }, None => Some(OutputOptions::Stdout(5.0 as f64)), } @@ -704,34 +850,50 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { let mut path = PathBuf::from(time_profiler_trace_path); path.pop(); if let Err(why) = fs::create_dir_all(&path) { - error!("Couldn't create/open {:?}: {:?}", - Path::new(time_profiler_trace_path).to_string_lossy(), why); + error!( + "Couldn't create/open {:?}: {:?}", + Path::new(time_profiler_trace_path).to_string_lossy(), + why + ); } } let mem_profiler_period = opt_match.opt_default("m", "5").map(|period| { - period.parse().unwrap_or_else(|err| args_fail(&format!("Error parsing option: -m ({})", err))) + period + .parse() + .unwrap_or_else(|err| args_fail(&format!("Error parsing option: -m ({})", err))) }); - let mut layout_threads: Option = opt_match.opt_str("y") - .map(|layout_threads_str| { - layout_threads_str.parse() - .unwrap_or_else(|err| args_fail(&format!("Error parsing option: -y ({})", err))) - }); + let mut layout_threads: Option = opt_match.opt_str("y").map(|layout_threads_str| { + layout_threads_str + .parse() + .unwrap_or_else(|err| args_fail(&format!("Error parsing option: -y ({})", err))) + }); let nonincremental_layout = opt_match.opt_present("i"); - let random_pipeline_closure_probability = opt_match.opt_str("random-pipeline-closure-probability").map(|prob| - prob.parse().unwrap_or_else(|err| { - args_fail(&format!("Error parsing option: --random-pipeline-closure-probability ({})", err)) - }) - ); + let random_pipeline_closure_probability = opt_match + .opt_str("random-pipeline-closure-probability") + .map(|prob| { + prob.parse().unwrap_or_else(|err| { + args_fail(&format!( + "Error parsing option: --random-pipeline-closure-probability ({})", + err + )) + }) + }); - let random_pipeline_closure_seed = opt_match.opt_str("random-pipeline-closure-seed").map(|seed| - seed.parse().unwrap_or_else(|err| { - args_fail(&format!("Error parsing option: --random-pipeline-closure-seed ({})", err)) - }) - ); + let random_pipeline_closure_seed = + opt_match + .opt_str("random-pipeline-closure-seed") + .map(|seed| { + seed.parse().unwrap_or_else(|err| { + args_fail(&format!( + "Error parsing option: --random-pipeline-closure-seed ({})", + err + )) + }) + }); let mut bubble_inline_sizes_separately = debug_options.bubble_widths; if debug_options.trace_layout { @@ -739,29 +901,40 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { bubble_inline_sizes_separately = true; } - let debugger_port = opt_match.opt_default("remote-debugging-port", "2794").map(|port| { - port.parse() - .unwrap_or_else(|err| args_fail(&format!("Error parsing option: --remote-debugging-port ({})", err))) - }); + let debugger_port = opt_match + .opt_default("remote-debugging-port", "2794") + .map(|port| { + port.parse().unwrap_or_else(|err| { + args_fail(&format!( + "Error parsing option: --remote-debugging-port ({})", + err + )) + }) + }); let devtools_port = opt_match.opt_default("devtools", "6000").map(|port| { - port.parse().unwrap_or_else(|err| args_fail(&format!("Error parsing option: --devtools ({})", err))) + port.parse() + .unwrap_or_else(|err| args_fail(&format!("Error parsing option: --devtools ({})", err))) }); let webdriver_port = opt_match.opt_default("webdriver", "7000").map(|port| { - port.parse().unwrap_or_else(|err| args_fail(&format!("Error parsing option: --webdriver ({})", err))) + port.parse().unwrap_or_else(|err| { + args_fail(&format!("Error parsing option: --webdriver ({})", err)) + }) }); let initial_window_size = match opt_match.opt_str("resolution") { Some(res_string) => { - let res: Vec = res_string.split('x').map(|r| { - r.parse().unwrap_or_else(|err| args_fail(&format!("Error parsing option: --resolution ({})", err))) - }).collect(); + let res: Vec = res_string + .split('x') + .map(|r| { + r.parse().unwrap_or_else(|err| { + args_fail(&format!("Error parsing option: --resolution ({})", err)) + }) + }).collect(); TypedSize2D::new(res[0], res[1]) - } - None => { - TypedSize2D::new(1024, 740) - } + }, + None => TypedSize2D::new(1024, 740), }; if opt_match.opt_present("M") { @@ -776,20 +949,24 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { None => default_user_agent_string(DEFAULT_USER_AGENT).into(), }; - let user_stylesheets = opt_match.opt_strs("user-stylesheet").iter().map(|filename| { - let path = cwd.join(filename); - let url = ServoUrl::from_url(Url::from_file_path(&path).unwrap()); - let mut contents = Vec::new(); - File::open(path) - .unwrap_or_else(|err| args_fail(&format!("Couldn't open {}: {}", filename, err))) - .read_to_end(&mut contents) - .unwrap_or_else(|err| args_fail(&format!("Couldn't read {}: {}", filename, err))); - (contents, url) - }).collect(); + let user_stylesheets = opt_match + .opt_strs("user-stylesheet") + .iter() + .map(|filename| { + let path = cwd.join(filename); + let url = ServoUrl::from_url(Url::from_file_path(&path).unwrap()); + let mut contents = Vec::new(); + File::open(path) + .unwrap_or_else(|err| args_fail(&format!("Couldn't open {}: {}", filename, err))) + .read_to_end(&mut contents) + .unwrap_or_else(|err| args_fail(&format!("Couldn't read {}: {}", filename, err))); + (contents, url) + }).collect(); - let do_not_use_native_titlebar = - opt_match.opt_present("b") || - !PREFS.get("shell.native-titlebar.enabled").as_boolean().unwrap(); + let do_not_use_native_titlebar = opt_match.opt_present("b") || !PREFS + .get("shell.native-titlebar.enabled") + .as_boolean() + .unwrap(); let is_printing_version = opt_match.opt_present("v") || opt_match.opt_present("version"); @@ -870,7 +1047,10 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { if let Some(layout_threads) = layout_threads { PREFS.set("layout.threads", PrefValue::Number(layout_threads as f64)); } else if let Some(layout_threads) = PREFS.get("layout.threads").as_string() { - PREFS.set("layout.threads", PrefValue::Number(layout_threads.parse::().unwrap())); + PREFS.set( + "layout.threads", + PrefValue::Number(layout_threads.parse::().unwrap()), + ); } else if *PREFS.get("layout.threads") == PrefValue::Missing { let layout_threads = cmp::max(num_cpus::get() * 3 / 4, 1); PREFS.set("layout.threads", PrefValue::Number(layout_threads as f64)); @@ -926,8 +1106,8 @@ pub fn parse_pref_from_command_line(pref: &str) { Some(&"true") | None => PREFS.set(pref_name, PrefValue::Boolean(true)), Some(value) => match value.parse::() { Ok(v) => PREFS.set(pref_name, PrefValue::Number(v)), - Err(_) => PREFS.set(pref_name, PrefValue::String(value.to_string())) - } + Err(_) => PREFS.set(pref_name, PrefValue::String(value.to_string())), + }, }; } @@ -941,7 +1121,7 @@ pub fn parse_url_or_filename(cwd: &Path, input: &str) -> Result { Ok(url) => Ok(url), Err(url::ParseError::RelativeUrlWithoutBase) => { Url::from_file_path(&*cwd.join(input)).map(ServoUrl::from_url) - } + }, Err(_) => Err(()), } } diff --git a/components/config/prefs.rs b/components/config/prefs.rs index e5019ea4fcb..792f3c9fb8f 100644 --- a/components/config/prefs.rs +++ b/components/config/prefs.rs @@ -30,7 +30,7 @@ pub enum PrefValue { Boolean(bool), String(String), Number(f64), - Missing + Missing, } impl PrefValue { @@ -41,26 +41,22 @@ impl PrefValue { Json::F64(x) => PrefValue::Number(x), Json::I64(x) => PrefValue::Number(x as f64), Json::U64(x) => PrefValue::Number(x as f64), - _ => return Err(()) + _ => return Err(()), }; Ok(value) } pub fn as_boolean(&self) -> Option { match *self { - PrefValue::Boolean(value) => { - Some(value) - }, - _ => None + PrefValue::Boolean(value) => Some(value), + _ => None, } } pub fn as_string(&self) -> Option<&str> { match *self { - PrefValue::String(ref value) => { - Some(&value) - }, - _ => None + PrefValue::String(ref value) => Some(&value), + _ => None, } } @@ -82,16 +78,10 @@ impl PrefValue { impl ToJson for PrefValue { fn to_json(&self) -> Json { match *self { - PrefValue::Boolean(x) => { - Json::Boolean(x) - }, - PrefValue::String(ref x) => { - Json::String(x.clone()) - }, - PrefValue::Number(x) => { - Json::F64(x) - }, - PrefValue::Missing => Json::Null + PrefValue::Boolean(x) => Json::Boolean(x), + PrefValue::String(ref x) => Json::String(x.clone()), + PrefValue::Number(x) => Json::F64(x), + PrefValue::Missing => Json::Null, } } } @@ -99,10 +89,9 @@ impl ToJson for PrefValue { #[derive(Clone, Debug, Deserialize, Serialize)] pub enum Pref { NoDefault(Arc), - WithDefault(Arc, Option>) + WithDefault(Arc, Option>), } - impl Pref { pub fn new(value: PrefValue) -> Pref { Pref::NoDefault(Arc::new(value)) @@ -120,12 +109,10 @@ impl Pref { pub fn value(&self) -> &Arc { match *self { Pref::NoDefault(ref x) => x, - Pref::WithDefault(ref default, ref override_value) => { - match *override_value { - Some(ref x) => x, - None => default - } - } + Pref::WithDefault(ref default, ref override_value) => match *override_value { + Some(ref x) => x, + None => default, + }, } } @@ -133,12 +120,8 @@ impl Pref { // TODO - this should error if we try to override a pref of one type // with a value of a different type match *self { - Pref::NoDefault(ref mut pref_value) => { - *pref_value = Arc::new(value) - }, - Pref::WithDefault(_, ref mut override_value) => { - *override_value = Some(Arc::new(value)) - } + Pref::NoDefault(ref mut pref_value) => *pref_value = Arc::new(value), + Pref::WithDefault(_, ref mut override_value) => *override_value = Some(Arc::new(value)), } } } @@ -151,8 +134,10 @@ impl ToJson for Pref { pub fn default_prefs() -> Preferences { let prefs = Preferences(Arc::new(RwLock::new(HashMap::new()))); - prefs.set("layout.threads", PrefValue::Number( - max(num_cpus::get() * 3 / 4, 1) as f64)); + prefs.set( + "layout.threads", + PrefValue::Number(max(num_cpus::get() * 3 / 4, 1) as f64), + ); prefs } @@ -169,7 +154,10 @@ pub fn read_prefs(txt: &str) -> Result, ()> { Ok(x) => { prefs.insert(name, x); }, - Err(_) => println!("Ignoring non-boolean/string/i64 preference value for {:?}", name), + Err(_) => println!( + "Ignoring non-boolean/string/i64 preference value for {:?}", + name + ), } } } @@ -181,14 +169,14 @@ pub fn add_user_prefs() { Some(ref config_path) => { let mut path = PathBuf::from(config_path); init_user_prefs(&mut path); - } + }, None => { if let Some(mut path) = default_config_dir() { if path.join("prefs.json").exists() { init_user_prefs(&mut path); } } - } + }, } } @@ -201,8 +189,10 @@ fn init_user_prefs(path: &mut PathBuf) { PREFS.extend(prefs); } } else { - writeln!(&mut stderr(), "Error opening prefs.json from config directory") - .expect("failed printing to stderr"); + writeln!( + &mut stderr(), + "Error opening prefs.json from config directory" + ).expect("failed printing to stderr"); } } @@ -210,7 +200,11 @@ pub struct Preferences(Arc>>); impl Preferences { pub fn get(&self, name: &str) -> Arc { - self.0.read().unwrap().get(name).map_or(Arc::new(PrefValue::Missing), |x| x.value().clone()) + self.0 + .read() + .unwrap() + .get(name) + .map_or(Arc::new(PrefValue::Missing), |x| x.value().clone()) } pub fn cloned(&self) -> HashMap { @@ -244,7 +238,12 @@ impl Preferences { pub fn reset_all(&self) { let names = { - self.0.read().unwrap().keys().cloned().collect::>() + self.0 + .read() + .unwrap() + .keys() + .cloned() + .collect::>() }; for name in names.iter() { self.reset(name); @@ -260,7 +259,9 @@ impl Preferences { } pub fn is_dom_to_texture_enabled(&self) -> bool { - self.get("dom.webgl.dom_to_texture.enabled").as_boolean().unwrap_or(false) + self.get("dom.webgl.dom_to_texture.enabled") + .as_boolean() + .unwrap_or(false) } pub fn is_webgl2_enabled(&self) -> bool { diff --git a/components/config/tests/opts.rs b/components/config/tests/opts.rs index 53a049e103c..e2db853a991 100644 --- a/components/config/tests/opts.rs +++ b/components/config/tests/opts.rs @@ -24,7 +24,10 @@ fn test_argument_parsing() { let url = parse_url_or_filename(fake_cwd, "file:///foo/bar.html").unwrap(); assert_eq!(url.scheme(), "file"); - assert_eq!(url.path_segments().unwrap().collect::>(), ["foo", "bar.html"]); + assert_eq!( + url.path_segments().unwrap().collect::>(), + ["foo", "bar.html"] + ); } #[test] @@ -34,7 +37,10 @@ fn test_file_path_parsing() { let url = parse_url_or_filename(fake_cwd, "bar.html").unwrap(); assert_eq!(url.scheme(), "file"); - assert_eq!(url.path_segments().unwrap().collect::>(), ["fake", "cwd", "bar.html"]); + assert_eq!( + url.path_segments().unwrap().collect::>(), + ["fake", "cwd", "bar.html"] + ); } #[test] @@ -44,7 +50,10 @@ fn test_file_path_parsing() { let url = parse_url_or_filename(fake_cwd, "bar.html").unwrap(); assert_eq!(url.scheme(), "file"); - assert_eq!(url.path_segments().unwrap().collect::>(), ["C:", "fake", "cwd", "bar.html"]); + assert_eq!( + url.path_segments().unwrap().collect::>(), + ["C:", "fake", "cwd", "bar.html"] + ); } #[test] @@ -57,16 +66,24 @@ fn test_argument_parsing_special() { let url = parse_url_or_filename(fake_cwd, "file:///foo/bar?baz#buzz.html").unwrap(); assert_eq!(&*url.to_file_path().unwrap(), Path::new("/foo/bar")); assert_eq!(url.scheme(), "file"); - assert_eq!(url.path_segments().unwrap().collect::>(), ["foo", "bar"]); + assert_eq!( + url.path_segments().unwrap().collect::>(), + ["foo", "bar"] + ); assert_eq!(url.query(), Some("baz")); assert_eq!(url.fragment(), Some("buzz.html")); // but not in file names. let url = parse_url_or_filename(fake_cwd, "./bar?baz#buzz.html").unwrap(); - assert_eq!(&*url.to_file_path().unwrap(), Path::new("/fake/cwd/bar?baz#buzz.html")); + assert_eq!( + &*url.to_file_path().unwrap(), + Path::new("/fake/cwd/bar?baz#buzz.html") + ); assert_eq!(url.scheme(), "file"); - assert_eq!(url.path_segments().unwrap().collect::>(), - ["fake", "cwd", "bar%3Fbaz%23buzz.html"]); + assert_eq!( + url.path_segments().unwrap().collect::>(), + ["fake", "cwd", "bar%3Fbaz%23buzz.html"] + ); assert_eq!(url.query(), None); assert_eq!(url.fragment(), None); } diff --git a/components/config/tests/prefs.rs b/components/config/tests/prefs.rs index 68188600ee8..823b03b76c2 100644 --- a/components/config/tests/prefs.rs +++ b/components/config/tests/prefs.rs @@ -12,10 +12,10 @@ use std::io::{Read, Write}; #[test] fn test_create_pref() { let json_str = "{\ - \"layout.writing-mode.enabled\": true,\ - \"network.mime.sniff\": false,\ - \"shell.homepage\": \"https://servo.org\"\ -}"; + \"layout.writing-mode.enabled\": true,\ + \"network.mime.sniff\": false,\ + \"shell.homepage\": \"https://servo.org\"\ + }"; let prefs = read_prefs(json_str); assert!(prefs.is_ok()); @@ -27,40 +27,52 @@ fn test_create_pref() { #[test] fn test_get_set_reset_extend() { let json_str = "{\ - \"layout.writing-mode.enabled\": true,\ - \"extra.stuff\": false,\ - \"shell.homepage\": \"https://google.com\"\ -}"; + \"layout.writing-mode.enabled\": true,\ + \"extra.stuff\": false,\ + \"shell.homepage\": \"https://google.com\"\ + }"; assert_eq!(*PREFS.get("test"), PrefValue::Missing); PREFS.set("test", PrefValue::String("hi".to_owned())); assert_eq!(*PREFS.get("test"), PrefValue::String("hi".to_owned())); - assert_eq!(*PREFS.get("shell.homepage"), PrefValue::String("https://servo.org".to_owned())); + assert_eq!( + *PREFS.get("shell.homepage"), + PrefValue::String("https://servo.org".to_owned()) + ); PREFS.set("shell.homepage", PrefValue::Boolean(true)); assert_eq!(*PREFS.get("shell.homepage"), PrefValue::Boolean(true)); PREFS.reset("shell.homepage"); - assert_eq!(*PREFS.get("shell.homepage"), PrefValue::String("https://servo.org".to_owned())); + assert_eq!( + *PREFS.get("shell.homepage"), + PrefValue::String("https://servo.org".to_owned()) + ); let extension = read_prefs(json_str).unwrap(); PREFS.extend(extension); - assert_eq!(*PREFS.get("shell.homepage"), PrefValue::String("https://google.com".to_owned())); - assert_eq!(*PREFS.get("layout.writing-mode.enabled"), PrefValue::Boolean(true)); + assert_eq!( + *PREFS.get("shell.homepage"), + PrefValue::String("https://google.com".to_owned()) + ); + assert_eq!( + *PREFS.get("layout.writing-mode.enabled"), + PrefValue::Boolean(true) + ); assert_eq!(*PREFS.get("extra.stuff"), PrefValue::Boolean(false)); } #[cfg(not(target_os = "android"))] #[test] fn test_default_config_dir_create_read_write() { - let json_str = "{\ - \"layout.writing-mode.enabled\": true,\ - \"extra.stuff\": false,\ - \"shell.homepage\": \"https://google.com\"\ -}"; + let json_str = "{\ + \"layout.writing-mode.enabled\": true,\ + \"extra.stuff\": false,\ + \"shell.homepage\": \"https://google.com\"\ + }"; let mut expected_json = String::new(); let config_path = basedir::default_config_dir().unwrap(); if !config_path.exists() { - fs::create_dir_all(&config_path).unwrap(); + fs::create_dir_all(&config_path).unwrap(); } let json_path = config_path.join("test_config.json"); diff --git a/components/debugger/lib.rs b/components/debugger/lib.rs index ec0e5ba0e80..6190ebec89b 100644 --- a/components/debugger/lib.rs +++ b/components/debugger/lib.rs @@ -18,7 +18,7 @@ enum Message { pub struct Sender(mpsc::Sender); struct Connection { - sender: ws::Sender + sender: ws::Sender, } impl Handler for Connection { @@ -39,23 +39,27 @@ impl Handler for Connection { pub fn start_server(port: u16) -> Sender { debug!("Starting server."); let (sender, receiver) = channel(); - thread::Builder::new().name("debugger".to_owned()).spawn(move || { - let socket = Builder::new().build(|sender: ws::Sender| { - Connection { sender: sender } - }).unwrap(); - let sender = socket.broadcaster(); - thread::Builder::new().name("debugger-websocket".to_owned()).spawn(move || { - socket.listen(("127.0.0.1", port)).unwrap(); - }).expect("Thread spawning failed"); - while let Ok(message) = receiver.recv() { - match message { - Message::ShutdownServer => { - break; + thread::Builder::new() + .name("debugger".to_owned()) + .spawn(move || { + let socket = Builder::new() + .build(|sender: ws::Sender| Connection { sender: sender }) + .unwrap(); + let sender = socket.broadcaster(); + thread::Builder::new() + .name("debugger-websocket".to_owned()) + .spawn(move || { + socket.listen(("127.0.0.1", port)).unwrap(); + }).expect("Thread spawning failed"); + while let Ok(message) = receiver.recv() { + match message { + Message::ShutdownServer => { + break; + }, } } - } - sender.shutdown().unwrap(); - }).expect("Thread spawning failed"); + sender.shutdown().unwrap(); + }).expect("Thread spawning failed"); Sender(sender) } diff --git a/components/deny_public_fields/lib.rs b/components/deny_public_fields/lib.rs index 8d5feb39cbe..28fbf85add0 100644 --- a/components/deny_public_fields/lib.rs +++ b/components/deny_public_fields/lib.rs @@ -14,8 +14,10 @@ decl_derive!([DenyPublicFields] => deny_public_fields_derive); fn deny_public_fields_derive(s: synstructure::Structure) -> proc_macro::TokenStream { s.each(|binding| { if binding.ast().vis != syn::Visibility::Inherited { - panic!("Field `{}` should not be public", - binding.ast().ident.as_ref().unwrap_or(&binding.binding)); + panic!( + "Field `{}` should not be public", + binding.ast().ident.as_ref().unwrap_or(&binding.binding) + ); } "".to_owned() diff --git a/components/devtools/actor.rs b/components/devtools/actor.rs index f2ee6398e9b..634622a2068 100644 --- a/components/devtools/actor.rs +++ b/components/devtools/actor.rs @@ -3,7 +3,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /// General actor system infrastructure. - use devtools_traits::PreciseTime; use serde_json::{Map, Value}; use std::any::Any; @@ -23,11 +22,13 @@ pub enum ActorMessageStatus { /// and the ability to process messages that are directed to particular actors. /// TODO: ensure the name is immutable pub trait Actor: Any + ActorAsAny { - fn handle_message(&self, - registry: &ActorRegistry, - msg_type: &str, - msg: &Map, - stream: &mut TcpStream) -> Result; + fn handle_message( + &self, + registry: &ActorRegistry, + msg_type: &str, + msg: &Map, + stream: &mut TcpStream, + ) -> Result; fn name(&self) -> String; } @@ -37,8 +38,12 @@ pub trait ActorAsAny { } impl ActorAsAny for T { - fn actor_as_any(&self) -> &Any { self } - fn actor_as_any_mut(&mut self) -> &mut Any { self } + fn actor_as_any(&self) -> &Any { + self + } + fn actor_as_any_mut(&mut self) -> &mut Any { + self + } } /// A list of known, owned actors. @@ -57,8 +62,8 @@ impl ActorRegistry { pub fn new() -> ActorRegistry { ActorRegistry { actors: HashMap::new(), - new_actors: RefCell::new(vec!()), - old_actors: RefCell::new(vec!()), + new_actors: RefCell::new(vec![]), + old_actors: RefCell::new(vec![]), script_actors: RefCell::new(HashMap::new()), shareable: None, next: Cell::new(0), @@ -149,29 +154,33 @@ impl ActorRegistry { /// Attempt to process a message as directed by its `to` property. If the actor is not /// found or does not indicate that it knew how to process the message, ignore the failure. - pub fn handle_message(&mut self, - msg: &Map, - stream: &mut TcpStream) - -> Result<(), ()> { + pub fn handle_message( + &mut self, + msg: &Map, + stream: &mut TcpStream, + ) -> Result<(), ()> { let to = msg.get("to").unwrap().as_str().unwrap(); match self.actors.get(to) { None => debug!("message received for unknown actor \"{}\"", to), Some(actor) => { let msg_type = msg.get("type").unwrap().as_str().unwrap(); - if actor.handle_message(self, msg_type, msg, stream)? - != ActorMessageStatus::Processed { - debug!("unexpected message type \"{}\" found for actor \"{}\"", - msg_type, to); + if actor.handle_message(self, msg_type, msg, stream)? != + ActorMessageStatus::Processed + { + debug!( + "unexpected message type \"{}\" found for actor \"{}\"", + msg_type, to + ); } - } + }, } - let new_actors = replace(&mut *self.new_actors.borrow_mut(), vec!()); + let new_actors = replace(&mut *self.new_actors.borrow_mut(), vec![]); for actor in new_actors.into_iter() { self.actors.insert(actor.name().to_owned(), actor); } - let old_actors = replace(&mut *self.old_actors.borrow_mut(), vec!()); + let old_actors = replace(&mut *self.old_actors.borrow_mut(), vec![]); for name in old_actors { self.drop_actor(name); } diff --git a/components/devtools/actors/console.rs b/components/devtools/actors/console.rs index 295ebca489b..e1996570164 100644 --- a/components/devtools/actors/console.rs +++ b/components/devtools/actors/console.rs @@ -94,32 +94,48 @@ impl Actor for ConsoleActor { self.name.clone() } - fn handle_message(&self, - registry: &ActorRegistry, - msg_type: &str, - msg: &Map, - stream: &mut TcpStream) -> Result { + fn handle_message( + &self, + registry: &ActorRegistry, + msg_type: &str, + msg: &Map, + stream: &mut TcpStream, + ) -> Result { Ok(match msg_type { "getCachedMessages" => { - let str_types = msg.get("messageTypes").unwrap().as_array().unwrap().into_iter().map(|json_type| { - json_type.as_str().unwrap() - }); + let str_types = msg + .get("messageTypes") + .unwrap() + .as_array() + .unwrap() + .into_iter() + .map(|json_type| json_type.as_str().unwrap()); let mut message_types = CachedConsoleMessageTypes::empty(); for str_type in str_types { match str_type { "PageError" => message_types.insert(CachedConsoleMessageTypes::PAGE_ERROR), - "ConsoleAPI" => message_types.insert(CachedConsoleMessageTypes::CONSOLE_API), + "ConsoleAPI" => { + message_types.insert(CachedConsoleMessageTypes::CONSOLE_API) + }, s => debug!("unrecognized message type requested: \"{}\"", s), }; - }; + } let (chan, port) = ipc::channel().unwrap(); - self.script_chan.send(DevtoolScriptControlMsg::GetCachedMessages( - self.pipeline, message_types, chan)).unwrap(); - let messages = port.recv().map_err(|_| ())?.into_iter().map(|message| { - let json_string = message.encode().unwrap(); - let json = serde_json::from_str::(&json_string).unwrap(); - json.as_object().unwrap().to_owned() - }).collect(); + self.script_chan + .send(DevtoolScriptControlMsg::GetCachedMessages( + self.pipeline, + message_types, + chan, + )).unwrap(); + let messages = port + .recv() + .map_err(|_| ())? + .into_iter() + .map(|message| { + let json_string = message.encode().unwrap(); + let json = serde_json::from_str::(&json_string).unwrap(); + json.as_object().unwrap().to_owned() + }).collect(); let msg = GetCachedMessagesReply { from: self.name(), @@ -127,56 +143,60 @@ impl Actor for ConsoleActor { }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, "startListeners" => { //TODO: actually implement listener filters that support starting/stopping let msg = StartedListenersReply { from: self.name(), nativeConsoleAPI: true, - startedListeners: - vec!("PageError".to_owned(), "ConsoleAPI".to_owned()), + startedListeners: vec!["PageError".to_owned(), "ConsoleAPI".to_owned()], traits: StartedListenersTraits { customNetworkRequest: true, - } + }, }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, "stopListeners" => { //TODO: actually implement listener filters that support starting/stopping let msg = StopListenersReply { from: self.name(), - stoppedListeners: msg.get("listeners") - .unwrap() - .as_array() - .unwrap_or(&vec!()) - .iter() - .map(|listener| listener.as_str().unwrap().to_owned()) - .collect(), + stoppedListeners: msg + .get("listeners") + .unwrap() + .as_array() + .unwrap_or(&vec![]) + .iter() + .map(|listener| listener.as_str().unwrap().to_owned()) + .collect(), }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, //TODO: implement autocompletion like onAutocomplete in // http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/webconsole.js "autocomplete" => { let msg = AutocompleteReply { from: self.name(), - matches: vec!(), + matches: vec![], matchProp: "".to_owned(), }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, "evaluateJS" => { let input = msg.get("text").unwrap().as_str().unwrap().to_owned(); let (chan, port) = ipc::channel().unwrap(); - self.script_chan.send(DevtoolScriptControlMsg::EvaluateJS( - self.pipeline, input.clone(), chan)).unwrap(); + self.script_chan + .send(DevtoolScriptControlMsg::EvaluateJS( + self.pipeline, + input.clone(), + chan, + )).unwrap(); //TODO: extract conversion into protocol module or some other useful place let result = match port.recv().map_err(|_| ())? { @@ -184,12 +204,12 @@ impl Actor for ConsoleActor { let mut m = Map::new(); m.insert("type".to_owned(), Value::String("undefined".to_owned())); Value::Object(m) - } + }, NullValue => { let mut m = Map::new(); m.insert("type".to_owned(), Value::String("null".to_owned())); Value::Object(m) - } + }, BooleanValue(val) => Value::Bool(val), NumberValue(val) => { if val.is_nan() { @@ -211,7 +231,7 @@ impl Actor for ConsoleActor { } else { Value::Number(Number::from_f64(val).unwrap()) } - } + }, StringValue(s) => Value::String(s), ActorValue { class, uuid } => { //TODO: make initial ActorValue message include these properties? @@ -225,7 +245,7 @@ impl Actor for ConsoleActor { m.insert("frozen".to_owned(), Value::Bool(false)); m.insert("sealed".to_owned(), Value::Bool(false)); Value::Object(m) - } + }, }; //TODO: catch and return exception values from JS evaluation @@ -240,7 +260,7 @@ impl Actor for ConsoleActor { }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, "setPreferences" => { let msg = SetPreferencesReply { @@ -249,9 +269,9 @@ impl Actor for ConsoleActor { }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, - _ => ActorMessageStatus::Ignored + _ => ActorMessageStatus::Ignored, }) } } diff --git a/components/devtools/actors/framerate.rs b/components/devtools/actors/framerate.rs index 39776c131cb..56145c63620 100644 --- a/components/devtools/actors/framerate.rs +++ b/components/devtools/actors/framerate.rs @@ -26,21 +26,24 @@ impl Actor for FramerateActor { self.name.clone() } - - fn handle_message(&self, - _registry: &ActorRegistry, - _msg_type: &str, - _msg: &Map, - _stream: &mut TcpStream) -> Result { + fn handle_message( + &self, + _registry: &ActorRegistry, + _msg_type: &str, + _msg: &Map, + _stream: &mut TcpStream, + ) -> Result { Ok(ActorMessageStatus::Ignored) } } impl FramerateActor { /// return name of actor - pub fn create(registry: &ActorRegistry, - pipeline_id: PipelineId, - script_sender: IpcSender) -> String { + pub fn create( + registry: &ActorRegistry, + pipeline_id: PipelineId, + script_sender: IpcSender, + ) -> String { let actor_name = registry.new_name("framerate"); let mut actor = FramerateActor { name: actor_name.clone(), @@ -60,8 +63,7 @@ impl FramerateActor { self.ticks.push(HighResolutionStamp::wrap(tick)); if self.is_recording { - let msg = DevtoolScriptControlMsg::RequestAnimationFrame(self.pipeline, - self.name()); + let msg = DevtoolScriptControlMsg::RequestAnimationFrame(self.pipeline, self.name()); self.script_sender.send(msg).unwrap(); } } @@ -78,8 +80,7 @@ impl FramerateActor { self.start_time = Some(precise_time_ns()); self.is_recording = true; - let msg = DevtoolScriptControlMsg::RequestAnimationFrame(self.pipeline, - self.name()); + let msg = DevtoolScriptControlMsg::RequestAnimationFrame(self.pipeline, self.name()); self.script_sender.send(msg).unwrap(); } @@ -90,7 +91,6 @@ impl FramerateActor { self.is_recording = false; self.start_time = None; } - } impl Drop for FramerateActor { diff --git a/components/devtools/actors/inspector.rs b/components/devtools/actors/inspector.rs index 22a69421ad8..040ba342155 100644 --- a/components/devtools/actors/inspector.rs +++ b/components/devtools/actors/inspector.rs @@ -61,27 +61,25 @@ impl Actor for HighlighterActor { self.name.clone() } - fn handle_message(&self, - _registry: &ActorRegistry, - msg_type: &str, - _msg: &Map, - stream: &mut TcpStream) -> Result { + fn handle_message( + &self, + _registry: &ActorRegistry, + msg_type: &str, + _msg: &Map, + stream: &mut TcpStream, + ) -> Result { Ok(match msg_type { "showBoxModel" => { - let msg = ShowBoxModelReply { - from: self.name(), - }; + let msg = ShowBoxModelReply { from: self.name() }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, "hideBoxModel" => { - let msg = HideBoxModelReply { - from: self.name(), - }; + let msg = HideBoxModelReply { from: self.name() }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, _ => ActorMessageStatus::Ignored, }) @@ -98,29 +96,33 @@ impl Actor for NodeActor { self.name.clone() } - fn handle_message(&self, - registry: &ActorRegistry, - msg_type: &str, - msg: &Map, - stream: &mut TcpStream) -> Result { + fn handle_message( + &self, + registry: &ActorRegistry, + msg_type: &str, + msg: &Map, + stream: &mut TcpStream, + ) -> Result { Ok(match msg_type { "modifyAttributes" => { let target = msg.get("to").unwrap().as_str().unwrap(); let mods = msg.get("modifications").unwrap().as_array().unwrap(); - let modifications = mods.iter().map(|json_mod| { - serde_json::from_str(&serde_json::to_string(json_mod).unwrap()).unwrap() - }).collect(); + let modifications = mods + .iter() + .map(|json_mod| { + serde_json::from_str(&serde_json::to_string(json_mod).unwrap()).unwrap() + }).collect(); - self.script_chan.send(ModifyAttribute(self.pipeline, - registry.actor_to_script(target.to_owned()), - modifications)) - .unwrap(); - let reply = ModifyAttributeReply { - from: self.name(), - }; + self.script_chan + .send(ModifyAttribute( + self.pipeline, + registry.actor_to_script(target.to_owned()), + modifications, + )).unwrap(); + let reply = ModifyAttributeReply { from: self.name() }; stream.write_json_packet(&reply); ActorMessageStatus::Processed - } + }, _ => ActorMessageStatus::Ignored, }) @@ -175,19 +177,23 @@ struct NodeActorMsg { } trait NodeInfoToProtocol { - fn encode(self, - actors: &ActorRegistry, - display: bool, - script_chan: IpcSender, - pipeline: PipelineId) -> NodeActorMsg; + fn encode( + self, + actors: &ActorRegistry, + display: bool, + script_chan: IpcSender, + pipeline: PipelineId, + ) -> NodeActorMsg; } impl NodeInfoToProtocol for NodeInfo { - fn encode(self, - actors: &ActorRegistry, - display: bool, - script_chan: IpcSender, - pipeline: PipelineId) -> NodeActorMsg { + fn encode( + self, + actors: &ActorRegistry, + display: bool, + script_chan: IpcSender, + pipeline: PipelineId, + ) -> NodeActorMsg { let actor_name = if !actors.script_actor_registered(self.uniqueId.clone()) { let name = actors.new_name("node"); let node_actor = NodeActor { @@ -215,15 +221,16 @@ impl NodeInfoToProtocol for NodeInfo { publicId: self.publicId, systemId: self.systemId, - attrs: self.attrs.into_iter().map(|attr| { - AttrMsg { + attrs: self + .attrs + .into_iter() + .map(|attr| AttrMsg { namespace: attr.namespace, name: attr.name, value: attr.value, - } - }).collect(), + }).collect(), - pseudoClassLocks: vec!(), //TODO get this data from script + pseudoClassLocks: vec![], //TODO get this data from script isDisplayed: display, @@ -272,25 +279,28 @@ impl Actor for WalkerActor { self.name.clone() } - fn handle_message(&self, - registry: &ActorRegistry, - msg_type: &str, - msg: &Map, - stream: &mut TcpStream) -> Result { + fn handle_message( + &self, + registry: &ActorRegistry, + msg_type: &str, + msg: &Map, + stream: &mut TcpStream, + ) -> Result { Ok(match msg_type { "querySelector" => { - let msg = QuerySelectorReply { - from: self.name(), - }; + let msg = QuerySelectorReply { from: self.name() }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, "documentElement" => { let (tx, rx) = ipc::channel().unwrap(); - self.script_chan.send(GetDocumentElement(self.pipeline, tx)).unwrap(); + self.script_chan + .send(GetDocumentElement(self.pipeline, tx)) + .unwrap(); let doc_elem_info = rx.recv().unwrap().ok_or(())?; - let node = doc_elem_info.encode(registry, true, self.script_chan.clone(), self.pipeline); + let node = + doc_elem_info.encode(registry, true, self.script_chan.clone(), self.pipeline); let msg = DocumentElementReply { from: self.name(), @@ -298,36 +308,38 @@ impl Actor for WalkerActor { }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, "clearPseudoClassLocks" => { - let msg = ClearPseudoclassesReply { - from: self.name(), - }; + let msg = ClearPseudoclassesReply { from: self.name() }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, "children" => { let target = msg.get("node").unwrap().as_str().unwrap(); let (tx, rx) = ipc::channel().unwrap(); - self.script_chan.send(GetChildren(self.pipeline, - registry.actor_to_script(target.to_owned()), - tx)) - .unwrap(); + self.script_chan + .send(GetChildren( + self.pipeline, + registry.actor_to_script(target.to_owned()), + tx, + )).unwrap(); let children = rx.recv().unwrap().ok_or(())?; let msg = ChildrenReply { hasFirst: true, hasLast: true, - nodes: children.into_iter().map(|child| { - child.encode(registry, true, self.script_chan.clone(), self.pipeline) - }).collect(), + nodes: children + .into_iter() + .map(|child| { + child.encode(registry, true, self.script_chan.clone(), self.pipeline) + }).collect(), from: self.name(), }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, _ => ActorMessageStatus::Ignored, }) @@ -447,52 +459,72 @@ impl Actor for PageStyleActor { self.name.clone() } - fn handle_message(&self, - registry: &ActorRegistry, - msg_type: &str, - msg: &Map, - stream: &mut TcpStream) -> Result { + fn handle_message( + &self, + registry: &ActorRegistry, + msg_type: &str, + msg: &Map, + stream: &mut TcpStream, + ) -> Result { Ok(match msg_type { "getApplied" => { //TODO: query script for relevant applied styles to node (msg.node) let msg = GetAppliedReply { - entries: vec!(), - rules: vec!(), - sheets: vec!(), + entries: vec![], + rules: vec![], + sheets: vec![], from: self.name(), }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, "getComputed" => { //TODO: query script for relevant computed styles on node (msg.node) let msg = GetComputedReply { - computed: vec!(), + computed: vec![], from: self.name(), }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, //TODO: query script for box layout properties of node (msg.node) "getLayout" => { let target = msg.get("node").unwrap().as_str().unwrap(); let (tx, rx) = ipc::channel().unwrap(); - self.script_chan.send(GetLayout(self.pipeline, - registry.actor_to_script(target.to_owned()), - tx)) - .unwrap(); + self.script_chan + .send(GetLayout( + self.pipeline, + registry.actor_to_script(target.to_owned()), + tx, + )).unwrap(); let ComputedNodeLayout { - display, position, zIndex, boxSizing, - autoMargins, marginTop, marginRight, marginBottom, marginLeft, - borderTopWidth, borderRightWidth, borderBottomWidth, borderLeftWidth, - paddingTop, paddingRight, paddingBottom, paddingLeft, - width, height, + display, + position, + zIndex, + boxSizing, + autoMargins, + marginTop, + marginRight, + marginBottom, + marginLeft, + borderTopWidth, + borderRightWidth, + borderBottomWidth, + borderLeftWidth, + paddingTop, + paddingRight, + paddingBottom, + paddingLeft, + width, + height, } = rx.recv().unwrap().ok_or(())?; - let auto_margins = msg.get("autoMargins") - .and_then(&Value::as_bool).unwrap_or(false); + let auto_margins = msg + .get("autoMargins") + .and_then(&Value::as_bool) + .unwrap_or(false); // http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/styles.js let msg = GetLayoutReply { @@ -504,10 +536,18 @@ impl Actor for PageStyleActor { autoMargins: if auto_margins { let mut m = Map::new(); let auto = serde_json::value::Value::String("auto".to_owned()); - if autoMargins.top { m.insert("top".to_owned(), auto.clone()); } - if autoMargins.right { m.insert("right".to_owned(), auto.clone()); } - if autoMargins.bottom { m.insert("bottom".to_owned(), auto.clone()); } - if autoMargins.left { m.insert("left".to_owned(), auto.clone()); } + if autoMargins.top { + m.insert("top".to_owned(), auto.clone()); + } + if autoMargins.right { + m.insert("right".to_owned(), auto.clone()); + } + if autoMargins.bottom { + m.insert("bottom".to_owned(), auto.clone()); + } + if autoMargins.left { + m.insert("left".to_owned(), auto.clone()); + } serde_json::value::Value::Object(m) } else { serde_json::value::Value::Null @@ -531,7 +571,7 @@ impl Actor for PageStyleActor { let msg = serde_json::from_str::(&msg).unwrap(); stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, _ => ActorMessageStatus::Ignored, }) @@ -543,11 +583,13 @@ impl Actor for InspectorActor { self.name.clone() } - fn handle_message(&self, - registry: &ActorRegistry, - msg_type: &str, - _msg: &Map, - stream: &mut TcpStream) -> Result { + fn handle_message( + &self, + registry: &ActorRegistry, + msg_type: &str, + _msg: &Map, + stream: &mut TcpStream, + ) -> Result { Ok(match msg_type { "getWalker" => { if self.walker.borrow().is_none() { @@ -562,21 +604,24 @@ impl Actor for InspectorActor { } let (tx, rx) = ipc::channel().unwrap(); - self.script_chan.send(GetRootNode(self.pipeline, tx)).unwrap(); + self.script_chan + .send(GetRootNode(self.pipeline, tx)) + .unwrap(); let root_info = rx.recv().unwrap().ok_or(())?; - let node = root_info.encode(registry, false, self.script_chan.clone(), self.pipeline); + let node = + root_info.encode(registry, false, self.script_chan.clone(), self.pipeline); let msg = GetWalkerReply { from: self.name(), walker: WalkerMsg { actor: self.walker.borrow().clone().unwrap(), root: node, - } + }, }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, "getPageStyle" => { if self.pageStyle.borrow().is_none() { @@ -598,7 +643,7 @@ impl Actor for InspectorActor { }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, //TODO: this is an old message; try adding highlightable to the root traits instead // and support getHighlighter instead @@ -621,7 +666,7 @@ impl Actor for InspectorActor { }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, _ => ActorMessageStatus::Ignored, }) diff --git a/components/devtools/actors/memory.rs b/components/devtools/actors/memory.rs index 518358ea69b..b88b5a3cf20 100644 --- a/components/devtools/actors/memory.rs +++ b/components/devtools/actors/memory.rs @@ -28,11 +28,13 @@ impl Actor for MemoryActor { self.name.clone() } - fn handle_message(&self, - _registry: &ActorRegistry, - _msg_type: &str, - _msg: &Map, - _stream: &mut TcpStream) -> Result { + fn handle_message( + &self, + _registry: &ActorRegistry, + _msg_type: &str, + _msg: &Map, + _stream: &mut TcpStream, + ) -> Result { Ok(ActorMessageStatus::Ignored) } } @@ -42,7 +44,7 @@ impl MemoryActor { pub fn create(registry: &ActorRegistry) -> String { let actor_name = registry.new_name("memory"); let actor = MemoryActor { - name: actor_name.clone() + name: actor_name.clone(), }; registry.register_later(Box::new(actor)); diff --git a/components/devtools/actors/network_event.rs b/components/devtools/actors/network_event.rs index 0906971821a..5e4fe01bcf3 100644 --- a/components/devtools/actors/network_event.rs +++ b/components/devtools/actors/network_event.rs @@ -34,7 +34,7 @@ struct HttpRequest { struct HttpResponse { headers: Option, status: Option, - body: Option> + body: Option>, } pub struct NetworkEventActor { @@ -52,7 +52,7 @@ pub struct EventActor { pub startedDateTime: String, pub timeStamp: i64, pub isXHR: bool, - pub private: bool + pub private: bool, } #[derive(Serialize)] @@ -79,14 +79,12 @@ pub struct ResponseContentMsg { pub discardResponseBody: bool, } - #[derive(Serialize)] pub struct ResponseHeadersMsg { pub headers: usize, pub headersSize: usize, } - #[derive(Serialize)] pub struct RequestCookiesMsg { pub cookies: usize, @@ -103,7 +101,7 @@ struct GetRequestHeadersReply { from: String, headers: Vec
, headerSize: usize, - rawHeaders: String + rawHeaders: String, } #[derive(Serialize)] @@ -117,7 +115,7 @@ struct GetResponseHeadersReply { from: String, headers: Vec
, headerSize: usize, - rawHeaders: String + rawHeaders: String, } #[derive(Serialize)] @@ -131,19 +129,19 @@ struct GetResponseContentReply { struct GetRequestPostDataReply { from: String, postData: Option>, - postDataDiscarded: bool + postDataDiscarded: bool, } #[derive(Serialize)] struct GetRequestCookiesReply { from: String, - cookies: Vec + cookies: Vec, } #[derive(Serialize)] struct GetResponseCookiesReply { from: String, - cookies: Vec + cookies: Vec, } #[derive(Serialize)] @@ -179,11 +177,13 @@ impl Actor for NetworkEventActor { self.name.clone() } - fn handle_message(&self, - _registry: &ActorRegistry, - msg_type: &str, - _msg: &Map, - stream: &mut TcpStream) -> Result { + fn handle_message( + &self, + _registry: &ActorRegistry, + msg_type: &str, + _msg: &Map, + stream: &mut TcpStream, + ) -> Result { Ok(match msg_type { "getRequestHeaders" => { let mut headers = Vec::new(); @@ -194,7 +194,10 @@ impl Actor for NetworkEventActor { let value = item.value_string(); rawHeadersString = rawHeadersString + name + ":" + &value + "\r\n"; headersSize += name.len() + value.len(); - headers.push(Header { name: name.to_owned(), value: value.to_owned() }); + headers.push(Header { + name: name.to_owned(), + value: value.to_owned(), + }); } let msg = GetRequestHeadersReply { from: self.name(), @@ -204,7 +207,7 @@ impl Actor for NetworkEventActor { }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, "getRequestCookies" => { let mut cookies = Vec::new(); if let Some(req_cookies) = self.request.headers.get_raw("Cookie") { @@ -221,7 +224,7 @@ impl Actor for NetworkEventActor { }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, "getRequestPostData" => { let msg = GetRequestPostDataReply { from: self.name(), @@ -230,7 +233,7 @@ impl Actor for NetworkEventActor { }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, "getResponseHeaders" => { if let Some(ref response_headers) = self.response.headers { let mut headers = vec![]; @@ -258,7 +261,7 @@ impl Actor for NetworkEventActor { stream.write_json_packet(&msg); } ActorMessageStatus::Processed - } + }, "getResponseCookies" => { let mut cookies = Vec::new(); if let Some(res_cookies) = self.request.headers.get_raw("set-cookie") { @@ -275,7 +278,7 @@ impl Actor for NetworkEventActor { }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, "getResponseContent" => { let msg = GetResponseContentReply { from: self.name(), @@ -284,7 +287,7 @@ impl Actor for NetworkEventActor { }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, "getEventTimings" => { // TODO: This is a fake timings msg let timingsObj = Timings { @@ -304,19 +307,19 @@ impl Actor for NetworkEventActor { }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, "getSecurityInfo" => { // TODO: Send the correct values for securityInfo. let msg = GetSecurityInfoReply { from: self.name(), securityInfo: SecurityInfo { - state: "insecure".to_owned() + state: "insecure".to_owned(), }, }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } - _ => ActorMessageStatus::Ignored + }, + _ => ActorMessageStatus::Ignored, }) } } @@ -382,8 +385,13 @@ impl NetworkEventActor { // TODO: Send the correct values for all these fields. let hSizeOption = self.response.headers.as_ref().map(|headers| headers.len()); let hSize = hSizeOption.unwrap_or(0); - let (status_code, status_message) = self.response.status.as_ref(). - map_or((0, "".to_owned()), |&RawStatus(ref code, ref text)| (*code, text.clone().into_owned())); + let (status_code, status_message) = self + .response + .status + .as_ref() + .map_or((0, "".to_owned()), |&RawStatus(ref code, ref text)| { + (*code, text.clone().into_owned()) + }); // TODO: Send the correct values for remoteAddress and remotePort and http_version. ResponseStartMsg { httpVersion: "HTTP/1.1".to_owned(), @@ -392,7 +400,7 @@ impl NetworkEventActor { status: status_code.to_string(), statusText: status_message, headersSize: hSize, - discardResponseBody: false + discardResponseBody: false, } } @@ -401,7 +409,7 @@ impl NetworkEventActor { if let Some(ref headers) = self.response.headers { mString = match headers.get() { Some(&ContentType(ref mime)) => mime.to_string(), - None => "".to_owned() + None => "".to_owned(), }; } // TODO: Set correct values when response's body is sent to the devtools in http_loader. @@ -418,7 +426,7 @@ impl NetworkEventActor { if let Some(ref headers) = self.response.headers { cookies_size = match headers.get() { Some(&Cookie(ref cookie)) => cookie.len(), - None => 0 + None => 0, }; } ResponseCookiesMsg { @@ -431,10 +439,9 @@ impl NetworkEventActor { let mut headers_byte_count = 0; if let Some(ref headers) = self.response.headers { headers_size = headers.len(); - for item in headers.iter() { + for item in headers.iter() { headers_byte_count += item.name().len() + item.value_string().len(); } - } ResponseHeadersMsg { headers: headers_size, @@ -443,10 +450,11 @@ impl NetworkEventActor { } pub fn request_headers(&self) -> RequestHeadersMsg { - let size = self.request - .headers - .iter() - .fold(0, |acc, h| acc + h.name().len() + h.value_string().len()); + let size = self + .request + .headers + .iter() + .fold(0, |acc, h| acc + h.name().len() + h.value_string().len()); RequestHeadersMsg { headers: self.request.headers.len(), headersSize: size, @@ -456,7 +464,7 @@ impl NetworkEventActor { pub fn request_cookies(&self) -> RequestCookiesMsg { let cookies_size = match self.request.headers.get() { Some(&Cookie(ref cookie)) => cookie.len(), - None => 0 + None => 0, }; RequestCookiesMsg { cookies: cookies_size, diff --git a/components/devtools/actors/object.rs b/components/devtools/actors/object.rs index 943adf8b5fc..0ed2facf848 100644 --- a/components/devtools/actors/object.rs +++ b/components/devtools/actors/object.rs @@ -15,11 +15,13 @@ impl Actor for ObjectActor { fn name(&self) -> String { self.name.clone() } - fn handle_message(&self, - _: &ActorRegistry, - _: &str, - _: &Map, - _: &mut TcpStream) -> Result { + fn handle_message( + &self, + _: &ActorRegistry, + _: &str, + _: &Map, + _: &mut TcpStream, + ) -> Result { Ok(ActorMessageStatus::Ignored) } } diff --git a/components/devtools/actors/performance.rs b/components/devtools/actors/performance.rs index c246cb26fa4..b3f367958a6 100644 --- a/components/devtools/actors/performance.rs +++ b/components/devtools/actors/performance.rs @@ -51,11 +51,13 @@ impl Actor for PerformanceActor { self.name.clone() } - fn handle_message(&self, - _registry: &ActorRegistry, - msg_type: &str, - _msg: &Map, - stream: &mut TcpStream) -> Result { + fn handle_message( + &self, + _registry: &ActorRegistry, + msg_type: &str, + _msg: &Map, + stream: &mut TcpStream, + ) -> Result { Ok(match msg_type { "connect" => { let msg = ConnectReply { @@ -79,11 +81,11 @@ impl Actor for PerformanceActor { value: SuccessMsg { success: true, errors: vec![], - } + }, }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, _ => ActorMessageStatus::Ignored, }) } @@ -91,28 +93,34 @@ impl Actor for PerformanceActor { impl PerformanceActor { pub fn new(name: String) -> PerformanceActor { - PerformanceActor { - name: name, - } + PerformanceActor { name: name } } pub fn description() -> ActorDescription { ActorDescription { category: "actor", typeName: "performance", - methods: vec![ - Method { - name: "canCurrentlyRecord", - request: Value::Object(vec![ - ("type".to_owned(), Value::String("canCurrentlyRecord".to_owned())), - ].into_iter().collect()), - response: Value::Object(vec![ - ("value".to_owned(), Value::Object(vec![ - ("_retval".to_owned(), Value::String("json".to_owned())), - ].into_iter().collect())), - ].into_iter().collect()), - }, - ], + methods: vec![Method { + name: "canCurrentlyRecord", + request: Value::Object( + vec![( + "type".to_owned(), + Value::String("canCurrentlyRecord".to_owned()), + )].into_iter() + .collect(), + ), + response: Value::Object( + vec![( + "value".to_owned(), + Value::Object( + vec![("_retval".to_owned(), Value::String("json".to_owned()))] + .into_iter() + .collect(), + ), + )].into_iter() + .collect(), + ), + }], } } } diff --git a/components/devtools/actors/profiler.rs b/components/devtools/actors/profiler.rs index a80e3c0018b..cb19f7afb6b 100644 --- a/components/devtools/actors/profiler.rs +++ b/components/devtools/actors/profiler.rs @@ -15,19 +15,19 @@ impl Actor for ProfilerActor { self.name.clone() } - fn handle_message(&self, - _registry: &ActorRegistry, - _msg_type: &str, - _msg: &Map, - _stream: &mut TcpStream) -> Result { + fn handle_message( + &self, + _registry: &ActorRegistry, + _msg_type: &str, + _msg: &Map, + _stream: &mut TcpStream, + ) -> Result { Ok(ActorMessageStatus::Ignored) } } impl ProfilerActor { pub fn new(name: String) -> ProfilerActor { - ProfilerActor { - name: name, - } + ProfilerActor { name: name } } } diff --git a/components/devtools/actors/root.rs b/components/devtools/actors/root.rs index 20629ea7a7b..4e12055ec8e 100644 --- a/components/devtools/actors/root.rs +++ b/components/devtools/actors/root.rs @@ -6,7 +6,6 @@ /// (http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/root.js). /// Connection point for all new remote devtools interactions, providing lists of know actors /// that perform more specific actions (tabs, addons, browser chrome, etc.) - use actor::{Actor, ActorMessageStatus, ActorRegistry}; use actors::performance::PerformanceActor; use actors::tab::{TabActor, TabActorMsg}; @@ -65,11 +64,13 @@ impl Actor for RootActor { "root".to_owned() } - fn handle_message(&self, - registry: &ActorRegistry, - msg_type: &str, - _msg: &Map, - stream: &mut TcpStream) -> Result { + fn handle_message( + &self, + registry: &ActorRegistry, + msg_type: &str, + _msg: &Map, + stream: &mut TcpStream, + ) -> Result { Ok(match msg_type { "listAddons" => { let actor = ListAddonsReply { @@ -78,20 +79,22 @@ impl Actor for RootActor { }; stream.write_json_packet(&actor); ActorMessageStatus::Processed - } + }, //https://wiki.mozilla.org/Remote_Debugging_Protocol#Listing_Browser_Tabs "listTabs" => { let actor = ListTabsReply { from: "root".to_owned(), selected: 0, - tabs: self.tabs.iter().map(|tab| { - registry.find::(tab).encodable() - }).collect() + tabs: self + .tabs + .iter() + .map(|tab| registry.find::(tab).encodable()) + .collect(), }; stream.write_json_packet(&actor); ActorMessageStatus::Processed - } + }, "protocolDescription" => { let msg = ProtocolDescriptionReply { @@ -102,9 +105,9 @@ impl Actor for RootActor { }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, - _ => ActorMessageStatus::Ignored + _ => ActorMessageStatus::Ignored, }) } } @@ -118,7 +121,7 @@ impl RootActor { sources: true, highlightable: true, customHighlighters: true, - networkMonitor: true + networkMonitor: true, }, } } diff --git a/components/devtools/actors/tab.rs b/components/devtools/actors/tab.rs index 916c5319386..e6f50773f68 100644 --- a/components/devtools/actors/tab.rs +++ b/components/devtools/actors/tab.rs @@ -37,7 +37,7 @@ struct TabDetachedReply { #[derive(Serialize)] struct ReconfigureReply { - from: String + from: String, } #[derive(Serialize)] @@ -84,25 +84,28 @@ impl Actor for TabActor { self.name.clone() } - fn handle_message(&self, - registry: &ActorRegistry, - msg_type: &str, - msg: &Map, - stream: &mut TcpStream) -> Result { + fn handle_message( + &self, + registry: &ActorRegistry, + msg_type: &str, + msg: &Map, + stream: &mut TcpStream, + ) -> Result { Ok(match msg_type { "reconfigure" => { if let Some(options) = msg.get("options").and_then(|o| o.as_object()) { if let Some(val) = options.get("performReload") { if val.as_bool().unwrap_or(false) { let console_actor = registry.find::(&self.console); - let _ = console_actor.script_chan.send( - DevtoolScriptControlMsg::Reload(console_actor.pipeline)); + let _ = console_actor + .script_chan + .send(DevtoolScriptControlMsg::Reload(console_actor.pipeline)); } } } stream.write_json_packet(&ReconfigureReply { from: self.name() }); ActorMessageStatus::Processed - } + }, // https://wiki.mozilla.org/Remote_Debugging_Protocol#Listing_Browser_Tabs // (see "To attach to a _tabActor_") @@ -116,12 +119,17 @@ impl Actor for TabActor { traits: TabTraits, }; let console_actor = registry.find::(&self.console); - console_actor.streams.borrow_mut().push(stream.try_clone().unwrap()); + console_actor + .streams + .borrow_mut() + .push(stream.try_clone().unwrap()); stream.write_json_packet(&msg); - console_actor.script_chan.send( - WantsLiveNotifications(console_actor.pipeline, true)).unwrap(); + console_actor + .script_chan + .send(WantsLiveNotifications(console_actor.pipeline, true)) + .unwrap(); ActorMessageStatus::Processed - } + }, //FIXME: The current implementation won't work for multiple connections. Need to ensure 105 // that the correct stream is removed. @@ -133,21 +141,23 @@ impl Actor for TabActor { let console_actor = registry.find::(&self.console); console_actor.streams.borrow_mut().pop(); stream.write_json_packet(&msg); - console_actor.script_chan.send( - WantsLiveNotifications(console_actor.pipeline, false)).unwrap(); + console_actor + .script_chan + .send(WantsLiveNotifications(console_actor.pipeline, false)) + .unwrap(); ActorMessageStatus::Processed - } + }, "listFrames" => { let msg = ListFramesReply { from: self.name(), - frames: vec!(), + frames: vec![], }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, - _ => ActorMessageStatus::Ignored + _ => ActorMessageStatus::Ignored, }) } } diff --git a/components/devtools/actors/thread.rs b/components/devtools/actors/thread.rs index 7be5bc55f23..dc2638bd135 100644 --- a/components/devtools/actors/thread.rs +++ b/components/devtools/actors/thread.rs @@ -35,7 +35,7 @@ struct ThreadResumedReply { #[derive(Serialize)] struct ReconfigureReply { - from: String + from: String, } #[derive(Serialize)] @@ -53,9 +53,7 @@ pub struct ThreadActor { impl ThreadActor { pub fn new(name: String) -> ThreadActor { - ThreadActor { - name: name, - } + ThreadActor { name: name } } } @@ -64,11 +62,13 @@ impl Actor for ThreadActor { self.name.clone() } - fn handle_message(&self, - registry: &ActorRegistry, - msg_type: &str, - _msg: &Map, - stream: &mut TcpStream) -> Result { + fn handle_message( + &self, + registry: &ActorRegistry, + msg_type: &str, + _msg: &Map, + stream: &mut TcpStream, + ) -> Result { Ok(match msg_type { "attach" => { let msg = ThreadAttachedReply { @@ -76,7 +76,9 @@ impl Actor for ThreadActor { type_: "paused".to_owned(), actor: registry.new_name("pause"), poppedFrames: vec![], - why: WhyMsg { type_: "attached".to_owned() }, + why: WhyMsg { + type_: "attached".to_owned(), + }, }; stream.write_json_packet(&msg); ActorMessageStatus::Processed @@ -94,7 +96,7 @@ impl Actor for ThreadActor { "reconfigure" => { stream.write_json_packet(&ReconfigureReply { from: self.name() }); ActorMessageStatus::Processed - } + }, "sources" => { let msg = SourcesReply { @@ -103,7 +105,7 @@ impl Actor for ThreadActor { }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, _ => ActorMessageStatus::Ignored, }) diff --git a/components/devtools/actors/timeline.rs b/components/devtools/actors/timeline.rs index 0ea57ad8dbb..d5b5295a138 100644 --- a/components/devtools/actors/timeline.rs +++ b/components/devtools/actors/timeline.rs @@ -44,7 +44,7 @@ struct Emitter { #[derive(Serialize)] struct IsRecordingReply { from: String, - value: bool + value: bool, } #[derive(Serialize)] @@ -103,8 +103,10 @@ pub struct HighResolutionStamp(f64); impl HighResolutionStamp { pub fn new(start_stamp: PreciseTime, time: PreciseTime) -> HighResolutionStamp { - let duration = start_stamp.to(time).num_microseconds() - .expect("Too big duration in microseconds"); + let duration = start_stamp + .to(time) + .num_microseconds() + .expect("Too big duration in microseconds"); HighResolutionStamp(duration as f64 / 1000 as f64) } @@ -122,11 +124,12 @@ impl Serialize for HighResolutionStamp { static DEFAULT_TIMELINE_DATA_PULL_TIMEOUT: u64 = 200; //ms impl TimelineActor { - pub fn new(name: String, - pipeline: PipelineId, - script_sender: IpcSender) -> TimelineActor { - let marker_types = vec!(TimelineMarkerType::Reflow, - TimelineMarkerType::DOMEvent); + pub fn new( + name: String, + pipeline: PipelineId, + script_sender: IpcSender, + ) -> TimelineActor { + let marker_types = vec![TimelineMarkerType::Reflow, TimelineMarkerType::DOMEvent]; TimelineActor { name: name, @@ -141,15 +144,20 @@ impl TimelineActor { } } - fn pull_timeline_data(&self, receiver: IpcReceiver>, mut emitter: Emitter) { + fn pull_timeline_data( + &self, + receiver: IpcReceiver>, + mut emitter: Emitter, + ) { let is_recording = self.is_recording.clone(); if !*is_recording.lock().unwrap() { return; } - thread::Builder::new().name("PullTimelineMarkers".to_owned()).spawn(move || { - loop { + thread::Builder::new() + .name("PullTimelineMarkers".to_owned()) + .spawn(move || loop { if !*is_recording.lock().unwrap() { break; } @@ -161,8 +169,7 @@ impl TimelineActor { emitter.send(markers); thread::sleep(Duration::from_millis(DEFAULT_TIMELINE_DATA_PULL_TIMEOUT)); - } - }).expect("Thread spawning failed"); + }).expect("Thread spawning failed"); } } @@ -171,19 +178,24 @@ impl Actor for TimelineActor { self.name.clone() } - fn handle_message(&self, - registry: &ActorRegistry, - msg_type: &str, - msg: &Map, - stream: &mut TcpStream) -> Result { + fn handle_message( + &self, + registry: &ActorRegistry, + msg_type: &str, + msg: &Map, + stream: &mut TcpStream, + ) -> Result { Ok(match msg_type { "start" => { **self.is_recording.lock().as_mut().unwrap() = true; let (tx, rx) = ipc::channel::>().unwrap(); - self.script_sender.send(SetTimelineMarkers(self.pipeline, - self.marker_types.clone(), - tx)).unwrap(); + self.script_sender + .send(SetTimelineMarkers( + self.pipeline, + self.marker_types.clone(), + tx, + )).unwrap(); *self.stream.borrow_mut() = stream.try_clone().ok(); @@ -198,18 +210,22 @@ impl Actor for TimelineActor { if let Some(with_ticks) = msg.get("withTicks") { if let Some(true) = with_ticks.as_bool() { let framerate_actor = Some(FramerateActor::create( - registry, - self.pipeline.clone(), - self.script_sender.clone())); + registry, + self.pipeline.clone(), + self.script_sender.clone(), + )); *self.framerate_actor.borrow_mut() = framerate_actor; } } - let emitter = Emitter::new(self.name(), registry.shareable(), - registry.start_stamp(), - stream.try_clone().unwrap(), - self.memory_actor.borrow().clone(), - self.framerate_actor.borrow().clone()); + let emitter = Emitter::new( + self.name(), + registry.shareable(), + registry.start_stamp(), + stream.try_clone().unwrap(), + self.memory_actor.borrow().clone(), + self.framerate_actor.borrow().clone(), + ); self.pull_timeline_data(rx, emitter); @@ -219,7 +235,7 @@ impl Actor for TimelineActor { }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, "stop" => { let msg = StopReply { @@ -228,7 +244,11 @@ impl Actor for TimelineActor { }; stream.write_json_packet(&msg); - self.script_sender.send(DropTimelineMarkers(self.pipeline, self.marker_types.clone())).unwrap(); + self.script_sender + .send(DropTimelineMarkers( + self.pipeline, + self.marker_types.clone(), + )).unwrap(); if let Some(ref actor_name) = *self.framerate_actor.borrow() { registry.drop_actor_later(actor_name.clone()); @@ -241,32 +261,32 @@ impl Actor for TimelineActor { **self.is_recording.lock().as_mut().unwrap() = false; self.stream.borrow_mut().take(); ActorMessageStatus::Processed - } + }, "isRecording" => { let msg = IsRecordingReply { from: self.name(), - value: self.is_recording.lock().unwrap().clone() + value: self.is_recording.lock().unwrap().clone(), }; stream.write_json_packet(&msg); ActorMessageStatus::Processed - } + }, - _ => { - ActorMessageStatus::Ignored - } + _ => ActorMessageStatus::Ignored, }) } } impl Emitter { - pub fn new(name: String, - registry: Arc>, - start_stamp: PreciseTime, - stream: TcpStream, - memory_actor_name: Option, - framerate_actor_name: Option) -> Emitter { + pub fn new( + name: String, + registry: Arc>, + start_stamp: PreciseTime, + stream: TcpStream, + memory_actor_name: Option, + framerate_actor_name: Option, + ) -> Emitter { Emitter { from: name, stream: stream, diff --git a/components/devtools/actors/worker.rs b/components/devtools/actors/worker.rs index 1beead719dc..9ccc5b2e10b 100644 --- a/components/devtools/actors/worker.rs +++ b/components/devtools/actors/worker.rs @@ -17,11 +17,13 @@ impl Actor for WorkerActor { fn name(&self) -> String { self.name.clone() } - fn handle_message(&self, - _: &ActorRegistry, - _: &str, - _: &Map, - _: &mut TcpStream) -> Result { + fn handle_message( + &self, + _: &ActorRegistry, + _: &str, + _: &Map, + _: &mut TcpStream, + ) -> Result { Ok(ActorMessageStatus::Processed) } } diff --git a/components/devtools/lib.rs b/components/devtools/lib.rs index 31a98d7d5a6..2e11fa0eda2 100644 --- a/components/devtools/lib.rs +++ b/components/devtools/lib.rs @@ -9,7 +9,6 @@ #![crate_name = "devtools"] #![crate_type = "rlib"] - #![allow(non_snake_case)] #![deny(unsafe_code)] @@ -19,7 +18,8 @@ extern crate ipc_channel; #[macro_use] extern crate log; extern crate msg; -#[macro_use] extern crate serde; +#[macro_use] +extern crate serde; extern crate serde_json; extern crate time; @@ -128,23 +128,24 @@ pub fn start_server(port: u16) -> Sender { let (sender, receiver) = channel(); { let sender = sender.clone(); - thread::Builder::new().name("Devtools".to_owned()).spawn(move || { - run_server(sender, receiver, port) - }).expect("Thread spawning failed"); + thread::Builder::new() + .name("Devtools".to_owned()) + .spawn(move || run_server(sender, receiver, port)) + .expect("Thread spawning failed"); } sender } -fn run_server(sender: Sender, - receiver: Receiver, - port: u16) { +fn run_server( + sender: Sender, + receiver: Receiver, + port: u16, +) { let listener = TcpListener::bind(&("127.0.0.1", port)).unwrap(); let mut registry = ActorRegistry::new(); - let root = Box::new(RootActor { - tabs: vec!(), - }); + let root = Box::new(RootActor { tabs: vec![] }); registry.register(root); registry.find::("root"); @@ -158,7 +159,6 @@ fn run_server(sender: Sender, let mut actor_workers: HashMap<(PipelineId, WorkerId), String> = HashMap::new(); - /// Process the input from a single devtools client until EOF. fn handle_client(actors: Arc>, mut stream: TcpStream) { debug!("connection established to {}", stream.peer_addr().unwrap()); @@ -171,21 +171,24 @@ fn run_server(sender: Sender, 'outer: loop { match stream.read_json_packet() { Ok(Some(json_packet)) => { - if let Err(()) = actors.lock().unwrap().handle_message(json_packet.as_object().unwrap(), - &mut stream) { + if let Err(()) = actors + .lock() + .unwrap() + .handle_message(json_packet.as_object().unwrap(), &mut stream) + { debug!("error: devtools actor stopped responding"); let _ = stream.shutdown(Shutdown::Both); - break 'outer + break 'outer; } - } + }, Ok(None) => { debug!("error: EOF"); - break 'outer - } + break 'outer; + }, Err(err_msg) => { debug!("error: {}", err_msg); - break 'outer - } + break 'outer; + }, } } } @@ -199,12 +202,14 @@ fn run_server(sender: Sender, // We need separate actor representations for each script global that exists; // clients can theoretically connect to multiple globals simultaneously. // TODO: move this into the root or tab modules? - fn handle_new_global(actors: Arc>, - ids: (PipelineId, Option), - script_sender: IpcSender, - actor_pipelines: &mut HashMap, - actor_workers: &mut HashMap<(PipelineId, WorkerId), String>, - page_info: DevtoolsPageInfo) { + fn handle_new_global( + actors: Arc>, + ids: (PipelineId, Option), + script_sender: IpcSender, + actor_pipelines: &mut HashMap, + actor_workers: &mut HashMap<(PipelineId, WorkerId), String>, + page_info: DevtoolsPageInfo, + ) { let mut actors = actors.lock().unwrap(); let (pipeline, worker_id) = ids; @@ -226,9 +231,7 @@ fn run_server(sender: Sender, pipeline: pipeline, }; - let timeline = TimelineActor::new(actors.new_name("timeline"), - pipeline, - script_sender); + let timeline = TimelineActor::new(actors.new_name("timeline"), pipeline, script_sender); let profiler = ProfilerActor::new(actors.new_name("profiler")); let performance = PerformanceActor::new(actors.new_name("performance")); @@ -251,7 +254,15 @@ fn run_server(sender: Sender, let root = actors.find_mut::("root"); root.tabs.push(tab.name.clone()); - (tab, console, inspector, timeline, profiler, performance, thread) + ( + tab, + console, + inspector, + timeline, + profiler, + performance, + thread, + ) }; if let Some(id) = worker_id { @@ -274,14 +285,21 @@ fn run_server(sender: Sender, actors.register(Box::new(thread)); } - fn handle_console_message(actors: Arc>, - id: PipelineId, - worker_id: Option, - console_message: ConsoleMessage, - actor_pipelines: &HashMap, - actor_workers: &HashMap<(PipelineId, WorkerId), String>) { - let console_actor_name = match find_console_actor(actors.clone(), id, worker_id, actor_workers, - actor_pipelines) { + fn handle_console_message( + actors: Arc>, + id: PipelineId, + worker_id: Option, + console_message: ConsoleMessage, + actor_pipelines: &HashMap, + actor_workers: &HashMap<(PipelineId, WorkerId), String>, + ) { + let console_actor_name = match find_console_actor( + actors.clone(), + id, + worker_id, + actor_workers, + actor_pipelines, + ) { Some(name) => name, None => return, }; @@ -296,10 +314,10 @@ fn run_server(sender: Sender, LogLevel::Info => "info", LogLevel::Warn => "warn", LogLevel::Error => "error", - _ => "log" + _ => "log", }.to_owned(), timeStamp: precise_time_ns(), - arguments: vec!(console_message.message), + arguments: vec![console_message.message], filename: console_message.filename, lineNumber: console_message.lineNumber, columnNumber: console_message.columnNumber, @@ -310,11 +328,13 @@ fn run_server(sender: Sender, } } - fn find_console_actor(actors: Arc>, - id: PipelineId, - worker_id: Option, - actor_workers: &HashMap<(PipelineId, WorkerId), String>, - actor_pipelines: &HashMap) -> Option { + fn find_console_actor( + actors: Arc>, + id: PipelineId, + worker_id: Option, + actor_workers: &HashMap<(PipelineId, WorkerId), String>, + actor_pipelines: &HashMap, + ) -> Option { let actors = actors.lock().unwrap(); if let Some(worker_id) = worker_id { let actor_name = (*actor_workers).get(&(id, worker_id))?; @@ -325,20 +345,28 @@ fn run_server(sender: Sender, } } - fn handle_network_event(actors: Arc>, - mut connections: Vec, - actor_pipelines: &HashMap, - actor_requests: &mut HashMap, - actor_workers: &HashMap<(PipelineId, WorkerId), String>, - pipeline_id: PipelineId, - request_id: String, - network_event: NetworkEvent) { - let console_actor_name = match find_console_actor(actors.clone(), pipeline_id, None, - actor_workers, actor_pipelines) { + fn handle_network_event( + actors: Arc>, + mut connections: Vec, + actor_pipelines: &HashMap, + actor_requests: &mut HashMap, + actor_workers: &HashMap<(PipelineId, WorkerId), String>, + pipeline_id: PipelineId, + request_id: String, + network_event: NetworkEvent, + ) { + let console_actor_name = match find_console_actor( + actors.clone(), + pipeline_id, + None, + actor_workers, + actor_pipelines, + ) { Some(name) => name, None => return, }; - let netevent_actor_name = find_network_event_actor(actors.clone(), actor_requests, request_id.clone()); + let netevent_actor_name = + find_network_event_actor(actors.clone(), actor_requests, request_id.clone()); let mut actors = actors.lock().unwrap(); let actor = actors.find_mut::(&netevent_actor_name); @@ -356,8 +384,7 @@ fn run_server(sender: Sender, for stream in &mut connections { stream.write_json_packet(&msg); } - - } + }, NetworkEvent::HttpResponse(httpresponse) => { //Store the response information in the actor actor.add_response(httpresponse); @@ -385,7 +412,7 @@ fn run_server(sender: Sender, from: netevent_actor_name.clone(), type_: "networkEventUpdate".to_owned(), updateType: "responseStart".to_owned(), - response: actor.response_start() + response: actor.response_start(), }; for stream in &mut connections { @@ -441,78 +468,109 @@ fn run_server(sender: Sender, for stream in &mut connections { stream.write_merged_json_packet(&msg, &actor.response_headers()); } - } + }, } } // Find the name of NetworkEventActor corresponding to request_id // Create a new one if it does not exist, add it to the actor_requests hashmap - fn find_network_event_actor(actors: Arc>, - actor_requests: &mut HashMap, - request_id: String) -> String { + fn find_network_event_actor( + actors: Arc>, + actor_requests: &mut HashMap, + request_id: String, + ) -> String { let mut actors = actors.lock().unwrap(); match (*actor_requests).entry(request_id) { Occupied(name) => { //TODO: Delete from map like Firefox does? name.into_mut().clone() - } + }, Vacant(entry) => { let actor_name = actors.new_name("netevent"); let actor = NetworkEventActor::new(actor_name.clone()); entry.insert(actor_name.clone()); actors.register(Box::new(actor)); actor_name - } + }, } } let sender_clone = sender.clone(); - thread::Builder::new().name("DevtoolsClientAcceptor".to_owned()).spawn(move || { - // accept connections and process them, spawning a new thread for each one - for stream in listener.incoming() { - // connection succeeded - sender_clone.send(DevtoolsControlMsg::FromChrome( - ChromeToDevtoolsControlMsg::AddClient(stream.unwrap()))).unwrap(); - } - }).expect("Thread spawning failed"); + thread::Builder::new() + .name("DevtoolsClientAcceptor".to_owned()) + .spawn(move || { + // accept connections and process them, spawning a new thread for each one + for stream in listener.incoming() { + // connection succeeded + sender_clone + .send(DevtoolsControlMsg::FromChrome( + ChromeToDevtoolsControlMsg::AddClient(stream.unwrap()), + )).unwrap(); + } + }).expect("Thread spawning failed"); while let Ok(msg) = receiver.recv() { match msg { DevtoolsControlMsg::FromChrome(ChromeToDevtoolsControlMsg::AddClient(stream)) => { let actors = actors.clone(); accepted_connections.push(stream.try_clone().unwrap()); - thread::Builder::new().name("DevtoolsClientHandler".to_owned()).spawn(move || { - handle_client(actors, stream.try_clone().unwrap()) - }).expect("Thread spawning failed"); - } + thread::Builder::new() + .name("DevtoolsClientHandler".to_owned()) + .spawn(move || handle_client(actors, stream.try_clone().unwrap())) + .expect("Thread spawning failed"); + }, DevtoolsControlMsg::FromScript(ScriptToDevtoolsControlMsg::FramerateTick( - actor_name, tick)) => - handle_framerate_tick(actors.clone(), actor_name, tick), + actor_name, + tick, + )) => handle_framerate_tick(actors.clone(), actor_name, tick), DevtoolsControlMsg::FromScript(ScriptToDevtoolsControlMsg::NewGlobal( - ids, script_sender, pageinfo)) => - handle_new_global(actors.clone(), ids, script_sender, &mut actor_pipelines, - &mut actor_workers, pageinfo), + ids, + script_sender, + pageinfo, + )) => handle_new_global( + actors.clone(), + ids, + script_sender, + &mut actor_pipelines, + &mut actor_workers, + pageinfo, + ), DevtoolsControlMsg::FromScript(ScriptToDevtoolsControlMsg::ConsoleAPI( - id, - console_message, - worker_id)) => - handle_console_message(actors.clone(), id, worker_id, console_message, - &actor_pipelines, &actor_workers), + id, + console_message, + worker_id, + )) => handle_console_message( + actors.clone(), + id, + worker_id, + console_message, + &actor_pipelines, + &actor_workers, + ), DevtoolsControlMsg::FromScript(ScriptToDevtoolsControlMsg::ReportCSSError( - id, - css_error)) => { - let console_message = ConsoleMessage { + id, + css_error, + )) => { + let console_message = ConsoleMessage { message: css_error.msg, logLevel: LogLevel::Warn, filename: css_error.filename, lineNumber: css_error.line as usize, columnNumber: css_error.column as usize, }; - handle_console_message(actors.clone(), id, None, console_message, - &actor_pipelines, &actor_workers) + handle_console_message( + actors.clone(), + id, + None, + console_message, + &actor_pipelines, + &actor_workers, + ) }, DevtoolsControlMsg::FromChrome(ChromeToDevtoolsControlMsg::NetworkEvent( - request_id, network_event)) => { + request_id, + network_event, + )) => { // copy the accepted_connections vector let mut connections = Vec::::new(); for stream in &accepted_connections { @@ -523,10 +581,18 @@ fn run_server(sender: Sender, NetworkEvent::HttpResponse(ref response) => response.pipeline_id, NetworkEvent::HttpRequest(ref request) => request.pipeline_id, }; - handle_network_event(actors.clone(), connections, &actor_pipelines, &mut actor_requests, - &actor_workers, pipeline_id, request_id, network_event); + handle_network_event( + actors.clone(), + connections, + &actor_pipelines, + &mut actor_requests, + &actor_workers, + pipeline_id, + request_id, + network_event, + ); }, - DevtoolsControlMsg::FromChrome(ChromeToDevtoolsControlMsg::ServerExitMsg) => break + DevtoolsControlMsg::FromChrome(ChromeToDevtoolsControlMsg::ServerExitMsg) => break, } } for connection in &mut accepted_connections { diff --git a/components/devtools/protocol.rs b/components/devtools/protocol.rs index f0bfce4b3d7..999514affde 100644 --- a/components/devtools/protocol.rs +++ b/components/devtools/protocol.rs @@ -55,11 +55,11 @@ impl JsonPacketStream for TcpStream { fn read_json_packet(&mut self) -> Result, String> { // https://wiki.mozilla.org/Remote_Debugging_Protocol_Stream_Transport // In short, each JSON packet is [ascii length]:[JSON data of given length] - let mut buffer = vec!(); + let mut buffer = vec![]; loop { let mut buf = [0]; let byte = match self.read(&mut buf) { - Ok(0) => return Ok(None), // EOF + Ok(0) => return Ok(None), // EOF Ok(1) => buf[0], Ok(_) => unreachable!(), Err(e) => return Err(e.description().to_owned()), diff --git a/components/devtools_traits/lib.rs b/components/devtools_traits/lib.rs index fe0f91c7e52..764af5da0a2 100644 --- a/components/devtools_traits/lib.rs +++ b/components/devtools_traits/lib.rs @@ -8,7 +8,6 @@ #![crate_name = "devtools_traits"] #![crate_type = "rlib"] - #![allow(non_snake_case)] #![deny(unsafe_code)] @@ -17,9 +16,11 @@ extern crate bitflags; extern crate hyper; extern crate ipc_channel; extern crate malloc_size_of; -#[macro_use] extern crate malloc_size_of_derive; +#[macro_use] +extern crate malloc_size_of_derive; extern crate msg; -#[macro_use] extern crate serde; +#[macro_use] +extern crate serde; extern crate servo_url; extern crate time; @@ -45,7 +46,7 @@ pub struct CSSError { pub filename: String, pub line: u32, pub column: u32, - pub msg: String + pub msg: String, } /// Messages to instruct the devtools server to update its known actors/state @@ -75,9 +76,11 @@ pub enum ChromeToDevtoolsControlMsg { pub enum ScriptToDevtoolsControlMsg { /// A new global object was created, associated with a particular pipeline. /// The means of communicating directly with it are provided. - NewGlobal((PipelineId, Option), - IpcSender, - DevtoolsPageInfo), + NewGlobal( + (PipelineId, Option), + IpcSender, + DevtoolsPageInfo, + ), /// A particular page has invoked the console API. ConsoleAPI(PipelineId, ConsoleMessage, Option), /// An animation frame with the given timestamp was processed in a script thread. @@ -201,13 +204,21 @@ pub enum DevtoolScriptControlMsg { /// Retrieve the computed layout properties of the given node in the given pipeline. GetLayout(PipelineId, String, IpcSender>), /// Retrieve all stored console messages for the given pipeline. - GetCachedMessages(PipelineId, CachedConsoleMessageTypes, IpcSender>), + GetCachedMessages( + PipelineId, + CachedConsoleMessageTypes, + IpcSender>, + ), /// Update a given node's attributes with a list of modifications. ModifyAttribute(PipelineId, String, Vec), /// Request live console messages for a given pipeline (true if desired, false otherwise). WantsLiveNotifications(PipelineId, bool), /// Request live notifications for a given set of timeline events for a given pipeline. - SetTimelineMarkers(PipelineId, Vec, IpcSender>), + SetTimelineMarkers( + PipelineId, + Vec, + IpcSender>, + ), /// Withdraw request for live timeline notifications for a given pipeline. DropTimelineMarkers(PipelineId, Vec), /// Request a callback directed at the given actor name from the next animation frame diff --git a/components/dom_struct/lib.rs b/components/dom_struct/lib.rs index 0fa5f4f8163..442aa6cf2cd 100644 --- a/components/dom_struct/lib.rs +++ b/components/dom_struct/lib.rs @@ -25,7 +25,6 @@ pub fn dom_struct(args: TokenStream, input: TokenStream) -> TokenStream { // Work around https://github.com/rust-lang/rust/issues/46489 let attributes: TokenStream = attributes.to_string().parse().unwrap(); - let output: TokenStream = attributes.into_iter().chain(input.into_iter()).collect(); let item: Item = syn::parse(output).unwrap(); @@ -36,7 +35,11 @@ pub fn dom_struct(args: TokenStream, input: TokenStream) -> TokenStream { return quote!(#s2).into(); } if let Fields::Named(ref f) = s.fields { - let f = f.named.first().expect("Must have at least one field").into_value(); + let f = f + .named + .first() + .expect("Must have at least one field") + .into_value(); let ident = f.ident.as_ref().expect("Must have named fields"); let name = &s.ident; let ty = &f.ty; diff --git a/components/domobject_derive/lib.rs b/components/domobject_derive/lib.rs index 1db1af05d70..7eff765b928 100644 --- a/components/domobject_derive/lib.rs +++ b/components/domobject_derive/lib.rs @@ -5,8 +5,10 @@ #![recursion_limit = "128"] extern crate proc_macro; -#[macro_use] extern crate quote; -#[macro_use] extern crate syn; +#[macro_use] +extern crate quote; +#[macro_use] +extern crate syn; #[proc_macro_derive(DomObject)] pub fn expand_token_stream(input: proc_macro::TokenStream) -> proc_macro::TokenStream { @@ -74,7 +76,9 @@ fn expand_dom_object(input: syn::DeriveInput) -> quote::Tokens { })); let mut generics = input.generics.clone(); - generics.params.push(parse_quote!(__T: ::dom::bindings::reflector::DomObject)); + generics + .params + .push(parse_quote!(__T: ::dom::bindings::reflector::DomObject)); let (impl_generics, _, where_clause) = generics.split_for_impl(); diff --git a/components/embedder_traits/lib.rs b/components/embedder_traits/lib.rs index 3d932281e0c..a02eb31a0f4 100644 --- a/components/embedder_traits/lib.rs +++ b/components/embedder_traits/lib.rs @@ -24,9 +24,8 @@ use std::sync::mpsc::{Receiver, Sender}; use style_traits::cursor::CursorKind; use webrender_api::{DeviceIntPoint, DeviceUintSize}; - /// Used to wake up the event loop, provided by the servo port/embedder. -pub trait EventLoopWaker : 'static + Send { +pub trait EventLoopWaker: 'static + Send { fn clone(&self) -> Box; fn wake(&self); } @@ -58,11 +57,13 @@ impl Clone for EmbedderProxy { /// The port that the embedder receives messages on. pub struct EmbedderReceiver { - pub receiver: Receiver<(Option, EmbedderMsg)> + pub receiver: Receiver<(Option, EmbedderMsg)>, } impl EmbedderReceiver { - pub fn try_recv_embedder_msg(&mut self) -> Option<(Option, EmbedderMsg)> { + pub fn try_recv_embedder_msg( + &mut self, + ) -> Option<(Option, EmbedderMsg)> { self.receiver.try_recv().ok() } pub fn recv_embedder_msg(&mut self) -> (Option, EmbedderMsg) { @@ -148,7 +149,7 @@ impl Debug for EmbedderMsg { EmbedderMsg::HideIME => write!(f, "HideIME"), EmbedderMsg::Shutdown => write!(f, "Shutdown"), EmbedderMsg::AllowOpeningBrowser(..) => write!(f, "AllowOpeningBrowser"), - EmbedderMsg::BrowserCreated(..) => write!(f, "BrowserCreated") + EmbedderMsg::BrowserCreated(..) => write!(f, "BrowserCreated"), } } } diff --git a/components/embedder_traits/resources.rs b/components/embedder_traits/resources.rs index 603a2a83c28..b38b36181a0 100644 --- a/components/embedder_traits/resources.rs +++ b/components/embedder_traits/resources.rs @@ -7,10 +7,12 @@ use std::sync::RwLock; lazy_static! { static ref RES: RwLock>> = RwLock::new({ - #[cfg(not(feature = "tests"))] { + #[cfg(not(feature = "tests"))] + { None } - #[cfg(feature = "tests")] { + #[cfg(feature = "tests")] + { Some(resources_for_tests()) } }); @@ -21,7 +23,11 @@ pub fn set(reader: Box) { } pub fn read_bytes(res: Resource) -> Vec { - RES.read().unwrap().as_ref().expect("Resource reader not set.").read(res) + RES.read() + .unwrap() + .as_ref() + .expect("Resource reader not set.") + .read(res) } pub fn read_string(res: Resource) -> String { @@ -29,11 +35,19 @@ pub fn read_string(res: Resource) -> String { } pub fn sandbox_access_files() -> Vec { - RES.read().unwrap().as_ref().expect("Resource reader not set.").sandbox_access_files() + RES.read() + .unwrap() + .as_ref() + .expect("Resource reader not set.") + .sandbox_access_files() } pub fn sandbox_access_files_dirs() -> Vec { - RES.read().unwrap().as_ref().expect("Resource reader not set.").sandbox_access_files_dirs() + RES.read() + .unwrap() + .as_ref() + .expect("Resource reader not set.") + .sandbox_access_files_dirs() } pub enum Resource { @@ -64,8 +78,12 @@ fn resources_for_tests() -> Box { use std::io::Read; struct ResourceReader; impl ResourceReaderMethods for ResourceReader { - fn sandbox_access_files(&self) -> Vec { vec![] } - fn sandbox_access_files_dirs(&self) -> Vec { vec![] } + fn sandbox_access_files(&self) -> Vec { + vec![] + } + fn sandbox_access_files_dirs(&self) -> Vec { + vec![] + } fn read(&self, file: Resource) -> Vec { let file = match file { Resource::Preferences => "prefs.json", @@ -92,8 +110,10 @@ fn resources_for_tests() -> Box { } path.push(file); let mut buffer = vec![]; - File::open(path).expect(&format!("Can't find file: {}", file)) - .read_to_end(&mut buffer).expect("Can't read file"); + File::open(path) + .expect(&format!("Can't find file: {}", file)) + .read_to_end(&mut buffer) + .expect("Can't read file"); buffer } } diff --git a/components/fallible/lib.rs b/components/fallible/lib.rs index c220699a786..ae6a40dc789 100644 --- a/components/fallible/lib.rs +++ b/components/fallible/lib.rs @@ -18,7 +18,6 @@ pub trait FallibleVec { fn try_push(&mut self, value: T) -> Result<(), FailedAllocationError>; } - ///////////////////////////////////////////////////////////////// // Vec @@ -52,14 +51,14 @@ fn try_double_vec(vec: &mut Vec) -> Result<(), FailedAllocationError> { let new_cap: usize = if old_cap == 0 { 4 } else { - old_cap.checked_mul(2).ok_or(FailedAllocationError::new( - "capacity overflow for Vec", - ))? + old_cap + .checked_mul(2) + .ok_or(FailedAllocationError::new("capacity overflow for Vec"))? }; - let new_size_bytes = new_cap.checked_mul(mem::size_of::()).ok_or( - FailedAllocationError::new("capacity overflow for Vec"), - )?; + let new_size_bytes = new_cap + .checked_mul(mem::size_of::()) + .ok_or(FailedAllocationError::new("capacity overflow for Vec"))?; let new_ptr = unsafe { if old_cap == 0 { @@ -75,15 +74,12 @@ fn try_double_vec(vec: &mut Vec) -> Result<(), FailedAllocationError> { )); } - let new_vec = unsafe { - Vec::from_raw_parts(new_ptr as *mut T, old_len, new_cap) - }; + let new_vec = unsafe { Vec::from_raw_parts(new_ptr as *mut T, old_len, new_cap) }; mem::forget(mem::replace(vec, new_vec)); Ok(()) } - ///////////////////////////////////////////////////////////////// // SmallVec @@ -107,8 +103,7 @@ impl FallibleVec for SmallVec { #[cfg(feature = "known_system_malloc")] #[inline(never)] #[cold] -fn try_double_small_vec(svec: &mut SmallVec) --> Result<(), FailedAllocationError> +fn try_double_small_vec(svec: &mut SmallVec) -> Result<(), FailedAllocationError> where T: Array, { @@ -122,20 +117,20 @@ where let new_cap: usize = if old_cap == 0 { 4 } else { - old_cap.checked_mul(2).ok_or(FailedAllocationError::new( - "capacity overflow for SmallVec", - ))? + old_cap + .checked_mul(2) + .ok_or(FailedAllocationError::new("capacity overflow for SmallVec"))? }; // This surely shouldn't fail, if |old_cap| was previously accepted as a // valid value. But err on the side of caution. - let old_size_bytes = old_cap.checked_mul(mem::size_of::()).ok_or( - FailedAllocationError::new("capacity overflow for SmallVec"), - )?; + let old_size_bytes = old_cap + .checked_mul(mem::size_of::()) + .ok_or(FailedAllocationError::new("capacity overflow for SmallVec"))?; - let new_size_bytes = new_cap.checked_mul(mem::size_of::()).ok_or( - FailedAllocationError::new("capacity overflow for SmallVec"), - )?; + let new_size_bytes = new_cap + .checked_mul(mem::size_of::()) + .ok_or(FailedAllocationError::new("capacity overflow for SmallVec"))?; let new_ptr; if svec.spilled() { @@ -149,8 +144,7 @@ where unsafe { new_ptr = alloc::alloc(new_size_bytes, 0); if !new_ptr.is_null() && old_size_bytes > 0 { - copy_nonoverlapping(old_ptr as *const u8, - new_ptr as *mut u8, old_size_bytes); + copy_nonoverlapping(old_ptr as *const u8, new_ptr as *mut u8, old_size_bytes); } } } @@ -161,9 +155,7 @@ where )); } - let new_vec = unsafe { - Vec::from_raw_parts(new_ptr as *mut T::Item, old_len, new_cap) - }; + let new_vec = unsafe { Vec::from_raw_parts(new_ptr as *mut T::Item, old_len, new_cap) }; let new_svec = SmallVec::from_vec(new_vec); mem::forget(mem::replace(svec, new_svec)); diff --git a/components/geometry/lib.rs b/components/geometry/lib.rs index c4bb9721bf6..2f421f6a277 100644 --- a/components/geometry/lib.rs +++ b/components/geometry/lib.rs @@ -5,8 +5,9 @@ extern crate app_units; extern crate euclid; extern crate malloc_size_of; +#[macro_use] +extern crate malloc_size_of_derive; extern crate style_traits; -#[macro_use] extern crate malloc_size_of_derive; extern crate webrender_api; use app_units::{Au, MAX_AU, MIN_AU}; @@ -48,7 +49,7 @@ impl MaxRect for Rect { fn max_rect() -> Rect { Rect::new( Point2D::new(MIN_AU / 2, MIN_AU / 2), - Size2D::new(MAX_AU, MAX_AU) + Size2D::new(MAX_AU, MAX_AU), ) } } @@ -64,12 +65,22 @@ impl MaxRect for LayoutRect { /// A helper function to convert a rect of `f32` pixels to a rect of app units. pub fn f32_rect_to_au_rect(rect: Rect) -> Rect { - Rect::new(Point2D::new(Au::from_f32_px(rect.origin.x), Au::from_f32_px(rect.origin.y)), - Size2D::new(Au::from_f32_px(rect.size.width), Au::from_f32_px(rect.size.height))) + Rect::new( + Point2D::new( + Au::from_f32_px(rect.origin.x), + Au::from_f32_px(rect.origin.y), + ), + Size2D::new( + Au::from_f32_px(rect.size.width), + Au::from_f32_px(rect.size.height), + ), + ) } /// A helper function to convert a rect of `Au` pixels to a rect of f32 units. pub fn au_rect_to_f32_rect(rect: Rect) -> Rect { - Rect::new(Point2D::new(rect.origin.x.to_f32_px(), rect.origin.y.to_f32_px()), - Size2D::new(rect.size.width.to_f32_px(), rect.size.height.to_f32_px())) + Rect::new( + Point2D::new(rect.origin.x.to_f32_px(), rect.origin.y.to_f32_px()), + Size2D::new(rect.size.width.to_f32_px(), rect.size.height.to_f32_px()), + ) } diff --git a/components/gfx/font.rs b/components/gfx/font.rs index de056747bd9..a3591e3b41a 100644 --- a/components/gfx/font.rs +++ b/components/gfx/font.rs @@ -32,9 +32,9 @@ use unicode_script::Script; use webrender_api; macro_rules! ot_tag { - ($t1:expr, $t2:expr, $t3:expr, $t4:expr) => ( + ($t1:expr, $t2:expr, $t3:expr, $t4:expr) => { (($t1 as u32) << 24) | (($t2 as u32) << 16) | (($t3 as u32) << 8) | ($t4 as u32) - ); + }; } pub const GPOS: u32 = ot_tag!('G', 'P', 'O', 'S'); @@ -87,10 +87,12 @@ trait FontTableTagConversions { impl FontTableTagConversions for FontTableTag { fn tag_to_str(&self) -> String { - let bytes = [(self >> 24) as u8, - (self >> 16) as u8, - (self >> 8) as u8, - (self >> 0) as u8]; + let bytes = [ + (self >> 24) as u8, + (self >> 16) as u8, + (self >> 8) as u8, + (self >> 0) as u8, + ]; str::from_utf8(&bytes).unwrap().to_owned() } } @@ -101,18 +103,18 @@ pub trait FontTableMethods { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct FontMetrics { - pub underline_size: Au, + pub underline_size: Au, pub underline_offset: Au, - pub strikeout_size: Au, + pub strikeout_size: Au, pub strikeout_offset: Au, - pub leading: Au, - pub x_height: Au, - pub em_size: Au, - pub ascent: Au, - pub descent: Au, - pub max_advance: Au, - pub average_advance: Au, - pub line_gap: Au, + pub leading: Au, + pub x_height: Au, + pub em_size: Au, + pub ascent: Au, + pub descent: Au, + pub max_advance: Au, + pub average_advance: Au, + pub line_gap: Au, } /// `FontDescriptor` describes the parameters of a `Font`. It represents rendering a given font @@ -149,10 +151,12 @@ pub struct Font { } impl Font { - pub fn new(handle: FontHandle, - descriptor: FontDescriptor, - actual_pt_size: Au, - font_key: webrender_api::FontInstanceKey) -> Font { + pub fn new( + handle: FontHandle, + descriptor: FontDescriptor, + actual_pt_size: Au, + font_key: webrender_api::FontInstanceKey, + ) -> Font { let metrics = handle.metrics(); Font { @@ -218,28 +222,39 @@ impl Font { text: text.to_owned(), options: *options, }; - let result = self.shape_cache.borrow_mut().entry(lookup_key).or_insert_with(|| { - let start_time = time::precise_time_ns(); - let mut glyphs = GlyphStore::new(text.len(), - options.flags.contains(ShapingFlags::IS_WHITESPACE_SHAPING_FLAG), - options.flags.contains(ShapingFlags::RTL_FLAG)); + let result = self + .shape_cache + .borrow_mut() + .entry(lookup_key) + .or_insert_with(|| { + let start_time = time::precise_time_ns(); + let mut glyphs = GlyphStore::new( + text.len(), + options + .flags + .contains(ShapingFlags::IS_WHITESPACE_SHAPING_FLAG), + options.flags.contains(ShapingFlags::RTL_FLAG), + ); - if self.can_do_fast_shaping(text, options) { - debug!("shape_text: Using ASCII fast path."); - self.shape_text_fast(text, options, &mut glyphs); - } else { - debug!("shape_text: Using Harfbuzz."); - if shaper.is_none() { - shaper = Some(Shaper::new(this)); + if self.can_do_fast_shaping(text, options) { + debug!("shape_text: Using ASCII fast path."); + self.shape_text_fast(text, options, &mut glyphs); + } else { + debug!("shape_text: Using Harfbuzz."); + if shaper.is_none() { + shaper = Some(Shaper::new(this)); + } + shaper + .as_ref() + .unwrap() + .shape_text(text, options, &mut glyphs); } - shaper.as_ref().unwrap().shape_text(text, options, &mut glyphs); - } - let end_time = time::precise_time_ns(); - TEXT_SHAPING_PERFORMANCE_COUNTER.fetch_add((end_time - start_time) as usize, - Ordering::Relaxed); - Arc::new(glyphs) - }).clone(); + let end_time = time::precise_time_ns(); + TEXT_SHAPING_PERFORMANCE_COUNTER + .fetch_add((end_time - start_time) as usize, Ordering::Relaxed); + Arc::new(glyphs) + }).clone(); self.shaper = shaper; result } @@ -285,12 +300,21 @@ impl Font { pub fn table_for_tag(&self, tag: FontTableTag) -> Option { let result = self.handle.table_for_tag(tag); - let status = if result.is_some() { "Found" } else { "Didn't find" }; + let status = if result.is_some() { + "Found" + } else { + "Didn't find" + }; - debug!("{} font table[{}] with family={}, face={}", - status, tag.tag_to_str(), - self.handle.family_name().unwrap_or("unavailable".to_owned()), - self.handle.face_name().unwrap_or("unavailable".to_owned())); + debug!( + "{} font table[{}] with family={}, face={}", + status, + tag.tag_to_str(), + self.handle + .family_name() + .unwrap_or("unavailable".to_owned()), + self.handle.face_name().unwrap_or("unavailable".to_owned()) + ); result } @@ -308,18 +332,21 @@ impl Font { self.glyph_index(codepoint).is_some() } - pub fn glyph_h_kerning(&self, first_glyph: GlyphId, second_glyph: GlyphId) - -> FractionalPixel { + pub fn glyph_h_kerning(&self, first_glyph: GlyphId, second_glyph: GlyphId) -> FractionalPixel { self.handle.glyph_h_kerning(first_glyph, second_glyph) } pub fn glyph_h_advance(&self, glyph: GlyphId) -> FractionalPixel { - *self.glyph_advance_cache.borrow_mut().entry(glyph).or_insert_with(|| { - match self.handle.glyph_h_advance(glyph) { - Some(adv) => adv, - None => 10f64 as FractionalPixel // FIXME: Need fallback strategy - } - }) + *self + .glyph_advance_cache + .borrow_mut() + .entry(glyph) + .or_insert_with(|| { + match self.handle.glyph_h_advance(glyph) { + Some(adv) => adv, + None => 10f64 as FractionalPixel, // FIXME: Need fallback strategy + } + }) } } @@ -339,10 +366,12 @@ impl FontGroup { pub fn new(style: &FontStyleStruct) -> FontGroup { let descriptor = FontDescriptor::from(style); - let families = - style.font_family.0.iter() - .map(|family| FontGroupFamily::new(descriptor.clone(), &family)) - .collect(); + let families = style + .font_family + .0 + .iter() + .map(|family| FontGroupFamily::new(descriptor.clone(), &family)) + .collect(); FontGroup { descriptor, @@ -358,25 +387,25 @@ impl FontGroup { pub fn find_by_codepoint( &mut self, mut font_context: &mut FontContext, - codepoint: char + codepoint: char, ) -> Option { let has_glyph = |font: &FontRef| font.borrow().has_glyph_for(codepoint); let font = self.find(&mut font_context, |font| has_glyph(font)); if font.is_some() { - return font + return font; } if let Some(ref fallback) = self.last_matching_fallback { if has_glyph(&fallback) { - return self.last_matching_fallback.clone() + return self.last_matching_fallback.clone(); } } let font = self.find_fallback(&mut font_context, Some(codepoint), has_glyph); if font.is_some() { self.last_matching_fallback = font.clone(); - return font + return font; } self.first(&mut font_context) @@ -385,7 +414,7 @@ impl FontGroup { /// Find the first available font in the group, or the first available fallback font. pub fn first( &mut self, - mut font_context: &mut FontContext + mut font_context: &mut FontContext, ) -> Option { self.find(&mut font_context, |_| true) .or_else(|| self.find_fallback(&mut font_context, None, |_| true)) @@ -393,16 +422,13 @@ impl FontGroup { /// Find a font which returns true for `predicate`. This method mutates because we may need to /// load new font data in the process of finding a suitable font. - fn find( - &mut self, - mut font_context: &mut FontContext, - predicate: P, - ) -> Option + fn find(&mut self, mut font_context: &mut FontContext, predicate: P) -> Option where S: FontSource, P: FnMut(&FontRef) -> bool, { - self.families.iter_mut() + self.families + .iter_mut() .filter_map(|family| family.font(&mut font_context)) .find(predicate) } @@ -422,15 +448,9 @@ impl FontGroup { P: FnMut(&FontRef) -> bool, { iter::once(FontFamilyDescriptor::default()) - .chain( - fallback_font_families(codepoint).into_iter().map(|family| { - FontFamilyDescriptor::new( - FontFamilyName::from(family), - FontSearchScope::Local, - ) - }) - ) - .filter_map(|family| font_context.font(&self.descriptor, &family)) + .chain(fallback_font_families(codepoint).into_iter().map(|family| { + FontFamilyDescriptor::new(FontFamilyName::from(family), FontSearchScope::Local) + })).filter_map(|family| font_context.font(&self.descriptor, &family)) .find(predicate) } } @@ -448,10 +468,8 @@ struct FontGroupFamily { impl FontGroupFamily { fn new(font_descriptor: FontDescriptor, family: &SingleFontFamily) -> FontGroupFamily { - let family_descriptor = FontFamilyDescriptor::new( - FontFamilyName::from(family), - FontSearchScope::Any - ); + let family_descriptor = + FontFamilyDescriptor::new(FontFamilyName::from(family), FontSearchScope::Any); FontGroupFamily { font_descriptor, @@ -477,17 +495,19 @@ impl FontGroupFamily { pub struct RunMetrics { // may be negative due to negative width (i.e., kerning of '.' in 'P.T.') pub advance_width: Au, - pub ascent: Au, // nonzero + pub ascent: Au, // nonzero pub descent: Au, // nonzero // this bounding box is relative to the left origin baseline. // so, bounding_box.position.y = -ascent - pub bounding_box: Rect + pub bounding_box: Rect, } impl RunMetrics { pub fn new(advance: Au, ascent: Au, descent: Au) -> RunMetrics { - let bounds = Rect::new(Point2D::new(Au(0), -ascent), - Size2D::new(advance, ascent + descent)); + let bounds = Rect::new( + Point2D::new(Au(0), -ascent), + Size2D::new(advance, ascent + descent), + ); // TODO(Issue #125): support loose and tight bounding boxes; using the // ascent+descent and advance is sometimes too generous and @@ -540,11 +560,13 @@ impl FontFamilyName { impl<'a> From<&'a SingleFontFamily> for FontFamilyName { fn from(other: &'a SingleFontFamily) -> FontFamilyName { match *other { - SingleFontFamily::FamilyName(ref family_name) => - FontFamilyName::Specific(family_name.name.clone()), + SingleFontFamily::FamilyName(ref family_name) => { + FontFamilyName::Specific(family_name.name.clone()) + }, - SingleFontFamily::Generic(ref generic_name) => - FontFamilyName::Generic(generic_name.clone()), + SingleFontFamily::Generic(ref generic_name) => { + FontFamilyName::Generic(generic_name.clone()) + }, } } } diff --git a/components/gfx/font_cache_thread.rs b/components/gfx/font_cache_thread.rs index 334a1bb41ec..4bfa3e6dfc2 100644 --- a/components/gfx/font_cache_thread.rs +++ b/components/gfx/font_cache_thread.rs @@ -40,14 +40,15 @@ pub struct FontTemplateInfo { impl FontTemplates { pub fn new() -> FontTemplates { - FontTemplates { - templates: vec!(), - } + FontTemplates { templates: vec![] } } /// Find a font in this family that matches a given descriptor. - pub fn find_font_for_style(&mut self, desc: &FontTemplateDescriptor, fctx: &FontContextHandle) - -> Option> { + pub fn find_font_for_style( + &mut self, + desc: &FontTemplateDescriptor, + fctx: &FontContextHandle, + ) -> Option> { // TODO(Issue #189): optimize lookup for // regular/bold/italic/bolditalic with fixed offsets and a // static decision table for fallback between these values. @@ -63,7 +64,8 @@ impl FontTemplates { let (mut best_template_data, mut best_distance) = (None, f32::MAX); for template in &mut self.templates { if let Some((template_data, distance)) = - template.data_for_approximate_descriptor(fctx, desc) { + template.data_for_approximate_descriptor(fctx, desc) + { if distance < best_distance { best_template_data = Some(template_data); best_distance = distance @@ -71,7 +73,7 @@ impl FontTemplates { } } if best_template_data.is_some() { - return best_template_data + return best_template_data; } // If a request is made for a font family that exists, @@ -103,8 +105,16 @@ impl FontTemplates { /// Commands that the FontContext sends to the font cache thread. #[derive(Debug, Deserialize, Serialize)] pub enum Command { - GetFontTemplate(FontTemplateDescriptor, FontFamilyDescriptor, IpcSender), - GetFontInstance(webrender_api::FontKey, Au, IpcSender), + GetFontTemplate( + FontTemplateDescriptor, + FontFamilyDescriptor, + IpcSender, + ), + GetFontInstance( + webrender_api::FontKey, + Au, + IpcSender, + ), AddWebFont(LowercaseString, EffectiveSources, IpcSender<()>), AddDownloadedWebFont(LowercaseString, ServoUrl, Vec, IpcSender<()>), Exit(IpcSender<()>), @@ -148,7 +158,7 @@ fn populate_generic_fonts() -> HashMap { ) { let family_name = match system_default_family(generic_name) { Some(system_default) => LowercaseString::new(&system_default), - None => LowercaseString::new(mapped_name) + None => LowercaseString::new(mapped_name), }; let generic_name = FontFamilyName::Generic(Atom::from(generic_name)); @@ -156,7 +166,6 @@ fn populate_generic_fonts() -> HashMap { generic_fonts.insert(generic_name, family_name); } - generic_fonts } @@ -167,50 +176,50 @@ impl FontCache { match msg { Command::GetFontTemplate(template_descriptor, family_descriptor, result) => { - let maybe_font_template = self.find_font_template(&template_descriptor, &family_descriptor); + let maybe_font_template = + self.find_font_template(&template_descriptor, &family_descriptor); let _ = result.send(Reply::GetFontTemplateReply(maybe_font_template)); - } + }, Command::GetFontInstance(font_key, size, result) => { let webrender_api = &self.webrender_api; - let instance_key = *self.font_instances - .entry((font_key, size)) - .or_insert_with(|| { - let key = webrender_api.generate_font_instance_key(); - let mut txn = webrender_api::Transaction::new(); - txn.add_font_instance(key, - font_key, - size, - None, - None, - Vec::new()); - webrender_api.update_resources(txn.resource_updates); - key - }); + let instance_key = + *self + .font_instances + .entry((font_key, size)) + .or_insert_with(|| { + let key = webrender_api.generate_font_instance_key(); + let mut txn = webrender_api::Transaction::new(); + txn.add_font_instance(key, font_key, size, None, None, Vec::new()); + webrender_api.update_resources(txn.resource_updates); + key + }); let _ = result.send(instance_key); - } + }, Command::AddWebFont(family_name, sources, result) => { self.handle_add_web_font(family_name, sources, result); - } + }, Command::AddDownloadedWebFont(family_name, url, bytes, result) => { let templates = &mut self.web_families.get_mut(&family_name).unwrap(); templates.add_template(Atom::from(url.to_string()), Some(bytes)); drop(result.send(())); - } + }, Command::Ping => (), Command::Exit(result) => { let _ = result.send(()); break; - } + }, } } } - fn handle_add_web_font(&mut self, - family_name: LowercaseString, - mut sources: EffectiveSources, - sender: IpcSender<()>) { + fn handle_add_web_font( + &mut self, + family_name: LowercaseString, + mut sources: EffectiveSources, + sender: IpcSender<()>, + ) { let src = if let Some(src) = sources.next() { src } else { @@ -236,7 +245,7 @@ impl FontCache { destination: Destination::Font, // TODO: Add a proper origin - Can't import GlobalScope from gfx // We can leave origin to be set by default - .. RequestInit::default() + ..RequestInit::default() }; let channel_to_self = self.channel_to_self.clone(); @@ -248,19 +257,27 @@ impl FontCache { FetchResponseMsg::ProcessRequestBody | FetchResponseMsg::ProcessRequestEOF => (), FetchResponseMsg::ProcessResponse(meta_result) => { - trace!("@font-face {} metadata ok={:?}", family_name, meta_result.is_ok()); + trace!( + "@font-face {} metadata ok={:?}", + family_name, + meta_result.is_ok() + ); *response_valid.lock().unwrap() = meta_result.is_ok(); - } + }, FetchResponseMsg::ProcessResponseChunk(new_bytes) => { trace!("@font-face {} chunk={:?}", family_name, new_bytes); if *response_valid.lock().unwrap() { bytes.lock().unwrap().extend(new_bytes.into_iter()) } - } + }, FetchResponseMsg::ProcessResponseEOF(response) => { trace!("@font-face {} EOF={:?}", family_name, response); if response.is_err() || !*response_valid.lock().unwrap() { - let msg = Command::AddWebFont(family_name.clone(), sources.clone(), sender.clone()); + let msg = Command::AddWebFont( + family_name.clone(), + sources.clone(), + sender.clone(), + ); channel_to_self.send(msg).unwrap(); return; } @@ -270,23 +287,31 @@ impl FontCache { Ok(san) => san, Err(_) => { // FIXME(servo/fontsan#1): get an error message - debug!("Sanitiser rejected web font: \ - family={} url={:?}", family_name, url); - let msg = Command::AddWebFont(family_name.clone(), sources.clone(), sender.clone()); + debug!( + "Sanitiser rejected web font: \ + family={} url={:?}", + family_name, url + ); + let msg = Command::AddWebFont( + family_name.clone(), + sources.clone(), + sender.clone(), + ); channel_to_self.send(msg).unwrap(); return; }, }; - let command = - Command::AddDownloadedWebFont(family_name.clone(), - url.clone(), - bytes, - sender.clone()); + let command = Command::AddDownloadedWebFont( + family_name.clone(), + url.clone(), + bytes, + sender.clone(), + ); channel_to_self.send(command).unwrap(); - } + }, } }); - } + }, Source::Local(ref font) => { let font_face_name = LowercaseString::new(&font.name); let templates = &mut self.web_families.get_mut(&family_name).unwrap(); @@ -301,7 +326,7 @@ impl FontCache { let msg = Command::AddWebFont(family_name, sources, sender); self.channel_to_self.send(msg).unwrap(); } - } + }, } } @@ -319,7 +344,7 @@ impl FontCache { fn transform_family(&self, family_name: &FontFamilyName) -> LowercaseString { match self.generic_fonts.get(family_name) { None => LowercaseString::from(family_name), - Some(mapped_family) => (*mapped_family).clone() + Some(mapped_family) => (*mapped_family).clone(), } } @@ -347,7 +372,10 @@ impl FontCache { s.find_font_for_style(template_descriptor, &self.font_context) } else { - debug!("FontList: Couldn't find font family with name={}", &*family_name); + debug!( + "FontList: Couldn't find font family with name={}", + &*family_name + ); None } } @@ -371,17 +399,19 @@ impl FontCache { let webrender_api = &self.webrender_api; let webrender_fonts = &mut self.webrender_fonts; - let font_key = *webrender_fonts.entry(template.identifier.clone()).or_insert_with(|| { - let font_key = webrender_api.generate_font_key(); - let mut txn = webrender_api::Transaction::new(); - match (template.bytes_if_in_memory(), template.native_font()) { - (Some(bytes), _) => txn.add_raw_font(font_key, bytes, 0), - (None, Some(native_font)) => txn.add_native_font(font_key, native_font), - (None, None) => txn.add_raw_font(font_key, template.bytes().clone(), 0), - } - webrender_api.update_resources(txn.resource_updates); - font_key - }); + let font_key = *webrender_fonts + .entry(template.identifier.clone()) + .or_insert_with(|| { + let font_key = webrender_api.generate_font_key(); + let mut txn = webrender_api::Transaction::new(); + match (template.bytes_if_in_memory(), template.native_font()) { + (Some(bytes), _) => txn.add_raw_font(font_key, bytes, 0), + (None, Some(native_font)) => txn.add_native_font(font_key, native_font), + (None, None) => txn.add_raw_font(font_key, template.bytes().clone(), 0), + } + webrender_api.update_resources(txn.resource_updates); + font_key + }); FontTemplateInfo { font_template: template, @@ -395,14 +425,15 @@ impl FontCache { family_descriptor: &FontFamilyDescriptor, ) -> Option { match family_descriptor.scope { - FontSearchScope::Any => { - self.find_font_in_web_family(&template_descriptor, &family_descriptor.name) - .or_else(|| self.find_font_in_local_family(&template_descriptor, &family_descriptor.name)) - } + FontSearchScope::Any => self + .find_font_in_web_family(&template_descriptor, &family_descriptor.name) + .or_else(|| { + self.find_font_in_local_family(&template_descriptor, &family_descriptor.name) + }), FontSearchScope::Local => { self.find_font_in_local_family(&template_descriptor, &family_descriptor.name) - } + }, }.map(|t| self.get_font_template_info(t)) } } @@ -415,59 +446,82 @@ pub struct FontCacheThread { } impl FontCacheThread { - pub fn new(core_resource_thread: CoreResourceThread, - webrender_api: webrender_api::RenderApi) -> FontCacheThread { + pub fn new( + core_resource_thread: CoreResourceThread, + webrender_api: webrender_api::RenderApi, + ) -> FontCacheThread { let (chan, port) = ipc::channel().unwrap(); let channel_to_self = chan.clone(); - thread::Builder::new().name("FontCacheThread".to_owned()).spawn(move || { - // TODO: Allow users to specify these. - let generic_fonts = populate_generic_fonts(); + thread::Builder::new() + .name("FontCacheThread".to_owned()) + .spawn(move || { + // TODO: Allow users to specify these. + let generic_fonts = populate_generic_fonts(); - let mut cache = FontCache { - port: port, - channel_to_self, - generic_fonts, - local_families: HashMap::new(), - web_families: HashMap::new(), - font_context: FontContextHandle::new(), - core_resource_thread, - webrender_api, - webrender_fonts: HashMap::new(), - font_instances: HashMap::new(), - }; + let mut cache = FontCache { + port: port, + channel_to_self, + generic_fonts, + local_families: HashMap::new(), + web_families: HashMap::new(), + font_context: FontContextHandle::new(), + core_resource_thread, + webrender_api, + webrender_fonts: HashMap::new(), + font_instances: HashMap::new(), + }; - cache.refresh_local_families(); - cache.run(); - }).expect("Thread spawning failed"); + cache.refresh_local_families(); + cache.run(); + }).expect("Thread spawning failed"); - FontCacheThread { - chan: chan, - } + FontCacheThread { chan: chan } } - pub fn add_web_font(&self, family: FamilyName, sources: EffectiveSources, sender: IpcSender<()>) { - self.chan.send(Command::AddWebFont(LowercaseString::new(&family.name), sources, sender)).unwrap(); + pub fn add_web_font( + &self, + family: FamilyName, + sources: EffectiveSources, + sender: IpcSender<()>, + ) { + self.chan + .send(Command::AddWebFont( + LowercaseString::new(&family.name), + sources, + sender, + )).unwrap(); } pub fn exit(&self) { let (response_chan, response_port) = ipc::channel().unwrap(); - self.chan.send(Command::Exit(response_chan)).expect("Couldn't send FontCacheThread exit message"); - response_port.recv().expect("Couldn't receive FontCacheThread reply"); + self.chan + .send(Command::Exit(response_chan)) + .expect("Couldn't send FontCacheThread exit message"); + response_port + .recv() + .expect("Couldn't receive FontCacheThread reply"); } } impl FontSource for FontCacheThread { - fn get_font_instance(&mut self, key: webrender_api::FontKey, size: Au) -> webrender_api::FontInstanceKey { - let (response_chan, response_port) = - ipc::channel().expect("failed to create IPC channel"); - self.chan.send(Command::GetFontInstance(key, size, response_chan)) + fn get_font_instance( + &mut self, + key: webrender_api::FontKey, + size: Au, + ) -> webrender_api::FontInstanceKey { + let (response_chan, response_port) = ipc::channel().expect("failed to create IPC channel"); + self.chan + .send(Command::GetFontInstance(key, size, response_chan)) .expect("failed to send message to font cache thread"); let instance_key = response_port.recv(); if instance_key.is_err() { let font_thread_has_closed = self.chan.send(Command::Ping).is_err(); - assert!(font_thread_has_closed, "Failed to receive a response from live font cache"); + assert!( + font_thread_has_closed, + "Failed to receive a response from live font cache" + ); panic!("Font cache thread has already exited."); } instance_key.unwrap() @@ -478,23 +532,27 @@ impl FontSource for FontCacheThread { template_descriptor: FontTemplateDescriptor, family_descriptor: FontFamilyDescriptor, ) -> Option { - let (response_chan, response_port) = - ipc::channel().expect("failed to create IPC channel"); - self.chan.send(Command::GetFontTemplate(template_descriptor, family_descriptor, response_chan)) - .expect("failed to send message to font cache thread"); + let (response_chan, response_port) = ipc::channel().expect("failed to create IPC channel"); + self.chan + .send(Command::GetFontTemplate( + template_descriptor, + family_descriptor, + response_chan, + )).expect("failed to send message to font cache thread"); let reply = response_port.recv(); if reply.is_err() { let font_thread_has_closed = self.chan.send(Command::Ping).is_err(); - assert!(font_thread_has_closed, "Failed to receive a response from live font cache"); + assert!( + font_thread_has_closed, + "Failed to receive a response from live font cache" + ); panic!("Font cache thread has already exited."); } match reply.unwrap() { - Reply::GetFontTemplateReply(data) => { - data - } + Reply::GetFontTemplateReply(data) => data, } } } diff --git a/components/gfx/font_context.rs b/components/gfx/font_context.rs index a09e6cf7b57..6cb4d8e7ed6 100644 --- a/components/gfx/font_context.rs +++ b/components/gfx/font_context.rs @@ -21,14 +21,18 @@ use style::computed_values::font_variant_caps::T as FontVariantCaps; use style::properties::style_structs::Font as FontStyleStruct; use webrender_api; -static SMALL_CAPS_SCALE_FACTOR: f32 = 0.8; // Matches FireFox (see gfxFont.h) +static SMALL_CAPS_SCALE_FACTOR: f32 = 0.8; // Matches FireFox (see gfxFont.h) /// An epoch for the font context cache. The cache is flushed if the current epoch does not match /// this one. static FONT_CACHE_EPOCH: AtomicUsize = ATOMIC_USIZE_INIT; pub trait FontSource { - fn get_font_instance(&mut self, key: webrender_api::FontKey, size: Au) -> webrender_api::FontInstanceKey; + fn get_font_instance( + &mut self, + key: webrender_api::FontKey, + size: Au, + ) -> webrender_api::FontInstanceKey; fn font_template( &mut self, @@ -74,7 +78,7 @@ impl FontContext { fn expire_font_caches_if_necessary(&mut self) { let current_epoch = FONT_CACHE_EPOCH.load(Ordering::SeqCst); if current_epoch == self.epoch { - return + return; } self.font_cache.clear(); @@ -95,7 +99,7 @@ impl FontContext { }; if let Some(ref font_group) = self.font_group_cache.get(&cache_key) { - return (*font_group).clone() + return (*font_group).clone(); } let font_group = Rc::new(RefCell::new(FontGroup::new(&cache_key.style))); @@ -115,27 +119,31 @@ impl FontContext { family_descriptor: family_descriptor.clone(), }; - self.font_cache.get(&cache_key).map(|v| v.clone()).unwrap_or_else(|| { - debug!( - "FontContext::font cache miss for font_descriptor={:?} family_descriptor={:?}", - font_descriptor, - family_descriptor - ); + self.font_cache + .get(&cache_key) + .map(|v| v.clone()) + .unwrap_or_else(|| { + debug!( + "FontContext::font cache miss for font_descriptor={:?} family_descriptor={:?}", + font_descriptor, family_descriptor + ); - let font = - self.font_template(&font_descriptor.template_descriptor, family_descriptor) - .and_then(|template_info| self.create_font(template_info, font_descriptor.to_owned()).ok()) - .map(|font| Rc::new(RefCell::new(font))); + let font = self + .font_template(&font_descriptor.template_descriptor, family_descriptor) + .and_then(|template_info| { + self.create_font(template_info, font_descriptor.to_owned()) + .ok() + }).map(|font| Rc::new(RefCell::new(font))); - self.font_cache.insert(cache_key, font.clone()); - font - }) + self.font_cache.insert(cache_key, font.clone()); + font + }) } fn font_template( &mut self, template_descriptor: &FontTemplateDescriptor, - family_descriptor: &FontFamilyDescriptor + family_descriptor: &FontFamilyDescriptor, ) -> Option { let cache_key = FontTemplateCacheKey { template_descriptor: template_descriptor.clone(), @@ -164,7 +172,7 @@ impl FontContext { fn create_font( &mut self, info: FontTemplateInfo, - descriptor: FontDescriptor + descriptor: FontDescriptor, ) -> Result { // TODO: (Bug #3463): Currently we only support fake small-caps // painting. We should also support true small-caps (where the @@ -177,11 +185,18 @@ impl FontContext { let handle = FontHandle::new_from_template( &self.platform_handle, info.font_template, - Some(actual_pt_size) + Some(actual_pt_size), )?; - let font_instance_key = self.font_source.get_font_instance(info.font_key, actual_pt_size); - Ok(Font::new(handle, descriptor.to_owned(), actual_pt_size, font_instance_key)) + let font_instance_key = self + .font_source + .get_font_instance(info.font_key, actual_pt_size); + Ok(Font::new( + handle, + descriptor.to_owned(), + actual_pt_size, + font_instance_key, + )) } } @@ -219,7 +234,10 @@ impl PartialEq for FontGroupCacheKey { impl Eq for FontGroupCacheKey {} impl Hash for FontGroupCacheKey { - fn hash(&self, hasher: &mut H) where H: Hasher { + fn hash(&self, hasher: &mut H) + where + H: Hasher, + { self.style.hash.hash(hasher) } } diff --git a/components/gfx/font_template.rs b/components/gfx/font_template.rs index 8a72360d0dc..80527dfae38 100644 --- a/components/gfx/font_template.rs +++ b/components/gfx/font_template.rs @@ -26,7 +26,6 @@ pub struct FontTemplateDescriptor { pub style: FontStyle, } - /// FontTemplateDescriptor contains floats, which are not Eq because of NaN. However, /// we know they will never be NaN, so we can manually implement Eq. impl Eq for FontTemplateDescriptor {} @@ -41,14 +40,9 @@ fn style_to_number(s: &FontStyle) -> f32 { } } - impl FontTemplateDescriptor { #[inline] - pub fn new( - weight: FontWeight, - stretch: FontStretch, - style: FontStyle, - ) -> Self { + pub fn new(weight: FontWeight, stretch: FontStretch, style: FontStyle) -> Self { Self { weight, stretch, @@ -138,7 +132,10 @@ impl FontTemplate { } /// Get the descriptor. Returns `None` when instantiating the data fails. - pub fn descriptor(&mut self, font_context: &FontContextHandle) -> Option { + pub fn descriptor( + &mut self, + font_context: &FontContextHandle, + ) -> Option { // The font template data can be unloaded when nothing is referencing // it (via the Weak reference to the Arc above). However, if we have // already loaded a font, store the style information about it separately, @@ -147,18 +144,22 @@ impl FontTemplate { self.descriptor.or_else(|| { if self.instantiate(font_context).is_err() { - return None + return None; }; - Some(self.descriptor.expect("Instantiation succeeded but no descriptor?")) + Some( + self.descriptor + .expect("Instantiation succeeded but no descriptor?"), + ) }) } /// Get the data for creating a font if it matches a given descriptor. - pub fn data_for_descriptor(&mut self, - fctx: &FontContextHandle, - requested_desc: &FontTemplateDescriptor) - -> Option> { + pub fn data_for_descriptor( + &mut self, + fctx: &FontContextHandle, + requested_desc: &FontTemplateDescriptor, + ) -> Option> { self.descriptor(&fctx).and_then(|descriptor| { if *requested_desc == descriptor { self.data().ok() @@ -176,21 +177,20 @@ impl FontTemplate { requested_descriptor: &FontTemplateDescriptor, ) -> Option<(Arc, f32)> { self.descriptor(&font_context).and_then(|descriptor| { - self.data().ok().map(|data| { - (data, descriptor.distance_from(requested_descriptor)) - }) + self.data() + .ok() + .map(|data| (data, descriptor.distance_from(requested_descriptor))) }) } fn instantiate(&mut self, font_context: &FontContextHandle) -> Result<(), ()> { if !self.is_valid { - return Err(()) + return Err(()); } let data = self.data().map_err(|_| ())?; - let handle: Result = FontHandleMethods::new_from_template(font_context, - data, - None); + let handle: Result = + FontHandleMethods::new_from_template(font_context, data, None); self.is_valid = handle.is_ok(); let handle = handle?; self.descriptor = Some(FontTemplateDescriptor::new( @@ -220,7 +220,7 @@ impl FontTemplate { }; if let Some(data) = maybe_data { - return Ok(data) + return Ok(data); } assert!(self.strong_ref.is_none()); diff --git a/components/gfx/lib.rs b/components/gfx/lib.rs index a1b72e4e0c9..442a9c8ae3a 100644 --- a/components/gfx/lib.rs +++ b/components/gfx/lib.rs @@ -9,14 +9,18 @@ extern crate app_units; extern crate bitflags; // Mac OS-specific library dependencies -#[cfg(target_os = "macos")] extern crate byteorder; -#[cfg(target_os = "macos")] extern crate core_foundation; -#[cfg(target_os = "macos")] extern crate core_graphics; -#[cfg(target_os = "macos")] extern crate core_text; +#[cfg(target_os = "macos")] +extern crate byteorder; +#[cfg(target_os = "macos")] +extern crate core_foundation; +#[cfg(target_os = "macos")] +extern crate core_graphics; +#[cfg(target_os = "macos")] +extern crate core_text; // Windows-specific library dependencies -#[cfg(target_os = "windows")] extern crate dwrote; -#[cfg(target_os = "windows")] extern crate truetype; +#[cfg(target_os = "windows")] +extern crate dwrote; extern crate euclid; extern crate fnv; @@ -24,8 +28,8 @@ extern crate fnv; #[cfg(target_os = "linux")] extern crate fontconfig; extern crate fontsan; -#[cfg(any(target_os = "linux", target_os = "android"))] extern crate freetype; -#[cfg(any(target_os = "linux", target_os = "android"))] extern crate servo_allocator; +#[cfg(any(target_os = "linux", target_os = "android"))] +extern crate freetype; extern crate gfx_traits; // Eventually we would like the shaper to be pluggable, as many operating systems have their own @@ -35,23 +39,33 @@ extern crate harfbuzz_sys as harfbuzz; extern crate ipc_channel; #[macro_use] extern crate lazy_static; -#[cfg(any(target_os = "linux", target_os = "android"))] extern crate libc; +#[cfg(any(target_os = "linux", target_os = "android"))] +extern crate libc; #[macro_use] extern crate log; #[cfg_attr(target_os = "windows", macro_use)] extern crate malloc_size_of; extern crate net_traits; extern crate ordered_float; -#[cfg(all(feature = "unstable", any(target_feature = "sse2", target_feature = "neon")))] +#[cfg(all( + feature = "unstable", + any(target_feature = "sse2", target_feature = "neon") +))] extern crate packed_simd; extern crate range; -#[macro_use] extern crate serde; +#[macro_use] +extern crate serde; +#[cfg(any(target_os = "linux", target_os = "android"))] +extern crate servo_allocator; extern crate servo_arc; -#[macro_use] extern crate servo_atoms; +#[macro_use] +extern crate servo_atoms; extern crate servo_url; extern crate smallvec; extern crate style; extern crate time; +#[cfg(target_os = "windows")] +extern crate truetype; extern crate ucd; extern crate unicode_bidi; extern crate unicode_script; @@ -61,7 +75,8 @@ extern crate xi_unicode; extern crate xml5ever; // Fonts -#[macro_use] pub mod font; +#[macro_use] +pub mod font; pub mod font_cache_thread; pub mod font_context; pub mod font_template; diff --git a/components/gfx/platform/freetype/android/font_list.rs b/components/gfx/platform/freetype/android/font_list.rs index 3c52e854112..ebca244078e 100644 --- a/components/gfx/platform/freetype/android/font_list.rs +++ b/components/gfx/platform/freetype/android/font_list.rs @@ -116,21 +116,18 @@ struct FontFamily { struct FontAlias { from: String, to: String, - weight: Option + weight: Option, } struct FontList { families: Vec, - aliases: Vec + aliases: Vec, } impl FontList { fn new() -> FontList { // Possible paths containing the font mapping xml file. - let paths = [ - "/etc/fonts.xml", - "/system/etc/system_fonts.xml" - ]; + let paths = ["/etc/fonts.xml", "/system/etc/system_fonts.xml"]; // Try to load and parse paths until one of them success. let mut result = None; @@ -146,7 +143,7 @@ impl FontList { None => FontList { families: Self::fallback_font_families(), aliases: Vec::new(), - } + }, } } @@ -154,25 +151,26 @@ impl FontList { fn from_path(path: &str) -> Option { let xml = match Self::load_file(path) { Ok(xml) => xml, - _=> { return None; }, + _ => { + return None; + }, }; - let dom: RcDom = parse_document(RcDom::default(), Default::default()) - .one(xml); + let dom: RcDom = parse_document(RcDom::default(), Default::default()).one(xml); let doc = &dom.document; // find familyset root node let children = doc.children.borrow(); - let familyset = children.iter().find(|child| { - match child.data { - NodeData::Element { ref name, .. } => &*name.local == "familyset", - _ => false, - } + let familyset = children.iter().find(|child| match child.data { + NodeData::Element { ref name, .. } => &*name.local == "familyset", + _ => false, }); let familyset = match familyset { Some(node) => node, - _ => { return None; } + _ => { + return None; + }, }; // Parse familyset node @@ -181,7 +179,11 @@ impl FontList { for node in familyset.children.borrow().iter() { match node.data { - NodeData::Element { ref name, ref attrs, .. } => { + NodeData::Element { + ref name, + ref attrs, + .. + } => { if &*name.local == "family" { Self::parse_family(&node, attrs, &mut families); } else if &*name.local == "alias" { @@ -191,13 +193,13 @@ impl FontList { } } }, - _=> {} + _ => {}, } } Some(FontList { families: families, - aliases: aliases + aliases: aliases, }) } @@ -209,17 +211,16 @@ impl FontList { ("Droid Sans", "DroidSans.ttf"), ]; - alternatives.iter().filter(|item| { - Path::new(&Self::font_absolute_path(item.1)).exists() - }).map(|item| { - FontFamily { + alternatives + .iter() + .filter(|item| Path::new(&Self::font_absolute_path(item.1)).exists()) + .map(|item| FontFamily { name: item.0.into(), fonts: vec![Font { filename: item.1.into(), weight: None, - }] - } - }). collect() + }], + }).collect() } // All Android fonts are located in /system/fonts @@ -227,15 +228,14 @@ impl FontList { format!("/system/fonts/{}", filename) } - fn find_family(&self, name: &str) -> Option<&FontFamily>{ + fn find_family(&self, name: &str) -> Option<&FontFamily> { self.families.iter().find(|f| f.name == name) } - fn find_alias(&self, name: &str) -> Option<&FontAlias>{ + fn find_alias(&self, name: &str) -> Option<&FontAlias> { self.aliases.iter().find(|f| f.from == name) } - fn load_file(path: &str) -> Result { let mut file = File::open(path)?; let mut content = String::new(); @@ -253,14 +253,16 @@ impl FontList { // Roboto-LightItalic.ttf // Roboto-Regular.ttf // - fn parse_family(familyset: &Node, attrs: &RefCell>, out:&mut Vec) { + fn parse_family(familyset: &Node, attrs: &RefCell>, out: &mut Vec) { // Fallback to old Android API v17 xml format if required - let using_api_17 = familyset.children.borrow().iter().any(|node| { - match node.data { + let using_api_17 = familyset + .children + .borrow() + .iter() + .any(|node| match node.data { NodeData::Element { ref name, .. } => &*name.local == "nameset", - _=> false, - } - }); + _ => false, + }); if using_api_17 { Self::parse_family_v17(familyset, out); return; @@ -269,25 +271,31 @@ impl FontList { // Parse family name let name = match Self::find_attrib("name", attrs) { Some(name) => name, - _ => { return; }, + _ => { + return; + }, }; let mut fonts = Vec::new(); // Parse font variants for node in familyset.children.borrow().iter() { match node.data { - NodeData::Element { ref name, ref attrs, .. } => { + NodeData::Element { + ref name, + ref attrs, + .. + } => { if &*name.local == "font" { FontList::parse_font(&node, attrs, &mut fonts); } }, - _=> {} + _ => {}, } } out.push(FontFamily { name: name, - fonts: fonts + fonts: fonts, }); } @@ -308,7 +316,7 @@ impl FontList { // Roboto-BoldItalic.ttf // // - fn parse_family_v17(familyset: &Node, out:&mut Vec) { + fn parse_family_v17(familyset: &Node, out: &mut Vec) { let mut nameset = Vec::new(); let mut fileset = Vec::new(); for node in familyset.children.borrow().iter() { @@ -320,21 +328,23 @@ impl FontList { Self::collect_contents_with_tag(node, "file", &mut fileset); } }, - _=> {} + _ => {}, } } // Create a families for each variation for name in nameset { - let fonts: Vec = fileset.iter().map(|f| Font { - filename: f.clone(), - weight: None, - }).collect(); + let fonts: Vec = fileset + .iter() + .map(|f| Font { + filename: f.clone(), + weight: None, + }).collect(); if !fonts.is_empty() { out.push(FontFamily { name: name, - fonts: fonts + fonts: fonts, }) } } @@ -342,11 +352,13 @@ impl FontList { // Example: // Roboto-Thin.ttf - fn parse_font(node: &Node, attrs: &RefCell>, out:&mut Vec) { + fn parse_font(node: &Node, attrs: &RefCell>, out: &mut Vec) { // Parse font filename let filename = match Self::text_content(node) { Some(filename) => filename, - _ => { return; } + _ => { + return; + }, }; // Parse font weight @@ -367,17 +379,21 @@ impl FontList { // // // - fn parse_alias(attrs: &RefCell>, out:&mut Vec) { + fn parse_alias(attrs: &RefCell>, out: &mut Vec) { // Parse alias name and referenced font let from = match Self::find_attrib("name", attrs) { Some(from) => from, - _ => { return; }, + _ => { + return; + }, }; // Parse referenced font let to = match Self::find_attrib("to", attrs) { Some(to) => to, - _ => { return; }, + _ => { + return; + }, }; // Parse optional weight filter @@ -391,23 +407,28 @@ impl FontList { } fn find_attrib(name: &str, attrs: &RefCell>) -> Option { - attrs.borrow().iter().find(|attr| &*attr.name.local == name).map(|s| String::from(&s.value)) + attrs + .borrow() + .iter() + .find(|attr| &*attr.name.local == name) + .map(|s| String::from(&s.value)) } fn text_content(node: &Node) -> Option { - node.children.borrow().get(0).and_then(|child| { - match child.data { + node.children + .borrow() + .get(0) + .and_then(|child| match child.data { NodeData::Text { ref contents } => { let mut result = String::new(); result.push_str(&contents.borrow()); Some(result) }, - _ => None - } - }) + _ => None, + }) } - fn collect_contents_with_tag(node: &Node, tag: &str, out:&mut Vec) { + fn collect_contents_with_tag(node: &Node, tag: &str, out: &mut Vec) { for child in node.children.borrow().iter() { match child.data { NodeData::Element { ref name, .. } => { @@ -417,14 +438,17 @@ impl FontList { } } }, - _=> {} + _ => {}, } } } } // Functions used by FontCacheThread -pub fn for_each_available_family(mut callback: F) where F: FnMut(String) { +pub fn for_each_available_family(mut callback: F) +where + F: FnMut(String), +{ for family in &FONT_LIST.families { callback(family.name.clone()); } @@ -434,7 +458,8 @@ pub fn for_each_available_family(mut callback: F) where F: FnMut(String) { } pub fn for_each_variation(family_name: &str, mut callback: F) - where F: FnMut(String) +where + F: FnMut(String), { if let Some(family) = FONT_LIST.find_family(family_name) { for font in &family.fonts { @@ -453,7 +478,7 @@ pub fn for_each_variation(family_name: &str, mut callback: F) callback(FontList::font_absolute_path(&font.filename)) } }, - _ => {} + _ => {}, } } } @@ -473,46 +498,44 @@ pub fn system_default_family(generic_name: &str) -> Option { // Based on gfxAndroidPlatform::GetCommonFallbackFonts() in Gecko pub fn fallback_font_families(codepoint: Option) -> Vec<&'static str> { - let mut families = vec!(); + let mut families = vec![]; if let Some(block) = codepoint.and_then(|c| c.block()) { match block { UnicodeBlock::Armenian => { families.push("Droid Sans Armenian"); - } + }, UnicodeBlock::Hebrew => { families.push("Droid Sans Hebrew"); - } + }, UnicodeBlock::Arabic => { families.push("Droid Sans Arabic"); - } + }, UnicodeBlock::Devanagari => { families.push("Noto Sans Devanagari"); families.push("Droid Sans Devanagari"); - } + }, UnicodeBlock::Tamil => { families.push("Noto Sans Tamil"); families.push("Droid Sans Tamil"); - } + }, UnicodeBlock::Thai => { families.push("Noto Sans Thai"); families.push("Droid Sans Thai"); - } + }, - UnicodeBlock::Georgian | - UnicodeBlock::GeorgianSupplement => { + UnicodeBlock::Georgian | UnicodeBlock::GeorgianSupplement => { families.push("Droid Sans Georgian"); - } + }, - UnicodeBlock::Ethiopic | - UnicodeBlock::EthiopicSupplement => { + UnicodeBlock::Ethiopic | UnicodeBlock::EthiopicSupplement => { families.push("Droid Sans Ethiopic"); - } + }, _ => { if is_cjk(codepoint.unwrap()) { @@ -520,7 +543,7 @@ pub fn fallback_font_families(codepoint: Option) -> Vec<&'static str> { families.push("Noto Sans CJK JP"); families.push("Droid Sans Japanese"); } - } + }, } } diff --git a/components/gfx/platform/freetype/font.rs b/components/gfx/platform/freetype/font.rs index 04318ce7ff8..c774728fef0 100644 --- a/components/gfx/platform/freetype/font.rs +++ b/components/gfx/platform/freetype/font.rs @@ -98,14 +98,21 @@ fn create_face( let face_index = 0 as FT_Long; let result = if let Some(ref bytes) = template.bytes { - FT_New_Memory_Face(lib, bytes.as_ptr(), bytes.len() as FT_Long, face_index, &mut face) + FT_New_Memory_Face( + lib, + bytes.as_ptr(), + bytes.len() as FT_Long, + face_index, + &mut face, + ) } else { // This will trigger a synchronous file read in the layout thread, which we may want to // revisit at some point. See discussion here: // // https://github.com/servo/servo/pull/20506#issuecomment-378838800 - let filename = CString::new(&*template.identifier).expect("filename contains NUL byte!"); + let filename = + CString::new(&*template.identifier).expect("filename contains NUL byte!"); FT_New_Face(lib, filename.as_ptr(), face_index, &mut face) }; @@ -122,25 +129,27 @@ fn create_face( } impl FontHandleMethods for FontHandle { - fn new_from_template(fctx: &FontContextHandle, - template: Arc, - pt_size: Option) - -> Result { + fn new_from_template( + fctx: &FontContextHandle, + template: Arc, + pt_size: Option, + ) -> Result { let ft_ctx: FT_Library = fctx.ctx.ctx; - if ft_ctx.is_null() { return Err(()); } + if ft_ctx.is_null() { + return Err(()); + } let face = create_face(ft_ctx, &template, pt_size)?; let mut handle = FontHandle { - face: face, - font_data: template.clone(), - handle: fctx.clone(), - can_do_fast_shaping: false, + face: face, + font_data: template.clone(), + handle: fctx.clone(), + can_do_fast_shaping: false, }; // TODO (#11310): Implement basic support for GPOS and GSUB. - handle.can_do_fast_shaping = handle.has_table(KERN) && - !handle.has_table(GPOS) && - !handle.has_table(GSUB); + handle.can_do_fast_shaping = + handle.has_table(KERN) && !handle.has_table(GPOS) && !handle.has_table(GSUB); Ok(handle) } @@ -203,7 +212,7 @@ impl FontHandleMethods for FontHandle { 7 => FontStretchKeyword::Expanded, 8 => FontStretchKeyword::ExtraExpanded, 9 => FontStretchKeyword::UltraExpanded, - _ => FontStretchKeyword::Normal + _ => FontStretchKeyword::Normal, } } else { FontStretchKeyword::Normal @@ -218,20 +227,26 @@ impl FontHandleMethods for FontHandle { if idx != 0 as FT_UInt { Some(idx as GlyphId) } else { - debug!("Invalid codepoint: U+{:04X} ('{}')", codepoint as u32, codepoint); + debug!( + "Invalid codepoint: U+{:04X} ('{}')", + codepoint as u32, codepoint + ); None } } } - fn glyph_h_kerning(&self, first_glyph: GlyphId, second_glyph: GlyphId) - -> FractionalPixel { + fn glyph_h_kerning(&self, first_glyph: GlyphId, second_glyph: GlyphId) -> FractionalPixel { assert!(!self.face.is_null()); let mut delta = FT_Vector { x: 0, y: 0 }; unsafe { - FT_Get_Kerning(self.face, first_glyph, second_glyph, - FT_Kerning_Mode::FT_KERNING_DEFAULT as FT_UInt, - &mut delta); + FT_Get_Kerning( + self.face, + first_glyph, + second_glyph, + FT_Kerning_Mode::FT_KERNING_DEFAULT as FT_UInt, + &mut delta, + ); } fixed_to_float_ft(delta.x as i32) } @@ -243,9 +258,7 @@ impl FontHandleMethods for FontHandle { fn glyph_h_advance(&self, glyph: GlyphId) -> Option { assert!(!self.face.is_null()); unsafe { - let res = FT_Load_Glyph(self.face, - glyph as FT_UInt, - GLYPH_LOAD_FLAGS); + let res = FT_Load_Glyph(self.face, glyph as FT_UInt, GLYPH_LOAD_FLAGS); if succeeded(res) { let void_glyph = (*self.face).glyph; let slot: FT_GlyphSlot = mem::transmute(void_glyph); @@ -291,23 +304,24 @@ impl FontHandleMethods for FontHandle { x_height = self.font_units_to_au(os2.sx_height as f64); } - let average_advance = self.glyph_index('0') - .and_then(|idx| self.glyph_h_advance(idx)) - .map_or(max_advance, |advance| self.font_units_to_au(advance)); + let average_advance = self + .glyph_index('0') + .and_then(|idx| self.glyph_h_advance(idx)) + .map_or(max_advance, |advance| self.font_units_to_au(advance)); let metrics = FontMetrics { - underline_size: underline_size, + underline_size: underline_size, underline_offset: underline_offset, - strikeout_size: strikeout_size, + strikeout_size: strikeout_size, strikeout_offset: strikeout_offset, - leading: leading, - x_height: x_height, - em_size: em_size, - ascent: ascent, - descent: -descent, // linux font's seem to use the opposite sign from mac - max_advance: max_advance, - average_advance: average_advance, - line_gap: height, + leading: leading, + x_height: x_height, + em_size: em_size, + ascent: ascent, + descent: -descent, // linux font's seem to use the opposite sign from mac + max_advance: max_advance, + average_advance: average_advance, + line_gap: height, }; debug!("Font metrics (@{}px): {:?}", em_size.to_f32_px(), metrics); @@ -320,13 +334,25 @@ impl FontHandleMethods for FontHandle { unsafe { // Get the length let mut len = 0; - if !succeeded(FT_Load_Sfnt_Table(self.face, tag, 0, ptr::null_mut(), &mut len)) { - return None + if !succeeded(FT_Load_Sfnt_Table( + self.face, + tag, + 0, + ptr::null_mut(), + &mut len, + )) { + return None; } // Get the bytes let mut buf = vec![0u8; len as usize]; - if !succeeded(FT_Load_Sfnt_Table(self.face, tag, 0, buf.as_mut_ptr(), &mut len)) { - return None + if !succeeded(FT_Load_Sfnt_Table( + self.face, + tag, + 0, + buf.as_mut_ptr(), + &mut len, + )) { + return None; } Some(FontTable { buffer: buf }) } @@ -338,25 +364,33 @@ impl FontHandleMethods for FontHandle { } impl<'a> FontHandle { - fn set_char_size(face: FT_Face, pt_size: Au) -> Result<(), ()>{ + fn set_char_size(face: FT_Face, pt_size: Au) -> Result<(), ()> { let char_size = pt_size.to_f64_px() * 64.0 + 0.5; unsafe { let result = FT_Set_Char_Size(face, char_size as FT_F26Dot6, 0, 0, 0); - if succeeded(result) { Ok(()) } else { Err(()) } + if succeeded(result) { + Ok(()) + } else { + Err(()) + } } } fn has_table(&self, tag: FontTableTag) -> bool { unsafe { - succeeded(FT_Load_Sfnt_Table(self.face, tag as FT_ULong, 0, ptr::null_mut(), &mut 0)) + succeeded(FT_Load_Sfnt_Table( + self.face, + tag as FT_ULong, + 0, + ptr::null_mut(), + &mut 0, + )) } } fn face_rec_mut(&'a self) -> &'a mut FT_FaceRec { - unsafe { - &mut (*self.face) - } + unsafe { &mut (*self.face) } } fn font_units_to_au(&self, value: f64) -> Au { @@ -378,11 +412,12 @@ impl<'a> FontHandle { fn os2_table(&self) -> Option { unsafe { - let os2 = FT_Get_Sfnt_Table(self.face_rec_mut(), FT_Sfnt_Tag::FT_SFNT_OS2) as *mut TT_OS2; + let os2 = + FT_Get_Sfnt_Table(self.face_rec_mut(), FT_Sfnt_Tag::FT_SFNT_OS2) as *mut TT_OS2; let valid = !os2.is_null() && (*os2).version != 0xffff; if !valid { - return None + return None; } Some(OS2Table { diff --git a/components/gfx/platform/freetype/font_context.rs b/components/gfx/platform/freetype/font_context.rs index 231d91ce17c..dbc8816efc5 100644 --- a/components/gfx/platform/freetype/font_context.rs +++ b/components/gfx/platform/freetype/font_context.rs @@ -23,10 +23,10 @@ pub struct User { size: usize, } -extern fn ft_alloc(mem: FT_Memory, req_size: c_long) -> *mut c_void { +extern "C" fn ft_alloc(mem: FT_Memory, req_size: c_long) -> *mut c_void { unsafe { let ptr = malloc(req_size as usize); - let ptr = ptr as *mut c_void; // libc::c_void vs std::os::raw::c_void + let ptr = ptr as *mut c_void; // libc::c_void vs std::os::raw::c_void let actual_size = usable_size(ptr); let user = (*mem).user as *mut User; (*user).size += actual_size; @@ -34,7 +34,7 @@ extern fn ft_alloc(mem: FT_Memory, req_size: c_long) -> *mut c_void { } } -extern fn ft_free(mem: FT_Memory, ptr: *mut c_void) { +extern "C" fn ft_free(mem: FT_Memory, ptr: *mut c_void) { unsafe { let actual_size = usable_size(ptr); let user = (*mem).user as *mut User; @@ -43,8 +43,12 @@ extern fn ft_free(mem: FT_Memory, ptr: *mut c_void) { } } -extern fn ft_realloc(mem: FT_Memory, _old_size: c_long, new_req_size: c_long, - old_ptr: *mut c_void) -> *mut c_void { +extern "C" fn ft_realloc( + mem: FT_Memory, + _old_size: c_long, + new_req_size: c_long, + old_ptr: *mut c_void, +) -> *mut c_void { unsafe { let old_actual_size = usable_size(old_ptr); let new_ptr = realloc(old_ptr as *mut _, new_req_size as usize); @@ -108,9 +112,7 @@ impl MallocSizeOf for FontContextHandle { impl FontContextHandle { pub fn new() -> FontContextHandle { - let user = Box::into_raw(Box::new(User { - size: 0, - })); + let user = Box::into_raw(Box::new(User { size: 0 })); let mem = Box::into_raw(Box::new(FT_MemoryRec_ { user: user as *mut c_void, alloc: Some(ft_alloc), @@ -121,12 +123,18 @@ impl FontContextHandle { let mut ctx: FT_Library = ptr::null_mut(); let result = FT_New_Library(mem, &mut ctx); - if !succeeded(result) { panic!("Unable to initialize FreeType library"); } + if !succeeded(result) { + panic!("Unable to initialize FreeType library"); + } FT_Add_Default_Modules(ctx); FontContextHandle { - ctx: Rc::new(FreeTypeLibraryHandle { ctx: ctx, mem: mem, user: user }), + ctx: Rc::new(FreeTypeLibraryHandle { + ctx: ctx, + mem: mem, + user: user, + }), } } } diff --git a/components/gfx/platform/freetype/font_list.rs b/components/gfx/platform/freetype/font_list.rs index ddafb94a031..e1ef486fa43 100644 --- a/components/gfx/platform/freetype/font_list.rs +++ b/components/gfx/platform/freetype/font_list.rs @@ -20,7 +20,10 @@ static FC_FILE: &'static [u8] = b"file\0"; static FC_INDEX: &'static [u8] = b"index\0"; static FC_FONTFORMAT: &'static [u8] = b"fontformat\0"; -pub fn for_each_available_family(mut callback: F) where F: FnMut(String) { +pub fn for_each_available_family(mut callback: F) +where + F: FnMut(String), +{ unsafe { let config = FcConfigGetCurrent(); let font_set = FcConfigGetFonts(config, FcSetSystem); @@ -29,19 +32,21 @@ pub fn for_each_available_family(mut callback: F) where F: FnMut(String) { let mut family: *mut FcChar8 = ptr::null_mut(); let mut format: *mut FcChar8 = ptr::null_mut(); let mut v: c_int = 0; - if FcPatternGetString(*font, FC_FONTFORMAT.as_ptr() as *mut c_char, v, &mut format) != FcResultMatch { + if FcPatternGetString(*font, FC_FONTFORMAT.as_ptr() as *mut c_char, v, &mut format) != + FcResultMatch + { continue; } // Skip bitmap fonts. They aren't supported by FreeType. let fontformat = c_str_to_string(format as *const c_char); - if fontformat != "TrueType" && - fontformat != "CFF" && - fontformat != "Type 1" { + if fontformat != "TrueType" && fontformat != "CFF" && fontformat != "Type 1" { continue; } - while FcPatternGetString(*font, FC_FAMILY.as_ptr() as *mut c_char, v, &mut family) == FcResultMatch { + while FcPatternGetString(*font, FC_FAMILY.as_ptr() as *mut c_char, v, &mut family) == + FcResultMatch + { let family_name = c_str_to_string(family as *const c_char); callback(family_name); v += 1; @@ -51,7 +56,8 @@ pub fn for_each_available_family(mut callback: F) where F: FnMut(String) { } pub fn for_each_variation(family_name: &str, mut callback: F) - where F: FnMut(String) +where + F: FnMut(String), { debug!("getting variations for {}", family_name); unsafe { @@ -62,7 +68,11 @@ pub fn for_each_variation(family_name: &str, mut callback: F) assert!(!pattern.is_null()); let family_name_c = CString::new(family_name).unwrap(); let family_name = family_name_c.as_ptr(); - let ok = FcPatternAddString(pattern, FC_FAMILY.as_ptr() as *mut c_char, family_name as *mut FcChar8); + let ok = FcPatternAddString( + pattern, + FC_FAMILY.as_ptr() as *mut c_char, + family_name as *mut FcChar8, + ); assert_ne!(ok, 0); let object_set = FcObjectSetCreate(); @@ -85,7 +95,8 @@ pub fn for_each_variation(family_name: &str, mut callback: F) panic!(); }; let mut index: libc::c_int = 0; - let result = FcPatternGetInteger(*font, FC_INDEX.as_ptr() as *mut c_char, 0, &mut index); + let result = + FcPatternGetInteger(*font, FC_INDEX.as_ptr() as *mut c_char, 0, &mut index); let index = if result == FcResultMatch { index } else { @@ -119,7 +130,12 @@ pub fn system_default_family(generic_name: &str) -> Option { let family_name = if result == FcResultMatch { let mut match_string: *mut FcChar8 = ptr::null_mut(); - FcPatternGetString(family_match, FC_FAMILY.as_ptr() as *mut c_char, 0, &mut match_string); + FcPatternGetString( + family_match, + FC_FAMILY.as_ptr() as *mut c_char, + 0, + &mut match_string, + ); let result = c_str_to_string(match_string as *const c_char); FcPatternDestroy(family_match); Some(result) @@ -136,12 +152,7 @@ pub static SANS_SERIF_FONT_FAMILY: &'static str = "DejaVu Sans"; // Based on gfxPlatformGtk::GetCommonFallbackFonts() in Gecko pub fn fallback_font_families(codepoint: Option) -> Vec<&'static str> { - let mut families = vec!( - "DejaVu Serif", - "FreeSerif", - "DejaVu Sans", - "FreeSans", - ); + let mut families = vec!["DejaVu Serif", "FreeSerif", "DejaVu Sans", "FreeSans"]; if let Some(codepoint) = codepoint { if is_cjk(codepoint) { diff --git a/components/gfx/platform/freetype/font_template.rs b/components/gfx/platform/freetype/font_template.rs index c4b4a9bc9e7..674739b69ce 100644 --- a/components/gfx/platform/freetype/font_template.rs +++ b/components/gfx/platform/freetype/font_template.rs @@ -15,7 +15,6 @@ use webrender_api::NativeFontHandle; #[derive(Deserialize, Serialize)] pub struct FontTemplateData { // If you add members here, review the Debug impl below - pub bytes: Option>, pub identifier: Atom, } @@ -23,9 +22,11 @@ pub struct FontTemplateData { impl fmt::Debug for FontTemplateData { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("FontTemplateData") - .field("bytes", &self.bytes.as_ref().map(|b| format!("[{} bytes]", b.len()))) - .field("identifier", &self.identifier) - .finish() + .field( + "bytes", + &self.bytes.as_ref().map(|b| format!("[{} bytes]", b.len())), + ).field("identifier", &self.identifier) + .finish() } } diff --git a/components/gfx/platform/macos/font.rs b/components/gfx/platform/macos/font.rs index e09407b9a39..842c52fd70c 100644 --- a/components/gfx/platform/macos/font.rs +++ b/components/gfx/platform/macos/font.rs @@ -3,7 +3,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /// Implementation of Quartz (CoreGraphics) fonts. - use app_units::Au; use byteorder::{BigEndian, ByteOrder}; use core_foundation::base::CFIndex; @@ -111,8 +110,8 @@ impl FontHandle { return None; } - let pt_per_font_unit = self.ctfont.pt_size() as f64 / - self.ctfont.units_per_em() as f64; + let pt_per_font_unit = + self.ctfont.pt_size() as f64 / self.ctfont.units_per_em() as f64; result.px_per_font_unit = pt_to_px(pt_per_font_unit); } start = end; @@ -160,15 +159,15 @@ impl fmt::Debug for CachedKernTable { } } - impl FontHandleMethods for FontHandle { - fn new_from_template(_fctx: &FontContextHandle, - template: Arc, - pt_size: Option) - -> Result { + fn new_from_template( + _fctx: &FontContextHandle, + template: Arc, + pt_size: Option, + ) -> Result { let size = match pt_size { Some(s) => s.to_f64_px(), - None => 0.0 + None => 0.0, }; match template.ctfont(size) { Some(ref ctfont) => { @@ -181,13 +180,11 @@ impl FontHandleMethods for FontHandle { handle.h_kern_subtable = handle.find_h_kern_subtable(); // TODO (#11310): Implement basic support for GPOS and GSUB. handle.can_do_fast_shaping = handle.h_kern_subtable.is_some() && - handle.table_for_tag(GPOS).is_none() && - handle.table_for_tag(GSUB).is_none(); + handle.table_for_tag(GPOS).is_none() && + handle.table_for_tag(GSUB).is_none(); Ok(handle) - } - None => { - Err(()) - } + }, + None => Err(()), } } @@ -213,13 +210,14 @@ impl FontHandleMethods for FontHandle { } fn boldness(&self) -> FontWeight { - let normalized = self.ctfont.all_traits().normalized_weight(); // [-1.0, 1.0] + let normalized = self.ctfont.all_traits().normalized_weight(); // [-1.0, 1.0] + // TODO(emilio): It may make sense to make this range [.01, 10.0], to // align with css-fonts-4's range of [1, 1000]. let normalized = if normalized <= 0.0 { - 4.0 + normalized * 3.0 // [1.0, 4.0] + 4.0 + normalized * 3.0 // [1.0, 4.0] } else { - 4.0 + normalized * 5.0 // [4.0, 9.0] + 4.0 + normalized * 5.0 // [4.0, 9.0] }; // [1.0, 9.0], centered on 4.0 FontWeight(normalized as f32 * 100.) } @@ -228,7 +226,7 @@ impl FontHandleMethods for FontHandle { use style::values::computed::Percentage; use style::values::generics::NonNegative; - let normalized = self.ctfont.all_traits().normalized_width(); // [-1.0, 1.0] + let normalized = self.ctfont.all_traits().normalized_width(); // [-1.0, 1.0] FontStretch(NonNegative(Percentage(normalized as f32 + 1.0))) } @@ -237,9 +235,9 @@ impl FontHandleMethods for FontHandle { let mut glyphs: [CGGlyph; 1] = [0 as CGGlyph]; let count: CFIndex = 1; - let result = self.ctfont.get_glyphs_for_characters(&characters[0], - &mut glyphs[0], - count); + let result = self + .ctfont + .get_glyphs_for_characters(&characters[0], &mut glyphs[0], count); if !result { // No glyph for this character @@ -265,10 +263,12 @@ impl FontHandleMethods for FontHandle { fn glyph_h_advance(&self, glyph: GlyphId) -> Option { let glyphs = [glyph as CGGlyph]; - let advance = self.ctfont.get_advances_for_glyphs(kCTFontDefaultOrientation, - &glyphs[0], - ptr::null_mut(), - 1); + let advance = self.ctfont.get_advances_for_glyphs( + kCTFontDefaultOrientation, + &glyphs[0], + ptr::null_mut(), + 1, + ); Some(advance as FractionalPixel) } @@ -283,39 +283,42 @@ impl FontHandleMethods for FontHandle { let line_gap = (ascent + descent + leading + 0.5).floor(); let max_advance_width = au_from_pt(bounding_rect.size.width as f64); - let average_advance = self.glyph_index('0') - .and_then(|idx| self.glyph_h_advance(idx)) - .map(Au::from_f64_px) - .unwrap_or(max_advance_width); + let average_advance = self + .glyph_index('0') + .and_then(|idx| self.glyph_h_advance(idx)) + .map(Au::from_f64_px) + .unwrap_or(max_advance_width); let metrics = FontMetrics { - underline_size: au_from_pt(self.ctfont.underline_thickness() as f64), + underline_size: au_from_pt(self.ctfont.underline_thickness() as f64), // TODO(Issue #201): underline metrics are not reliable. Have to pull out of font table // directly. // // see also: https://bugs.webkit.org/show_bug.cgi?id=16768 // see also: https://bugreports.qt-project.org/browse/QTBUG-13364 underline_offset: au_from_pt(self.ctfont.underline_position() as f64), - strikeout_size: Au(0), // FIXME(Issue #942) + strikeout_size: Au(0), // FIXME(Issue #942) strikeout_offset: Au(0), // FIXME(Issue #942) - leading: au_from_pt(leading), - x_height: au_from_pt((self.ctfont.x_height() as f64) * scale), - em_size: em_size, - ascent: au_from_pt(ascent * scale), - descent: au_from_pt(descent * scale), - max_advance: max_advance_width, - average_advance: average_advance, - line_gap: Au::from_f64_px(line_gap), + leading: au_from_pt(leading), + x_height: au_from_pt((self.ctfont.x_height() as f64) * scale), + em_size: em_size, + ascent: au_from_pt(ascent * scale), + descent: au_from_pt(descent * scale), + max_advance: max_advance_width, + average_advance: average_advance, + line_gap: Au::from_f64_px(line_gap), }; - debug!("Font metrics (@{} pt): {:?}", self.ctfont.pt_size() as f64, metrics); + debug!( + "Font metrics (@{} pt): {:?}", + self.ctfont.pt_size() as f64, + metrics + ); metrics } fn table_for_tag(&self, tag: FontTableTag) -> Option { let result: Option = self.ctfont.get_font_table(tag); - result.and_then(|data| { - Some(FontTable::wrap(data)) - }) + result.and_then(|data| Some(FontTable::wrap(data))) } fn identifier(&self) -> Atom { diff --git a/components/gfx/platform/macos/font_context.rs b/components/gfx/platform/macos/font_context.rs index b9a6b193a6d..3de73025a82 100644 --- a/components/gfx/platform/macos/font_context.rs +++ b/components/gfx/platform/macos/font_context.rs @@ -6,7 +6,7 @@ use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; #[derive(Clone, Debug)] pub struct FontContextHandle { - ctx: () + ctx: (), } impl FontContextHandle { diff --git a/components/gfx/platform/macos/font_list.rs b/components/gfx/platform/macos/font_list.rs index 656cc043907..df78a3917c8 100644 --- a/components/gfx/platform/macos/font_list.rs +++ b/components/gfx/platform/macos/font_list.rs @@ -6,14 +6,20 @@ use core_text; use text::util::unicode_plane; use ucd::{Codepoint, UnicodeBlock}; -pub fn for_each_available_family(mut callback: F) where F: FnMut(String) { +pub fn for_each_available_family(mut callback: F) +where + F: FnMut(String), +{ let family_names = core_text::font_collection::get_family_names(); for family_name in family_names.iter() { callback(family_name.to_string()); } } -pub fn for_each_variation(family_name: &str, mut callback: F) where F: FnMut(String) { +pub fn for_each_variation(family_name: &str, mut callback: F) +where + F: FnMut(String), +{ debug!("Looking for faces of family: {}", family_name); let family_collection = core_text::font_collection::create_for_family(family_name); @@ -31,7 +37,7 @@ pub fn system_default_family(_generic_name: &str) -> Option { // Based on gfxPlatformMac::GetCommonFallbackFonts() in Gecko pub fn fallback_font_families(codepoint: Option) -> Vec<&'static str> { - let mut families = vec!("Lucida Grande"); + let mut families = vec!["Lucida Grande"]; if let Some(codepoint) = codepoint { match unicode_plane(codepoint) { @@ -45,66 +51,65 @@ pub fn fallback_font_families(codepoint: Option) -> Vec<&'static str> { UnicodeBlock::Thaana | UnicodeBlock::NKo => { families.push("Geeza Pro"); - } + }, UnicodeBlock::Devanagari => { families.push("Devanagari Sangam MN"); - } + }, UnicodeBlock::Gurmukhi => { families.push("Gurmukhi MN"); - } + }, UnicodeBlock::Gujarati => { families.push("Gujarati Sangam MN"); - } + }, UnicodeBlock::Tamil => { families.push("Tamil MN"); - } + }, UnicodeBlock::Lao => { families.push("Lao MN"); - } + }, UnicodeBlock::Tibetan => { families.push("Songti SC"); - } + }, UnicodeBlock::Myanmar => { families.push("Myanmar MN"); - } + }, UnicodeBlock::Ethiopic | UnicodeBlock::EthiopicSupplement | UnicodeBlock::EthiopicExtended | UnicodeBlock::EthiopicExtendedA => { families.push("Kefa"); - } + }, UnicodeBlock::Cherokee => { families.push("Plantagenet Cherokee"); - } + }, UnicodeBlock::UnifiedCanadianAboriginalSyllabics | UnicodeBlock::UnifiedCanadianAboriginalSyllabicsExtended => { families.push("Euphemia UCAS"); - } + }, UnicodeBlock::Mongolian | UnicodeBlock::YiSyllables | UnicodeBlock::YiRadicals => { families.push("STHeiti"); - } + }, - UnicodeBlock::Khmer | - UnicodeBlock::KhmerSymbols => { + UnicodeBlock::Khmer | UnicodeBlock::KhmerSymbols => { families.push("Khmer MN"); - } + }, UnicodeBlock::TaiLe => { families.push("Microsoft Tai Le"); - } + }, UnicodeBlock::GeneralPunctuation | UnicodeBlock::SuperscriptsandSubscripts | @@ -134,11 +139,11 @@ pub fn fallback_font_families(codepoint: Option) -> Vec<&'static str> { families.push("Apple Symbols"); families.push("Menlo"); families.push("STIXGeneral"); - } + }, UnicodeBlock::BraillePatterns => { families.push("Apple Braille"); - } + }, UnicodeBlock::Bopomofo | UnicodeBlock::HangulCompatibilityJamo | @@ -147,7 +152,7 @@ pub fn fallback_font_families(codepoint: Option) -> Vec<&'static str> { UnicodeBlock::CJKStrokes | UnicodeBlock::KatakanaPhoneticExtensions => { families.push("Hiragino Sans GB"); - } + }, UnicodeBlock::YijingHexagramSymbols | UnicodeBlock::CyrillicExtendedB | @@ -158,27 +163,27 @@ pub fn fallback_font_families(codepoint: Option) -> Vec<&'static str> { UnicodeBlock::HalfwidthandFullwidthForms | UnicodeBlock::Specials => { families.push("Apple Symbols"); - } + }, - _ => {} + _ => {}, } } - } + }, // https://en.wikipedia.org/wiki/Plane_(Unicode)#Supplementary_Multilingual_Plane 1 => { families.push("Apple Symbols"); families.push("STIXGeneral"); - } + }, // https://en.wikipedia.org/wiki/Plane_(Unicode)#Supplementary_Ideographic_Plane 2 => { // Systems with MS Office may have these fonts families.push("MingLiU-ExtB"); families.push("SimSun-ExtB"); - } + }, - _ => {} + _ => {}, } } diff --git a/components/gfx/platform/macos/font_template.rs b/components/gfx/platform/macos/font_template.rs index 15cc2a8689c..85d134f45a2 100644 --- a/components/gfx/platform/macos/font_template.rs +++ b/components/gfx/platform/macos/font_template.rs @@ -27,7 +27,6 @@ use webrender_api::NativeFontHandle; #[derive(Deserialize, Serialize)] pub struct FontTemplateData { // If you add members here, review the Debug impl below - /// The `CTFont` object, if present. This is cached here so that we don't have to keep creating /// `CTFont` instances over and over. It can always be recreated from the `identifier` and/or /// `font_data` fields. @@ -38,21 +37,21 @@ pub struct FontTemplateData { ctfont: CachedCTFont, pub identifier: Atom, - pub font_data: Option>> + pub font_data: Option>>, } impl fmt::Debug for FontTemplateData { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("FontTemplateData") - .field("ctfont", &self.ctfont) - .field("identifier", &self.identifier) - .field( - "font_data", - &self.font_data + .field("ctfont", &self.ctfont) + .field("identifier", &self.identifier) + .field( + "font_data", + &self + .font_data .as_ref() - .map(|bytes| format!("[{} bytes]", bytes.len())) - ) - .finish() + .map(|bytes| format!("[{} bytes]", bytes.len())), + ).finish() } } @@ -64,7 +63,7 @@ impl FontTemplateData { Ok(FontTemplateData { ctfont: CachedCTFont(Mutex::new(HashMap::new())), identifier: identifier.to_owned(), - font_data: font_data.map(Arc::new) + font_data: font_data.map(Arc::new), }) } @@ -83,10 +82,10 @@ impl FontTemplateData { match cgfont_result { Ok(cgfont) => { Some(core_text::font::new_from_CGFont(&cgfont, clamped_pt_size)) - } - Err(_) => None + }, + Err(_) => None, } - } + }, None => core_text::font::new_from_name(&*self.identifier, clamped_pt_size).ok(), }; if let Some(ctfont) = ctfont { @@ -104,16 +103,23 @@ impl FontTemplateData { return font_data; } - let path = ServoUrl::parse(&*self.ctfont(0.0) - .expect("No Core Text font available!") - .url() - .expect("No URL for Core Text font!") - .get_string() - .to_string()).expect("Couldn't parse Core Text font URL!") - .as_url().to_file_path() - .expect("Core Text font didn't name a path!"); + let path = ServoUrl::parse( + &*self + .ctfont(0.0) + .expect("No Core Text font available!") + .url() + .expect("No URL for Core Text font!") + .get_string() + .to_string(), + ).expect("Couldn't parse Core Text font URL!") + .as_url() + .to_file_path() + .expect("Core Text font didn't name a path!"); let mut bytes = Vec::new(); - File::open(path).expect("Couldn't open font file!").read_to_end(&mut bytes).unwrap(); + File::open(path) + .expect("Couldn't open font file!") + .read_to_end(&mut bytes) + .unwrap(); bytes } @@ -125,7 +131,8 @@ impl FontTemplateData { /// Returns the native font that underlies this font template, if applicable. pub fn native_font(&self) -> Option { - self.ctfont(0.0).map(|ctfont| NativeFontHandle(ctfont.copy_to_CGFont())) + self.ctfont(0.0) + .map(|ctfont| NativeFontHandle(ctfont.copy_to_CGFont())) } } @@ -140,14 +147,19 @@ impl Deref for CachedCTFont { } impl Serialize for CachedCTFont { - fn serialize(&self, serializer: S) -> Result where S: Serializer { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { serializer.serialize_none() } } impl<'de> Deserialize<'de> for CachedCTFont { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> { + where + D: Deserializer<'de>, + { struct NoneOptionVisitor; impl<'de> Visitor<'de> for NoneOptionVisitor { @@ -158,7 +170,10 @@ impl<'de> Deserialize<'de> for CachedCTFont { } #[inline] - fn visit_none(self) -> Result where E: Error { + fn visit_none(self) -> Result + where + E: Error, + { Ok(CachedCTFont(Mutex::new(HashMap::new()))) } } diff --git a/components/gfx/platform/mod.rs b/components/gfx/platform/mod.rs index 897fbe9e8d3..106b232e308 100644 --- a/components/gfx/platform/mod.rs +++ b/components/gfx/platform/mod.rs @@ -23,7 +23,9 @@ mod freetype { /// Creates a String from the given null-terminated buffer. /// Panics if the buffer does not contain UTF-8. unsafe fn c_str_to_string(s: *const c_char) -> String { - str::from_utf8(CStr::from_ptr(s).to_bytes()).unwrap().to_owned() + str::from_utf8(CStr::from_ptr(s).to_bytes()) + .unwrap() + .to_owned() } pub mod font; diff --git a/components/gfx/platform/windows/font.rs b/components/gfx/platform/windows/font.rs index 6ea8dcf0538..074bc62748a 100644 --- a/components/gfx/platform/windows/font.rs +++ b/components/gfx/platform/windows/font.rs @@ -27,10 +27,18 @@ use text::glyph::GlyphId; use truetype; // 1em = 12pt = 16px, assuming 72 points per inch and 96 px per inch -fn pt_to_px(pt: f64) -> f64 { pt / 72. * 96. } -fn em_to_px(em: f64) -> f64 { em * 16. } -fn au_from_em(em: f64) -> Au { Au::from_f64_px(em_to_px(em)) } -fn au_from_pt(pt: f64) -> Au { Au::from_f64_px(pt_to_px(pt)) } +fn pt_to_px(pt: f64) -> f64 { + pt / 72. * 96. +} +fn em_to_px(em: f64) -> f64 { + em * 16. +} +fn au_from_em(em: f64) -> Au { + Au::from_f64_px(em_to_px(em)) +} +fn au_from_pt(pt: f64) -> Au { + Au::from_f64_px(pt_to_px(pt)) +} pub struct FontTable { data: Vec, @@ -38,7 +46,9 @@ pub struct FontTable { impl FontTable { pub fn wrap(data: &[u8]) -> FontTable { - FontTable { data: data.to_vec() } + FontTable { + data: data.to_vec(), + } } } @@ -139,7 +149,7 @@ impl FontInfo { } else { return Err(()); } - } + }, }; let mut os2_table_cursor = Cursor::new(os2_table_bytes.as_ref().unwrap()); @@ -163,18 +173,20 @@ impl FontInfo { let weight = StyleFontWeight(weight_val as f32); - let stretch = StyleFontStretch(NonNegative(match min(9, max(1, width_val)) { - 1 => FontStretchKeyword::UltraCondensed, - 2 => FontStretchKeyword::ExtraCondensed, - 3 => FontStretchKeyword::Condensed, - 4 => FontStretchKeyword::SemiCondensed, - 5 => FontStretchKeyword::Normal, - 6 => FontStretchKeyword::SemiExpanded, - 7 => FontStretchKeyword::Expanded, - 8 => FontStretchKeyword::ExtraExpanded, - 9 => FontStretchKeyword::UltraExpanded, - _ => return Err(()), - }.compute())); + let stretch = StyleFontStretch(NonNegative( + match min(9, max(1, width_val)) { + 1 => FontStretchKeyword::UltraCondensed, + 2 => FontStretchKeyword::ExtraCondensed, + 3 => FontStretchKeyword::Condensed, + 4 => FontStretchKeyword::SemiCondensed, + 5 => FontStretchKeyword::Normal, + 6 => FontStretchKeyword::SemiExpanded, + 7 => FontStretchKeyword::Expanded, + 8 => FontStretchKeyword::ExtraExpanded, + 9 => FontStretchKeyword::UltraExpanded, + _ => return Err(()), + }.compute(), + )); let style = if italic_bool { GenericFontStyle::Italic @@ -212,18 +224,20 @@ impl FontInfo { // slightly blacker black FontWeight::ExtraBlack => 1000., }); - let stretch = StyleFontStretch(NonNegative(match font.stretch() { - FontStretch::Undefined => FontStretchKeyword::Normal, - FontStretch::UltraCondensed => FontStretchKeyword::UltraCondensed, - FontStretch::ExtraCondensed => FontStretchKeyword::ExtraCondensed, - FontStretch::Condensed => FontStretchKeyword::Condensed, - FontStretch::SemiCondensed => FontStretchKeyword::SemiCondensed, - FontStretch::Normal => FontStretchKeyword::Normal, - FontStretch::SemiExpanded => FontStretchKeyword::SemiExpanded, - FontStretch::Expanded => FontStretchKeyword::Expanded, - FontStretch::ExtraExpanded => FontStretchKeyword::ExtraExpanded, - FontStretch::UltraExpanded => FontStretchKeyword::UltraExpanded, - }.compute())); + let stretch = StyleFontStretch(NonNegative( + match font.stretch() { + FontStretch::Undefined => FontStretchKeyword::Normal, + FontStretch::UltraCondensed => FontStretchKeyword::UltraCondensed, + FontStretch::ExtraCondensed => FontStretchKeyword::ExtraCondensed, + FontStretch::Condensed => FontStretchKeyword::Condensed, + FontStretch::SemiCondensed => FontStretchKeyword::SemiCondensed, + FontStretch::Normal => FontStretchKeyword::Normal, + FontStretch::SemiExpanded => FontStretchKeyword::SemiExpanded, + FontStretch::Expanded => FontStretchKeyword::Expanded, + FontStretch::ExtraExpanded => FontStretchKeyword::ExtraExpanded, + FontStretch::UltraExpanded => FontStretchKeyword::UltraExpanded, + }.compute(), + )); Ok(FontInfo { family_name: font.family_name(), @@ -246,13 +260,14 @@ pub struct FontHandle { scaled_du_to_px: f32, } -impl FontHandle { -} +impl FontHandle {} impl FontHandleMethods for FontHandle { - fn new_from_template(_: &FontContextHandle, template: Arc, pt_size: Option) - -> Result - { + fn new_from_template( + _: &FontContextHandle, + template: Arc, + pt_size: Option, + ) -> Result { let (info, face) = if let Some(ref raw_font) = template.bytes { let font_file = FontFile::new_from_data(&raw_font); if font_file.is_none() { @@ -260,7 +275,9 @@ impl FontHandleMethods for FontHandle { return Err(()); } - let face = font_file.unwrap().create_face(0, dwrote::DWRITE_FONT_SIMULATIONS_NONE); + let face = font_file + .unwrap() + .create_face(0, dwrote::DWRITE_FONT_SIMULATIONS_NONE); let info = FontInfo::new_from_face(&face)?; (info, face) } else { @@ -350,32 +367,34 @@ impl FontHandleMethods for FontHandle { let dm = self.face.metrics(); let au_from_du = |du| -> Au { Au::from_f32_px(du as f32 * self.du_to_px) }; - let au_from_du_s = |du| -> Au { Au:: from_f32_px(du as f32 * self.scaled_du_to_px) }; + let au_from_du_s = |du| -> Au { Au::from_f32_px(du as f32 * self.scaled_du_to_px) }; // anything that we calculate and don't just pull out of self.face.metrics // is pulled out here for clarity let leading = dm.ascent - dm.capHeight; let metrics = FontMetrics { - underline_size: au_from_du(dm.underlineThickness as i32), + underline_size: au_from_du(dm.underlineThickness as i32), underline_offset: au_from_du_s(dm.underlinePosition as i32), - strikeout_size: au_from_du(dm.strikethroughThickness as i32), + strikeout_size: au_from_du(dm.strikethroughThickness as i32), strikeout_offset: au_from_du_s(dm.strikethroughPosition as i32), - leading: au_from_du_s(leading as i32), - x_height: au_from_du_s(dm.xHeight as i32), - em_size: au_from_em(self.em_size as f64), - ascent: au_from_du_s(dm.ascent as i32), - descent: au_from_du_s(dm.descent as i32), - max_advance: au_from_pt(0.0), // FIXME - average_advance: au_from_pt(0.0), // FIXME - line_gap: au_from_du_s((dm.ascent + dm.descent + dm.lineGap as u16) as i32), + leading: au_from_du_s(leading as i32), + x_height: au_from_du_s(dm.xHeight as i32), + em_size: au_from_em(self.em_size as f64), + ascent: au_from_du_s(dm.ascent as i32), + descent: au_from_du_s(dm.descent as i32), + max_advance: au_from_pt(0.0), // FIXME + average_advance: au_from_pt(0.0), // FIXME + line_gap: au_from_du_s((dm.ascent + dm.descent + dm.lineGap as u16) as i32), }; debug!("Font metrics (@{} pt): {:?}", self.em_size * 12., metrics); metrics } fn table_for_tag(&self, tag: FontTableTag) -> Option { - self.face.get_font_table(tag).map(|bytes| FontTable { data: bytes }) + self.face + .get_font_table(tag) + .map(|bytes| FontTable { data: bytes }) } fn identifier(&self) -> Atom { diff --git a/components/gfx/platform/windows/font_list.rs b/components/gfx/platform/windows/font_list.rs index 3271b77e7fb..b2d73b3db5c 100644 --- a/components/gfx/platform/windows/font_list.rs +++ b/components/gfx/platform/windows/font_list.rs @@ -21,7 +21,10 @@ pub fn system_default_family(_: &str) -> Option { Some("Verdana".to_owned()) } -pub fn for_each_available_family(mut callback: F) where F: FnMut(String) { +pub fn for_each_available_family(mut callback: F) +where + F: FnMut(String), +{ let system_fc = FontCollection::system(); for family in system_fc.families_iter() { callback(family.name()); @@ -37,7 +40,10 @@ pub fn for_each_available_family(mut callback: F) where F: FnMut(String) { // we'll stringify, and then put them all in a HashMap with // the actual FontDescriptor there. -pub fn for_each_variation(family_name: &str, mut callback: F) where F: FnMut(String) { +pub fn for_each_variation(family_name: &str, mut callback: F) +where + F: FnMut(String), +{ let system_fc = FontCollection::system(); if let Some(family) = system_fc.get_font_family_by_name(family_name) { let count = family.get_font_count(); @@ -65,12 +71,14 @@ pub fn descriptor_from_atom(ident: &Atom) -> FontDescriptor { pub fn font_from_atom(ident: &Atom) -> Font { let fonts = FONT_ATOM_MAP.lock().unwrap(); - FontCollection::system().get_font_from_descriptor(fonts.get(ident).unwrap()).unwrap() + FontCollection::system() + .get_font_from_descriptor(fonts.get(ident).unwrap()) + .unwrap() } // Based on gfxWindowsPlatform::GetCommonFallbackFonts() in Gecko pub fn fallback_font_families(codepoint: Option) -> Vec<&'static str> { - let mut families = vec!("Arial"); + let mut families = vec!["Arial"]; if let Some(codepoint) = codepoint { match unicode_plane(codepoint) { @@ -83,31 +91,29 @@ pub fn fallback_font_families(codepoint: Option) -> Vec<&'static str> { UnicodeBlock::Hebrew => { families.push("Estrangelo Edessa"); families.push("Cambria"); - } + }, - UnicodeBlock::Arabic | - UnicodeBlock::ArabicSupplement => { + UnicodeBlock::Arabic | UnicodeBlock::ArabicSupplement => { families.push("Microsoft Uighur"); - } + }, UnicodeBlock::Syriac => { families.push("Estrangelo Edessa"); - } + }, UnicodeBlock::Thaana => { families.push("MV Boli"); - } + }, UnicodeBlock::NKo => { families.push("Ebrima"); - } + }, - UnicodeBlock::Devanagari | - UnicodeBlock::Bengali => { + UnicodeBlock::Devanagari | UnicodeBlock::Bengali => { families.push("Nirmala UI"); families.push("Utsaah"); families.push("Aparajita"); - } + }, UnicodeBlock::Gurmukhi | UnicodeBlock::Gujarati | @@ -123,21 +129,21 @@ pub fn fallback_font_families(codepoint: Option) -> Vec<&'static str> { UnicodeBlock::SundaneseSupplement | UnicodeBlock::VedicExtensions => { families.push("Nirmala UI"); - } + }, UnicodeBlock::Thai => { families.push("Leelawadee UI"); - } + }, UnicodeBlock::Lao => { families.push("Lao UI"); - } + }, UnicodeBlock::Myanmar | UnicodeBlock::MyanmarExtendedA | UnicodeBlock::MyanmarExtendedB => { families.push("Myanmar Text"); - } + }, UnicodeBlock::HangulJamo | UnicodeBlock::HangulJamoExtendedA | @@ -145,48 +151,47 @@ pub fn fallback_font_families(codepoint: Option) -> Vec<&'static str> { UnicodeBlock::HangulJamoExtendedB | UnicodeBlock::HangulCompatibilityJamo => { families.push("Malgun Gothic"); - } + }, UnicodeBlock::Ethiopic | UnicodeBlock::EthiopicSupplement | UnicodeBlock::EthiopicExtended | UnicodeBlock::EthiopicExtendedA => { families.push("Nyala"); - } + }, UnicodeBlock::Cherokee => { families.push("Plantagenet Cherokee"); - } + }, UnicodeBlock::UnifiedCanadianAboriginalSyllabics | UnicodeBlock::UnifiedCanadianAboriginalSyllabicsExtended => { families.push("Euphemia"); families.push("Segoe UI"); - } + }, - UnicodeBlock::Khmer | - UnicodeBlock::KhmerSymbols => { + UnicodeBlock::Khmer | UnicodeBlock::KhmerSymbols => { families.push("Khmer UI"); families.push("Leelawadee UI"); - } + }, UnicodeBlock::Mongolian => { families.push("Mongolian Baiti"); - } + }, UnicodeBlock::TaiLe => { families.push("Microsoft Tai Le"); - } + }, UnicodeBlock::NewTaiLue => { families.push("Microsoft New Tai Lue"); - } + }, UnicodeBlock::Buginese | UnicodeBlock::TaiTham | UnicodeBlock::CombiningDiacriticalMarksExtended => { families.push("Leelawadee UI"); - } + }, UnicodeBlock::GeneralPunctuation | UnicodeBlock::SuperscriptsandSubscripts | @@ -220,7 +225,7 @@ pub fn fallback_font_families(codepoint: Option) -> Vec<&'static str> { families.push("Meiryo"); families.push("Lucida Sans Unicode"); families.push("Ebrima"); - } + }, UnicodeBlock::GeorgianSupplement | UnicodeBlock::Tifinagh | @@ -232,11 +237,11 @@ pub fn fallback_font_families(codepoint: Option) -> Vec<&'static str> { families.push("Segoe UI"); families.push("Segoe UI Symbol"); families.push("Meiryo"); - } + }, UnicodeBlock::BraillePatterns => { families.push("Segoe UI Symbol"); - } + }, UnicodeBlock::CJKSymbolsandPunctuation | UnicodeBlock::Hiragana | @@ -249,21 +254,20 @@ pub fn fallback_font_families(codepoint: Option) -> Vec<&'static str> { UnicodeBlock::CJKUnifiedIdeographs => { families.push("Microsoft YaHei"); families.push("Yu Gothic"); - } + }, UnicodeBlock::EnclosedCJKLettersandMonths => { families.push("Malgun Gothic"); - } + }, UnicodeBlock::YijingHexagramSymbols => { families.push("Segoe UI Symbol"); - } + }, - UnicodeBlock::YiSyllables | - UnicodeBlock::YiRadicals => { + UnicodeBlock::YiSyllables | UnicodeBlock::YiRadicals => { families.push("Microsoft Yi Baiti"); families.push("Segoe UI"); - } + }, UnicodeBlock::Vai | UnicodeBlock::CyrillicExtendedB | @@ -273,36 +277,34 @@ pub fn fallback_font_families(codepoint: Option) -> Vec<&'static str> { families.push("Ebrima"); families.push("Segoe UI"); families.push("Cambria Math"); - } + }, UnicodeBlock::SylotiNagri | UnicodeBlock::CommonIndicNumberForms | UnicodeBlock::Phagspa | UnicodeBlock::Saurashtra | UnicodeBlock::DevanagariExtended => { - families.push("Microsoft PhagsPa"); - families.push("Nirmala UI"); - } + families.push("Microsoft PhagsPa"); + families.push("Nirmala UI"); + }, - UnicodeBlock::KayahLi | - UnicodeBlock::Rejang | - UnicodeBlock::Javanese => { - families.push("Malgun Gothic"); - families.push("Javanese Text"); - families.push("Leelawadee UI"); - } + UnicodeBlock::KayahLi | UnicodeBlock::Rejang | UnicodeBlock::Javanese => { + families.push("Malgun Gothic"); + families.push("Javanese Text"); + families.push("Leelawadee UI"); + }, UnicodeBlock::AlphabeticPresentationForms => { families.push("Microsoft Uighur"); families.push("Gabriola"); families.push("Sylfaen"); - } + }, UnicodeBlock::ArabicPresentationFormsA | UnicodeBlock::ArabicPresentationFormsB => { families.push("Traditional Arabic"); families.push("Arabic Typesetting"); - } + }, UnicodeBlock::VariationSelectors | UnicodeBlock::VerticalForms | @@ -312,12 +314,12 @@ pub fn fallback_font_families(codepoint: Option) -> Vec<&'static str> { UnicodeBlock::HalfwidthandFullwidthForms | UnicodeBlock::Specials => { families.push("Microsoft JhengHei"); - } + }, - _ => {} + _ => {}, } } - } + }, // https://en.wikipedia.org/wiki/Plane_(Unicode)#Supplementary_Multilingual_Plane 1 => { @@ -325,9 +327,9 @@ pub fn fallback_font_families(codepoint: Option) -> Vec<&'static str> { families.push("Ebrima"); families.push("Nirmala UI"); families.push("Cambria Math"); - } + }, - _ => {} + _ => {}, } } diff --git a/components/gfx/platform/windows/font_template.rs b/components/gfx/platform/windows/font_template.rs index 5aff546701f..53eae0347fd 100644 --- a/components/gfx/platform/windows/font_template.rs +++ b/components/gfx/platform/windows/font_template.rs @@ -11,7 +11,6 @@ use webrender_api::NativeFontHandle; #[derive(Deserialize, Serialize)] pub struct FontTemplateData { // If you add members here, review the Debug impl below - pub bytes: Option>, pub identifier: Atom, } @@ -19,20 +18,22 @@ pub struct FontTemplateData { impl fmt::Debug for FontTemplateData { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("FontTemplateData") - .field( - "bytes", - &self.bytes + .field( + "bytes", + &self + .bytes .as_ref() - .map(|bytes| format!("[{} bytes]", bytes.len())) - ) - .field("identifier", &self.identifier) - .finish() + .map(|bytes| format!("[{} bytes]", bytes.len())), + ).field("identifier", &self.identifier) + .finish() } } impl FontTemplateData { - pub fn new(identifier: Atom, - font_data: Option>) -> Result { + pub fn new( + identifier: Atom, + font_data: Option>, + ) -> Result { Ok(FontTemplateData { bytes: font_data, identifier: identifier, diff --git a/components/gfx/tests/font_context.rs b/components/gfx/tests/font_context.rs index dc9d1ac2df5..8608f38329e 100644 --- a/components/gfx/tests/font_context.rs +++ b/components/gfx/tests/font_context.rs @@ -58,26 +58,24 @@ impl TestFontSource { } fn add_face(family: &mut FontTemplates, name: &str, identifier: Option<&str>) { - let mut path: PathBuf = [ - env!("CARGO_MANIFEST_DIR"), - "tests", - "support", - "CSSTest", - ].iter().collect(); + let mut path: PathBuf = [env!("CARGO_MANIFEST_DIR"), "tests", "support", "CSSTest"] + .iter() + .collect(); path.push(format!("{}.ttf", name)); let file = File::open(path).unwrap(); let identifier = Atom::from(identifier.unwrap_or(name)); - family.add_template( - identifier, - Some(file.bytes().map(|b| b.unwrap()).collect()) - ) + family.add_template(identifier, Some(file.bytes().map(|b| b.unwrap()).collect())) } } impl FontSource for TestFontSource { - fn get_font_instance(&mut self, _key: webrender_api::FontKey, _size: Au) -> webrender_api::FontInstanceKey { + fn get_font_instance( + &mut self, + _key: webrender_api::FontKey, + _size: Au, + ) -> webrender_api::FontInstanceKey { webrender_api::FontInstanceKey(webrender_api::IdNamespace(0), 0) } @@ -92,11 +90,9 @@ impl FontSource for TestFontSource { self.families .get_mut(family_descriptor.name()) .and_then(|family| family.find_font_for_style(&template_descriptor, handle)) - .map(|template| { - FontTemplateInfo { - font_template: template, - font_key: webrender_api::FontKey(webrender_api::IdNamespace(0), 0), - } + .map(|template| FontTemplateInfo { + font_template: template, + font_key: webrender_api::FontKey(webrender_api::IdNamespace(0), 0), }) } } @@ -116,12 +112,14 @@ fn style() -> FontStyleStruct { } fn font_family(names: Vec<&str>) -> FontFamily { - let names: Vec = names.into_iter().map(|name| - SingleFontFamily::FamilyName(FamilyName { - name: Atom::from(name), - syntax: FamilyNameSyntax::Quoted, - }) - ).collect(); + let names: Vec = names + .into_iter() + .map(|name| { + SingleFontFamily::FamilyName(FamilyName { + name: Atom::from(name), + syntax: FamilyNameSyntax::Quoted, + }) + }).collect(); FontFamily(FontFamilyList::new(names.into_boxed_slice())) } @@ -156,19 +154,36 @@ fn test_font_group_find_by_codepoint() { let mut context = FontContext::new(source); let mut style = style(); - style.set_font_family(font_family(vec!("CSSTest ASCII", "CSSTest Basic"))); + style.set_font_family(font_family(vec!["CSSTest ASCII", "CSSTest Basic"])); let group = context.font_group(Arc::new(style)); - let font = group.borrow_mut().find_by_codepoint(&mut context, 'a').unwrap(); + let font = group + .borrow_mut() + .find_by_codepoint(&mut context, 'a') + .unwrap(); assert_eq!(&*font.borrow().identifier(), "csstest-ascii"); - assert_eq!(count.get(), 1, "only the first font in the list should have been loaded"); + assert_eq!( + count.get(), + 1, + "only the first font in the list should have been loaded" + ); - let font = group.borrow_mut().find_by_codepoint(&mut context, 'a').unwrap(); + let font = group + .borrow_mut() + .find_by_codepoint(&mut context, 'a') + .unwrap(); assert_eq!(&*font.borrow().identifier(), "csstest-ascii"); - assert_eq!(count.get(), 1, "we shouldn't load the same font a second time"); + assert_eq!( + count.get(), + 1, + "we shouldn't load the same font a second time" + ); - let font = group.borrow_mut().find_by_codepoint(&mut context, 'á').unwrap(); + let font = group + .borrow_mut() + .find_by_codepoint(&mut context, 'á') + .unwrap(); assert_eq!(&*font.borrow().identifier(), "csstest-basic-regular"); assert_eq!(count.get(), 2, "both fonts should now have been loaded"); } @@ -179,19 +194,27 @@ fn test_font_fallback() { let mut context = FontContext::new(source); let mut style = style(); - style.set_font_family(font_family(vec!("CSSTest ASCII"))); + style.set_font_family(font_family(vec!["CSSTest ASCII"])); let group = context.font_group(Arc::new(style)); - let font = group.borrow_mut().find_by_codepoint(&mut context, 'a').unwrap(); + let font = group + .borrow_mut() + .find_by_codepoint(&mut context, 'a') + .unwrap(); assert_eq!( - &*font.borrow().identifier(), "csstest-ascii", + &*font.borrow().identifier(), + "csstest-ascii", "a family in the group should be used if there is a matching glyph" ); - let font = group.borrow_mut().find_by_codepoint(&mut context, 'á').unwrap(); + let font = group + .borrow_mut() + .find_by_codepoint(&mut context, 'á') + .unwrap(); assert_eq!( - &*font.borrow().identifier(), "fallback", + &*font.borrow().identifier(), + "fallback", "a fallback font should be used if there is no matching glyph in the group" ); } @@ -212,10 +235,8 @@ fn test_font_template_is_cached() { pt_size: Au(10), }; - let family_descriptor = FontFamilyDescriptor::new( - FontFamilyName::from("CSSTest Basic"), - FontSearchScope::Any, - ); + let family_descriptor = + FontFamilyDescriptor::new(FontFamilyName::from("CSSTest Basic"), FontSearchScope::Any); let font1 = context.font(&font_descriptor, &family_descriptor).unwrap(); @@ -228,5 +249,9 @@ fn test_font_template_is_cached() { "the same font should not have been returned" ); - assert_eq!(count.get(), 1, "we should only have fetched the template data from the cache thread once"); + assert_eq!( + count.get(), + 1, + "we should only have fetched the template data from the cache thread once" + ); } diff --git a/components/gfx/tests/font_template.rs b/components/gfx/tests/font_template.rs index e5857ce4ef7..a6caea2f375 100644 --- a/components/gfx/tests/font_template.rs +++ b/components/gfx/tests/font_template.rs @@ -2,9 +2,12 @@ * 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/. */ -#[cfg(not(target_os = "macos"))] extern crate gfx; -#[cfg(not(target_os = "macos"))] extern crate servo_atoms; -#[cfg(not(target_os = "macos"))] extern crate style; +#[cfg(not(target_os = "macos"))] +extern crate gfx; +#[cfg(not(target_os = "macos"))] +extern crate servo_atoms; +#[cfg(not(target_os = "macos"))] +extern crate style; // Test doesn't yet run on Mac, see https://github.com/servo/servo/pull/19928 for explanation. #[cfg(not(target_os = "macos"))] @@ -28,14 +31,16 @@ fn test_font_template_descriptor() { "support", "dejavu-fonts-ttf-2.37", "ttf", - ].iter().collect(); + ] + .iter() + .collect(); path.push(format!("{}.ttf", filename)); let file = File::open(path).unwrap(); let mut template = FontTemplate::new( Atom::from(filename), - Some(file.bytes().map(|b| b.unwrap()).collect()) + Some(file.bytes().map(|b| b.unwrap()).collect()), ).unwrap(); let context = FontContextHandle::new(); @@ -43,27 +48,39 @@ fn test_font_template_descriptor() { template.descriptor(&context).unwrap() } - assert_eq!(descriptor("DejaVuSans"), FontTemplateDescriptor { - weight: FontWeight::normal(), - stretch: FontStretch::hundred(), - style: FontStyle::Normal, - }); + assert_eq!( + descriptor("DejaVuSans"), + FontTemplateDescriptor { + weight: FontWeight::normal(), + stretch: FontStretch::hundred(), + style: FontStyle::Normal, + } + ); - assert_eq!(descriptor("DejaVuSans-Bold"), FontTemplateDescriptor { - weight: FontWeight::bold(), - stretch: FontStretch::hundred(), - style: FontStyle::Normal, - }); + assert_eq!( + descriptor("DejaVuSans-Bold"), + FontTemplateDescriptor { + weight: FontWeight::bold(), + stretch: FontStretch::hundred(), + style: FontStyle::Normal, + } + ); - assert_eq!(descriptor("DejaVuSans-Oblique"), FontTemplateDescriptor { - weight: FontWeight::normal(), - stretch: FontStretch::hundred(), - style: FontStyle::Italic, - }); + assert_eq!( + descriptor("DejaVuSans-Oblique"), + FontTemplateDescriptor { + weight: FontWeight::normal(), + stretch: FontStretch::hundred(), + style: FontStyle::Italic, + } + ); - assert_eq!(descriptor("DejaVuSansCondensed-BoldOblique"), FontTemplateDescriptor { - weight: FontWeight::bold(), - stretch: FontStretch(NonNegative(Percentage(0.875))), - style: FontStyle::Italic, - }); + assert_eq!( + descriptor("DejaVuSansCondensed-BoldOblique"), + FontTemplateDescriptor { + weight: FontWeight::bold(), + stretch: FontStretch(NonNegative(Percentage(0.875))), + style: FontStyle::Italic, + } + ); } diff --git a/components/gfx/tests/text_util.rs b/components/gfx/tests/text_util.rs index 7729a6f78a7..0b8132e9c88 100644 --- a/components/gfx/tests/text_util.rs +++ b/components/gfx/tests/text_util.rs @@ -29,26 +29,13 @@ fn test_transform_compress_none() { #[test] fn test_transform_discard_newline() { let test_strs = [ - (" foo bar", - " foo bar"), - - ("foo bar ", - "foo bar "), - - ("foo\n bar", - "foo bar"), - - ("foo \nbar", - "foo bar"), - - (" foo bar \nbaz", - " foo bar baz"), - - ("foo bar baz", - "foo bar baz"), - - ("foobarbaz\n\n", - "foobarbaz"), + (" foo bar", " foo bar"), + ("foo bar ", "foo bar "), + ("foo\n bar", "foo bar"), + ("foo \nbar", "foo bar"), + (" foo bar \nbaz", " foo bar baz"), + ("foo bar baz", "foo bar baz"), + ("foobarbaz\n\n", "foobarbaz"), ]; let mode = CompressionMode::DiscardNewline; @@ -62,26 +49,13 @@ fn test_transform_discard_newline() { #[test] fn test_transform_compress_whitespace() { let test_strs = [ - (" foo bar", - "foo bar"), - - ("foo bar ", - "foo bar "), - - ("foo\n bar", - "foo\n bar"), - - ("foo \nbar", - "foo \nbar"), - - (" foo bar \nbaz", - "foo bar \nbaz"), - - ("foo bar baz", - "foo bar baz"), - - ("foobarbaz\n\n", - "foobarbaz\n\n"), + (" foo bar", "foo bar"), + ("foo bar ", "foo bar "), + ("foo\n bar", "foo\n bar"), + ("foo \nbar", "foo \nbar"), + (" foo bar \nbaz", "foo bar \nbaz"), + ("foo bar baz", "foo bar baz"), + ("foobarbaz\n\n", "foobarbaz\n\n"), ]; let mode = CompressionMode::CompressWhitespace; @@ -95,26 +69,13 @@ fn test_transform_compress_whitespace() { #[test] fn test_transform_compress_whitespace_newline() { let test_strs = vec![ - (" foo bar", - "foo bar"), - - ("foo bar ", - "foo bar "), - - ("foo\n bar", - "foo bar"), - - ("foo \nbar", - "foo bar"), - - (" foo bar \nbaz", - "foo bar baz"), - - ("foo bar baz", - "foo bar baz"), - - ("foobarbaz\n\n", - "foobarbaz "), + (" foo bar", "foo bar"), + ("foo bar ", "foo bar "), + ("foo\n bar", "foo bar"), + ("foo \nbar", "foo bar"), + (" foo bar \nbaz", "foo bar baz"), + ("foo bar baz", "foo bar baz"), + ("foobarbaz\n\n", "foobarbaz "), ]; let mode = CompressionMode::CompressWhitespaceNewline; @@ -128,29 +89,14 @@ fn test_transform_compress_whitespace_newline() { #[test] fn test_transform_compress_whitespace_newline_no_incoming() { let test_strs = [ - (" foo bar", - " foo bar"), - - ("\nfoo bar", - " foo bar"), - - ("foo bar ", - "foo bar "), - - ("foo\n bar", - "foo bar"), - - ("foo \nbar", - "foo bar"), - - (" foo bar \nbaz", - " foo bar baz"), - - ("foo bar baz", - "foo bar baz"), - - ("foobarbaz\n\n", - "foobarbaz "), + (" foo bar", " foo bar"), + ("\nfoo bar", " foo bar"), + ("foo bar ", "foo bar "), + ("foo\n bar", "foo bar"), + ("foo \nbar", "foo bar"), + (" foo bar \nbaz", " foo bar baz"), + ("foo bar baz", "foo bar baz"), + ("foobarbaz\n\n", "foobarbaz "), ]; let mode = CompressionMode::CompressWhitespaceNewline; diff --git a/components/gfx/text/glyph.rs b/components/gfx/text/glyph.rs index 78f02881058..8e4c56e309b 100644 --- a/components/gfx/text/glyph.rs +++ b/components/gfx/text/glyph.rs @@ -4,7 +4,10 @@ use app_units::Au; use euclid::Point2D; -#[cfg(all(feature = "unstable", any(target_feature = "sse2", target_feature = "neon")))] +#[cfg(all( + feature = "unstable", + any(target_feature = "sse2", target_feature = "neon") +))] use packed_simd::u32x4; use range::{self, EachIndex, Range, RangeIndex}; use std::{fmt, mem, u16}; @@ -28,9 +31,7 @@ pub struct GlyphEntry { impl GlyphEntry { fn new(value: u32) -> GlyphEntry { - GlyphEntry { - value: value, - } + GlyphEntry { value: value } } fn initial() -> GlyphEntry { @@ -54,11 +55,11 @@ impl GlyphEntry { fn complex(starts_cluster: bool, starts_ligature: bool, glyph_count: usize) -> GlyphEntry { assert!(glyph_count <= u16::MAX as usize); - debug!("creating complex glyph entry: starts_cluster={}, starts_ligature={}, \ - glyph_count={}", - starts_cluster, - starts_ligature, - glyph_count); + debug!( + "creating complex glyph entry: starts_cluster={}, starts_ligature={}, \ + glyph_count={}", + starts_cluster, starts_ligature, glyph_count + ); GlyphEntry::new(glyph_count as u32) } @@ -73,16 +74,16 @@ pub type GlyphId = u32; // TODO: make this more type-safe. -const FLAG_CHAR_IS_SPACE: u32 = 0x40000000; +const FLAG_CHAR_IS_SPACE: u32 = 0x40000000; #[cfg(feature = "unstable")] #[cfg(any(target_feature = "sse2", target_feature = "neon"))] const FLAG_CHAR_IS_SPACE_SHIFT: u32 = 30; -const FLAG_IS_SIMPLE_GLYPH: u32 = 0x80000000; +const FLAG_IS_SIMPLE_GLYPH: u32 = 0x80000000; // glyph advance; in Au's. -const GLYPH_ADVANCE_MASK: u32 = 0x3FFF0000; -const GLYPH_ADVANCE_SHIFT: u32 = 16; -const GLYPH_ID_MASK: u32 = 0x0000FFFF; +const GLYPH_ADVANCE_MASK: u32 = 0x3FFF0000; +const GLYPH_ADVANCE_SHIFT: u32 = 16; +const GLYPH_ID_MASK: u32 = 0x0000FFFF; // Non-simple glyphs (more than one glyph per char; missing glyph, // newline, tab, large advance, or nonzero x/y offsets) may have one @@ -91,7 +92,7 @@ const GLYPH_ID_MASK: u32 = 0x0000FFFF; // unicode char. // The number of detailed glyphs for this char. -const GLYPH_COUNT_MASK: u32 = 0x0000FFFF; +const GLYPH_COUNT_MASK: u32 = 0x0000FFFF; fn is_simple_glyph_id(id: GlyphId) -> bool { ((id as u32) & GLYPH_ID_MASK) == id @@ -205,8 +206,8 @@ struct DetailedGlyphStore { impl<'a> DetailedGlyphStore { fn new() -> DetailedGlyphStore { DetailedGlyphStore { - detail_buffer: vec!(), // TODO: default size? - detail_lookup: vec!(), + detail_buffer: vec![], // TODO: default size? + detail_lookup: vec![], lookup_is_sorted: false, } } @@ -217,7 +218,10 @@ impl<'a> DetailedGlyphStore { detail_offset: self.detail_buffer.len(), }; - debug!("Adding entry[off={:?}] for detailed glyphs: {:?}", entry_offset, glyphs); + debug!( + "Adding entry[off={:?}] for detailed glyphs: {:?}", + entry_offset, glyphs + ); /* TODO: don't actually assert this until asserts are compiled in/out based on severity, debug/release, etc. This assertion @@ -235,9 +239,15 @@ impl<'a> DetailedGlyphStore { self.lookup_is_sorted = false; } - fn detailed_glyphs_for_entry(&'a self, entry_offset: ByteIndex, count: u16) - -> &'a [DetailedGlyph] { - debug!("Requesting detailed glyphs[n={}] for entry[off={:?}]", count, entry_offset); + fn detailed_glyphs_for_entry( + &'a self, + entry_offset: ByteIndex, + count: u16, + ) -> &'a [DetailedGlyph] { + debug!( + "Requesting detailed glyphs[n={}] for entry[off={:?}]", + count, entry_offset + ); // FIXME: Is this right? --pcwalton // TODO: should fix this somewhere else @@ -253,18 +263,21 @@ impl<'a> DetailedGlyphStore { detail_offset: 0, // unused }; - let i = self.detail_lookup.binary_search(&key) + let i = self + .detail_lookup + .binary_search(&key) .expect("Invalid index not found in detailed glyph lookup table!"); let main_detail_offset = self.detail_lookup[i].detail_offset; assert!(main_detail_offset + (count as usize) <= self.detail_buffer.len()); // return a slice into the buffer - &self.detail_buffer[main_detail_offset .. main_detail_offset + count as usize] + &self.detail_buffer[main_detail_offset..main_detail_offset + count as usize] } - fn detailed_glyph_with_index(&'a self, - entry_offset: ByteIndex, - detail_offset: u16) - -> &'a DetailedGlyph { + fn detailed_glyph_with_index( + &'a self, + entry_offset: ByteIndex, + detail_offset: u16, + ) -> &'a DetailedGlyph { assert!((detail_offset as usize) <= self.detail_buffer.len()); assert!(self.lookup_is_sorted); @@ -273,7 +286,9 @@ impl<'a> DetailedGlyphStore { detail_offset: 0, // unused }; - let i = self.detail_lookup.binary_search(&key) + let i = self + .detail_lookup + .binary_search(&key) .expect("Invalid index not found in detailed glyph lookup table!"); let main_detail_offset = self.detail_lookup[i].detail_offset; assert!(main_detail_offset + (detail_offset as usize) < self.detail_buffer.len()); @@ -290,7 +305,7 @@ impl<'a> DetailedGlyphStore { // immutable locations thus don't play well with freezing. // Thar be dragons here. You have been warned. (Tips accepted.) - let mut unsorted_records: Vec = vec!(); + let mut unsorted_records: Vec = vec![]; mem::swap(&mut self.detail_lookup, &mut unsorted_records); let mut mut_records: Vec = unsorted_records; mut_records.sort_by(|a, b| { @@ -320,12 +335,13 @@ pub struct GlyphData { impl GlyphData { /// Creates a new entry for one glyph. - pub fn new(id: GlyphId, - advance: Au, - offset: Option>, - cluster_start: bool, - ligature_start: bool) - -> GlyphData { + pub fn new( + id: GlyphId, + advance: Au, + offset: Option>, + cluster_start: bool, + ligature_start: bool, + ) -> GlyphData { GlyphData { id: id, advance: advance, @@ -351,8 +367,11 @@ impl<'a> GlyphInfo<'a> { match self { GlyphInfo::Simple(store, entry_i) => store.entry_buffer[entry_i.to_usize()].id(), GlyphInfo::Detail(store, entry_i, detail_j) => { - store.detail_store.detailed_glyph_with_index(entry_i, detail_j).id - } + store + .detail_store + .detailed_glyph_with_index(entry_i, detail_j) + .id + }, } } @@ -362,8 +381,11 @@ impl<'a> GlyphInfo<'a> { match self { GlyphInfo::Simple(store, entry_i) => store.entry_buffer[entry_i.to_usize()].advance(), GlyphInfo::Detail(store, entry_i, detail_j) => { - store.detail_store.detailed_glyph_with_index(entry_i, detail_j).advance - } + store + .detail_store + .detailed_glyph_with_index(entry_i, detail_j) + .advance + }, } } @@ -371,9 +393,12 @@ impl<'a> GlyphInfo<'a> { pub fn offset(self) -> Option> { match self { GlyphInfo::Simple(_, _) => None, - GlyphInfo::Detail(store, entry_i, detail_j) => { - Some(store.detail_store.detailed_glyph_with_index(entry_i, detail_j).offset) - } + GlyphInfo::Detail(store, entry_i, detail_j) => Some( + store + .detail_store + .detailed_glyph_with_index(entry_i, detail_j) + .offset, + ), } } @@ -477,14 +502,11 @@ impl<'a> GlyphStore { } /// Adds a single glyph. - pub fn add_glyph_for_byte_index(&mut self, - i: ByteIndex, - character: char, - data: &GlyphData) { + pub fn add_glyph_for_byte_index(&mut self, i: ByteIndex, character: char, data: &GlyphData) { let glyph_is_compressible = is_simple_glyph_id(data.id) && is_simple_advance(data.advance) && - data.offset == Point2D::zero() && - data.cluster_start; // others are stored in detail buffer + data.offset == Point2D::zero() && + data.cluster_start; // others are stored in detail buffer debug_assert!(data.ligature_start); // can't compress ligature continuation glyphs. debug_assert!(i < self.len()); @@ -512,20 +534,29 @@ impl<'a> GlyphStore { let glyph_count = data_for_glyphs.len(); let first_glyph_data = data_for_glyphs[0]; - let glyphs_vec: Vec = (0..glyph_count).map(|i| { - DetailedGlyph::new(data_for_glyphs[i].id, - data_for_glyphs[i].advance, - data_for_glyphs[i].offset) - }).collect(); + let glyphs_vec: Vec = (0..glyph_count) + .map(|i| { + DetailedGlyph::new( + data_for_glyphs[i].id, + data_for_glyphs[i].advance, + data_for_glyphs[i].offset, + ) + }).collect(); self.has_detailed_glyphs = true; - self.detail_store.add_detailed_glyphs_for_entry(i, &glyphs_vec); + self.detail_store + .add_detailed_glyphs_for_entry(i, &glyphs_vec); - let entry = GlyphEntry::complex(first_glyph_data.cluster_start, - first_glyph_data.ligature_start, - glyph_count); + let entry = GlyphEntry::complex( + first_glyph_data.cluster_start, + first_glyph_data.ligature_start, + glyph_count, + ); - debug!("Adding multiple glyphs[idx={:?}, count={}]: {:?}", i, glyph_count, entry); + debug!( + "Adding multiple glyphs[idx={:?}, count={}]: {:?}", + i, glyph_count, entry + ); self.entry_buffer[i.to_usize()] = entry; } @@ -540,9 +571,13 @@ impl<'a> GlyphStore { } GlyphIterator { - store: self, - byte_index: if self.is_rtl { range.end() } else { range.begin() - ByteIndex(1) }, - byte_range: *range, + store: self, + byte_index: if self.is_rtl { + range.end() + } else { + range.begin() - ByteIndex(1) + }, + byte_range: *range, glyph_range: None, } } @@ -551,7 +586,12 @@ impl<'a> GlyphStore { // and advance of the glyph in the range at the given advance, if reached. Otherwise, returns the // the number of glyphs and the advance for the given range. #[inline] - pub fn range_index_of_advance(&self, range: &Range, advance: Au, extra_word_spacing: Au) -> (usize, Au) { + pub fn range_index_of_advance( + &self, + range: &Range, + advance: Au, + extra_word_spacing: Au, + ) -> (usize, Au) { let mut index = 0; let mut current_advance = Au(0); for glyph in self.iter_glyphs_for_byte_range(range) { @@ -580,7 +620,11 @@ impl<'a> GlyphStore { } #[inline] - pub fn advance_for_byte_range_slow_path(&self, range: &Range, extra_word_spacing: Au) -> Au { + pub fn advance_for_byte_range_slow_path( + &self, + range: &Range, + extra_word_spacing: Au, + ) -> Au { self.iter_glyphs_for_byte_range(range) .fold(Au(0), |advance, glyph| { if glyph.char_is_space() { @@ -594,7 +638,11 @@ impl<'a> GlyphStore { #[inline] #[cfg(feature = "unstable")] #[cfg(any(target_feature = "sse2", target_feature = "neon"))] - fn advance_for_byte_range_simple_glyphs(&self, range: &Range, extra_word_spacing: Au) -> Au { + fn advance_for_byte_range_simple_glyphs( + &self, + range: &Range, + extra_word_spacing: Au, + ) -> Au { let advance_mask = u32x4::splat(GLYPH_ADVANCE_MASK); let space_flag_mask = u32x4::splat(FLAG_CHAR_IS_SPACE); let mut simd_advance = u32x4::splat(0); @@ -614,16 +662,14 @@ impl<'a> GlyphStore { simd_spaces = simd_spaces + spaces; } - let advance = - (simd_advance.extract(0) + - simd_advance.extract(1) + - simd_advance.extract(2) + - simd_advance.extract(3)) as i32; - let spaces = - (simd_spaces.extract(0) + - simd_spaces.extract(1) + - simd_spaces.extract(2) + - simd_spaces.extract(3)) as i32; + let advance = (simd_advance.extract(0) + + simd_advance.extract(1) + + simd_advance.extract(2) + + simd_advance.extract(3)) as i32; + let spaces = (simd_spaces.extract(0) + + simd_spaces.extract(1) + + simd_spaces.extract(2) + + simd_spaces.extract(3)) as i32; let mut leftover_advance = Au(0); let mut leftover_spaces = 0; for i in leftover_entries..range.end().to_usize() { @@ -637,8 +683,15 @@ impl<'a> GlyphStore { /// When SIMD isn't available, fallback to the slow path. #[inline] - #[cfg(not(all(feature = "unstable", any(target_feature = "sse2", target_feature = "neon"))))] - fn advance_for_byte_range_simple_glyphs(&self, range: &Range, extra_word_spacing: Au) -> Au { + #[cfg(not(all( + feature = "unstable", + any(target_feature = "sse2", target_feature = "neon") + )))] + fn advance_for_byte_range_simple_glyphs( + &self, + range: &Range, + extra_word_spacing: Au, + ) -> Au { self.advance_for_byte_range_slow_path(range, extra_word_spacing) } @@ -676,23 +729,27 @@ impl fmt::Debug for GlyphStore { let mut detailed_buffer = self.detail_store.detail_buffer.iter(); for entry in self.entry_buffer.iter() { if entry.is_simple() { - write!(formatter, - " simple id={:?} advance={:?}\n", - entry.id(), - entry.advance())?; - continue + write!( + formatter, + " simple id={:?} advance={:?}\n", + entry.id(), + entry.advance() + )?; + continue; } if entry.is_initial() { - continue + continue; } write!(formatter, " complex...")?; if detailed_buffer.next().is_none() { - continue + continue; } - write!(formatter, - " detailed id={:?} advance={:?}\n", - entry.id(), - entry.advance())?; + write!( + formatter, + " detailed id={:?} advance={:?}\n", + entry.id(), + entry.advance() + )?; } Ok(()) } @@ -712,27 +769,37 @@ impl<'a> GlyphIterator<'a> { fn next_glyph_range(&mut self) -> Option> { match self.glyph_range.as_mut().unwrap().next() { Some(j) => { - Some(GlyphInfo::Detail(self.store, self.byte_index, j.get() as u16 /* ??? */)) - } + Some(GlyphInfo::Detail( + self.store, + self.byte_index, + j.get() as u16, /* ??? */ + )) + }, None => { // No more glyphs for current character. Try to get another. self.glyph_range = None; self.next() - } + }, } } // Slow path when there is a complex glyph. #[inline(never)] fn next_complex_glyph(&mut self, entry: &GlyphEntry, i: ByteIndex) -> Option> { - let glyphs = self.store.detail_store.detailed_glyphs_for_entry(i, entry.glyph_count()); - self.glyph_range = Some(range::each_index(ByteIndex(0), ByteIndex(glyphs.len() as isize))); + let glyphs = self + .store + .detail_store + .detailed_glyphs_for_entry(i, entry.glyph_count()); + self.glyph_range = Some(range::each_index( + ByteIndex(0), + ByteIndex(glyphs.len() as isize), + )); self.next() } } impl<'a> Iterator for GlyphIterator<'a> { - type Item = GlyphInfo<'a>; + type Item = GlyphInfo<'a>; // I tried to start with something simpler and apply FlatMap, but the // inability to store free variables in the FlatMap struct was problematic. @@ -744,7 +811,7 @@ impl<'a> Iterator for GlyphIterator<'a> { fn next(&mut self) -> Option> { // Would use 'match' here but it borrows contents in a way that interferes with mutation. if self.glyph_range.is_some() { - return self.next_glyph_range() + return self.next_glyph_range(); } // No glyph range. Look at next byte. @@ -755,7 +822,7 @@ impl<'a> Iterator for GlyphIterator<'a> { }; let i = self.byte_index; if !self.byte_range.contains(i) { - return None + return None; } debug_assert!(i < self.store.len()); let entry = self.store.entry_buffer[i.to_usize()]; diff --git a/components/gfx/text/mod.rs b/components/gfx/text/mod.rs index 5aae0876428..24c434e2e69 100644 --- a/components/gfx/text/mod.rs +++ b/components/gfx/text/mod.rs @@ -9,4 +9,3 @@ pub mod glyph; pub mod shaping; pub mod text_run; pub mod util; - diff --git a/components/gfx/text/shaping/harfbuzz.rs b/components/gfx/text/shaping/harfbuzz.rs index a07003b6ec3..eb6b7b8cd4a 100644 --- a/components/gfx/text/shaping/harfbuzz.rs +++ b/components/gfx/text/shaping/harfbuzz.rs @@ -147,10 +147,11 @@ impl Drop for Shaper { impl Shaper { pub fn new(font: *const Font) -> Shaper { unsafe { - let hb_face: *mut hb_face_t = - hb_face_create_for_tables(Some(font_table_func), - font as *const c_void as *mut c_void, - None); + let hb_face: *mut hb_face_t = hb_face_create_for_tables( + Some(font_table_func), + font as *const c_void as *mut c_void, + None, + ); let hb_font: *mut hb_font_t = hb_font_create(hb_face); // Set points-per-em. if zero, performs no hinting in that direction. @@ -158,12 +159,19 @@ impl Shaper { hb_font_set_ppem(hb_font, pt_size as c_uint, pt_size as c_uint); // Set scaling. Note that this takes 16.16 fixed point. - hb_font_set_scale(hb_font, - Shaper::float_to_fixed(pt_size) as c_int, - Shaper::float_to_fixed(pt_size) as c_int); + hb_font_set_scale( + hb_font, + Shaper::float_to_fixed(pt_size) as c_int, + Shaper::float_to_fixed(pt_size) as c_int, + ); // configure static function callbacks. - hb_font_set_funcs(hb_font, HB_FONT_FUNCS.0, font as *mut Font as *mut c_void, None); + hb_font_set_funcs( + hb_font, + HB_FONT_FUNCS.0, + font as *mut Font as *mut c_void, + None, + ); Shaper { hb_face: hb_face, @@ -188,22 +196,30 @@ impl ShaperMethods for Shaper { fn shape_text(&self, text: &str, options: &ShapingOptions, glyphs: &mut GlyphStore) { unsafe { let hb_buffer: *mut hb_buffer_t = hb_buffer_create(); - hb_buffer_set_direction(hb_buffer, if options.flags.contains(ShapingFlags::RTL_FLAG) { - HB_DIRECTION_RTL - } else { - HB_DIRECTION_LTR - }); + hb_buffer_set_direction( + hb_buffer, + if options.flags.contains(ShapingFlags::RTL_FLAG) { + HB_DIRECTION_RTL + } else { + HB_DIRECTION_LTR + }, + ); hb_buffer_set_script(hb_buffer, options.script.to_hb_script()); - hb_buffer_add_utf8(hb_buffer, - text.as_ptr() as *const c_char, - text.len() as c_int, - 0, - text.len() as c_int); + hb_buffer_add_utf8( + hb_buffer, + text.as_ptr() as *const c_char, + text.len() as c_int, + 0, + text.len() as c_int, + ); let mut features = Vec::new(); - if options.flags.contains(ShapingFlags::IGNORE_LIGATURES_SHAPING_FLAG) { + if options + .flags + .contains(ShapingFlags::IGNORE_LIGATURES_SHAPING_FLAG) + { features.push(hb_feature_t { tag: LIGA, value: 0, @@ -211,7 +227,10 @@ impl ShaperMethods for Shaper { end: hb_buffer_get_length(hb_buffer), }) } - if options.flags.contains(ShapingFlags::DISABLE_KERNING_SHAPING_FLAG) { + if options + .flags + .contains(ShapingFlags::DISABLE_KERNING_SHAPING_FLAG) + { features.push(hb_feature_t { tag: KERN, value: 0, @@ -220,7 +239,12 @@ impl ShaperMethods for Shaper { }) } - hb_shape(self.hb_font, hb_buffer, features.as_mut_ptr(), features.len() as u32); + hb_shape( + self.hb_font, + hb_buffer, + features.as_mut_ptr(), + features.len() as u32, + ); self.save_glyph_results(text, options, glyphs, hb_buffer); hb_buffer_destroy(hb_buffer); } @@ -228,18 +252,21 @@ impl ShaperMethods for Shaper { } impl Shaper { - fn save_glyph_results(&self, - text: &str, - options: &ShapingOptions, - glyphs: &mut GlyphStore, - buffer: *mut hb_buffer_t) { + fn save_glyph_results( + &self, + text: &str, + options: &ShapingOptions, + glyphs: &mut GlyphStore, + buffer: *mut hb_buffer_t, + ) { let glyph_data = ShapedGlyphData::new(buffer); let glyph_count = glyph_data.len(); let byte_max = text.len(); - debug!("Shaped text[byte count={}], got back {} glyph info records.", - byte_max, - glyph_count); + debug!( + "Shaped text[byte count={}], got back {} glyph info records.", + byte_max, glyph_count + ); // make map of what chars have glyphs let mut byte_to_glyph = vec![NO_GLYPH; byte_max]; @@ -250,9 +277,10 @@ impl Shaper { if loc < byte_max { byte_to_glyph[loc] = i as i32; } else { - debug!("ERROR: tried to set out of range byte_to_glyph: idx={}, glyph idx={}", - loc, - i); + debug!( + "ERROR: tried to set out of range byte_to_glyph: idx={}, glyph idx={}", + loc, i + ); } debug!("{} -> {}", i, loc); } @@ -296,10 +324,14 @@ impl Shaper { } // if there's just one glyph, then we don't need further checks. - if glyph_span.len() == 1 { break; } + if glyph_span.len() == 1 { + break; + } // if no glyphs were found yet, extend the char byte range more. - if glyph_span.len() == 0 { continue; } + if glyph_span.len() == 0 { + continue; + } // If byte_range now includes all the byte offsets found in glyph_span, then we // have found a contiguous "cluster" and can stop extending it. @@ -308,11 +340,11 @@ impl Shaper { let loc = glyph_data.byte_offset_of_glyph(j) as usize; if !(byte_range.start <= loc && loc < byte_range.end) { all_glyphs_are_within_cluster = false; - break + break; } } if all_glyphs_are_within_cluster { - break + break; } // Otherwise, the bytes we have seen so far correspond to a non-contiguous set of @@ -348,34 +380,29 @@ impl Shaper { const TAB_COLS: i32 = 8; let (space_glyph_id, space_advance) = glyph_space_advance(self.font); let advance = Au::from_f64_px(space_advance) * TAB_COLS; - let data = GlyphData::new(space_glyph_id, - advance, - Default::default(), - true, - true); + let data = + GlyphData::new(space_glyph_id, advance, Default::default(), true, true); glyphs.add_glyph_for_byte_index(byte_idx, character, &data); } else { let shape = glyph_data.entry_for_glyph(glyph_span.start, &mut y_pos); let advance = self.advance_for_shaped_glyph(shape.advance, character, options); - let data = GlyphData::new(shape.codepoint, - advance, - shape.offset, - true, - true); + let data = GlyphData::new(shape.codepoint, advance, shape.offset, true, true); glyphs.add_glyph_for_byte_index(byte_idx, character, &data); } } else { // collect all glyphs to be assigned to the first character. - let mut datas = vec!(); + let mut datas = vec![]; for glyph_i in glyph_span.clone() { let shape = glyph_data.entry_for_glyph(glyph_i, &mut y_pos); - datas.push(GlyphData::new(shape.codepoint, - shape.advance, - shape.offset, - true, // treat as cluster start - glyph_i > glyph_span.start)); - // all but first are ligature continuations + datas.push(GlyphData::new( + shape.codepoint, + shape.advance, + shape.offset, + true, // treat as cluster start + glyph_i > glyph_span.start, + )); + // all but first are ligature continuations } // now add the detailed glyph entry. glyphs.add_glyphs_for_byte_index(byte_idx, &datas); @@ -390,8 +417,12 @@ impl Shaper { glyphs.finalize_changes(); } - fn advance_for_shaped_glyph(&self, mut advance: Au, character: char, options: &ShapingOptions) - -> Au { + fn advance_for_shaped_glyph( + &self, + mut advance: Au, + character: char, + options: &ShapingOptions, + ) -> Au { if let Some(letter_spacing) = options.letter_spacing { advance = advance + letter_spacing; }; @@ -403,7 +434,8 @@ impl Shaper { if character == ' ' || character == '\u{a0}' { // https://drafts.csswg.org/css-text-3/#word-spacing-property let (length, percent) = options.word_spacing; - advance = (advance + length) + Au::new((advance.0 as f32 * percent.into_inner()) as i32); + advance = + (advance + length) + Au::new((advance.0 as f32 * percent.into_inner()) as i32); } advance @@ -420,20 +452,29 @@ lazy_static! { let hb_funcs = hb_font_funcs_create(); hb_font_funcs_set_nominal_glyph_func(hb_funcs, Some(glyph_func), ptr::null_mut(), None); hb_font_funcs_set_glyph_h_advance_func( - hb_funcs, Some(glyph_h_advance_func), ptr::null_mut(), None); + hb_funcs, + Some(glyph_h_advance_func), + ptr::null_mut(), + None, + ); hb_font_funcs_set_glyph_h_kerning_func( - hb_funcs, Some(glyph_h_kerning_func), ptr::null_mut(), None); + hb_funcs, + Some(glyph_h_kerning_func), + ptr::null_mut(), + None, + ); FontFuncs(hb_funcs) }; } -extern fn glyph_func(_: *mut hb_font_t, - font_data: *mut c_void, - unicode: hb_codepoint_t, - glyph: *mut hb_codepoint_t, - _: *mut c_void) - -> hb_bool_t { +extern "C" fn glyph_func( + _: *mut hb_font_t, + font_data: *mut c_void, + unicode: hb_codepoint_t, + glyph: *mut hb_codepoint_t, + _: *mut c_void, +) -> hb_bool_t { let font: *const Font = font_data as *const Font; assert!(!font.is_null()); @@ -442,17 +483,18 @@ extern fn glyph_func(_: *mut hb_font_t, Some(g) => { *glyph = g as hb_codepoint_t; true as hb_bool_t - } - None => false as hb_bool_t + }, + None => false as hb_bool_t, } } } -extern fn glyph_h_advance_func(_: *mut hb_font_t, - font_data: *mut c_void, - glyph: hb_codepoint_t, - _: *mut c_void) - -> hb_position_t { +extern "C" fn glyph_h_advance_func( + _: *mut hb_font_t, + font_data: *mut c_void, + glyph: hb_codepoint_t, + _: *mut c_void, +) -> hb_position_t { let font: *mut Font = font_data as *mut Font; assert!(!font.is_null()); @@ -468,19 +510,20 @@ fn glyph_space_advance(font: *const Font) -> (hb_codepoint_t, f64) { match unsafe { (*font).glyph_index(space_unicode) } { Some(g) => { space_glyph = g as hb_codepoint_t; - } - None => panic!("No space info") + }, + None => panic!("No space info"), } let space_advance = unsafe { (*font).glyph_h_advance(space_glyph as GlyphId) }; (space_glyph, space_advance) } -extern fn glyph_h_kerning_func(_: *mut hb_font_t, - font_data: *mut c_void, - first_glyph: hb_codepoint_t, - second_glyph: hb_codepoint_t, - _: *mut c_void) - -> hb_position_t { +extern "C" fn glyph_h_kerning_func( + _: *mut hb_font_t, + font_data: *mut c_void, + first_glyph: hb_codepoint_t, + second_glyph: hb_codepoint_t, + _: *mut c_void, +) -> hb_position_t { let font: *mut Font = font_data as *mut Font; assert!(!font.is_null()); @@ -491,10 +534,11 @@ extern fn glyph_h_kerning_func(_: *mut hb_font_t, } // Callback to get a font table out of a font. -extern fn font_table_func(_: *mut hb_face_t, - tag: hb_tag_t, - user_data: *mut c_void) - -> *mut hb_blob_t { +extern "C" fn font_table_func( + _: *mut hb_face_t, + tag: hb_tag_t, + user_data: *mut c_void, +) -> *mut hb_blob_t { unsafe { // NB: These asserts have security implications. let font = user_data as *const Font; @@ -511,20 +555,22 @@ extern fn font_table_func(_: *mut hb_face_t, let buf = (*font_table_ptr).buffer(); // HarfBuzz calls `destroy_blob_func` when the buffer is no longer needed. - let blob = hb_blob_create(buf.as_ptr() as *const c_char, - buf.len() as c_uint, - HB_MEMORY_MODE_READONLY, - font_table_ptr as *mut c_void, - Some(destroy_blob_func)); + let blob = hb_blob_create( + buf.as_ptr() as *const c_char, + buf.len() as c_uint, + HB_MEMORY_MODE_READONLY, + font_table_ptr as *mut c_void, + Some(destroy_blob_func), + ); assert!(!blob.is_null()); blob - } + }, } } } -extern fn destroy_blob_func(font_table_ptr: *mut c_void) { +extern "C" fn destroy_blob_func(font_table_ptr: *mut c_void) { unsafe { drop(Box::from_raw(font_table_ptr as *mut FontTable)); } diff --git a/components/gfx/text/shaping/mod.rs b/components/gfx/text/shaping/mod.rs index 79e5452db06..97d96980596 100644 --- a/components/gfx/text/shaping/mod.rs +++ b/components/gfx/text/shaping/mod.rs @@ -17,4 +17,3 @@ pub mod harfbuzz; pub trait ShaperMethods { fn shape_text(&self, text: &str, options: &ShapingOptions, glyphs: &mut GlyphStore); } - diff --git a/components/gfx/text/text_run.rs b/components/gfx/text/text_run.rs index 62126ab838a..39b96a934e6 100644 --- a/components/gfx/text/text_run.rs +++ b/components/gfx/text/text_run.rs @@ -155,7 +155,7 @@ impl<'a> Iterator for CharacterSliceIterator<'a> { let byte_start = self.range.begin(); let byte_len = match self.text[byte_start.to_usize()..].chars().next() { Some(ch) => ByteIndex(ch.len_utf8() as isize), - None => unreachable!() // XXX refactor? + None => unreachable!(), // XXX refactor? }; self.range.adjust_by(byte_len, -byte_len); @@ -178,24 +178,36 @@ impl<'a> Iterator for CharacterSliceIterator<'a> { impl<'a> TextRun { /// Constructs a new text run. Also returns if there is a line break at the beginning - pub fn new(font: &mut Font, text: String, options: &ShapingOptions, - bidi_level: bidi::Level, breaker: &mut Option) -> (TextRun, bool) { + pub fn new( + font: &mut Font, + text: String, + options: &ShapingOptions, + bidi_level: bidi::Level, + breaker: &mut Option, + ) -> (TextRun, bool) { let (glyphs, break_at_zero) = TextRun::break_and_shape(font, &text, options, breaker); - (TextRun { - text: Arc::new(text), - font_metrics: font.metrics.clone(), - font_template: font.handle.template(), - font_key: font.font_key, - actual_pt_size: font.actual_pt_size, - glyphs: Arc::new(glyphs), - bidi_level: bidi_level, - extra_word_spacing: Au(0), - }, break_at_zero) + ( + TextRun { + text: Arc::new(text), + font_metrics: font.metrics.clone(), + font_template: font.handle.template(), + font_key: font.font_key, + actual_pt_size: font.actual_pt_size, + glyphs: Arc::new(glyphs), + bidi_level: bidi_level, + extra_word_spacing: Au(0), + }, + break_at_zero, + ) } - pub fn break_and_shape(font: &mut Font, text: &str, options: &ShapingOptions, - breaker: &mut Option) -> (Vec, bool) { - let mut glyphs = vec!(); + pub fn break_and_shape( + font: &mut Font, + text: &str, + options: &ShapingOptions, + breaker: &mut Option, + ) -> (Vec, bool) { + let mut glyphs = vec![]; let mut slice = 0..0; let mut finished = false; @@ -203,7 +215,7 @@ impl<'a> TextRun { if breaker.is_none() { if text.len() == 0 { - return (glyphs, true) + return (glyphs, true); } *breaker = Some(LineBreakLeafIter::new(&text, 0)); } @@ -225,29 +237,39 @@ impl<'a> TextRun { // Split off any trailing whitespace into a separate glyph run. let mut whitespace = slice.end..slice.end; - if let Some((i, _)) = word.char_indices().rev() - .take_while(|&(_, c)| char_is_whitespace(c)).last() { - whitespace.start = slice.start + i; - slice.end = whitespace.start; - } else if idx != text.len() && options.flags.contains(ShapingFlags::KEEP_ALL_FLAG) { - // If there's no whitespace and word-break is set to - // keep-all, try increasing the slice. - continue; - } + if let Some((i, _)) = word + .char_indices() + .rev() + .take_while(|&(_, c)| char_is_whitespace(c)) + .last() + { + whitespace.start = slice.start + i; + slice.end = whitespace.start; + } else if idx != text.len() && options.flags.contains(ShapingFlags::KEEP_ALL_FLAG) { + // If there's no whitespace and word-break is set to + // keep-all, try increasing the slice. + continue; + } if slice.len() > 0 { glyphs.push(GlyphRun { glyph_store: font.shape_text(&text[slice.clone()], options), - range: Range::new(ByteIndex(slice.start as isize), - ByteIndex(slice.len() as isize)), + range: Range::new( + ByteIndex(slice.start as isize), + ByteIndex(slice.len() as isize), + ), }); } if whitespace.len() > 0 { let mut options = options.clone(); - options.flags.insert(ShapingFlags::IS_WHITESPACE_SHAPING_FLAG); + options + .flags + .insert(ShapingFlags::IS_WHITESPACE_SHAPING_FLAG); glyphs.push(GlyphRun { glyph_store: font.shape_text(&text[whitespace.clone()], &options), - range: Range::new(ByteIndex(whitespace.start as isize), - ByteIndex(whitespace.len() as isize)), + range: Range::new( + ByteIndex(whitespace.start as isize), + ByteIndex(whitespace.len() as isize), + ), }); } slice.start = whitespace.end; @@ -265,36 +287,46 @@ impl<'a> TextRun { pub fn advance_for_range(&self, range: &Range) -> Au { if range.is_empty() { - return Au(0) + return Au(0); } // TODO(Issue #199): alter advance direction for RTL // TODO(Issue #98): using inter-char and inter-word spacing settings when measuring text self.natural_word_slices_in_range(range) .fold(Au(0), |advance, slice| { - advance + slice.glyphs.advance_for_byte_range(&slice.range, self.extra_word_spacing) + advance + slice + .glyphs + .advance_for_byte_range(&slice.range, self.extra_word_spacing) }) } pub fn metrics_for_range(&self, range: &Range) -> RunMetrics { - RunMetrics::new(self.advance_for_range(range), - self.font_metrics.ascent, - self.font_metrics.descent) + RunMetrics::new( + self.advance_for_range(range), + self.font_metrics.ascent, + self.font_metrics.descent, + ) } - pub fn metrics_for_slice(&self, glyphs: &GlyphStore, slice_range: &Range) - -> RunMetrics { - RunMetrics::new(glyphs.advance_for_byte_range(slice_range, self.extra_word_spacing), - self.font_metrics.ascent, - self.font_metrics.descent) + pub fn metrics_for_slice( + &self, + glyphs: &GlyphStore, + slice_range: &Range, + ) -> RunMetrics { + RunMetrics::new( + glyphs.advance_for_byte_range(slice_range, self.extra_word_spacing), + self.font_metrics.ascent, + self.font_metrics.descent, + ) } pub fn min_width_for_range(&self, range: &Range) -> Au { debug!("iterating outer range {:?}", range); - self.natural_word_slices_in_range(range).fold(Au(0), |max_piece_width, slice| { - debug!("iterated on {:?}[{:?}]", slice.offset, slice.range); - max(max_piece_width, self.advance_for_range(&slice.range)) - }) + self.natural_word_slices_in_range(range) + .fold(Au(0), |max_piece_width, slice| { + debug!("iterated on {:?}[{:?}]", slice.offset, slice.range); + max(max_piece_width, self.advance_for_range(&slice.range)) + }) } pub fn minimum_splittable_inline_size(&self, range: &Range) -> Au { @@ -309,13 +341,15 @@ impl<'a> TextRun { let self_ptr = self as *const TextRun; INDEX_OF_FIRST_GLYPH_RUN_CACHE.with(|index_of_first_glyph_run_cache| { if let Some((last_text_run, last_index, last_result)) = - index_of_first_glyph_run_cache.get() { + index_of_first_glyph_run_cache.get() + { if last_text_run == self_ptr && last_index == index { - return Some(last_result) + return Some(last_result); } } - if let Ok(result) = (&**self.glyphs).binary_search_by(|current| current.compare(&index)) { + if let Ok(result) = (&**self.glyphs).binary_search_by(|current| current.compare(&index)) + { index_of_first_glyph_run_cache.set(Some((self_ptr, index, result))); Some(result) } else { @@ -339,18 +373,22 @@ impl<'a> TextRun { let mut remaining = advance; self.natural_word_slices_in_range(range) .map(|slice| { - let (slice_index, slice_advance) = - slice.glyphs.range_index_of_advance(&slice.range, remaining, self.extra_word_spacing); + let (slice_index, slice_advance) = slice.glyphs.range_index_of_advance( + &slice.range, + remaining, + self.extra_word_spacing, + ); remaining -= slice_advance; slice_index - }) - .sum() + }).sum() } /// Returns an iterator that will iterate over all slices of glyphs that represent natural /// words in the given range. - pub fn natural_word_slices_in_range(&'a self, range: &Range) - -> NaturalWordSliceIterator<'a> { + pub fn natural_word_slices_in_range( + &'a self, + range: &Range, + ) -> NaturalWordSliceIterator<'a> { let index = match self.index_of_first_glyph_run_containing(range.begin()) { None => self.glyphs.len(), Some(index) => index, @@ -365,20 +403,22 @@ impl<'a> TextRun { /// Returns an iterator that over natural word slices in visual order (left to right or /// right to left, depending on the bidirectional embedding level). - pub fn natural_word_slices_in_visual_order(&'a self, range: &Range) - -> NaturalWordSliceIterator<'a> { + pub fn natural_word_slices_in_visual_order( + &'a self, + range: &Range, + ) -> NaturalWordSliceIterator<'a> { // Iterate in reverse order if bidi level is RTL. let reverse = self.bidi_level.is_rtl(); let index = if reverse { match self.index_of_first_glyph_run_containing(range.end() - ByteIndex(1)) { Some(i) => i + 1, // In reverse mode, index points one past the next element. - None => 0 + None => 0, } } else { match self.index_of_first_glyph_run_containing(range.begin()) { Some(i) => i, - None => self.glyphs.len() + None => self.glyphs.len(), } }; NaturalWordSliceIterator { @@ -391,8 +431,10 @@ impl<'a> TextRun { /// Returns an iterator that will iterate over all slices of glyphs that represent individual /// characters in the given range. - pub fn character_slices_in_range(&'a self, range: &Range) - -> CharacterSliceIterator<'a> { + pub fn character_slices_in_range( + &'a self, + range: &Range, + ) -> CharacterSliceIterator<'a> { let index = match self.index_of_first_glyph_run_containing(range.begin()) { None => self.glyphs.len(), Some(index) => index, diff --git a/components/gfx/text/util.rs b/components/gfx/text/util.rs index f740c4a54e6..b1bf25724ba 100644 --- a/components/gfx/text/util.rs +++ b/components/gfx/text/util.rs @@ -9,7 +9,7 @@ pub enum CompressionMode { CompressNone, CompressWhitespace, CompressWhitespaceNewline, - DiscardNewline + DiscardNewline, } // ported from Gecko's nsTextFrameUtils::TransformText. @@ -22,11 +22,12 @@ pub enum CompressionMode { // * Issue #114: record skipped and kept chars for mapping original to new text // // * Untracked: various edge cases for bidi, CJK, etc. -pub fn transform_text(text: &str, - mode: CompressionMode, - incoming_whitespace: bool, - output_text: &mut String) - -> bool { +pub fn transform_text( + text: &str, + mode: CompressionMode, + incoming_whitespace: bool, + output_text: &mut String, +) -> bool { let out_whitespace = match mode { CompressionMode::CompressNone | CompressionMode::DiscardNewline => { for ch in text.chars() { @@ -53,12 +54,13 @@ pub fn transform_text(text: &str, if is_always_discardable_char(ch) { // revert whitespace setting, since this char was discarded next_in_whitespace = in_whitespace; - // TODO: record skipped char + // TODO: record skipped char } else { // TODO: record kept char output_text.push(ch); } - } else { /* next_in_whitespace; possibly add a space char */ + } else { + /* next_in_whitespace; possibly add a space char */ if in_whitespace { // TODO: record skipped char } else { @@ -70,17 +72,17 @@ pub fn transform_text(text: &str, in_whitespace = next_in_whitespace; } /* /for str::each_char */ in_whitespace - } + }, }; return out_whitespace; fn is_in_whitespace(ch: char, mode: CompressionMode) -> bool { match (ch, mode) { - (' ', _) => true, + (' ', _) => true, ('\t', _) => true, ('\n', CompressionMode::CompressWhitespaceNewline) => true, - (_, _) => false + (_, _) => false, } } @@ -89,8 +91,10 @@ pub fn transform_text(text: &str, return true; } match mode { - CompressionMode::DiscardNewline | CompressionMode::CompressWhitespaceNewline => ch == '\n', - _ => false + CompressionMode::DiscardNewline | CompressionMode::CompressWhitespaceNewline => { + ch == '\n' + }, + _ => false, } } @@ -113,7 +117,7 @@ pub fn is_bidi_control(c: char) -> bool { '\u{202A}'...'\u{202E}' => true, '\u{2066}'...'\u{2069}' => true, '\u{200E}' | '\u{200F}' | '\u{061C}' => true, - _ => false + _ => false, } } @@ -143,15 +147,12 @@ pub fn is_cjk(codepoint: char) -> bool { UnicodeBlock::CJKUnifiedIdeographs | UnicodeBlock::CJKCompatibilityIdeographs | UnicodeBlock::CJKCompatibilityForms | - UnicodeBlock::HalfwidthandFullwidthForms => { - return true - } + UnicodeBlock::HalfwidthandFullwidthForms => return true, - _ => {} + _ => {}, } } - // https://en.wikipedia.org/wiki/Plane_(Unicode)#Supplementary_Ideographic_Plane unicode_plane(codepoint) == 2 } diff --git a/components/gfx_traits/lib.rs b/components/gfx_traits/lib.rs index 247396ca04e..457814abddf 100644 --- a/components/gfx_traits/lib.rs +++ b/components/gfx_traits/lib.rs @@ -4,13 +4,15 @@ #![crate_name = "gfx_traits"] #![crate_type = "rlib"] - #![deny(unsafe_code)] extern crate malloc_size_of; -#[macro_use] extern crate malloc_size_of_derive; -#[macro_use] extern crate range; -#[macro_use] extern crate serde; +#[macro_use] +extern crate malloc_size_of_derive; +#[macro_use] +extern crate range; +#[macro_use] +extern crate serde; pub mod print_tree; @@ -32,7 +34,7 @@ impl Epoch { pub struct StackingContextId( /// The identifier for this StackingContext, derived from the Flow's memory address /// and fragment type. As a space optimization, these are combined into a single word. - pub u64 + pub u64, ); impl StackingContextId { @@ -87,7 +89,7 @@ fn next_special_id() -> usize { SPECIAL_SCROLL_ROOT_ID_MASK } -pub fn combine_id_with_fragment_type(id: usize, fragment_type: FragmentType) -> usize { +pub fn combine_id_with_fragment_type(id: usize, fragment_type: FragmentType) -> usize { debug_assert_eq!(id & (fragment_type as usize), 0); if fragment_type == FragmentType::FragmentBody { id diff --git a/components/hashglobe/src/alloc.rs b/components/hashglobe/src/alloc.rs index b0d622972db..b1c7a6eca5e 100644 --- a/components/hashglobe/src/alloc.rs +++ b/components/hashglobe/src/alloc.rs @@ -1,25 +1,26 @@ // FORK NOTE: Copied from liballoc_system, removed unnecessary APIs, // APIs take size/align directly instead of Layout - - - // The minimum alignment guaranteed by the architecture. This value is used to // add fast paths for low alignment values. In practice, the alignment is a // constant at the call site and the branch will be optimized out. -#[cfg(all(any(target_arch = "x86", - target_arch = "arm", - target_arch = "mips", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "asmjs", - target_arch = "wasm32")))] +#[cfg(all(any( + target_arch = "x86", + target_arch = "arm", + target_arch = "mips", + target_arch = "powerpc", + target_arch = "powerpc64", + target_arch = "asmjs", + target_arch = "wasm32" +)))] const MIN_ALIGN: usize = 8; -#[cfg(all(any(target_arch = "x86_64", - target_arch = "aarch64", - target_arch = "mips64", - target_arch = "s390x", - target_arch = "sparc64")))] +#[cfg(all(any( + target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "mips64", + target_arch = "s390x", + target_arch = "sparc64" +)))] const MIN_ALIGN: usize = 16; pub use self::platform::{alloc, dealloc, realloc}; @@ -100,7 +101,6 @@ mod platform { type DWORD = u32; type BOOL = i32; - extern "system" { fn GetProcessHeap() -> HANDLE; fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID; @@ -123,8 +123,7 @@ mod platform { } #[inline] - unsafe fn allocate_with_flags(size: usize, align: usize, flags: DWORD) -> *mut u8 - { + unsafe fn allocate_with_flags(size: usize, align: usize, flags: DWORD) -> *mut u8 { if align <= MIN_ALIGN { HeapAlloc(GetProcessHeap(), flags, size) } else { @@ -147,21 +146,16 @@ mod platform { pub unsafe fn dealloc(ptr: *mut u8, align: usize) { if align <= MIN_ALIGN { let err = HeapFree(GetProcessHeap(), 0, ptr as LPVOID); - debug_assert!(err != 0, "Failed to free heap memory: {}", - GetLastError()); + debug_assert!(err != 0, "Failed to free heap memory: {}", GetLastError()); } else { let header = get_header(ptr); let err = HeapFree(GetProcessHeap(), 0, header.0 as LPVOID); - debug_assert!(err != 0, "Failed to free heap memory: {}", - GetLastError()); + debug_assert!(err != 0, "Failed to free heap memory: {}", GetLastError()); } } #[inline] pub unsafe fn realloc(ptr: *mut u8, new_size: usize) -> *mut u8 { - HeapReAlloc(GetProcessHeap(), - 0, - ptr as LPVOID, - new_size) as *mut u8 + HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, new_size) as *mut u8 } } diff --git a/components/hashglobe/src/fake.rs b/components/hashglobe/src/fake.rs index eba21e04148..c5cd9d39bb7 100644 --- a/components/hashglobe/src/fake.rs +++ b/components/hashglobe/src/fake.rs @@ -26,7 +26,6 @@ pub use std::collections::hash_set::{Iter as SetIter, IntoIter as SetIntoIter}; #[derive(Clone)] pub struct HashMap(StdMap); - use FailedAllocationError; impl Deref for HashMap { @@ -43,8 +42,9 @@ impl DerefMut for HashMap { } impl HashMap - where K: Eq + Hash, - S: BuildHasher +where + K: Eq + Hash, + S: BuildHasher, { #[inline] pub fn try_with_hasher(hash_builder: S) -> Result, FailedAllocationError> { @@ -52,17 +52,20 @@ impl HashMap } #[inline] - pub fn try_with_capacity_and_hasher(capacity: usize, - hash_builder: S) - -> Result, FailedAllocationError> { - Ok(HashMap(StdMap::with_capacity_and_hasher(capacity, hash_builder))) + pub fn try_with_capacity_and_hasher( + capacity: usize, + hash_builder: S, + ) -> Result, FailedAllocationError> { + Ok(HashMap(StdMap::with_capacity_and_hasher( + capacity, + hash_builder, + ))) } pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> HashMap { HashMap(StdMap::with_capacity_and_hasher(capacity, hash_builder)) } - #[inline] pub fn try_reserve(&mut self, additional: usize) -> Result<(), FailedAllocationError> { Ok(self.reserve(additional)) @@ -85,7 +88,6 @@ impl HashMap #[derive(Clone)] pub struct HashSet(StdSet); - impl Deref for HashSet { type Target = StdSet; fn deref(&self) -> &Self::Target { @@ -111,17 +113,16 @@ impl HashSet { } } - impl HashSet - where T: Eq + Hash, - S: BuildHasher +where + T: Eq + Hash, + S: BuildHasher, { #[inline] pub fn with_hasher(hasher: S) -> HashSet { HashSet(StdSet::with_hasher(hasher)) } - #[inline] pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> HashSet { HashSet(StdSet::with_capacity_and_hasher(capacity, hasher)) @@ -153,18 +154,21 @@ impl Default for HashMap { } impl fmt::Debug for HashMap - where K: Eq + Hash + fmt::Debug, - V: fmt::Debug, - S: BuildHasher { +where + K: Eq + Hash + fmt::Debug, + V: fmt::Debug, + S: BuildHasher, +{ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0.fmt(f) } } impl PartialEq for HashMap - where K: Eq + Hash, - V: PartialEq, - S: BuildHasher +where + K: Eq + Hash, + V: PartialEq, + S: BuildHasher, { fn eq(&self, other: &HashMap) -> bool { self.0.eq(&other.0) @@ -172,15 +176,17 @@ impl PartialEq for HashMap } impl Eq for HashMap - where K: Eq + Hash, - V: Eq, - S: BuildHasher +where + K: Eq + Hash, + V: Eq, + S: BuildHasher, { } impl<'a, K, V, S> IntoIterator for &'a HashMap - where K: Eq + Hash, - S: BuildHasher +where + K: Eq + Hash, + S: BuildHasher, { type Item = (&'a K, &'a V); type IntoIter = MapIter<'a, K, V>; @@ -191,8 +197,9 @@ impl<'a, K, V, S> IntoIterator for &'a HashMap } impl<'a, K, V, S> IntoIterator for &'a mut HashMap - where K: Eq + Hash, - S: BuildHasher +where + K: Eq + Hash, + S: BuildHasher, { type Item = (&'a K, &'a mut V); type IntoIter = MapIterMut<'a, K, V>; @@ -209,8 +216,9 @@ impl Default for HashSet { } impl fmt::Debug for HashSet - where T: Eq + Hash + fmt::Debug, - S: BuildHasher +where + T: Eq + Hash + fmt::Debug, + S: BuildHasher, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0.fmt(f) @@ -218,8 +226,9 @@ impl fmt::Debug for HashSet } impl PartialEq for HashSet - where T: Eq + Hash, - S: BuildHasher +where + T: Eq + Hash, + S: BuildHasher, { fn eq(&self, other: &HashSet) -> bool { self.0.eq(&other.0) @@ -227,14 +236,16 @@ impl PartialEq for HashSet } impl Eq for HashSet - where T: Eq + Hash, - S: BuildHasher +where + T: Eq + Hash, + S: BuildHasher, { } impl<'a, T, S> IntoIterator for &'a HashSet - where T: Eq + Hash, - S: BuildHasher +where + T: Eq + Hash, + S: BuildHasher, { type Item = &'a T; type IntoIter = SetIter<'a, T>; @@ -245,16 +256,14 @@ impl<'a, T, S> IntoIterator for &'a HashSet } impl IntoIterator for HashSet - where T: Eq + Hash, - S: BuildHasher +where + T: Eq + Hash, + S: BuildHasher, { type Item = T; type IntoIter = SetIntoIter; - fn into_iter(self) -> SetIntoIter { self.0.into_iter() } } - - diff --git a/components/hashglobe/src/hash_map.rs b/components/hashglobe/src/hash_map.rs index 27077526b3a..57ac9bcc049 100644 --- a/components/hashglobe/src/hash_map.rs +++ b/components/hashglobe/src/hash_map.rs @@ -25,7 +25,7 @@ use super::table::BucketState::{Empty, Full}; use FailedAllocationError; -const MIN_NONZERO_RAW_CAPACITY: usize = 32; // must be a power of two +const MIN_NONZERO_RAW_CAPACITY: usize = 32; // must be a power of two /// The default behavior of HashMap implements a maximum load factor of 90.9%. #[derive(Clone)] @@ -50,7 +50,9 @@ impl DefaultResizePolicy { // 3. Ensure it is at least the minimum size. let mut raw_cap = len * 11 / 10; assert!(raw_cap >= len, "raw_cap overflow"); - raw_cap = raw_cap.checked_next_power_of_two().expect("raw_capacity overflow"); + raw_cap = raw_cap + .checked_next_power_of_two() + .expect("raw_capacity overflow"); raw_cap = max(MIN_NONZERO_RAW_CAPACITY, raw_cap); raw_cap } @@ -398,8 +400,9 @@ pub struct HashMap { /// Search for a pre-hashed key. #[inline] fn search_hashed(table: M, hash: SafeHash, mut is_match: F) -> InternalEntry - where M: Deref>, - F: FnMut(&K) -> bool +where + M: Deref>, + F: FnMut(&K) -> bool, { // This is the only function where capacity can be zero. To avoid // undefined behavior when Bucket::new gets the raw bucket in this @@ -420,7 +423,7 @@ fn search_hashed(table: M, hash: SafeHash, mut is_match: F) -> Inter hash, elem: NoElem(bucket, displacement), }; - } + }, Full(bucket) => bucket, }; @@ -449,9 +452,7 @@ fn search_hashed(table: M, hash: SafeHash, mut is_match: F) -> Inter } } -fn pop_internal(starting_bucket: FullBucketMut) - -> (K, V, &mut RawTable) -{ +fn pop_internal(starting_bucket: FullBucketMut) -> (K, V, &mut RawTable) { let (empty, retkey, retval) = starting_bucket.take(); let mut gap = match empty.gap_peek() { Ok(b) => b, @@ -475,12 +476,13 @@ fn pop_internal(starting_bucket: FullBucketMut) /// also pass that bucket's displacement so we don't have to recalculate it. /// /// `hash`, `key`, and `val` are the elements to "robin hood" into the hashtable. -fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>, - mut displacement: usize, - mut hash: SafeHash, - mut key: K, - mut val: V) - -> FullBucketMut<'a, K, V> { +fn robin_hood<'a, K: 'a, V: 'a>( + bucket: FullBucketMut<'a, K, V>, + mut displacement: usize, + mut hash: SafeHash, + mut key: K, + mut val: V, +) -> FullBucketMut<'a, K, V> { let size = bucket.table().size(); let raw_capacity = bucket.table().capacity(); // There can be at most `size - dib` buckets to displace, because @@ -513,7 +515,7 @@ fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>, // FullBucketMut, into just one FullBucketMut. The "table" // refers to the inner FullBucketMut in this context. return bucket.into_table(); - } + }, Full(bucket) => bucket, }; @@ -531,11 +533,13 @@ fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>, } impl HashMap - where K: Eq + Hash, - S: BuildHasher +where + K: Eq + Hash, + S: BuildHasher, { fn make_hash(&self, x: &X) -> SafeHash - where X: Hash + where + X: Hash, { table::make_hash(&self.hash_builder, x) } @@ -545,8 +549,9 @@ impl HashMap /// search_hashed. #[inline] fn search<'a, Q: ?Sized>(&'a self, q: &Q) -> InternalEntry> - where K: Borrow, - Q: Eq + Hash + where + K: Borrow, + Q: Eq + Hash, { let hash = self.make_hash(q); search_hashed(&self.table, hash, |k| q.eq(k.borrow())) @@ -554,8 +559,9 @@ impl HashMap #[inline] fn search_mut<'a, Q: ?Sized>(&'a mut self, q: &Q) -> InternalEntry> - where K: Borrow, - Q: Eq + Hash + where + K: Borrow, + Q: Eq + Hash, { let hash = self.make_hash(q); search_hashed(&mut self.table, hash, |k| q.eq(k.borrow())) @@ -574,7 +580,7 @@ impl HashMap Empty(empty) => { empty.put(hash, k, v); return; - } + }, Full(b) => b.into_bucket(), }; buckets.next(); @@ -584,8 +590,9 @@ impl HashMap } impl HashMap - where K: Eq + Hash, - S: BuildHasher +where + K: Eq + Hash, + S: BuildHasher, { /// Creates an empty `HashMap` which will use the given hash builder to hash /// keys. @@ -643,7 +650,10 @@ impl HashMap /// map.insert(1, 2); /// ``` #[inline] - pub fn try_with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Result, FailedAllocationError> { + pub fn try_with_capacity_and_hasher( + capacity: usize, + hash_builder: S, + ) -> Result, FailedAllocationError> { let resize_policy = DefaultResizePolicy::new(); let raw_cap = resize_policy.raw_capacity(capacity); Ok(HashMap { @@ -708,12 +718,14 @@ impl HashMap self.try_reserve(additional).unwrap(); } - #[inline] pub fn try_reserve(&mut self, additional: usize) -> Result<(), FailedAllocationError> { let remaining = self.capacity() - self.len(); // this can't overflow if remaining < additional { - let min_cap = self.len().checked_add(additional).expect("reserve overflow"); + let min_cap = self + .len() + .checked_add(additional) + .expect("reserve overflow"); let raw_cap = self.resize_policy.raw_capacity(min_cap); self.try_resize(raw_cap)?; } else if self.table.tag() && remaining <= self.len() { @@ -763,7 +775,7 @@ impl HashMap break; } b.into_bucket() - } + }, Empty(b) => b.into_bucket(), }; bucket.next(); @@ -822,7 +834,7 @@ impl HashMap Some(Vacant(elem)) => { elem.insert(v); None - } + }, None => unreachable!(), } } @@ -892,7 +904,9 @@ impl HashMap /// } /// ``` pub fn values_mut(&mut self) -> ValuesMut { - ValuesMut { inner: self.iter_mut() } + ValuesMut { + inner: self.iter_mut(), + } } /// An iterator visiting all key-value pairs in arbitrary order. @@ -913,7 +927,9 @@ impl HashMap /// } /// ``` pub fn iter(&self) -> Iter { - Iter { inner: self.table.iter() } + Iter { + inner: self.table.iter(), + } } /// An iterator visiting all key-value pairs in arbitrary order, @@ -940,7 +956,9 @@ impl HashMap /// } /// ``` pub fn iter_mut(&mut self) -> IterMut { - IterMut { inner: self.table.iter_mut() } + IterMut { + inner: self.table.iter_mut(), + } } /// Gets the given key's corresponding entry in the map for in-place manipulation. @@ -972,7 +990,8 @@ impl HashMap self.try_reserve(1)?; let hash = self.make_hash(&key); Ok(search_hashed(&mut self.table, hash, |q| q.eq(&key)) - .into_entry(key).expect("unreachable")) + .into_entry(key) + .expect("unreachable")) } /// Returns the number of elements in the map. @@ -1028,8 +1047,14 @@ impl HashMap /// assert!(a.is_empty()); /// ``` #[inline] - pub fn drain(&mut self) -> Drain where K: 'static, V: 'static { - Drain { inner: self.table.drain() } + pub fn drain(&mut self) -> Drain + where + K: 'static, + V: 'static, + { + Drain { + inner: self.table.drain(), + } } /// Clears the map, removing all key-value pairs. Keeps the allocated memory @@ -1046,7 +1071,11 @@ impl HashMap /// assert!(a.is_empty()); /// ``` #[inline] - pub fn clear(&mut self) where K: 'static, V: 'static { + pub fn clear(&mut self) + where + K: 'static, + V: 'static, + { self.drain(); } @@ -1070,10 +1099,13 @@ impl HashMap /// assert_eq!(map.get(&2), None); /// ``` pub fn get(&self, k: &Q) -> Option<&V> - where K: Borrow, - Q: Hash + Eq + where + K: Borrow, + Q: Hash + Eq, { - self.search(k).into_occupied_bucket().map(|bucket| bucket.into_refs().1) + self.search(k) + .into_occupied_bucket() + .map(|bucket| bucket.into_refs().1) } /// Returns true if the map contains a value for the specified key. @@ -1096,8 +1128,9 @@ impl HashMap /// assert_eq!(map.contains_key(&2), false); /// ``` pub fn contains_key(&self, k: &Q) -> bool - where K: Borrow, - Q: Hash + Eq + where + K: Borrow, + Q: Hash + Eq, { self.search(k).into_occupied_bucket().is_some() } @@ -1124,10 +1157,13 @@ impl HashMap /// assert_eq!(map[&1], "b"); /// ``` pub fn get_mut(&mut self, k: &Q) -> Option<&mut V> - where K: Borrow, - Q: Hash + Eq + where + K: Borrow, + Q: Hash + Eq, { - self.search_mut(k).into_occupied_bucket().map(|bucket| bucket.into_mut_refs().1) + self.search_mut(k) + .into_occupied_bucket() + .map(|bucket| bucket.into_mut_refs().1) } /// Inserts a key-value pair into the map. @@ -1187,14 +1223,17 @@ impl HashMap /// assert_eq!(map.remove(&1), None); /// ``` pub fn remove(&mut self, k: &Q) -> Option - where K: Borrow, - Q: Hash + Eq + where + K: Borrow, + Q: Hash + Eq, { if self.table.size() == 0 { return None; } - self.search_mut(k).into_occupied_bucket().map(|bucket| pop_internal(bucket).1) + self.search_mut(k) + .into_occupied_bucket() + .map(|bucket| pop_internal(bucket).1) } /// Retains only the elements specified by the predicate. @@ -1211,7 +1250,8 @@ impl HashMap /// assert_eq!(map.len(), 4); /// ``` pub fn retain(&mut self, mut f: F) - where F: FnMut(&K, &mut V) -> bool + where + F: FnMut(&K, &mut V) -> bool, { if self.table.size() == 0 { return; @@ -1236,41 +1276,43 @@ impl HashMap full.into_bucket() } }, - Empty(b) => { - b.into_bucket() - } + Empty(b) => b.into_bucket(), }; - bucket.prev(); // reverse iteration + bucket.prev(); // reverse iteration debug_assert!(elems_left == 0 || bucket.index() != start_index); } } } impl PartialEq for HashMap - where K: Eq + Hash, - V: PartialEq, - S: BuildHasher +where + K: Eq + Hash, + V: PartialEq, + S: BuildHasher, { fn eq(&self, other: &HashMap) -> bool { if self.len() != other.len() { return false; } - self.iter().all(|(key, value)| other.get(key).map_or(false, |v| *value == *v)) + self.iter() + .all(|(key, value)| other.get(key).map_or(false, |v| *value == *v)) } } impl Eq for HashMap - where K: Eq + Hash, - V: Eq, - S: BuildHasher +where + K: Eq + Hash, + V: Eq, + S: BuildHasher, { } impl Debug for HashMap - where K: Eq + Hash + Debug, - V: Debug, - S: BuildHasher +where + K: Eq + Hash + Debug, + V: Debug, + S: BuildHasher, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_map().entries(self.iter()).finish() @@ -1278,8 +1320,9 @@ impl Debug for HashMap } impl Default for HashMap - where K: Eq + Hash, - S: BuildHasher + Default +where + K: Eq + Hash, + S: BuildHasher + Default, { /// Creates an empty `HashMap`, with the `Default` value for the hasher. fn default() -> HashMap { @@ -1288,9 +1331,10 @@ impl Default for HashMap } impl<'a, K, Q: ?Sized, V, S> Index<&'a Q> for HashMap - where K: Eq + Hash + Borrow, - Q: Eq + Hash, - S: BuildHasher +where + K: Eq + Hash + Borrow, + Q: Eq + Hash, + S: BuildHasher, { type Output = V; @@ -1314,15 +1358,15 @@ pub struct Iter<'a, K: 'a, V: 'a> { // FIXME(#19839) Remove in favor of `#[derive(Clone)]` impl<'a, K, V> Clone for Iter<'a, K, V> { fn clone(&self) -> Iter<'a, K, V> { - Iter { inner: self.inner.clone() } + Iter { + inner: self.inner.clone(), + } } } impl<'a, K: Debug, V: Debug> fmt::Debug for Iter<'a, K, V> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_list() - .entries(self.clone()) - .finish() + f.debug_list().entries(self.clone()).finish() } } @@ -1362,15 +1406,15 @@ pub struct Keys<'a, K: 'a, V: 'a> { // FIXME(#19839) Remove in favor of `#[derive(Clone)]` impl<'a, K, V> Clone for Keys<'a, K, V> { fn clone(&self) -> Keys<'a, K, V> { - Keys { inner: self.inner.clone() } + Keys { + inner: self.inner.clone(), + } } } impl<'a, K: Debug, V> fmt::Debug for Keys<'a, K, V> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_list() - .entries(self.clone()) - .finish() + f.debug_list().entries(self.clone()).finish() } } @@ -1388,15 +1432,15 @@ pub struct Values<'a, K: 'a, V: 'a> { // FIXME(#19839) Remove in favor of `#[derive(Clone)]` impl<'a, K, V> Clone for Values<'a, K, V> { fn clone(&self) -> Values<'a, K, V> { - Values { inner: self.inner.clone() } + Values { + inner: self.inner.clone(), + } } } impl<'a, K, V: Debug> fmt::Debug for Values<'a, K, V> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_list() - .entries(self.clone()) - .finish() + f.debug_list().entries(self.clone()).finish() } } @@ -1423,7 +1467,9 @@ pub struct ValuesMut<'a, K: 'a, V: 'a> { } enum InternalEntry { - Occupied { elem: FullBucket }, + Occupied { + elem: FullBucket, + }, Vacant { hash: SafeHash, elem: VacantEntryState, @@ -1445,19 +1491,11 @@ impl<'a, K, V> InternalEntry> { #[inline] fn into_entry(self, key: K) -> Option> { match self { - InternalEntry::Occupied { elem } => { - Some(Occupied(OccupiedEntry { - key: Some(key), - elem, - })) - } - InternalEntry::Vacant { hash, elem } => { - Some(Vacant(VacantEntry { - hash, - key, - elem, - })) - } + InternalEntry::Occupied { elem } => Some(Occupied(OccupiedEntry { + key: Some(key), + elem, + })), + InternalEntry::Vacant { hash, elem } => Some(Vacant(VacantEntry { hash, key, elem })), InternalEntry::TableIsEmpty => None, } } @@ -1471,25 +1509,17 @@ impl<'a, K, V> InternalEntry> { /// [`entry`]: struct.HashMap.html#method.entry pub enum Entry<'a, K: 'a, V: 'a> { /// An occupied entry. - Occupied( OccupiedEntry<'a, K, V>), + Occupied(OccupiedEntry<'a, K, V>), /// A vacant entry. - Vacant( VacantEntry<'a, K, V>), + Vacant(VacantEntry<'a, K, V>), } impl<'a, K: 'a + Debug, V: 'a + Debug> Debug for Entry<'a, K, V> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - Vacant(ref v) => { - f.debug_tuple("Entry") - .field(v) - .finish() - } - Occupied(ref o) => { - f.debug_tuple("Entry") - .field(o) - .finish() - } + Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(), + Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(), } } } @@ -1524,9 +1554,7 @@ pub struct VacantEntry<'a, K: 'a, V: 'a> { impl<'a, K: 'a + Debug, V: 'a> Debug for VacantEntry<'a, K, V> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_tuple("VacantEntry") - .field(self.key()) - .finish() + f.debug_tuple("VacantEntry").field(self.key()).finish() } } @@ -1540,8 +1568,9 @@ enum VacantEntryState { } impl<'a, K, V, S> IntoIterator for &'a HashMap - where K: Eq + Hash, - S: BuildHasher +where + K: Eq + Hash, + S: BuildHasher, { type Item = (&'a K, &'a V); type IntoIter = Iter<'a, K, V>; @@ -1552,8 +1581,9 @@ impl<'a, K, V, S> IntoIterator for &'a HashMap } impl<'a, K, V, S> IntoIterator for &'a mut HashMap - where K: Eq + Hash, - S: BuildHasher +where + K: Eq + Hash, + S: BuildHasher, { type Item = (&'a K, &'a mut V); type IntoIter = IterMut<'a, K, V>; @@ -1564,8 +1594,9 @@ impl<'a, K, V, S> IntoIterator for &'a mut HashMap } impl IntoIterator for HashMap - where K: Eq + Hash, - S: BuildHasher +where + K: Eq + Hash, + S: BuildHasher, { type Item = (K, V); type IntoIter = IntoIter; @@ -1588,7 +1619,9 @@ impl IntoIterator for HashMap /// let vec: Vec<(&str, isize)> = map.into_iter().collect(); /// ``` fn into_iter(self) -> IntoIter { - IntoIter { inner: self.table.into_iter() } + IntoIter { + inner: self.table.into_iter(), + } } } @@ -1611,7 +1644,6 @@ impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> { } } - impl<'a, K, V> Iterator for IterMut<'a, K, V> { type Item = (&'a K, &'a mut V); @@ -1632,13 +1664,12 @@ impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> { } impl<'a, K, V> fmt::Debug for IterMut<'a, K, V> - where K: fmt::Debug, - V: fmt::Debug, +where + K: fmt::Debug, + V: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_list() - .entries(self.inner.iter()) - .finish() + f.debug_list().entries(self.inner.iter()).finish() } } @@ -1663,9 +1694,7 @@ impl ExactSizeIterator for IntoIter { impl fmt::Debug for IntoIter { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_list() - .entries(self.inner.iter()) - .finish() + f.debug_list().entries(self.inner.iter()).finish() } } @@ -1726,13 +1755,12 @@ impl<'a, K, V> ExactSizeIterator for ValuesMut<'a, K, V> { } impl<'a, K, V> fmt::Debug for ValuesMut<'a, K, V> - where K: fmt::Debug, - V: fmt::Debug, +where + K: fmt::Debug, + V: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_list() - .entries(self.inner.inner.iter()) - .finish() + f.debug_list().entries(self.inner.inner.iter()).finish() } } @@ -1756,20 +1784,19 @@ impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> { } impl<'a, K, V> fmt::Debug for Drain<'a, K, V> - where K: fmt::Debug, - V: fmt::Debug, +where + K: fmt::Debug, + V: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_list() - .entries(self.inner.iter()) - .finish() + f.debug_list().entries(self.inner.iter()).finish() } } // FORK NOTE: Removed Placer impl impl<'a, K, V> Entry<'a, K, V> { - /// Ensures a value is in the entry by inserting the default if empty, and returns + /// Ensures a value is in the entry by inserting the default if empty, and returns /// a mutable reference to the value in the entry. /// /// # Examples @@ -1792,7 +1819,7 @@ impl<'a, K, V> Entry<'a, K, V> { } } - /// Ensures a value is in the entry by inserting the result of the default function if empty, + /// Ensures a value is in the entry by inserting the result of the default function if empty, /// and returns a mutable reference to the value in the entry. /// /// # Examples @@ -1824,7 +1851,7 @@ impl<'a, K, V> Entry<'a, K, V> { /// let mut map: HashMap<&str, u32> = HashMap::new(); /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); /// ``` - pub fn key(&self) -> &K { + pub fn key(&self) -> &K { match *self { Occupied(ref entry) => entry.key(), Vacant(ref entry) => entry.key(), @@ -1844,7 +1871,7 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { /// map.entry("poneyland").or_insert(12); /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); /// ``` - pub fn key(&self) -> &K { + pub fn key(&self) -> &K { self.elem.read().0 } @@ -1866,7 +1893,7 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { /// /// assert_eq!(map.contains_key("poneyland"), false); /// ``` - pub fn remove_entry(self) -> (K, V) { + pub fn remove_entry(self) -> (K, V) { let (k, v, _) = pop_internal(self.elem); (k, v) } @@ -1886,7 +1913,7 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { /// assert_eq!(o.get(), &12); /// } /// ``` - pub fn get(&self) -> &V { + pub fn get(&self) -> &V { self.elem.read().1 } @@ -1908,7 +1935,7 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { /// /// assert_eq!(map["poneyland"], 22); /// ``` - pub fn get_mut(&mut self) -> &mut V { + pub fn get_mut(&mut self) -> &mut V { self.elem.read_mut().1 } @@ -1931,7 +1958,7 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { /// /// assert_eq!(map["poneyland"], 22); /// ``` - pub fn into_mut(self) -> &'a mut V { + pub fn into_mut(self) -> &'a mut V { self.elem.into_mut_refs().1 } @@ -1952,7 +1979,7 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { /// /// assert_eq!(map["poneyland"], 15); /// ``` - pub fn insert(&mut self, mut value: V) -> V { + pub fn insert(&mut self, mut value: V) -> V { let old_value = self.get_mut(); mem::swap(&mut value, old_value); value @@ -1975,7 +2002,7 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { /// /// assert_eq!(map.contains_key("poneyland"), false); /// ``` - pub fn remove(self) -> V { + pub fn remove(self) -> V { pop_internal(self.elem).1 } @@ -1999,7 +2026,7 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> { /// let mut map: HashMap<&str, u32> = HashMap::new(); /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); /// ``` - pub fn key(&self) -> &K { + pub fn key(&self) -> &K { &self.key } @@ -2017,7 +2044,7 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> { /// v.into_key(); /// } /// ``` - pub fn into_key(self) -> K { + pub fn into_key(self) -> K { self.key } @@ -2037,7 +2064,7 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> { /// } /// assert_eq!(map["poneyland"], 37); /// ``` - pub fn insert(self, value: V) -> &'a mut V { + pub fn insert(self, value: V) -> &'a mut V { let b = match self.elem { NeqElem(mut bucket, disp) => { if disp >= DISPLACEMENT_THRESHOLD { @@ -2057,8 +2084,9 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> { } impl FromIterator<(K, V)> for HashMap - where K: Eq + Hash, - S: BuildHasher + Default +where + K: Eq + Hash, + S: BuildHasher + Default, { fn from_iter>(iter: T) -> HashMap { let mut map = HashMap::with_hasher(Default::default()); @@ -2068,8 +2096,9 @@ impl FromIterator<(K, V)> for HashMap } impl Extend<(K, V)> for HashMap - where K: Eq + Hash, - S: BuildHasher +where + K: Eq + Hash, + S: BuildHasher, { fn extend>(&mut self, iter: T) { // Keys may be already present or show multiple times in the iterator. @@ -2090,9 +2119,10 @@ impl Extend<(K, V)> for HashMap } impl<'a, K, V, S> Extend<(&'a K, &'a V)> for HashMap - where K: Eq + Hash + Copy, - V: Copy, - S: BuildHasher +where + K: Eq + Hash + Copy, + V: Copy, + S: BuildHasher, { fn extend>(&mut self, iter: T) { self.extend(iter.into_iter().map(|(&key, &value)| (key, value))); @@ -2102,16 +2132,18 @@ impl<'a, K, V, S> Extend<(&'a K, &'a V)> for HashMap // FORK NOTE: These can be reused pub use std::collections::hash_map::{DefaultHasher, RandomState}; - impl super::Recover for HashMap - where K: Eq + Hash + Borrow, - S: BuildHasher, - Q: Eq + Hash +where + K: Eq + Hash + Borrow, + S: BuildHasher, + Q: Eq + Hash, { type Key = K; fn get(&self, key: &Q) -> Option<&K> { - self.search(key).into_occupied_bucket().map(|bucket| bucket.into_refs().0) + self.search(key) + .into_occupied_bucket() + .map(|bucket| bucket.into_refs().0) } fn take(&mut self, key: &Q) -> Option { @@ -2119,7 +2151,9 @@ impl super::Recover for HashMap return None; } - self.search_mut(key).into_occupied_bucket().map(|bucket| pop_internal(bucket).0) + self.search_mut(key) + .into_occupied_bucket() + .map(|bucket| pop_internal(bucket).0) } fn replace(&mut self, key: K) -> Option { @@ -2129,11 +2163,11 @@ impl super::Recover for HashMap Occupied(mut occupied) => { let key = occupied.take_key().unwrap(); Some(mem::replace(occupied.elem.read_mut().0, key)) - } + }, Vacant(vacant) => { vacant.insert(()); None - } + }, } } } @@ -2170,8 +2204,9 @@ fn assert_covariance() { fn values_val<'a, 'new>(v: Values<'a, u8, &'static str>) -> Values<'a, u8, &'new str> { v } - fn drain<'new>(d: Drain<'static, &'static str, &'static str>) - -> Drain<'new, &'new str, &'new str> { + fn drain<'new>( + d: Drain<'static, &'static str, &'static str>, + ) -> Drain<'new, &'new str, &'new str> { d } } @@ -2319,19 +2354,19 @@ mod test_map { DROP_VECTOR.with(|v| { assert_eq!(v.borrow()[i], 1); - assert_eq!(v.borrow()[i+100], 1); + assert_eq!(v.borrow()[i + 100], 1); }); } DROP_VECTOR.with(|v| { for i in 0..50 { assert_eq!(v.borrow()[i], 0); - assert_eq!(v.borrow()[i+100], 0); + assert_eq!(v.borrow()[i + 100], 0); } for i in 50..100 { assert_eq!(v.borrow()[i], 1); - assert_eq!(v.borrow()[i+100], 1); + assert_eq!(v.borrow()[i + 100], 1); } }); } @@ -2388,13 +2423,9 @@ mod test_map { for _ in half.by_ref() {} DROP_VECTOR.with(|v| { - let nk = (0..100) - .filter(|&i| v.borrow()[i] == 1) - .count(); + let nk = (0..100).filter(|&i| v.borrow()[i] == 1).count(); - let nv = (0..100) - .filter(|&i| v.borrow()[i + 100] == 1) - .count(); + let nv = (0..100).filter(|&i| v.borrow()[i + 100] == 1).count(); assert_eq!(nk, 50); assert_eq!(nv, 50); @@ -2419,7 +2450,7 @@ mod test_map { let mut m: HashMap = HashMap::new(); match m.entry(0) { Occupied(_) => panic!(), - Vacant(_) => {} + Vacant(_) => {}, } assert!(*m.entry(0).or_insert(true)); assert_eq!(m.len(), 1); @@ -2574,7 +2605,7 @@ mod test_map { fn test_iterate() { let mut m = HashMap::with_capacity(4); for i in 0..32 { - assert!(m.insert(i, i*2).is_none()); + assert!(m.insert(i, i * 2).is_none()); } assert_eq!(m.len(), 32); @@ -2662,8 +2693,7 @@ mod test_map { let map_str = format!("{:?}", map); - assert!(map_str == "{1: 2, 3: 4}" || - map_str == "{3: 4, 1: 2}"); + assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}"); assert_eq!(format!("{:?}", empty), "{}"); } @@ -2876,12 +2906,11 @@ mod test_map { Occupied(mut view) => { assert_eq!(view.get(), &10); assert_eq!(view.insert(100), 10); - } + }, } assert_eq!(map.get(&1).unwrap(), &100); assert_eq!(map.len(), 6); - // Existing key (update) match map.entry(2) { Vacant(_) => unreachable!(), @@ -2889,7 +2918,7 @@ mod test_map { let v = view.get_mut(); let new_v = (*v) * 10; *v = new_v; - } + }, } assert_eq!(map.get(&2).unwrap(), &200); assert_eq!(map.len(), 6); @@ -2899,18 +2928,17 @@ mod test_map { Vacant(_) => unreachable!(), Occupied(view) => { assert_eq!(view.remove(), 30); - } + }, } assert_eq!(map.get(&3), None); assert_eq!(map.len(), 5); - // Inexistent key (insert) match map.entry(10) { Occupied(_) => unreachable!(), Vacant(view) => { assert_eq!(*view.insert(1000), 1000); - } + }, } assert_eq!(map.get(&10).unwrap(), &1000); assert_eq!(map.len(), 6); @@ -2919,11 +2947,10 @@ mod test_map { #[test] fn test_entry_take_doesnt_corrupt() { #![allow(deprecated)] //rand - // Test for #19292 + // Test for #19292 fn check(m: &HashMap) { for k in m.keys() { - assert!(m.contains_key(k), - "{} is in keys() but not in the map?", k); + assert!(m.contains_key(k), "{} is in keys() but not in the map?", k); } } @@ -2939,11 +2966,11 @@ mod test_map { for i in 0..1000 { let x = rng.gen_range(-10, 10); match m.entry(x) { - Vacant(_) => {} + Vacant(_) => {}, Occupied(e) => { println!("{}: remove {}", i, x); e.remove(); - } + }, } check(&m); @@ -3021,7 +3048,7 @@ mod test_map { Vacant(e) => { assert_eq!(key, *e.key()); e.insert(value.clone()); - } + }, } assert_eq!(a.len(), 1); assert_eq!(a[key], value); @@ -3029,7 +3056,7 @@ mod test_map { #[test] fn test_retain() { - let mut map: HashMap = (0..100).map(|x|(x, x*10)).collect(); + let mut map: HashMap = (0..100).map(|x| (x, x * 10)).collect(); map.retain(|&k, _| k % 2 == 0); assert_eq!(map.len(), 50); diff --git a/components/hashglobe/src/hash_set.rs b/components/hashglobe/src/hash_set.rs index 2139b58a601..34e657e44fc 100644 --- a/components/hashglobe/src/hash_set.rs +++ b/components/hashglobe/src/hash_set.rs @@ -122,8 +122,9 @@ pub struct HashSet { } impl HashSet - where T: Eq + Hash, - S: BuildHasher +where + T: Eq + Hash, + S: BuildHasher, { /// Creates a new empty hash set which will use the given hasher to hash /// keys. @@ -147,7 +148,9 @@ impl HashSet /// ``` #[inline] pub fn with_hasher(hasher: S) -> HashSet { - HashSet { map: HashMap::with_hasher(hasher) } + HashSet { + map: HashMap::with_hasher(hasher), + } } /// Creates an empty `HashSet` with with the specified capacity, using @@ -173,7 +176,9 @@ impl HashSet /// ``` #[inline] pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> HashSet { - HashSet { map: HashMap::with_capacity_and_hasher(capacity, hasher) } + HashSet { + map: HashMap::with_capacity_and_hasher(capacity, hasher), + } } /// Returns a reference to the set's [`BuildHasher`]. @@ -265,7 +270,9 @@ impl HashSet /// } /// ``` pub fn iter(&self) -> Iter { - Iter { iter: self.map.keys() } + Iter { + iter: self.map.keys(), + } } /// Visits the values representing the difference, @@ -319,10 +326,13 @@ impl HashSet /// assert_eq!(diff1, diff2); /// assert_eq!(diff1, [1, 4].iter().collect()); /// ``` - pub fn symmetric_difference<'a>(&'a self, - other: &'a HashSet) - -> SymmetricDifference<'a, T, S> { - SymmetricDifference { iter: self.difference(other).chain(other.difference(self)) } + pub fn symmetric_difference<'a>( + &'a self, + other: &'a HashSet, + ) -> SymmetricDifference<'a, T, S> { + SymmetricDifference { + iter: self.difference(other).chain(other.difference(self)), + } } /// Visits the values representing the intersection, @@ -369,7 +379,9 @@ impl HashSet /// assert_eq!(union, [1, 2, 3, 4].iter().collect()); /// ``` pub fn union<'a>(&'a self, other: &'a HashSet) -> Union<'a, T, S> { - Union { iter: self.iter().chain(other.difference(self)) } + Union { + iter: self.iter().chain(other.difference(self)), + } } /// Returns the number of elements in the set. @@ -423,7 +435,9 @@ impl HashSet /// ``` #[inline] pub fn drain(&mut self) -> Drain { - Drain { iter: self.map.drain() } + Drain { + iter: self.map.drain(), + } } /// Clears the set, removing all values. @@ -438,7 +452,10 @@ impl HashSet /// v.clear(); /// assert!(v.is_empty()); /// ``` - pub fn clear(&mut self) where T: 'static { + pub fn clear(&mut self) + where + T: 'static, + { self.map.clear() } @@ -461,8 +478,9 @@ impl HashSet /// [`Eq`]: ../../std/cmp/trait.Eq.html /// [`Hash`]: ../../std/hash/trait.Hash.html pub fn contains(&self, value: &Q) -> bool - where T: Borrow, - Q: Hash + Eq + where + T: Borrow, + Q: Hash + Eq, { self.map.contains_key(value) } @@ -476,8 +494,9 @@ impl HashSet /// [`Eq`]: ../../std/cmp/trait.Eq.html /// [`Hash`]: ../../std/hash/trait.Hash.html pub fn get(&self, value: &Q) -> Option<&T> - where T: Borrow, - Q: Hash + Eq + where + T: Borrow, + Q: Hash + Eq, { Recover::get(&self.map, value) } @@ -598,8 +617,9 @@ impl HashSet /// [`Eq`]: ../../std/cmp/trait.Eq.html /// [`Hash`]: ../../std/hash/trait.Hash.html pub fn remove(&mut self, value: &Q) -> bool - where T: Borrow, - Q: Hash + Eq + where + T: Borrow, + Q: Hash + Eq, { self.map.remove(value).is_some() } @@ -613,8 +633,9 @@ impl HashSet /// [`Eq`]: ../../std/cmp/trait.Eq.html /// [`Hash`]: ../../std/hash/trait.Hash.html pub fn take(&mut self, value: &Q) -> Option - where T: Borrow, - Q: Hash + Eq + where + T: Borrow, + Q: Hash + Eq, { Recover::take(&mut self.map, value) } @@ -634,15 +655,17 @@ impl HashSet /// assert_eq!(set.len(), 3); /// ``` pub fn retain(&mut self, mut f: F) - where F: FnMut(&T) -> bool + where + F: FnMut(&T) -> bool, { self.map.retain(|k, _| f(k)); } } impl PartialEq for HashSet - where T: Eq + Hash, - S: BuildHasher +where + T: Eq + Hash, + S: BuildHasher, { fn eq(&self, other: &HashSet) -> bool { if self.len() != other.len() { @@ -654,14 +677,16 @@ impl PartialEq for HashSet } impl Eq for HashSet - where T: Eq + Hash, - S: BuildHasher +where + T: Eq + Hash, + S: BuildHasher, { } impl fmt::Debug for HashSet - where T: Eq + Hash + fmt::Debug, - S: BuildHasher +where + T: Eq + Hash + fmt::Debug, + S: BuildHasher, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_set().entries(self.iter()).finish() @@ -669,8 +694,9 @@ impl fmt::Debug for HashSet } impl FromIterator for HashSet - where T: Eq + Hash, - S: BuildHasher + Default +where + T: Eq + Hash, + S: BuildHasher + Default, { fn from_iter>(iter: I) -> HashSet { let mut set = HashSet::with_hasher(Default::default()); @@ -680,8 +706,9 @@ impl FromIterator for HashSet } impl Extend for HashSet - where T: Eq + Hash, - S: BuildHasher +where + T: Eq + Hash, + S: BuildHasher, { fn extend>(&mut self, iter: I) { self.map.extend(iter.into_iter().map(|k| (k, ()))); @@ -689,8 +716,9 @@ impl Extend for HashSet } impl<'a, T, S> Extend<&'a T> for HashSet - where T: 'a + Eq + Hash + Copy, - S: BuildHasher +where + T: 'a + Eq + Hash + Copy, + S: BuildHasher, { fn extend>(&mut self, iter: I) { self.extend(iter.into_iter().cloned()); @@ -698,18 +726,22 @@ impl<'a, T, S> Extend<&'a T> for HashSet } impl Default for HashSet - where T: Eq + Hash, - S: BuildHasher + Default +where + T: Eq + Hash, + S: BuildHasher + Default, { /// Creates an empty `HashSet` with the `Default` value for the hasher. fn default() -> HashSet { - HashSet { map: HashMap::default() } + HashSet { + map: HashMap::default(), + } } } impl<'a, 'b, T, S> BitOr<&'b HashSet> for &'a HashSet - where T: Eq + Hash + Clone, - S: BuildHasher + Default +where + T: Eq + Hash + Clone, + S: BuildHasher + Default, { type Output = HashSet; @@ -739,8 +771,9 @@ impl<'a, 'b, T, S> BitOr<&'b HashSet> for &'a HashSet } impl<'a, 'b, T, S> BitAnd<&'b HashSet> for &'a HashSet - where T: Eq + Hash + Clone, - S: BuildHasher + Default +where + T: Eq + Hash + Clone, + S: BuildHasher + Default, { type Output = HashSet; @@ -770,8 +803,9 @@ impl<'a, 'b, T, S> BitAnd<&'b HashSet> for &'a HashSet } impl<'a, 'b, T, S> BitXor<&'b HashSet> for &'a HashSet - where T: Eq + Hash + Clone, - S: BuildHasher + Default +where + T: Eq + Hash + Clone, + S: BuildHasher + Default, { type Output = HashSet; @@ -801,8 +835,9 @@ impl<'a, 'b, T, S> BitXor<&'b HashSet> for &'a HashSet } impl<'a, 'b, T, S> Sub<&'b HashSet> for &'a HashSet - where T: Eq + Hash + Clone, - S: BuildHasher + Default +where + T: Eq + Hash + Clone, + S: BuildHasher + Default, { type Output = HashSet; @@ -915,8 +950,9 @@ pub struct Union<'a, T: 'a, S: 'a> { } impl<'a, T, S> IntoIterator for &'a HashSet - where T: Eq + Hash, - S: BuildHasher +where + T: Eq + Hash, + S: BuildHasher, { type Item = &'a T; type IntoIter = Iter<'a, T>; @@ -927,8 +963,9 @@ impl<'a, T, S> IntoIterator for &'a HashSet } impl IntoIterator for HashSet - where T: Eq + Hash, - S: BuildHasher +where + T: Eq + Hash, + S: BuildHasher, { type Item = T; type IntoIter = IntoIter; @@ -954,13 +991,17 @@ impl IntoIterator for HashSet /// } /// ``` fn into_iter(self) -> IntoIter { - IntoIter { iter: self.map.into_iter() } + IntoIter { + iter: self.map.into_iter(), + } } } impl<'a, K> Clone for Iter<'a, K> { fn clone(&self) -> Iter<'a, K> { - Iter { iter: self.iter.clone() } + Iter { + iter: self.iter.clone(), + } } } impl<'a, K> Iterator for Iter<'a, K> { @@ -1003,10 +1044,7 @@ impl ExactSizeIterator for IntoIter { impl fmt::Debug for IntoIter { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let entries_iter = self.iter - .inner - .iter() - .map(|(k, _)| k); + let entries_iter = self.iter.inner.iter().map(|(k, _)| k); f.debug_list().entries(entries_iter).finish() } } @@ -1029,23 +1067,24 @@ impl<'a, K> ExactSizeIterator for Drain<'a, K> { impl<'a, K: fmt::Debug> fmt::Debug for Drain<'a, K> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let entries_iter = self.iter - .inner - .iter() - .map(|(k, _)| k); + let entries_iter = self.iter.inner.iter().map(|(k, _)| k); f.debug_list().entries(entries_iter).finish() } } impl<'a, T, S> Clone for Intersection<'a, T, S> { fn clone(&self) -> Intersection<'a, T, S> { - Intersection { iter: self.iter.clone(), ..*self } + Intersection { + iter: self.iter.clone(), + ..*self + } } } impl<'a, T, S> Iterator for Intersection<'a, T, S> - where T: Eq + Hash, - S: BuildHasher +where + T: Eq + Hash, + S: BuildHasher, { type Item = &'a T; @@ -1065,8 +1104,9 @@ impl<'a, T, S> Iterator for Intersection<'a, T, S> } impl<'a, T, S> fmt::Debug for Intersection<'a, T, S> - where T: fmt::Debug + Eq + Hash, - S: BuildHasher +where + T: fmt::Debug + Eq + Hash, + S: BuildHasher, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_list().entries(self.clone()).finish() @@ -1075,13 +1115,17 @@ impl<'a, T, S> fmt::Debug for Intersection<'a, T, S> impl<'a, T, S> Clone for Difference<'a, T, S> { fn clone(&self) -> Difference<'a, T, S> { - Difference { iter: self.iter.clone(), ..*self } + Difference { + iter: self.iter.clone(), + ..*self + } } } impl<'a, T, S> Iterator for Difference<'a, T, S> - where T: Eq + Hash, - S: BuildHasher +where + T: Eq + Hash, + S: BuildHasher, { type Item = &'a T; @@ -1101,8 +1145,9 @@ impl<'a, T, S> Iterator for Difference<'a, T, S> } impl<'a, T, S> fmt::Debug for Difference<'a, T, S> - where T: fmt::Debug + Eq + Hash, - S: BuildHasher +where + T: fmt::Debug + Eq + Hash, + S: BuildHasher, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_list().entries(self.clone()).finish() @@ -1111,13 +1156,16 @@ impl<'a, T, S> fmt::Debug for Difference<'a, T, S> impl<'a, T, S> Clone for SymmetricDifference<'a, T, S> { fn clone(&self) -> SymmetricDifference<'a, T, S> { - SymmetricDifference { iter: self.iter.clone() } + SymmetricDifference { + iter: self.iter.clone(), + } } } impl<'a, T, S> Iterator for SymmetricDifference<'a, T, S> - where T: Eq + Hash, - S: BuildHasher +where + T: Eq + Hash, + S: BuildHasher, { type Item = &'a T; @@ -1130,8 +1178,9 @@ impl<'a, T, S> Iterator for SymmetricDifference<'a, T, S> } impl<'a, T, S> fmt::Debug for SymmetricDifference<'a, T, S> - where T: fmt::Debug + Eq + Hash, - S: BuildHasher +where + T: fmt::Debug + Eq + Hash, + S: BuildHasher, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_list().entries(self.clone()).finish() @@ -1140,13 +1189,16 @@ impl<'a, T, S> fmt::Debug for SymmetricDifference<'a, T, S> impl<'a, T, S> Clone for Union<'a, T, S> { fn clone(&self) -> Union<'a, T, S> { - Union { iter: self.iter.clone() } + Union { + iter: self.iter.clone(), + } } } impl<'a, T, S> fmt::Debug for Union<'a, T, S> - where T: fmt::Debug + Eq + Hash, - S: BuildHasher +where + T: fmt::Debug + Eq + Hash, + S: BuildHasher, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_list().entries(self.clone()).finish() @@ -1154,8 +1206,9 @@ impl<'a, T, S> fmt::Debug for Union<'a, T, S> } impl<'a, T, S> Iterator for Union<'a, T, S> - where T: Eq + Hash, - S: BuildHasher +where + T: Eq + Hash, + S: BuildHasher, { type Item = &'a T; @@ -1178,20 +1231,24 @@ fn assert_covariance() { fn into_iter<'new>(v: IntoIter<&'static str>) -> IntoIter<&'new str> { v } - fn difference<'a, 'new>(v: Difference<'a, &'static str, RandomState>) - -> Difference<'a, &'new str, RandomState> { + fn difference<'a, 'new>( + v: Difference<'a, &'static str, RandomState>, + ) -> Difference<'a, &'new str, RandomState> { v } - fn symmetric_difference<'a, 'new>(v: SymmetricDifference<'a, &'static str, RandomState>) - -> SymmetricDifference<'a, &'new str, RandomState> { + fn symmetric_difference<'a, 'new>( + v: SymmetricDifference<'a, &'static str, RandomState>, + ) -> SymmetricDifference<'a, &'new str, RandomState> { v } - fn intersection<'a, 'new>(v: Intersection<'a, &'static str, RandomState>) - -> Intersection<'a, &'new str, RandomState> { + fn intersection<'a, 'new>( + v: Intersection<'a, &'static str, RandomState>, + ) -> Intersection<'a, &'new str, RandomState> { v } - fn union<'a, 'new>(v: Union<'a, &'static str, RandomState>) - -> Union<'a, &'new str, RandomState> { + fn union<'a, 'new>( + v: Union<'a, &'static str, RandomState>, + ) -> Union<'a, &'new str, RandomState> { v } fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { diff --git a/components/hashglobe/src/lib.rs b/components/hashglobe/src/lib.rs index 49038a51859..cf6e9710f5f 100644 --- a/components/hashglobe/src/lib.rs +++ b/components/hashglobe/src/lib.rs @@ -44,7 +44,10 @@ pub struct FailedAllocationError { impl FailedAllocationError { #[inline] pub fn new(reason: &'static str) -> Self { - Self { reason, allocation_info: None } + Self { + reason, + allocation_info: None, + } } } @@ -57,9 +60,11 @@ impl error::Error for FailedAllocationError { impl fmt::Display for FailedAllocationError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.allocation_info { - Some(ref info) => { - write!(f, "{}, allocation: (size: {}, alignment: {})", self.reason, info.size, info.alignment) - }, + Some(ref info) => write!( + f, + "{}, allocation: (size: {}, alignment: {})", + self.reason, info.size, info.alignment + ), None => self.reason.fmt(f), } } diff --git a/components/hashglobe/src/shim.rs b/components/hashglobe/src/shim.rs index 146ff851a0e..855dbdcfa15 100644 --- a/components/hashglobe/src/shim.rs +++ b/components/hashglobe/src/shim.rs @@ -29,11 +29,11 @@ impl Unique { } } -unsafe impl Send for Unique { } +unsafe impl Send for Unique {} -unsafe impl Sync for Unique { } +unsafe impl Sync for Unique {} -pub struct Shared { +pub struct Shared { ptr: NonZeroPtr, _marker: PhantomData, // force it to be !Send/!Sync diff --git a/components/hashglobe/src/table.rs b/components/hashglobe/src/table.rs index bd801b43544..0b8b49001e2 100644 --- a/components/hashglobe/src/table.rs +++ b/components/hashglobe/src/table.rs @@ -203,7 +203,9 @@ impl SafeHash { // // Truncate hash to fit in `HashUint`. let hash_bits = size_of::() * 8; - SafeHash { hash: (1 << (hash_bits - 1)) | (hash as HashUint) } + SafeHash { + hash: (1 << (hash_bits - 1)) | (hash as HashUint), + } } } @@ -211,8 +213,9 @@ impl SafeHash { /// This function wraps up `hash_keyed` to be the only way outside this /// module to generate a SafeHash. pub fn make_hash(hash_state: &S, t: &T) -> SafeHash - where T: Hash, - S: BuildHasher +where + T: Hash, + S: BuildHasher, { let mut state = hash_state.build_hasher(); t.hash(&mut state); @@ -294,7 +297,8 @@ impl Bucket { } impl Deref for FullBucket - where M: Deref> +where + M: Deref>, { type Target = RawTable; fn deref(&self) -> &RawTable { @@ -308,7 +312,6 @@ pub trait Put { unsafe fn borrow_table_mut(&mut self) -> &mut RawTable; } - impl<'t, K, V> Put for &'t mut RawTable { unsafe fn borrow_table_mut(&mut self) -> &mut RawTable { *self @@ -316,7 +319,8 @@ impl<'t, K, V> Put for &'t mut RawTable { } impl Put for Bucket - where M: Put +where + M: Put, { unsafe fn borrow_table_mut(&mut self) -> &mut RawTable { self.table.borrow_table_mut() @@ -324,7 +328,8 @@ impl Put for Bucket } impl Put for FullBucket - where M: Put +where + M: Put, { unsafe fn borrow_table_mut(&mut self) -> &mut RawTable { self.table.borrow_table_mut() @@ -336,20 +341,17 @@ impl>> Bucket { Bucket::at_index(table, hash.inspect() as usize) } - pub fn new_from(r: RawBucket, t: M) - -> Bucket - { - Bucket { - raw: r, - table: t, - } + pub fn new_from(r: RawBucket, t: M) -> Bucket { + Bucket { raw: r, table: t } } pub fn at_index(table: M, ib_index: usize) -> Bucket { // if capacity is 0, then the RawBucket will be populated with bogus pointers. // This is an uncommon case though, so avoid it in release builds. - debug_assert!(table.capacity() > 0, - "Table should have capacity at this point"); + debug_assert!( + table.capacity() > 0, + "Table should have capacity at this point" + ); let ib_index = ib_index & table.capacity_mask; Bucket { raw: table.raw_bucket_at(ib_index), @@ -387,11 +389,11 @@ impl>> Bucket { } // Leaving this bucket in the last cluster for later. full.into_bucket() - } + }, Empty(b) => { // Encountered a hole between clusters. b.into_bucket() - } + }, }; bucket.next(); } @@ -404,18 +406,14 @@ impl>> Bucket { /// this module. pub fn peek(self) -> BucketState { match unsafe { *self.raw.hash() } { - EMPTY_BUCKET => { - Empty(EmptyBucket { - raw: self.raw, - table: self.table, - }) - } - _ => { - Full(FullBucket { - raw: self.raw, - table: self.table, - }) - } + EMPTY_BUCKET => Empty(EmptyBucket { + raw: self.raw, + table: self.table, + }), + _ => Full(FullBucket { + raw: self.raw, + table: self.table, + }), } } @@ -453,19 +451,15 @@ impl>> EmptyBucket { }; match self.next().peek() { - Full(bucket) => { - Ok(GapThenFull { - gap, - full: bucket, - }) - } + Full(bucket) => Ok(GapThenFull { gap, full: bucket }), Empty(e) => Err(e.into_bucket()), } } } impl EmptyBucket - where M: Put +where + M: Put, { /// Puts given key and value pair, along with the key's hash, /// into this bucket in the hashtable. Note how `self` is 'moved' into @@ -528,7 +522,11 @@ impl>> FullBucket { #[inline] pub fn hash(&self) -> SafeHash { - unsafe { SafeHash { hash: *self.raw.hash() } } + unsafe { + SafeHash { + hash: *self.raw.hash(), + } + } } /// Gets references to the key and value at a given index. @@ -554,12 +552,14 @@ impl<'t, K, V> FullBucket> { unsafe { *self.raw.hash() = EMPTY_BUCKET; let (k, v) = ptr::read(self.raw.pair()); - (EmptyBucket { - raw: self.raw, - table: self.table, - }, - k, - v) + ( + EmptyBucket { + raw: self.raw, + table: self.table, + }, + k, + v, + ) } } } @@ -567,7 +567,8 @@ impl<'t, K, V> FullBucket> { // This use of `Put` is misleading and restrictive, but safe and sufficient for our use cases // where `M` is a full bucket or table reference type with mutable access to the table. impl FullBucket - where M: Put +where + M: Put, { pub fn replace(&mut self, h: SafeHash, k: K, v: V) -> (SafeHash, K, V) { unsafe { @@ -580,7 +581,8 @@ impl FullBucket } impl FullBucket - where M: Deref> + DerefMut +where + M: Deref> + DerefMut, { /// Gets mutable references to the key and value at a given index. pub fn read_mut(&mut self) -> (&mut K, &mut V) { @@ -592,7 +594,8 @@ impl FullBucket } impl<'t, K, V, M> FullBucket - where M: Deref> + 't +where + M: Deref> + 't, { /// Exchange a bucket state for immutable references into the table. /// Because the underlying reference to the table is also consumed, @@ -608,7 +611,8 @@ impl<'t, K, V, M> FullBucket } impl<'t, K, V, M> FullBucket - where M: Deref> + DerefMut + 't +where + M: Deref> + DerefMut + 't, { /// This works similarly to `into_refs`, exchanging a bucket state /// for mutable references into the table. @@ -621,7 +625,8 @@ impl<'t, K, V, M> FullBucket } impl GapThenFull - where M: Deref> +where + M: Deref>, { #[inline] pub fn full(&self) -> &FullBucket { @@ -649,13 +654,12 @@ impl GapThenFull self.full = bucket; Ok(self) - } + }, Empty(b) => Err(b.into_bucket()), } } } - /// Rounds up to a multiple of a power of two. Returns the closest multiple /// of `target_alignment` that is higher or equal to `unrounded`. /// @@ -681,10 +685,11 @@ fn test_rounding() { // Returns a tuple of (pairs_offset, end_of_pairs_offset), // from the start of a mallocated array. #[inline] -fn calculate_offsets(hashes_size: usize, - pairs_size: usize, - pairs_align: usize) - -> (usize, usize, bool) { +fn calculate_offsets( + hashes_size: usize, + pairs_size: usize, + pairs_align: usize, +) -> (usize, usize, bool) { let pairs_offset = round_up_to_next(hashes_size, pairs_align); let (end_of_pairs, oflo) = pairs_offset.overflowing_add(pairs_size); @@ -693,11 +698,12 @@ fn calculate_offsets(hashes_size: usize, // Returns a tuple of (minimum required malloc alignment, hash_offset, // array_size), from the start of a mallocated array. -fn calculate_allocation(hash_size: usize, - hash_align: usize, - pairs_size: usize, - pairs_align: usize) - -> (usize, usize, usize, bool) { +fn calculate_allocation( + hash_size: usize, + hash_align: usize, + pairs_size: usize, + pairs_align: usize, +) -> (usize, usize, usize, bool) { let hash_offset = 0; let (_, end_of_pairs, oflo) = calculate_offsets(hash_size, pairs_size, pairs_align); @@ -728,7 +734,9 @@ impl RawTable { /// Does not initialize the buckets. The caller should ensure they, /// at the very least, set every hash to EMPTY_BUCKET. - unsafe fn try_new_uninitialized(capacity: usize) -> Result, FailedAllocationError> { + unsafe fn try_new_uninitialized( + capacity: usize, + ) -> Result, FailedAllocationError> { if capacity == 0 { return Ok(RawTable { size: 0, @@ -751,29 +759,38 @@ impl RawTable { // This is great in theory, but in practice getting the alignment // right is a little subtle. Therefore, calculating offsets has been // factored out into a different function. - let (alignment, hash_offset, size, oflo) = calculate_allocation(hashes_size, - align_of::(), - pairs_size, - align_of::<(K, V)>()); + let (alignment, hash_offset, size, oflo) = calculate_allocation( + hashes_size, + align_of::(), + pairs_size, + align_of::<(K, V)>(), + ); if oflo { - return Err(FailedAllocationError::new("capacity overflow when allocating RawTable" )); + return Err(FailedAllocationError::new( + "capacity overflow when allocating RawTable", + )); } // One check for overflow that covers calculation and rounding of size. - let size_of_bucket = size_of::().checked_add(size_of::<(K, V)>()).unwrap(); + let size_of_bucket = size_of::() + .checked_add(size_of::<(K, V)>()) + .unwrap(); let cap_bytes = capacity.checked_mul(size_of_bucket); if let Some(cap_bytes) = cap_bytes { if size < cap_bytes { - return Err(FailedAllocationError::new("capacity overflow when allocating RawTable")); + return Err(FailedAllocationError::new( + "capacity overflow when allocating RawTable", + )); } } else { - return Err(FailedAllocationError::new("capacity overflow when allocating RawTable")); + return Err(FailedAllocationError::new( + "capacity overflow when allocating RawTable", + )); } - // FORK NOTE: Uses alloc shim instead of Heap.alloc let buffer = alloc(size, alignment); @@ -857,7 +874,9 @@ impl RawTable { } pub fn into_iter(self) -> IntoIter { - let RawBuckets { raw, elems_left, .. } = self.raw_buckets(); + let RawBuckets { + raw, elems_left, .. + } = self.raw_buckets(); // Replace the marker regardless of lifetime bounds on parameters. IntoIter { iter: RawBuckets { @@ -870,7 +889,9 @@ impl RawTable { } pub fn drain(&mut self) -> Drain { - let RawBuckets { raw, elems_left, .. } = self.raw_buckets(); + let RawBuckets { + raw, elems_left, .. + } = self.raw_buckets(); // Replace the marker regardless of lifetime bounds on parameters. Drain { iter: RawBuckets { @@ -937,7 +958,6 @@ impl<'a, K, V> Clone for RawBuckets<'a, K, V> { } } - impl<'a, K, V> Iterator for RawBuckets<'a, K, V> { type Item = RawBucket; @@ -1112,12 +1132,16 @@ impl<'a, K, V> Iterator for Drain<'a, K, V> { #[inline] fn next(&mut self) -> Option<(SafeHash, K, V)> { - self.iter.next().map(|raw| { - unsafe { - self.table.as_mut().size -= 1; - let (k, v) = ptr::read(raw.pair()); - (SafeHash { hash: ptr::replace(&mut *raw.hash(), EMPTY_BUCKET) }, k, v) - } + self.iter.next().map(|raw| unsafe { + self.table.as_mut().size -= 1; + let (k, v) = ptr::read(raw.pair()); + ( + SafeHash { + hash: ptr::replace(&mut *raw.hash(), EMPTY_BUCKET), + }, + k, + v, + ) }) } @@ -1181,17 +1205,19 @@ impl Drop for RawTable { unsafe { // FORK NOTE: Can't needs_drop on stable // if needs_drop::<(K, V)>() { - // avoid linear runtime for types that don't need drop - self.rev_drop_buckets(); + // avoid linear runtime for types that don't need drop + self.rev_drop_buckets(); // } } let hashes_size = self.capacity() * size_of::(); let pairs_size = self.capacity() * size_of::<(K, V)>(); - let (align, _, _, oflo) = calculate_allocation(hashes_size, - align_of::(), - pairs_size, - align_of::<(K, V)>()); + let (align, _, _, oflo) = calculate_allocation( + hashes_size, + align_of::(), + pairs_size, + align_of::<(K, V)>(), + ); debug_assert!(!oflo, "should be impossible"); diff --git a/components/jstraceable_derive/lib.rs b/components/jstraceable_derive/lib.rs index a780a6e2167..ac793f4d85a 100644 --- a/components/jstraceable_derive/lib.rs +++ b/components/jstraceable_derive/lib.rs @@ -3,15 +3,15 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ extern crate quote; -#[macro_use] extern crate syn; -#[macro_use] extern crate synstructure; +#[macro_use] +extern crate syn; +#[macro_use] +extern crate synstructure; decl_derive!([JSTraceable] => js_traceable_derive); fn js_traceable_derive(s: synstructure::Structure) -> quote::Tokens { - let match_body = s.each(|binding| { - Some(quote!(#binding.trace(tracer);)) - }); + let match_body = s.each(|binding| Some(quote!(#binding.trace(tracer);))); let ast = s.ast(); let name = ast.ident; @@ -19,7 +19,9 @@ fn js_traceable_derive(s: synstructure::Structure) -> quote::Tokens { let mut where_clause = where_clause.unwrap_or(&parse_quote!(where)).clone(); for param in ast.generics.type_params() { let ident = param.ident; - where_clause.predicates.push(parse_quote!(#ident: ::dom::bindings::trace::JSTraceable)) + where_clause + .predicates + .push(parse_quote!(#ident: ::dom::bindings::trace::JSTraceable)) } let tokens = quote! { diff --git a/components/layout/animation.rs b/components/layout/animation.rs index 3a09094b2a9..d8b305644c0 100644 --- a/components/layout/animation.rs +++ b/components/layout/animation.rs @@ -32,8 +32,7 @@ pub fn update_animation_state( new_animations_receiver: &Receiver, pipeline_id: PipelineId, timer: &Timer, -) -where +) where E: TElement, { let mut new_running_animations = vec![]; @@ -66,7 +65,7 @@ where if running_animations.is_empty() && new_running_animations.is_empty() { // Nothing to do. Return early so we don't flood the compositor with // `ChangeRunningAnimationsState` messages. - return + return; } let now = timer.seconds(); @@ -82,30 +81,32 @@ where let still_running = !running_animation.is_expired() && match running_animation { Animation::Transition(_, started_at, ref frame, _expired) => { now < started_at + frame.duration - } + }, Animation::Keyframes(_, _, _, ref mut state) => { // This animation is still running, or we need to keep // iterating. now < state.started_at + state.duration || state.tick() - } + }, }; if still_running { animations_still_running.push(running_animation); - continue + continue; } if let Animation::Transition(node, _, ref frame, _) = running_animation { - script_chan.send(ConstellationControlMsg::TransitionEnd(node.to_untrusted_node_address(), - frame.property_animation - .property_name().into(), - frame.duration)) - .unwrap(); + script_chan + .send(ConstellationControlMsg::TransitionEnd( + node.to_untrusted_node_address(), + frame.property_animation.property_name().into(), + frame.duration, + )).unwrap(); } - expired_animations.entry(*key) - .or_insert_with(Vec::new) - .push(running_animation); + expired_animations + .entry(*key) + .or_insert_with(Vec::new) + .push(running_animation); } if animations_still_running.is_empty() { @@ -125,16 +126,17 @@ where match newly_transitioning_nodes { Some(ref mut nodes) => { nodes.push(new_running_animation.node().to_untrusted_node_address()); - } + }, None => { warn!("New transition encountered from compositor-initiated layout."); - } + }, } } - running_animations.entry(*new_running_animation.node()) - .or_insert_with(Vec::new) - .push(new_running_animation) + running_animations + .entry(*new_running_animation.node()) + .or_insert_with(Vec::new) + .push(new_running_animation) } let animation_state = if running_animations.is_empty() { @@ -143,9 +145,11 @@ where AnimationState::AnimationsPresent }; - constellation_chan.send(ConstellationMsg::ChangeRunningAnimationsState(pipeline_id, - animation_state)) - .unwrap(); + constellation_chan + .send(ConstellationMsg::ChangeRunningAnimationsState( + pipeline_id, + animation_state, + )).unwrap(); } /// Recalculates style for a set of animations. This does *not* run with the DOM @@ -154,8 +158,7 @@ pub fn recalc_style_for_animations( context: &LayoutContext, flow: &mut Flow, animations: &FxHashMap>, -) -where +) where E: TElement, { let mut damage = RestyleDamage::empty(); @@ -170,10 +173,7 @@ where &ServoMetricsProvider, ); let difference = - RestyleDamage::compute_style_difference( - &old_style, - &fragment.style, - ); + RestyleDamage::compute_style_difference(&old_style, &fragment.style); damage |= difference.damage; } } diff --git a/components/layout/block.rs b/components/layout/block.rs index 00759909063..ae1bc242e32 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -93,15 +93,16 @@ struct BSizeConstraintSolution { block_start: Au, block_size: Au, margin_block_start: Au, - margin_block_end: Au + margin_block_end: Au, } impl BSizeConstraintSolution { - fn new(block_start: Au, - block_size: Au, - margin_block_start: Au, - margin_block_end: Au) - -> BSizeConstraintSolution { + fn new( + block_start: Au, + block_size: Au, + margin_block_start: Au, + margin_block_end: Au, + ) -> BSizeConstraintSolution { BSizeConstraintSolution { block_start: block_start, block_size: block_size, @@ -119,14 +120,15 @@ impl BSizeConstraintSolution { /// [aka available_block-size] /// /// Return the solution for the equation. - fn solve_vertical_constraints_abs_nonreplaced(block_size: MaybeAuto, - block_start_margin: MaybeAuto, - block_end_margin: MaybeAuto, - block_start: MaybeAuto, - block_end: MaybeAuto, - content_block_size: Au, - available_block_size: Au) - -> BSizeConstraintSolution { + fn solve_vertical_constraints_abs_nonreplaced( + block_size: MaybeAuto, + block_start_margin: MaybeAuto, + block_end_margin: MaybeAuto, + block_start: MaybeAuto, + block_end: MaybeAuto, + content_block_size: Au, + available_block_size: Au, + ) -> BSizeConstraintSolution { let (block_start, block_size, margin_block_start, margin_block_end) = match (block_start, block_end, block_size) { (MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Auto) => { @@ -137,64 +139,103 @@ impl BSizeConstraintSolution { let block_size = content_block_size; // Use a dummy value for `block_start`, since it has the static position. (Au(0), block_size, margin_block_start, margin_block_end) - } - (MaybeAuto::Specified(block_start), - MaybeAuto::Specified(block_end), - MaybeAuto::Specified(block_size)) => { + }, + ( + MaybeAuto::Specified(block_start), + MaybeAuto::Specified(block_end), + MaybeAuto::Specified(block_size), + ) => { match (block_start_margin, block_end_margin) { (MaybeAuto::Auto, MaybeAuto::Auto) => { let total_margin_val = available_block_size - block_start - block_end - block_size; - (block_start, - block_size, - total_margin_val.scale_by(0.5), - total_margin_val.scale_by(0.5)) - } + ( + block_start, + block_size, + total_margin_val.scale_by(0.5), + total_margin_val.scale_by(0.5), + ) + }, (MaybeAuto::Specified(margin_block_start), MaybeAuto::Auto) => { let sum = block_start + block_end + block_size + margin_block_start; - (block_start, - block_size, - margin_block_start, - available_block_size - sum) - } + ( + block_start, + block_size, + margin_block_start, + available_block_size - sum, + ) + }, (MaybeAuto::Auto, MaybeAuto::Specified(margin_block_end)) => { let sum = block_start + block_end + block_size + margin_block_end; - (block_start, block_size, available_block_size - sum, margin_block_end) - } - (MaybeAuto::Specified(margin_block_start), - MaybeAuto::Specified(margin_block_end)) => { + ( + block_start, + block_size, + available_block_size - sum, + margin_block_end, + ) + }, + ( + MaybeAuto::Specified(margin_block_start), + MaybeAuto::Specified(margin_block_end), + ) => { // Values are over-constrained. Ignore value for 'block-end'. - (block_start, block_size, margin_block_start, margin_block_end) - } + ( + block_start, + block_size, + margin_block_start, + margin_block_end, + ) + }, } - } + }, // For the rest of the cases, auto values for margin are set to 0 // If only one is Auto, solve for it - (MaybeAuto::Auto, - MaybeAuto::Specified(block_end), - MaybeAuto::Specified(block_size)) => { + ( + MaybeAuto::Auto, + MaybeAuto::Specified(block_end), + MaybeAuto::Specified(block_size), + ) => { let margin_block_start = block_start_margin.specified_or_zero(); let margin_block_end = block_end_margin.specified_or_zero(); let sum = block_end + block_size + margin_block_start + margin_block_end; - (available_block_size - sum, block_size, margin_block_start, margin_block_end) - } - (MaybeAuto::Specified(block_start), - MaybeAuto::Auto, - MaybeAuto::Specified(block_size)) => { + ( + available_block_size - sum, + block_size, + margin_block_start, + margin_block_end, + ) + }, + ( + MaybeAuto::Specified(block_start), + MaybeAuto::Auto, + MaybeAuto::Specified(block_size), + ) => { let margin_block_start = block_start_margin.specified_or_zero(); let margin_block_end = block_end_margin.specified_or_zero(); - (block_start, block_size, margin_block_start, margin_block_end) - } - (MaybeAuto::Specified(block_start), - MaybeAuto::Specified(block_end), - MaybeAuto::Auto) => { + ( + block_start, + block_size, + margin_block_start, + margin_block_end, + ) + }, + ( + MaybeAuto::Specified(block_start), + MaybeAuto::Specified(block_end), + MaybeAuto::Auto, + ) => { let margin_block_start = block_start_margin.specified_or_zero(); let margin_block_end = block_end_margin.specified_or_zero(); let sum = block_start + block_end + margin_block_start + margin_block_end; - (block_start, available_block_size - sum, margin_block_start, margin_block_end) - } + ( + block_start, + available_block_size - sum, + margin_block_start, + margin_block_end, + ) + }, // If block-size is auto, then block-size is content block-size. Solve for the // non-auto value. @@ -202,25 +243,40 @@ impl BSizeConstraintSolution { let margin_block_start = block_start_margin.specified_or_zero(); let margin_block_end = block_end_margin.specified_or_zero(); let block_size = content_block_size; - (block_start, block_size, margin_block_start, margin_block_end) - } + ( + block_start, + block_size, + margin_block_start, + margin_block_end, + ) + }, (MaybeAuto::Auto, MaybeAuto::Specified(block_end), MaybeAuto::Auto) => { let margin_block_start = block_start_margin.specified_or_zero(); let margin_block_end = block_end_margin.specified_or_zero(); let block_size = content_block_size; let sum = block_end + block_size + margin_block_start + margin_block_end; - (available_block_size - sum, block_size, margin_block_start, margin_block_end) - } + ( + available_block_size - sum, + block_size, + margin_block_start, + margin_block_end, + ) + }, (MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Specified(block_size)) => { let margin_block_start = block_start_margin.specified_or_zero(); let margin_block_end = block_end_margin.specified_or_zero(); // Use a dummy value for `block_start`, since it has the static position. (Au(0), block_size, margin_block_start, margin_block_end) - } + }, }; - BSizeConstraintSolution::new(block_start, block_size, margin_block_start, margin_block_end) + BSizeConstraintSolution::new( + block_start, + block_size, + margin_block_start, + margin_block_end, + ) } /// Solve the vertical constraint equation for absolute replaced elements. @@ -234,14 +290,15 @@ impl BSizeConstraintSolution { /// [aka available block-size] /// /// Return the solution for the equation. - fn solve_vertical_constraints_abs_replaced(block_size: Au, - block_start_margin: MaybeAuto, - block_end_margin: MaybeAuto, - block_start: MaybeAuto, - block_end: MaybeAuto, - _: Au, - available_block_size: Au) - -> BSizeConstraintSolution { + fn solve_vertical_constraints_abs_replaced( + block_size: Au, + block_start_margin: MaybeAuto, + block_end_margin: MaybeAuto, + block_start: MaybeAuto, + block_end: MaybeAuto, + _: Au, + available_block_size: Au, + ) -> BSizeConstraintSolution { let (block_start, block_size, margin_block_start, margin_block_end) = match (block_start, block_end) { (MaybeAuto::Auto, MaybeAuto::Auto) => { @@ -249,50 +306,81 @@ impl BSizeConstraintSolution { let margin_block_end = block_end_margin.specified_or_zero(); // Use a dummy value for `block_start`, since it has the static position. (Au(0), block_size, margin_block_start, margin_block_end) - } + }, (MaybeAuto::Specified(block_start), MaybeAuto::Specified(block_end)) => { match (block_start_margin, block_end_margin) { (MaybeAuto::Auto, MaybeAuto::Auto) => { - let total_margin_val = available_block_size - block_start - block_end - - block_size; - (block_start, - block_size, - total_margin_val.scale_by(0.5), - total_margin_val.scale_by(0.5)) - } + let total_margin_val = + available_block_size - block_start - block_end - block_size; + ( + block_start, + block_size, + total_margin_val.scale_by(0.5), + total_margin_val.scale_by(0.5), + ) + }, (MaybeAuto::Specified(margin_block_start), MaybeAuto::Auto) => { let sum = block_start + block_end + block_size + margin_block_start; - (block_start, - block_size, - margin_block_start, - available_block_size - sum) - } + ( + block_start, + block_size, + margin_block_start, + available_block_size - sum, + ) + }, (MaybeAuto::Auto, MaybeAuto::Specified(margin_block_end)) => { let sum = block_start + block_end + block_size + margin_block_end; - (block_start, block_size, available_block_size - sum, margin_block_end) - } - (MaybeAuto::Specified(margin_block_start), - MaybeAuto::Specified(margin_block_end)) => { + ( + block_start, + block_size, + available_block_size - sum, + margin_block_end, + ) + }, + ( + MaybeAuto::Specified(margin_block_start), + MaybeAuto::Specified(margin_block_end), + ) => { // Values are over-constrained. Ignore value for 'block-end'. - (block_start, block_size, margin_block_start, margin_block_end) - } + ( + block_start, + block_size, + margin_block_start, + margin_block_end, + ) + }, } - } + }, // If only one is Auto, solve for it (MaybeAuto::Auto, MaybeAuto::Specified(block_end)) => { let margin_block_start = block_start_margin.specified_or_zero(); let margin_block_end = block_end_margin.specified_or_zero(); let sum = block_end + block_size + margin_block_start + margin_block_end; - (available_block_size - sum, block_size, margin_block_start, margin_block_end) - } + ( + available_block_size - sum, + block_size, + margin_block_start, + margin_block_end, + ) + }, (MaybeAuto::Specified(block_start), MaybeAuto::Auto) => { let margin_block_start = block_start_margin.specified_or_zero(); let margin_block_end = block_end_margin.specified_or_zero(); - (block_start, block_size, margin_block_start, margin_block_end) - } + ( + block_start, + block_size, + margin_block_start, + margin_block_end, + ) + }, }; - BSizeConstraintSolution::new(block_start, block_size, margin_block_start, margin_block_end) + BSizeConstraintSolution::new( + block_start, + block_size, + margin_block_start, + margin_block_end, + ) } } @@ -314,21 +402,26 @@ impl CandidateBSizeIterator { /// Creates a new candidate block-size iterator. `block_container_block-size` is `None` if the block-size /// of the block container has not been determined yet. It will always be `Some` in the case of /// absolutely-positioned containing blocks. - pub fn new(fragment: &Fragment, block_container_block_size: Option) - -> CandidateBSizeIterator { + pub fn new( + fragment: &Fragment, + block_container_block_size: Option, + ) -> CandidateBSizeIterator { // Per CSS 2.1 § 10.7, (assuming an horizontal writing mode,) // percentages in `min-height` and `max-height` refer to the height of // the containing block. // If that is not determined yet by the time we need to resolve // `min-height` and `max-height`, percentage values are ignored. - let block_size = match (fragment.style.content_block_size(), block_container_block_size) { + let block_size = match ( + fragment.style.content_block_size(), + block_container_block_size, + ) { (LengthOrPercentageOrAuto::Percentage(percent), Some(block_container_block_size)) => { MaybeAuto::Specified(block_container_block_size.scale_by(percent.0)) - } + }, (LengthOrPercentageOrAuto::Calc(calc), _) => { MaybeAuto::from_option(calc.to_used_value(block_container_block_size)) - } + }, (LengthOrPercentageOrAuto::Percentage(_), None) | (LengthOrPercentageOrAuto::Auto, _) => MaybeAuto::Auto, (LengthOrPercentageOrAuto::Length(length), _) => MaybeAuto::Specified(Au::from(length)), @@ -336,10 +429,10 @@ impl CandidateBSizeIterator { let max_block_size = match (fragment.style.max_block_size(), block_container_block_size) { (LengthOrPercentageOrNone::Percentage(percent), Some(block_container_block_size)) => { Some(block_container_block_size.scale_by(percent.0)) - } + }, (LengthOrPercentageOrNone::Calc(calc), _) => { calc.to_used_value(block_container_block_size) - } + }, (LengthOrPercentageOrNone::Percentage(_), None) | (LengthOrPercentageOrNone::None, _) => None, (LengthOrPercentageOrNone::Length(length), _) => Some(Au::from(length)), @@ -347,10 +440,10 @@ impl CandidateBSizeIterator { let min_block_size = match (fragment.style.min_block_size(), block_container_block_size) { (LengthOrPercentage::Percentage(percent), Some(block_container_block_size)) => { block_container_block_size.scale_by(percent.0) - } - (LengthOrPercentage::Calc(calc), _) => { - calc.to_used_value(block_container_block_size).unwrap_or(Au(0)) - } + }, + (LengthOrPercentage::Calc(calc), _) => calc + .to_used_value(block_container_block_size) + .unwrap_or(Au(0)), (LengthOrPercentage::Percentage(_), None) => Au(0), (LengthOrPercentage::Length(length), _) => Au::from(length), }; @@ -380,37 +473,35 @@ impl Iterator for CandidateBSizeIterator { fn next(&mut self) -> Option { self.status = match self.status { CandidateBSizeIteratorStatus::Initial => CandidateBSizeIteratorStatus::Trying, - CandidateBSizeIteratorStatus::Trying => { - match self.max_block_size { - Some(max_block_size) if self.candidate_value > max_block_size => { - CandidateBSizeIteratorStatus::TryingMax - } - _ if self.candidate_value < self.min_block_size => { - CandidateBSizeIteratorStatus::TryingMin - } - _ => CandidateBSizeIteratorStatus::Found, - } - } + CandidateBSizeIteratorStatus::Trying => match self.max_block_size { + Some(max_block_size) if self.candidate_value > max_block_size => { + CandidateBSizeIteratorStatus::TryingMax + }, + _ if self.candidate_value < self.min_block_size => { + CandidateBSizeIteratorStatus::TryingMin + }, + _ => CandidateBSizeIteratorStatus::Found, + }, CandidateBSizeIteratorStatus::TryingMax => { if self.candidate_value < self.min_block_size { CandidateBSizeIteratorStatus::TryingMin } else { CandidateBSizeIteratorStatus::Found } - } + }, CandidateBSizeIteratorStatus::TryingMin | CandidateBSizeIteratorStatus::Found => { CandidateBSizeIteratorStatus::Found - } + }, }; match self.status { CandidateBSizeIteratorStatus::Trying => Some(self.block_size), CandidateBSizeIteratorStatus::TryingMax => { Some(MaybeAuto::Specified(self.max_block_size.unwrap())) - } + }, CandidateBSizeIteratorStatus::TryingMin => { Some(MaybeAuto::Specified(self.min_block_size)) - } + }, CandidateBSizeIteratorStatus::Found => None, CandidateBSizeIteratorStatus::Initial => panic!(), } @@ -451,17 +542,25 @@ impl<'a> PreorderFlowTraversal for AbsoluteAssignBSizesTraversal<'a> { #[inline] fn process(&self, flow: &mut Flow) { if !flow.is_block_like() { - return + return; } // This flow might not be an absolutely positioned flow if it is the root of the tree. let block = flow.as_mut_block(); - if !block.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { + if !block + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { return; } - if !block.base.restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) { - return + if !block + .base + .restyle_damage + .intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) + { + return; } block.calculate_absolute_block_size_and_margins(self.0); @@ -533,14 +632,20 @@ impl BlockFlow { BlockFlow::from_fragment_and_float_kind(fragment, None) } - pub fn from_fragment_and_float_kind(fragment: Fragment, float_kind: Option) - -> BlockFlow { + pub fn from_fragment_and_float_kind( + fragment: Fragment, + float_kind: Option, + ) -> BlockFlow { let writing_mode = fragment.style().writing_mode; BlockFlow { - base: BaseFlow::new(Some(fragment.style()), writing_mode, match float_kind { - Some(_) => ForceNonfloatedFlag::FloatIfNecessary, - None => ForceNonfloatedFlag::ForceNonfloated, - }), + base: BaseFlow::new( + Some(fragment.style()), + writing_mode, + match float_kind { + Some(_) => ForceNonfloatedFlag::FloatIfNecessary, + None => ForceNonfloatedFlag::ForceNonfloated, + }, + ), fragment: fragment, float: float_kind.map(|kind| Box::new(FloatedBlockInfo::new(kind))), flags: BlockFlowFlags::empty(), @@ -552,7 +657,11 @@ impl BlockFlow { /// This determines the algorithm used to calculate inline-size, block-size, and the /// relevant margins for this Block. pub fn block_type(&self) -> BlockType { - if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { + if self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { if self.fragment.is_replaced() { BlockType::AbsoluteReplaced } else { @@ -582,65 +691,85 @@ impl BlockFlow { } /// Compute the actual inline size and position for this block. - pub fn compute_used_inline_size(&mut self, - shared_context: &SharedStyleContext, - containing_block_inline_size: Au) { + pub fn compute_used_inline_size( + &mut self, + shared_context: &SharedStyleContext, + containing_block_inline_size: Au, + ) { let block_type = self.block_type(); match block_type { BlockType::AbsoluteReplaced => { let inline_size_computer = AbsoluteReplaced; - inline_size_computer.compute_used_inline_size(self, - shared_context, - containing_block_inline_size); - } + inline_size_computer.compute_used_inline_size( + self, + shared_context, + containing_block_inline_size, + ); + }, BlockType::AbsoluteNonReplaced => { let inline_size_computer = AbsoluteNonReplaced; - inline_size_computer.compute_used_inline_size(self, - shared_context, - containing_block_inline_size); - } + inline_size_computer.compute_used_inline_size( + self, + shared_context, + containing_block_inline_size, + ); + }, BlockType::FloatReplaced => { let inline_size_computer = FloatReplaced; - inline_size_computer.compute_used_inline_size(self, - shared_context, - containing_block_inline_size); - } + inline_size_computer.compute_used_inline_size( + self, + shared_context, + containing_block_inline_size, + ); + }, BlockType::FloatNonReplaced => { let inline_size_computer = FloatNonReplaced; - inline_size_computer.compute_used_inline_size(self, - shared_context, - containing_block_inline_size); - } + inline_size_computer.compute_used_inline_size( + self, + shared_context, + containing_block_inline_size, + ); + }, BlockType::InlineBlockReplaced => { let inline_size_computer = InlineBlockReplaced; - inline_size_computer.compute_used_inline_size(self, - shared_context, - containing_block_inline_size); - } + inline_size_computer.compute_used_inline_size( + self, + shared_context, + containing_block_inline_size, + ); + }, BlockType::InlineBlockNonReplaced => { let inline_size_computer = InlineBlockNonReplaced; - inline_size_computer.compute_used_inline_size(self, - shared_context, - containing_block_inline_size); - } + inline_size_computer.compute_used_inline_size( + self, + shared_context, + containing_block_inline_size, + ); + }, BlockType::Replaced => { let inline_size_computer = BlockReplaced; - inline_size_computer.compute_used_inline_size(self, - shared_context, - containing_block_inline_size); - } + inline_size_computer.compute_used_inline_size( + self, + shared_context, + containing_block_inline_size, + ); + }, BlockType::NonReplaced => { let inline_size_computer = BlockNonReplaced; - inline_size_computer.compute_used_inline_size(self, - shared_context, - containing_block_inline_size); - } + inline_size_computer.compute_used_inline_size( + self, + shared_context, + containing_block_inline_size, + ); + }, BlockType::InlineFlexItem => { let inline_size_computer = InlineFlexItem; - inline_size_computer.compute_used_inline_size(self, - shared_context, - containing_block_inline_size); - } + inline_size_computer.compute_used_inline_size( + self, + shared_context, + containing_block_inline_size, + ); + }, } } @@ -652,9 +781,15 @@ impl BlockFlow { pub fn stacking_relative_border_box(&self, coor: CoordinateSystem) -> Rect { return self.fragment.stacking_relative_border_box( &self.base.stacking_relative_position, - &self.base.early_absolute_position_info.relative_containing_block_size, - self.base.early_absolute_position_info.relative_containing_block_mode, - coor); + &self + .base + .early_absolute_position_info + .relative_containing_block_size, + self.base + .early_absolute_position_info + .relative_containing_block_mode, + coor, + ); } /// Return the size of the containing block for the given immediate absolute descendant of this @@ -663,14 +798,23 @@ impl BlockFlow { /// Right now, this only gets the containing block size for absolutely positioned elements. /// Note: We assume this is called in a top-down traversal, so it is ok to reference the CB. #[inline] - pub fn containing_block_size(&self, viewport_size: &Size2D, descendant: OpaqueFlow) - -> LogicalSize { - debug_assert!(self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED)); + pub fn containing_block_size( + &self, + viewport_size: &Size2D, + descendant: OpaqueFlow, + ) -> LogicalSize { + debug_assert!( + self.base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + ); if self.is_fixed() || self.is_root() { // Initial containing block is the CB for the root LogicalSize::from_physical(self.base.writing_mode, *viewport_size) } else { - self.base.absolute_cb.generated_containing_block_size(descendant) + self.base + .absolute_cb + .generated_containing_block_size(descendant) } } @@ -680,8 +824,13 @@ impl BlockFlow { /// calculated in the bubble-inline-sizes traversal. pub fn get_shrink_to_fit_inline_size(&self, available_inline_size: Au) -> Au { let content_intrinsic_inline_sizes = self.content_intrinsic_inline_sizes(); - min(content_intrinsic_inline_sizes.preferred_inline_size, - max(content_intrinsic_inline_sizes.minimum_inline_size, available_inline_size)) + min( + content_intrinsic_inline_sizes.preferred_inline_size, + max( + content_intrinsic_inline_sizes.minimum_inline_size, + available_inline_size, + ), + ) } /// If this is the root flow, shifts all kids down and adjusts our size to account for @@ -689,22 +838,24 @@ impl BlockFlow { /// /// TODO(#2017, pcwalton): This is somewhat inefficient (traverses kids twice); can we do /// better? - fn adjust_fragments_for_collapsed_margins_if_root(&mut self, - shared_context: &SharedStyleContext) { + fn adjust_fragments_for_collapsed_margins_if_root( + &mut self, + shared_context: &SharedStyleContext, + ) { if !self.is_root() { - return + return; } - let (block_start_margin_value, block_end_margin_value) = - match self.base.collapsible_margins { - CollapsibleMargins::CollapseThrough(_) => { - panic!("Margins unexpectedly collapsed through root flow.") - } - CollapsibleMargins::Collapse(block_start_margin, block_end_margin) => { - (block_start_margin.collapse(), block_end_margin.collapse()) - } - CollapsibleMargins::None(block_start, block_end) => (block_start, block_end), - }; + let (block_start_margin_value, block_end_margin_value) = match self.base.collapsible_margins + { + CollapsibleMargins::CollapseThrough(_) => { + panic!("Margins unexpectedly collapsed through root flow.") + }, + CollapsibleMargins::Collapse(block_start_margin, block_end_margin) => { + (block_start_margin.collapse(), block_end_margin.collapse()) + }, + CollapsibleMargins::None(block_start, block_end) => (block_start, block_end), + }; // Shift all kids down (or up, if margins are negative) if necessary. if block_start_margin_value != Au(0) { @@ -718,12 +869,14 @@ impl BlockFlow { // is not correct behavior according to CSS 2.1 § 10.5. Instead I think we should treat the // root element as having `overflow: scroll` and use the layers-based scrolling // infrastructure to make it scrollable. - let viewport_size = - LogicalSize::from_physical(self.fragment.style.writing_mode, - shared_context.viewport_size()); - let block_size = max(viewport_size.block, - self.fragment.border_box.size.block + block_start_margin_value + - block_end_margin_value); + let viewport_size = LogicalSize::from_physical( + self.fragment.style.writing_mode, + shared_context.viewport_size(), + ); + let block_size = max( + viewport_size.block, + self.fragment.border_box.size.block + block_start_margin_value + block_end_margin_value, + ); self.base.position.size.block = block_size; self.fragment.border_box.size.block = block_size; @@ -774,69 +927,95 @@ impl BlockFlow { /// `inline(always)` because this is only ever called by in-order or non-in-order top-level /// methods. #[inline(always)] - pub fn assign_block_size_block_base(&mut self, - layout_context: &LayoutContext, - mut fragmentation_context: Option, - margins_may_collapse: MarginsMayCollapseFlag) - -> Option> { - let _scope = layout_debug_scope!("assign_block_size_block_base {:x}", - self.base.debug_id()); + pub fn assign_block_size_block_base( + &mut self, + layout_context: &LayoutContext, + mut fragmentation_context: Option, + margins_may_collapse: MarginsMayCollapseFlag, + ) -> Option> { + let _scope = layout_debug_scope!("assign_block_size_block_base {:x}", self.base.debug_id()); let mut break_at = None; let content_box = self.fragment.content_box(); - if self.base.restyle_damage.contains(ServoRestyleDamage::REFLOW) { + if self + .base + .restyle_damage + .contains(ServoRestyleDamage::REFLOW) + { // Our current border-box position. let mut cur_b = Au(0); // Absolute positioning establishes a block formatting context. Don't propagate floats // in or out. (But do propagate them between kids.) - if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) || - margins_may_collapse != MarginsMayCollapseFlag::MarginsMayCollapse { + if self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) || + margins_may_collapse != MarginsMayCollapseFlag::MarginsMayCollapse + { self.base.floats = Floats::new(self.fragment.style.writing_mode); } let writing_mode = self.base.floats.writing_mode; self.base.floats.translate(LogicalSize::new( - writing_mode, -self.fragment.inline_start_offset(), Au(0))); + writing_mode, + -self.fragment.inline_start_offset(), + Au(0), + )); // The sum of our block-start border and block-start padding. let block_start_offset = self.fragment.border_padding.block_start; translate_including_floats(&mut cur_b, block_start_offset, &mut self.base.floats); - let can_collapse_block_start_margin_with_kids = - margins_may_collapse == MarginsMayCollapseFlag::MarginsMayCollapse && - !self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && + let can_collapse_block_start_margin_with_kids = margins_may_collapse == + MarginsMayCollapseFlag::MarginsMayCollapse && + !self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && self.fragment.border_padding.block_start == Au(0); let mut margin_collapse_info = MarginCollapseInfo::initialize_block_start_margin( &self.fragment, - can_collapse_block_start_margin_with_kids); + can_collapse_block_start_margin_with_kids, + ); // At this point, `cur_b` is at the content edge of our box. Now iterate over children. let mut floats = self.base.floats.clone(); let thread_id = self.base.thread_id; let (mut had_floated_children, mut had_children_with_clearance) = (false, false); for (child_index, kid) in self.base.child_iter_mut().enumerate() { - if kid.base().flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { + if kid + .base() + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { // Assume that the *hypothetical box* for an absolute flow starts immediately // after the margin-end border edge of the previous flow. - if kid.base().flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) { + if kid + .base() + .flags + .contains(FlowFlags::BLOCK_POSITION_IS_STATIC) + { let previous_bottom_margin = margin_collapse_info.current_float_ceiling(); kid.mut_base().position.start.b = cur_b + - kid.base().collapsible_margins - .block_start_margin_for_noncollapsible_context() + + kid.base() + .collapsible_margins + .block_start_margin_for_noncollapsible_context() + previous_bottom_margin } kid.place_float_if_applicable(); if !kid.base().flags.is_float() { - kid.assign_block_size_for_inorder_child_if_necessary(layout_context, - thread_id, - content_box); + kid.assign_block_size_for_inorder_child_if_necessary( + layout_context, + thread_id, + content_box, + ); } // Skip the collapsing and float processing for absolute flow kids and continue // with the next flow. - continue + continue; } let previous_b = cur_b; @@ -865,7 +1044,7 @@ impl BlockFlow { let kid_base = kid.mut_base(); floats = kid_base.floats.clone(); - continue + continue; } // If we have clearance, assume there are no floats in. @@ -880,22 +1059,26 @@ impl BlockFlow { } // Lay the child out if this was an in-order traversal. - let need_to_process_child_floats = - kid.assign_block_size_for_inorder_child_if_necessary(layout_context, - thread_id, - content_box); + let need_to_process_child_floats = kid + .assign_block_size_for_inorder_child_if_necessary( + layout_context, + thread_id, + content_box, + ); if !had_children_with_clearance && - floats.is_present() && - (kid.base().flags.contains(FlowFlags::CLEARS_LEFT) || - kid.base().flags.contains(FlowFlags::CLEARS_RIGHT)) { + floats.is_present() && + (kid.base().flags.contains(FlowFlags::CLEARS_LEFT) || + kid.base().flags.contains(FlowFlags::CLEARS_RIGHT)) + { had_children_with_clearance = true } // Handle any (possibly collapsed) top margin. let delta = margin_collapse_info.advance_block_start_margin( &kid.base().collapsible_margins, - !had_children_with_clearance); + !had_children_with_clearance, + ); translate_including_floats(&mut cur_b, delta, &mut floats); // Collapse-through margins should be placed at the top edge, @@ -905,8 +1088,10 @@ impl BlockFlow { } // Clear past the floats that came in, if necessary. - let clearance = match (kid.base().flags.contains(FlowFlags::CLEARS_LEFT), - kid.base().flags.contains(FlowFlags::CLEARS_RIGHT)) { + let clearance = match ( + kid.base().flags.contains(FlowFlags::CLEARS_LEFT), + kid.base().flags.contains(FlowFlags::CLEARS_RIGHT), + ) { (false, false) => Au(0), (true, false) => floats.clearance(ClearType::Left), (false, true) => floats.clearance(ClearType::Right), @@ -942,19 +1127,19 @@ impl BlockFlow { cur_b = cur_b + delta; kid_base.position.start.b = kid_base.position.start.b + delta; delta - } - _ => Au(0) + }, + _ => Au(0), }; if break_at.is_some() { - break + break; } if let Some(ref mut ctx) = fragmentation_context { if cur_b > ctx.available_block_size && !ctx.this_fragment_is_empty { break_at = Some((child_index, None)); cur_b = previous_b; - break + break; } ctx.this_fragment_is_empty = false } @@ -965,38 +1150,50 @@ impl BlockFlow { } // Add in our block-end margin and compute our collapsible margins. - let can_collapse_block_end_margin_with_kids = - margins_may_collapse == MarginsMayCollapseFlag::MarginsMayCollapse && - !self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && + let can_collapse_block_end_margin_with_kids = margins_may_collapse == + MarginsMayCollapseFlag::MarginsMayCollapse && + !self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && self.fragment.border_padding.block_end == Au(0); - let (collapsible_margins, delta) = - margin_collapse_info.finish_and_compute_collapsible_margins( - &self.fragment, - self.base.block_container_explicit_block_size, - can_collapse_block_end_margin_with_kids, - !had_floated_children); + let (collapsible_margins, delta) = margin_collapse_info + .finish_and_compute_collapsible_margins( + &self.fragment, + self.base.block_container_explicit_block_size, + can_collapse_block_end_margin_with_kids, + !had_floated_children, + ); self.base.collapsible_margins = collapsible_margins; translate_including_floats(&mut cur_b, delta, &mut floats); let mut block_size = cur_b - block_start_offset; let is_root = self.is_root(); - if is_root || self.formatting_context_type() != FormattingContextType::None || - self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { + if is_root || self.formatting_context_type() != FormattingContextType::None || self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { // The content block-size includes all the floats per CSS 2.1 § 10.6.7. The easiest // way to handle this is to just treat it as clearance. block_size = block_size + floats.clearance(ClearType::Both); } - if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { + if self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { // FIXME(#2003, pcwalton): The max is taken here so that you can scroll the page, // but this is not correct behavior according to CSS 2.1 § 10.5. Instead I think we // should treat the root element as having `overflow: scroll` and use the layers- // based scrolling infrastructure to make it scrollable. if is_root { - let viewport_size = - LogicalSize::from_physical(self.fragment.style.writing_mode, - layout_context.shared_context().viewport_size()); + let viewport_size = LogicalSize::from_physical( + self.fragment.style.writing_mode, + layout_context.shared_context().viewport_size(), + ); block_size = max(viewport_size.block, block_size) } @@ -1007,23 +1204,26 @@ impl BlockFlow { self.fragment.border_box.size.block = block_size; } - - if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { + if self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { self.propagate_early_absolute_position_info_to_children(); - return None + return None; } // Compute any explicitly-specified block size. // Can't use `for` because we assign to `candidate_block_size_iterator.candidate_value`. let mut candidate_block_size_iterator = CandidateBSizeIterator::new( &self.fragment, - self.base.block_container_explicit_block_size); + self.base.block_container_explicit_block_size, + ); while let Some(candidate_block_size) = candidate_block_size_iterator.next() { - candidate_block_size_iterator.candidate_value = - match candidate_block_size { - MaybeAuto::Auto => block_size, - MaybeAuto::Specified(value) => value - } + candidate_block_size_iterator.candidate_value = match candidate_block_size { + MaybeAuto::Auto => block_size, + MaybeAuto::Specified(value) => value, + } } // Adjust `cur_b` as necessary to account for the explicitly-specified block-size. @@ -1046,9 +1246,11 @@ impl BlockFlow { // Translate the current set of floats back into the parent coordinate system in the // inline direction, and store them in the flow so that flows that come later in the // document can access them. - floats.translate(LogicalSize::new(writing_mode, - self.fragment.inline_start_offset(), - Au(0))); + floats.translate(LogicalSize::new( + writing_mode, + self.fragment.inline_start_offset(), + Au(0), + )); self.base.floats = floats.clone(); self.adjust_fragments_for_collapsed_margins_if_root(layout_context.shared_context()); } else { @@ -1056,9 +1258,11 @@ impl BlockFlow { // necessary. let thread_id = self.base.thread_id; for kid in self.base.child_iter_mut() { - kid.assign_block_size_for_inorder_child_if_necessary(layout_context, - thread_id, - content_box); + kid.assign_block_size_for_inorder_child_if_necessary( + layout_context, + thread_id, + content_box, + ); } } @@ -1075,10 +1279,18 @@ impl BlockFlow { // Also don't remove the dirty bits if we're a block formatting context since our inline // size has not yet been computed. (See `assign_inline_position_for_formatting_context()`.) if (self.base.flags.is_float() || - self.formatting_context_type() == FormattingContextType::None) && - !self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { - self.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); - self.fragment.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); + self.formatting_context_type() == FormattingContextType::None) && + !self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { + self.base + .restyle_damage + .remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); + self.fragment + .restyle_damage + .remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); } break_at.and_then(|(i, child_remaining)| { @@ -1116,15 +1328,18 @@ impl BlockFlow { // Our `position` field accounts for positive margins, but not negative margins. (See // calculation of `extra_inline_size_from_margin` below.) Negative margins must be taken // into account for float placement, however. So we add them in here. - let inline_size_for_float_placement = self.base.position.size.inline + - min(Au(0), self.fragment.margin.inline_start_end()); + let inline_size_for_float_placement = + self.base.position.size.inline + min(Au(0), self.fragment.margin.inline_start_end()); let info = PlacementInfo { size: LogicalSize::new( self.fragment.style.writing_mode, inline_size_for_float_placement, - block_size + self.fragment.margin.block_start_end()) - .convert(self.fragment.style.writing_mode, self.base.floats.writing_mode), + block_size + self.fragment.margin.block_start_end(), + ).convert( + self.fragment.style.writing_mode, + self.base.floats.writing_mode, + ), ceiling: clearance + float_info.float_ceiling, max_inline_size: float_info.containing_inline_size, kind: float_info.float_kind, @@ -1139,32 +1354,51 @@ impl BlockFlow { // Move in from the margin edge, as per CSS 2.1 § 9.5, floats may not overlap anything on // their margin edges. - let float_offset = self.base.floats.last_float_pos().unwrap() - .convert(self.base.floats.writing_mode, - self.base.writing_mode, - container_size) - .start; - let margin_offset = LogicalPoint::new(self.base.writing_mode, - Au(0), - self.fragment.margin.block_start); + let float_offset = self + .base + .floats + .last_float_pos() + .unwrap() + .convert( + self.base.floats.writing_mode, + self.base.writing_mode, + container_size, + ).start; + let margin_offset = LogicalPoint::new( + self.base.writing_mode, + Au(0), + self.fragment.margin.block_start, + ); - let mut origin = LogicalPoint::new(self.base.writing_mode, - self.base.position.start.i, - self.base.position.start.b); + let mut origin = LogicalPoint::new( + self.base.writing_mode, + self.base.position.start.i, + self.base.position.start.b, + ); origin = origin.add_point(&float_offset).add_point(&margin_offset); - self.base.position = LogicalRect::from_point_size(self.base.writing_mode, - origin, - self.base.position.size); + self.base.position = + LogicalRect::from_point_size(self.base.writing_mode, origin, self.base.position.size); } - pub fn explicit_block_containing_size(&self, shared_context: &SharedStyleContext) -> Option { + pub fn explicit_block_containing_size( + &self, + shared_context: &SharedStyleContext, + ) -> Option { if self.is_root() || self.is_fixed() { - let viewport_size = LogicalSize::from_physical(self.fragment.style.writing_mode, - shared_context.viewport_size()); + let viewport_size = LogicalSize::from_physical( + self.fragment.style.writing_mode, + shared_context.viewport_size(), + ); Some(viewport_size.block) - } else if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && - self.base.block_container_explicit_block_size.is_none() { - self.base.absolute_cb.explicit_block_containing_size(shared_context) + } else if self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && + self.base.block_container_explicit_block_size.is_none() + { + self.base + .absolute_cb + .explicit_block_containing_size(shared_context) } else { self.base.block_container_explicit_block_size } @@ -1174,58 +1408,56 @@ impl BlockFlow { let content_block_size = self.fragment.style().content_block_size(); match (content_block_size, containing_block_size) { - (LengthOrPercentageOrAuto::Calc(calc), _) => { - calc.to_used_value(containing_block_size) - } + (LengthOrPercentageOrAuto::Calc(calc), _) => calc.to_used_value(containing_block_size), (LengthOrPercentageOrAuto::Length(length), _) => Some(Au::from(length)), (LengthOrPercentageOrAuto::Percentage(percent), Some(container_size)) => { Some(container_size.scale_by(percent.0)) - } + }, (LengthOrPercentageOrAuto::Percentage(_), None) | - (LengthOrPercentageOrAuto::Auto, None) => { - None - } + (LengthOrPercentageOrAuto::Auto, None) => None, (LengthOrPercentageOrAuto::Auto, Some(container_size)) => { let (block_start, block_end) = { let position = self.fragment.style().logical_position(); - (MaybeAuto::from_style(position.block_start, container_size), - MaybeAuto::from_style(position.block_end, container_size)) + ( + MaybeAuto::from_style(position.block_start, container_size), + MaybeAuto::from_style(position.block_end, container_size), + ) }; match (block_start, block_end) { (MaybeAuto::Specified(block_start), MaybeAuto::Specified(block_end)) => { - let available_block_size = container_size - self.fragment.border_padding.block_start_end(); + let available_block_size = + container_size - self.fragment.border_padding.block_start_end(); // Non-auto margin-block-start and margin-block-end values have already been // calculated during assign-inline-size. let margin = self.fragment.style().logical_margin(); let margin_block_start = match margin.block_start { LengthOrPercentageOrAuto::Auto => MaybeAuto::Auto, - _ => MaybeAuto::Specified(self.fragment.margin.block_start) + _ => MaybeAuto::Specified(self.fragment.margin.block_start), }; let margin_block_end = match margin.block_end { LengthOrPercentageOrAuto::Auto => MaybeAuto::Auto, - _ => MaybeAuto::Specified(self.fragment.margin.block_end) + _ => MaybeAuto::Specified(self.fragment.margin.block_end), }; let margin_block_start = margin_block_start.specified_or_zero(); let margin_block_end = margin_block_end.specified_or_zero(); let sum = block_start + block_end + margin_block_start + margin_block_end; Some(available_block_size - sum) - } + }, - (_, _) => { - None - } + (_, _) => None, } - } + }, } } fn calculate_absolute_block_size_and_margins(&mut self, shared_context: &SharedStyleContext) { let opaque_self = OpaqueFlow::from_flow(self); - let containing_block_block_size = - self.containing_block_size(&shared_context.viewport_size(), opaque_self).block; + let containing_block_block_size = self + .containing_block_size(&shared_context.viewport_size(), opaque_self) + .block; // This is the stored content block-size value from assign-block-size let content_block_size = self.fragment.border_box.size.block; @@ -1237,24 +1469,24 @@ impl BlockFlow { let margin = self.fragment.style().logical_margin(); let margin_block_start = match margin.block_start { LengthOrPercentageOrAuto::Auto => MaybeAuto::Auto, - _ => MaybeAuto::Specified(self.fragment.margin.block_start) + _ => MaybeAuto::Specified(self.fragment.margin.block_start), }; let margin_block_end = match margin.block_end { LengthOrPercentageOrAuto::Auto => MaybeAuto::Auto, - _ => MaybeAuto::Specified(self.fragment.margin.block_end) + _ => MaybeAuto::Specified(self.fragment.margin.block_end), }; let block_start; let block_end; { let position = self.fragment.style().logical_position(); - block_start = MaybeAuto::from_style(position.block_start, - containing_block_block_size); + block_start = + MaybeAuto::from_style(position.block_start, containing_block_block_size); block_end = MaybeAuto::from_style(position.block_end, containing_block_block_size); } - let available_block_size = containing_block_block_size - - self.fragment.border_padding.block_start_end(); + let available_block_size = + containing_block_block_size - self.fragment.border_padding.block_start_end(); if self.fragment.is_replaced() { // Calculate used value of block-size just like we do for inline replaced elements. // TODO: Pass in the containing block block-size when Fragment's @@ -1265,21 +1497,24 @@ impl BlockFlow { // Check this when that has been fixed. let block_size_used_val = self.fragment.border_box.size.block - self.fragment.border_padding.block_start_end(); - solution = Some(BSizeConstraintSolution::solve_vertical_constraints_abs_replaced( + solution = Some( + BSizeConstraintSolution::solve_vertical_constraints_abs_replaced( block_size_used_val, margin_block_start, margin_block_end, block_start, block_end, content_block_size, - available_block_size)) + available_block_size, + ), + ) } else { let mut candidate_block_size_iterator = CandidateBSizeIterator::new(&self.fragment, Some(containing_block_block_size)); // Can't use `for` because we assign to // `candidate_block_size_iterator.candidate_value`. - while let Some(block_size_used_val) = candidate_block_size_iterator.next() { + while let Some(block_size_used_val) = candidate_block_size_iterator.next() { solution = Some( BSizeConstraintSolution::solve_vertical_constraints_abs_nonreplaced( block_size_used_val, @@ -1288,10 +1523,11 @@ impl BlockFlow { block_start, block_end, content_block_size, - available_block_size)); + available_block_size, + ), + ); - candidate_block_size_iterator.candidate_value = - solution.unwrap().block_size; + candidate_block_size_iterator.candidate_value = solution.unwrap().block_size; } } } @@ -1301,7 +1537,11 @@ impl BlockFlow { self.fragment.margin.block_end = solution.margin_block_end; self.fragment.border_box.start.b = Au(0); - if !self.base.flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) { + if !self + .base + .flags + .contains(FlowFlags::BLOCK_POSITION_IS_STATIC) + { self.base.position.start.b = solution.block_start + self.fragment.margin.block_start } @@ -1310,8 +1550,12 @@ impl BlockFlow { self.fragment.border_box.size.block = block_size; self.base.position.size.block = block_size; - self.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); - self.fragment.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); + self.base + .restyle_damage + .remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); + self.fragment + .restyle_damage + .remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); } /// Compute inline size based using the `block_container_inline_size` set by the parent flow. @@ -1332,18 +1576,16 @@ impl BlockFlow { /// `#[inline(always)]` because this is called only from block or table inline-size assignment /// and the code for block layout is significantly simpler. #[inline(always)] - pub fn propagate_assigned_inline_size_to_children(&mut self, - shared_context: &SharedStyleContext, - inline_start_content_edge: Au, - inline_end_content_edge: Au, - content_inline_size: Au, - mut callback: F) - where F: FnMut(&mut Flow, - usize, - Au, - WritingMode, - &mut Au, - &mut Au) { + pub fn propagate_assigned_inline_size_to_children( + &mut self, + shared_context: &SharedStyleContext, + inline_start_content_edge: Au, + inline_end_content_edge: Au, + content_inline_size: Au, + mut callback: F, + ) where + F: FnMut(&mut Flow, usize, Au, WritingMode, &mut Au, &mut Au), + { let flags = self.base.flags.clone(); let opaque_self = OpaqueFlow::from_flow(self); @@ -1355,13 +1597,20 @@ impl BlockFlow { }; let parent_container_size = self.explicit_block_containing_size(shared_context); // https://drafts.csswg.org/css-ui-3/#box-sizing - let mut explicit_content_size = self - .explicit_block_size(parent_container_size) - .map(|x| if x < box_border { Au(0) } else { x - box_border }); - if self.is_root() { explicit_content_size = max(parent_container_size, explicit_content_size); } + let mut explicit_content_size = self.explicit_block_size(parent_container_size).map(|x| { + if x < box_border { + Au(0) + } else { + x - box_border + } + }); + if self.is_root() { + explicit_content_size = max(parent_container_size, explicit_content_size); + } // Calculate containing block inline size. let containing_block_size = if flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { - self.containing_block_size(&shared_context.viewport_size(), opaque_self).inline + self.containing_block_size(&shared_context.viewport_size(), opaque_self) + .inline } else { content_inline_size }; @@ -1388,13 +1637,17 @@ impl BlockFlow { // float child does not have `REFLOW` set, we must be careful to avoid touching its // inline position, as no logic will run afterward to set its true value. let kid_base = kid.mut_base(); - let reflow_damage = if kid_base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { + let reflow_damage = if kid_base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { ServoRestyleDamage::REFLOW_OUT_OF_FLOW } else { ServoRestyleDamage::REFLOW }; - if kid_base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) && - kid_base.restyle_damage.contains(reflow_damage) { + if kid_base + .flags + .contains(FlowFlags::INLINE_POSITION_IS_STATIC) && + kid_base.restyle_damage.contains(reflow_damage) + { kid_base.position.start.i = if kid_mode.is_bidi_ltr() == containing_block_mode.is_bidi_ltr() { inline_start_content_edge @@ -1409,26 +1662,33 @@ impl BlockFlow { // Call the callback to propagate extra inline size information down to the child. This // is currently used for tables. - callback(kid, - i, - content_inline_size, - containing_block_mode, - &mut inline_start_margin_edge, - &mut inline_end_margin_edge); + callback( + kid, + i, + content_inline_size, + containing_block_mode, + &mut inline_start_margin_edge, + &mut inline_end_margin_edge, + ); // Per CSS 2.1 § 16.3.1, text alignment propagates to all children in flow. // // TODO(#2265, pcwalton): Do this in the cascade instead. let containing_block_text_align = self.fragment.style().get_inherited_text().text_align; - kid.mut_base().flags.set_text_align(containing_block_text_align); + kid.mut_base() + .flags + .set_text_align(containing_block_text_align); // Handle `text-indent` on behalf of any inline children that we have. This is // necessary because any percentages are relative to the containing block, which only // we know. if kid.is_inline_flow() { - kid.as_mut_inline().first_line_indentation = - self.fragment.style().get_inherited_text().text_indent - .to_used_value(containing_block_size); + kid.as_mut_inline().first_line_indentation = self + .fragment + .style() + .get_inherited_text() + .text_indent + .to_used_value(containing_block_size); } } } @@ -1437,11 +1697,11 @@ impl BlockFlow { /// `FormattingContextType`. pub fn formatting_context_type(&self) -> FormattingContextType { if self.is_inline_flex_item() || self.is_block_flex_item() { - return FormattingContextType::Other + return FormattingContextType::Other; } let style = self.fragment.style(); if style.get_box().float != Float::None { - return FormattingContextType::Other + return FormattingContextType::Other; } match style.get_box().display { Display::TableCell | @@ -1449,14 +1709,13 @@ impl BlockFlow { Display::TableRowGroup | Display::Table | Display::InlineBlock | - Display::Flex => { - FormattingContextType::Other - } + Display::Flex => FormattingContextType::Other, _ if style.get_box().overflow_x != StyleOverflow::Visible || - style.get_box().overflow_y != StyleOverflow::Visible || - style.is_multicol() => { + style.get_box().overflow_y != StyleOverflow::Visible || + style.is_multicol() => + { FormattingContextType::Block - } + }, _ => FormattingContextType::None, } } @@ -1472,18 +1731,28 @@ impl BlockFlow { /// on the floats we could see at the time of inline-size assignment. The job of this function, /// therefore, is not only to assign the final size but also to perform the layout again for /// this block formatting context if our speculation was wrong. - fn assign_inline_position_for_formatting_context(&mut self, - layout_context: &LayoutContext, - content_box: LogicalRect) { + fn assign_inline_position_for_formatting_context( + &mut self, + layout_context: &LayoutContext, + content_box: LogicalRect, + ) { debug_assert_ne!(self.formatting_context_type(), FormattingContextType::None); - if !self.base.restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) { - return + if !self + .base + .restyle_damage + .intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) + { + return; } // We do this first to avoid recomputing our inline size when we propagate it. - self.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); - self.fragment.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); + self.base + .restyle_damage + .remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); + self.fragment + .restyle_damage + .remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); // The code below would completely wreck the layout if run on a flex item, however: // * Flex items are always the children of flex containers. @@ -1494,16 +1763,18 @@ impl BlockFlow { // Therefore, a flex item cannot be impacted by a float. // See also: https://www.w3.org/TR/css-flexbox-1/#flex-containers if !self.base.might_have_floats_in() { - return + return; } // If you remove the might_have_floats_in conditional, this will go off. debug_assert!(!self.is_inline_flex_item()); // Compute the available space for us, based on the actual floats. - let rect = self.base.floats.available_rect(Au(0), - self.fragment.border_box.size.block, - content_box.size.inline); + let rect = self.base.floats.available_rect( + Au(0), + self.fragment.border_box.size.block, + content_box.size.inline, + ); let available_inline_size = if let Some(rect) = rect { // Offset our position by whatever displacement is needed to not impact the floats. // Also, account for margins sliding behind floats. @@ -1525,25 +1796,29 @@ impl BlockFlow { } else { content_box.size.inline } - self.fragment.margin.inline_start_end(); - let max_inline_size = - self.fragment.style().max_inline_size() - .to_used_value(self.base.block_container_inline_size) - .unwrap_or(MAX_AU); - let min_inline_size = - self.fragment.style().min_inline_size().to_used_value(self.base.block_container_inline_size); + let max_inline_size = self + .fragment + .style() + .max_inline_size() + .to_used_value(self.base.block_container_inline_size) + .unwrap_or(MAX_AU); + let min_inline_size = self + .fragment + .style() + .min_inline_size() + .to_used_value(self.base.block_container_inline_size); let specified_inline_size = self.fragment.style().content_inline_size(); let container_size = self.base.block_container_inline_size; - let inline_size = - if let MaybeAuto::Specified(size) = MaybeAuto::from_style(specified_inline_size, - container_size) { - match self.fragment.style().get_position().box_sizing { - BoxSizing::BorderBox => size, - BoxSizing::ContentBox => - size + self.fragment.border_padding.inline_start_end(), - } - } else { - max(min_inline_size, min(available_inline_size, max_inline_size)) - }; + let inline_size = if let MaybeAuto::Specified(size) = + MaybeAuto::from_style(specified_inline_size, container_size) + { + match self.fragment.style().get_position().box_sizing { + BoxSizing::BorderBox => size, + BoxSizing::ContentBox => size + self.fragment.border_padding.inline_start_end(), + } + } else { + max(min_inline_size, min(available_inline_size, max_inline_size)) + }; self.base.position.size.inline = inline_size + self.fragment.margin.inline_start_end(); // If float speculation failed, fixup our layout, and re-layout all the children. @@ -1563,12 +1838,15 @@ impl BlockFlow { self.assign_block_size(layout_context); } - debug_assert_eq!(self.fragment.margin_box_inline_size(), self.base.position.size.inline); + debug_assert_eq!( + self.fragment.margin_box_inline_size(), + self.base.position.size.inline + ); } fn is_inline_block_or_inline_flex(&self) -> bool { self.fragment.style().get_box().display == Display::InlineBlock || - self.fragment.style().get_box().display == Display::InlineFlex + self.fragment.style().get_box().display == Display::InlineFlex } /// Computes the content portion (only) of the intrinsic inline sizes of this flow. This is @@ -1578,9 +1856,11 @@ impl BlockFlow { let (border_padding, margin) = self.fragment.surrounding_intrinsic_inline_size(); IntrinsicISizes { minimum_inline_size: self.base.intrinsic_inline_sizes.minimum_inline_size - - border_padding - margin, + border_padding - + margin, preferred_inline_size: self.base.intrinsic_inline_sizes.preferred_inline_size - - border_padding - margin, + border_padding - + margin, } } @@ -1599,9 +1879,13 @@ impl BlockFlow { } else { flags.remove(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS); for kid in self.base.children.iter() { - if kid.base().flags.contains(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS) { + if kid + .base() + .flags + .contains(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS) + { flags.insert(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS); - break + break; } } } @@ -1617,15 +1901,21 @@ impl BlockFlow { let (mut left_float_width_accumulator, mut right_float_width_accumulator) = (Au(0), Au(0)); let mut preferred_inline_size_of_children_without_text_or_replaced_fragments = Au(0); for kid in self.base.child_iter_mut() { - if kid.base().flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) || !consult_children { - continue + if kid + .base() + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) || + !consult_children + { + continue; } let child_base = kid.mut_base(); let float_kind = child_base.flags.float_kind(); - computation.content_intrinsic_sizes.minimum_inline_size = - max(computation.content_intrinsic_sizes.minimum_inline_size, - child_base.intrinsic_inline_sizes.minimum_inline_size); + computation.content_intrinsic_sizes.minimum_inline_size = max( + computation.content_intrinsic_sizes.minimum_inline_size, + child_base.intrinsic_inline_sizes.minimum_inline_size, + ); if child_base.flags.contains(FlowFlags::CLEARS_LEFT) { left_float_width = max(left_float_width, left_float_width_accumulator); @@ -1636,25 +1926,34 @@ impl BlockFlow { right_float_width_accumulator = Au(0) } - match (float_kind, child_base.flags.contains(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS)) { + match ( + float_kind, + child_base + .flags + .contains(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS), + ) { (Float::None, true) => { - computation.content_intrinsic_sizes.preferred_inline_size = - max(computation.content_intrinsic_sizes.preferred_inline_size, - child_base.intrinsic_inline_sizes.preferred_inline_size); - } + computation.content_intrinsic_sizes.preferred_inline_size = max( + computation.content_intrinsic_sizes.preferred_inline_size, + child_base.intrinsic_inline_sizes.preferred_inline_size, + ); + }, (Float::None, false) => { preferred_inline_size_of_children_without_text_or_replaced_fragments = max( preferred_inline_size_of_children_without_text_or_replaced_fragments, - child_base.intrinsic_inline_sizes.preferred_inline_size) - } + child_base.intrinsic_inline_sizes.preferred_inline_size, + ) + }, (Float::Left, _) => { - left_float_width_accumulator = left_float_width_accumulator + - child_base.intrinsic_inline_sizes.preferred_inline_size; - } + left_float_width_accumulator = left_float_width_accumulator + child_base + .intrinsic_inline_sizes + .preferred_inline_size; + }, (Float::Right, _) => { - right_float_width_accumulator = right_float_width_accumulator + - child_base.intrinsic_inline_sizes.preferred_inline_size; - } + right_float_width_accumulator = right_float_width_accumulator + child_base + .intrinsic_inline_sizes + .preferred_inline_size; + }, } } @@ -1662,37 +1961,50 @@ impl BlockFlow { right_float_width = max(right_float_width, right_float_width_accumulator); computation.content_intrinsic_sizes.preferred_inline_size = - computation.content_intrinsic_sizes.preferred_inline_size + left_float_width + - right_float_width; - computation.content_intrinsic_sizes.preferred_inline_size = - max(computation.content_intrinsic_sizes.preferred_inline_size, - preferred_inline_size_of_children_without_text_or_replaced_fragments); + computation.content_intrinsic_sizes.preferred_inline_size + + left_float_width + + right_float_width; + computation.content_intrinsic_sizes.preferred_inline_size = max( + computation.content_intrinsic_sizes.preferred_inline_size, + preferred_inline_size_of_children_without_text_or_replaced_fragments, + ); self.base.intrinsic_inline_sizes = computation.finish(); self.base.flags = flags } pub fn overflow_style_may_require_clip_scroll_node(&self) -> bool { - match (self.fragment.style().get_box().overflow_x, - self.fragment.style().get_box().overflow_y) { - (StyleOverflow::Auto, _) | (StyleOverflow::Scroll, _) | (StyleOverflow::Hidden, _) | - (_, StyleOverflow::Auto) | (_, StyleOverflow::Scroll) | (_, StyleOverflow::Hidden) => - true, + match ( + self.fragment.style().get_box().overflow_x, + self.fragment.style().get_box().overflow_y, + ) { + (StyleOverflow::Auto, _) | + (StyleOverflow::Scroll, _) | + (StyleOverflow::Hidden, _) | + (_, StyleOverflow::Auto) | + (_, StyleOverflow::Scroll) | + (_, StyleOverflow::Hidden) => true, (_, _) => false, } } pub fn compute_inline_sizes(&mut self, shared_context: &SharedStyleContext) { - if !self.base.restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) { - return + if !self + .base + .restyle_damage + .intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) + { + return; } - debug!("assign_inline_sizes({}): assigning inline_size for flow", - if self.base.flags.is_float() { - "float" - } else { - "block" - }); + debug!( + "assign_inline_sizes({}): assigning inline_size for flow", + if self.base.flags.is_float() { + "float" + } else { + "block" + } + ); self.base.floats = Floats::new(self.base.writing_mode); @@ -1712,8 +2024,9 @@ impl BlockFlow { if self.is_root() { debug!("Setting root position"); self.base.position.start = LogicalPoint::zero(self.base.writing_mode); - self.base.block_container_inline_size = LogicalSize::from_physical( - self.base.writing_mode, shared_context.viewport_size()).inline; + self.base.block_container_inline_size = + LogicalSize::from_physical(self.base.writing_mode, shared_context.viewport_size()) + .inline; self.base.block_container_writing_mode = self.base.writing_mode; } } @@ -1721,14 +2034,14 @@ impl BlockFlow { fn guess_inline_size_for_block_formatting_context_if_necessary(&mut self) { // We don't need to guess anything unless this is a block formatting context. if self.formatting_context_type() != FormattingContextType::Block { - return + return; } // If `max-width` is set, then don't perform this speculation. We guess that the // page set `max-width` in order to avoid hitting floats. The search box on Google // SERPs falls into this category. if self.fragment.style.max_inline_size() != LengthOrPercentageOrNone::None { - return + return; } // At this point, we know we can't precisely compute the inline-size of this block now, @@ -1736,39 +2049,51 @@ impl BlockFlow { // inline-size computed above minus the inline-size of the previous left and/or right // floats. let speculated_left_float_size = if self.fragment.margin.inline_start >= Au(0) && - self.base.speculated_float_placement_in.left > self.fragment.margin.inline_start { + self.base.speculated_float_placement_in.left > self.fragment.margin.inline_start + { self.base.speculated_float_placement_in.left - self.fragment.margin.inline_start } else { Au(0) }; let speculated_right_float_size = if self.fragment.margin.inline_end >= Au(0) && - self.base.speculated_float_placement_in.right > self.fragment.margin.inline_end { + self.base.speculated_float_placement_in.right > self.fragment.margin.inline_end + { self.base.speculated_float_placement_in.right - self.fragment.margin.inline_end } else { Au(0) }; self.fragment.border_box.size.inline = self.fragment.border_box.size.inline - - speculated_left_float_size - speculated_right_float_size + speculated_left_float_size - + speculated_right_float_size } fn definitely_has_zero_block_size(&self) -> bool { - if !self.fragment.style.content_block_size().is_definitely_zero() { - return false + if !self + .fragment + .style + .content_block_size() + .is_definitely_zero() + { + return false; } let border_width = self.fragment.border_width(); if border_width.block_start != Au(0) || border_width.block_end != Au(0) { - return false + return false; } let padding = self.fragment.style.logical_padding(); padding.block_start.is_definitely_zero() && padding.block_end.is_definitely_zero() } pub fn is_inline_flex_item(&self) -> bool { - self.fragment.flags.contains(FragmentFlags::IS_INLINE_FLEX_ITEM) + self.fragment + .flags + .contains(FragmentFlags::IS_INLINE_FLEX_ITEM) } pub fn is_block_flex_item(&self) -> bool { - self.fragment.flags.contains(FragmentFlags::IS_BLOCK_FLEX_ITEM) + self.fragment + .flags + .contains(FragmentFlags::IS_BLOCK_FLEX_ITEM) } pub fn mark_scrolling_overflow(&mut self, has_scrolling_overflow: bool) { @@ -1785,22 +2110,30 @@ impl BlockFlow { // Return offset from original position because of `position: sticky`. pub fn sticky_position(&self) -> SideOffsets2D { - let containing_block_size = &self.base.early_absolute_position_info - .relative_containing_block_size; - let writing_mode = self.base.early_absolute_position_info.relative_containing_block_mode; + let containing_block_size = &self + .base + .early_absolute_position_info + .relative_containing_block_size; + let writing_mode = self + .base + .early_absolute_position_info + .relative_containing_block_mode; let offsets = self.fragment.style().logical_position(); - let as_margins = LogicalMargin::new(writing_mode, + let as_margins = LogicalMargin::new( + writing_mode, MaybeAuto::from_style(offsets.block_start, containing_block_size.inline), MaybeAuto::from_style(offsets.inline_end, containing_block_size.inline), MaybeAuto::from_style(offsets.block_end, containing_block_size.inline), - MaybeAuto::from_style(offsets.inline_start, containing_block_size.inline)); + MaybeAuto::from_style(offsets.inline_start, containing_block_size.inline), + ); as_margins.to_physical(writing_mode) } pub fn background_border_section(&self) -> DisplayListSection { if self.base.flags.is_float() { DisplayListSection::BackgroundAndBorders - } else if self.base + } else if self + .base .flags .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { @@ -1842,7 +2175,9 @@ impl Flow for BlockFlow { _ => true, }; self.bubble_inline_sizes_for_block(consult_children); - self.fragment.restyle_damage.remove(ServoRestyleDamage::BUBBLE_ISIZES); + self.fragment + .restyle_damage + .remove(ServoRestyleDamage::BUBBLE_ISIZES); } /// Recursively (top-down) determines the actual inline-size of child contexts and fragments. @@ -1857,23 +2192,24 @@ impl Flow for BlockFlow { self.compute_inline_sizes(shared_context); // Move in from the inline-start border edge. - let inline_start_content_edge = self.fragment.border_box.start.i + - self.fragment.border_padding.inline_start; + let inline_start_content_edge = + self.fragment.border_box.start.i + self.fragment.border_padding.inline_start; let padding_and_borders = self.fragment.border_padding.inline_start_end(); // Distance from the inline-end margin edge to the inline-end content edge. let inline_end_content_edge = - self.fragment.margin.inline_end + - self.fragment.border_padding.inline_end; + self.fragment.margin.inline_end + self.fragment.border_padding.inline_end; let content_inline_size = self.fragment.border_box.size.inline - padding_and_borders; - self.propagate_assigned_inline_size_to_children(shared_context, - inline_start_content_edge, - inline_end_content_edge, - content_inline_size, - |_, _, _, _, _, _| {}); + self.propagate_assigned_inline_size_to_children( + shared_context, + inline_start_content_edge, + inline_end_content_edge, + content_inline_size, + |_, _, _, _, _, _| {}, + ); } fn place_float_if_applicable<'a>(&mut self) { @@ -1882,29 +2218,38 @@ impl Flow for BlockFlow { } } - fn assign_block_size_for_inorder_child_if_necessary(&mut self, - layout_context: &LayoutContext, - parent_thread_id: u8, - content_box: LogicalRect) - -> bool { + fn assign_block_size_for_inorder_child_if_necessary( + &mut self, + layout_context: &LayoutContext, + parent_thread_id: u8, + content_box: LogicalRect, + ) -> bool { if self.base.flags.is_float() { - return false + return false; } let is_formatting_context = self.formatting_context_type() != FormattingContextType::None; - if !self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && is_formatting_context { + if !self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && + is_formatting_context + { self.assign_inline_position_for_formatting_context(layout_context, content_box); } if (self as &Flow).floats_might_flow_through() { self.base.thread_id = parent_thread_id; - if self.base.restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | - ServoRestyleDamage::REFLOW) { + if self + .base + .restyle_damage + .intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) + { self.assign_block_size(layout_context); // Don't remove the restyle damage; `assign_block_size` decides whether that is // appropriate (which in the case of e.g. absolutely-positioned flows, it is not). } - return true + return true; } if is_formatting_context { @@ -1912,8 +2257,10 @@ impl Flow for BlockFlow { // translate the floats past us. let writing_mode = self.base.floats.writing_mode; let delta = self.base.position.size.block; - self.base.floats.translate(LogicalSize::new(writing_mode, Au(0), -delta)); - return true + self.base + .floats + .translate(LogicalSize::new(writing_mode, Au(0), -delta)); + return true; } false @@ -1924,47 +2271,68 @@ impl Flow for BlockFlow { debug_assert!(remaining.is_none()); } - fn fragment(&mut self, layout_context: &LayoutContext, - fragmentation_context: Option) - -> Option> { + fn fragment( + &mut self, + layout_context: &LayoutContext, + fragmentation_context: Option, + ) -> Option> { if self.fragment.is_replaced() { - let _scope = layout_debug_scope!("assign_replaced_block_size_if_necessary {:x}", - self.base.debug_id()); + let _scope = layout_debug_scope!( + "assign_replaced_block_size_if_necessary {:x}", + self.base.debug_id() + ); // Assign block-size for fragment if it is an image fragment. self.fragment.assign_replaced_block_size_if_necessary(); - if !self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { + if !self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { self.base.position.size.block = self.fragment.border_box.size.block; - let mut block_start = AdjoiningMargins::from_margin(self.fragment.margin.block_start); + let mut block_start = + AdjoiningMargins::from_margin(self.fragment.margin.block_start); let block_end = AdjoiningMargins::from_margin(self.fragment.margin.block_end); if self.fragment.border_box.size.block == Au(0) { block_start.union(block_end); - self.base.collapsible_margins = CollapsibleMargins::CollapseThrough(block_start); + self.base.collapsible_margins = + CollapsibleMargins::CollapseThrough(block_start); } else { - self.base.collapsible_margins = CollapsibleMargins::Collapse(block_start, block_end); + self.base.collapsible_margins = + CollapsibleMargins::Collapse(block_start, block_end); } - self.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); - self.fragment.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | - ServoRestyleDamage::REFLOW); + self.base + .restyle_damage + .remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); + self.fragment + .restyle_damage + .remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); } None } else if self.is_root() || - self.formatting_context_type() != FormattingContextType::None || - self.base.flags.contains(FlowFlags::MARGINS_CANNOT_COLLAPSE) { + self.formatting_context_type() != FormattingContextType::None || + self.base.flags.contains(FlowFlags::MARGINS_CANNOT_COLLAPSE) + { // Root element margins should never be collapsed according to CSS § 8.3.1. - debug!("assign_block_size: assigning block_size for root flow {:?}", - self.base().debug_id()); + debug!( + "assign_block_size: assigning block_size for root flow {:?}", + self.base().debug_id() + ); self.assign_block_size_block_base( layout_context, fragmentation_context, - MarginsMayCollapseFlag::MarginsMayNotCollapse) + MarginsMayCollapseFlag::MarginsMayNotCollapse, + ) } else { - debug!("assign_block_size: assigning block_size for block {:?}", - self.base().debug_id()); + debug!( + "assign_block_size: assigning block_size for block {:?}", + self.base().debug_id() + ); self.assign_block_size_block_base( layout_context, fragmentation_context, - MarginsMayCollapseFlag::MarginsMayCollapse) + MarginsMayCollapseFlag::MarginsMayCollapse, + ) } } @@ -1977,9 +2345,16 @@ impl Flow for BlockFlow { self.base.clip = Rect::max_rect(); } - if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { - let position_start = self.base.position.start.to_physical(self.base.writing_mode, - container_size); + if self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { + let position_start = self + .base + .position + .start + .to_physical(self.base.writing_mode, container_size); // Compute our position relative to the nearest ancestor stacking context. This will be // passed down later as part of containing block details for absolute descendants. @@ -1991,21 +2366,38 @@ impl Flow for BlockFlow { // flow w.r.t. the containing block. self.base .late_absolute_position_info - .stacking_relative_position_of_absolute_containing_block + position_start.to_vector() + .stacking_relative_position_of_absolute_containing_block + + position_start.to_vector() }; if !self.base.writing_mode.is_vertical() { - if !self.base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) { + if !self + .base + .flags + .contains(FlowFlags::INLINE_POSITION_IS_STATIC) + { self.base.stacking_relative_position.x = absolute_stacking_relative_position.x } - if !self.base.flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) { + if !self + .base + .flags + .contains(FlowFlags::BLOCK_POSITION_IS_STATIC) + { self.base.stacking_relative_position.y = absolute_stacking_relative_position.y } } else { - if !self.base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) { + if !self + .base + .flags + .contains(FlowFlags::INLINE_POSITION_IS_STATIC) + { self.base.stacking_relative_position.y = absolute_stacking_relative_position.y } - if !self.base.flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) { + if !self + .base + .flags + .contains(FlowFlags::BLOCK_POSITION_IS_STATIC) + { self.base.stacking_relative_position.x = absolute_stacking_relative_position.x } } @@ -2014,28 +2406,33 @@ impl Flow for BlockFlow { // For relatively-positioned descendants, the containing block formed by a block is just // the content box. The containing block for absolutely-positioned descendants, on the // other hand, is established in other circumstances (see `is_absolute_containing_block'). - let relative_offset = - self.fragment.relative_position(&self.base - .early_absolute_position_info - .relative_containing_block_size); + let relative_offset = self.fragment.relative_position( + &self + .base + .early_absolute_position_info + .relative_containing_block_size, + ); if self.is_absolute_containing_block() { - let border_box_origin = (self.fragment.border_box - - self.fragment.style.logical_border_width()).start; + let border_box_origin = + (self.fragment.border_box - self.fragment.style.logical_border_width()).start; self.base .late_absolute_position_info .stacking_relative_position_of_absolute_containing_block = - self.base.stacking_relative_position.to_point() + - (border_box_origin + relative_offset).to_physical(self.base.writing_mode, - container_size).to_vector() + self.base.stacking_relative_position.to_point() + + (border_box_origin + relative_offset) + .to_physical(self.base.writing_mode, container_size) + .to_vector() } // Compute absolute position info for children. let stacking_relative_position_of_absolute_containing_block_for_children = if self.fragment.establishes_stacking_context() { let logical_border_width = self.fragment.style().logical_border_width(); - let position = LogicalPoint::new(self.base.writing_mode, - logical_border_width.inline_start, - logical_border_width.block_start); + let position = LogicalPoint::new( + self.base.writing_mode, + logical_border_width.inline_start, + logical_border_width.block_start, + ); let position = position.to_physical(self.base.writing_mode, container_size); // Some blocks establish a stacking context, but not a containing block for @@ -2061,7 +2458,9 @@ impl Flow for BlockFlow { self.base.position.size.to_physical(self.base.writing_mode); // Compute the origin and clipping rectangle for children. - let relative_offset = relative_offset.to_physical(self.base.writing_mode).to_vector(); + let relative_offset = relative_offset + .to_physical(self.base.writing_mode) + .to_vector(); let is_stacking_context = self.fragment.establishes_stacking_context(); let origin_for_children = if is_stacking_context { // We establish a stacking context, so the position of our children is vertically @@ -2078,36 +2477,48 @@ impl Flow for BlockFlow { // Process children. for kid in self.base.child_iter_mut() { - if kid.base().flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) || - kid.base().flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) { + if kid + .base() + .flags + .contains(FlowFlags::INLINE_POSITION_IS_STATIC) || + kid.base() + .flags + .contains(FlowFlags::BLOCK_POSITION_IS_STATIC) + { let kid_base = kid.mut_base(); - let physical_position = kid_base.position.to_physical(kid_base.writing_mode, - container_size_for_children); + let physical_position = kid_base + .position + .to_physical(kid_base.writing_mode, container_size_for_children); // Set the inline and block positions as necessary. if !kid_base.writing_mode.is_vertical() { - if kid_base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) { - kid_base.stacking_relative_position.x = origin_for_children.x + - physical_position.origin.x + if kid_base + .flags + .contains(FlowFlags::INLINE_POSITION_IS_STATIC) + { + kid_base.stacking_relative_position.x = + origin_for_children.x + physical_position.origin.x } if kid_base.flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) { - kid_base.stacking_relative_position.y = origin_for_children.y + - physical_position.origin.y + kid_base.stacking_relative_position.y = + origin_for_children.y + physical_position.origin.y } } else { - if kid_base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) { - kid_base.stacking_relative_position.y = origin_for_children.y + - physical_position.origin.y + if kid_base + .flags + .contains(FlowFlags::INLINE_POSITION_IS_STATIC) + { + kid_base.stacking_relative_position.y = + origin_for_children.y + physical_position.origin.y } if kid_base.flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) { - kid_base.stacking_relative_position.x = origin_for_children.x + - physical_position.origin.x + kid_base.stacking_relative_position.x = + origin_for_children.x + physical_position.origin.x } } } - kid.mut_base().late_absolute_position_info = - late_absolute_position_info_for_children; + kid.mut_base().late_absolute_position_info = late_absolute_position_info_for_children; } } @@ -2132,8 +2543,9 @@ impl Flow for BlockFlow { /// Returns true if this flow contains fragments that are roots of an absolute flow tree. fn contains_roots_of_absolute_flow_tree(&self) -> bool { - self.contains_relatively_positioned_fragments() || self.is_root() || - self.fragment.has_filter_transform_or_perspective() + self.contains_relatively_positioned_fragments() || + self.is_root() || + self.fragment.has_filter_transform_or_perspective() } /// Returns true if this is an absolute containing block. @@ -2142,21 +2554,27 @@ impl Flow for BlockFlow { } fn update_late_computed_inline_position_if_necessary(&mut self, inline_position: Au) { - if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && - self.fragment.style().logical_position().inline_start == - LengthOrPercentageOrAuto::Auto && - self.fragment.style().logical_position().inline_end == - LengthOrPercentageOrAuto::Auto { + if self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && + self.fragment.style().logical_position().inline_start == + LengthOrPercentageOrAuto::Auto && + self.fragment.style().logical_position().inline_end == LengthOrPercentageOrAuto::Auto + { self.base.position.start.i = inline_position } } fn update_late_computed_block_position_if_necessary(&mut self, block_position: Au) { - if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && - self.fragment.style().logical_position().block_start == - LengthOrPercentageOrAuto::Auto && - self.fragment.style().logical_position().block_end == - LengthOrPercentageOrAuto::Auto { + if self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && + self.fragment.style().logical_position().block_start == + LengthOrPercentageOrAuto::Auto && + self.fragment.style().logical_position().block_end == LengthOrPercentageOrAuto::Auto + { self.base.position.start.b = block_position } } @@ -2175,33 +2593,43 @@ impl Flow for BlockFlow { fn compute_overflow(&self) -> Overflow { let flow_size = self.base.position.size.to_physical(self.base.writing_mode); - let overflow = self.fragment.compute_overflow(&flow_size, - &self.base - .early_absolute_position_info - .relative_containing_block_size); + let overflow = self.fragment.compute_overflow( + &flow_size, + &self + .base + .early_absolute_position_info + .relative_containing_block_size, + ); overflow } - fn iterate_through_fragment_border_boxes(&self, - iterator: &mut FragmentBorderBoxIterator, - level: i32, - stacking_context_position: &Point2D) { + fn iterate_through_fragment_border_boxes( + &self, + iterator: &mut FragmentBorderBoxIterator, + level: i32, + stacking_context_position: &Point2D, + ) { if !iterator.should_process(&self.fragment) { - return + return; } - iterator.process(&self.fragment, - level, - &self.fragment - .stacking_relative_border_box(&self.base.stacking_relative_position, - &self.base - .early_absolute_position_info - .relative_containing_block_size, - self.base - .early_absolute_position_info - .relative_containing_block_mode, - CoordinateSystem::Own) - .translate(&stacking_context_position.to_vector())); + iterator.process( + &self.fragment, + level, + &self + .fragment + .stacking_relative_border_box( + &self.base.stacking_relative_position, + &self + .base + .early_absolute_position_info + .relative_containing_block_size, + self.base + .early_absolute_position_info + .relative_containing_block_mode, + CoordinateSystem::Own, + ).translate(&stacking_context_position.to_vector()), + ); } fn mutate_fragments(&mut self, mutator: &mut FnMut(&mut Fragment)) { @@ -2215,11 +2643,13 @@ impl Flow for BlockFlow { impl fmt::Debug for BlockFlow { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, - "{:?}({:x}) {:?}", - self.class(), - self.base.debug_id(), - self.base) + write!( + f, + "{:?}({:x}) {:?}", + self.class(), + self.base.debug_id(), + self.base + ) } } @@ -2236,14 +2666,15 @@ pub struct ISizeConstraintInput { } impl ISizeConstraintInput { - pub fn new(computed_inline_size: MaybeAuto, - inline_start_margin: MaybeAuto, - inline_end_margin: MaybeAuto, - inline_start: MaybeAuto, - inline_end: MaybeAuto, - text_align: TextAlign, - available_inline_size: Au) - -> ISizeConstraintInput { + pub fn new( + computed_inline_size: MaybeAuto, + inline_start_margin: MaybeAuto, + inline_end_margin: MaybeAuto, + inline_start: MaybeAuto, + inline_end: MaybeAuto, + text_align: TextAlign, + available_inline_size: Au, + ) -> ISizeConstraintInput { ISizeConstraintInput { computed_inline_size: computed_inline_size, inline_start_margin: inline_start_margin, @@ -2262,12 +2693,15 @@ pub struct ISizeConstraintSolution { pub inline_start: Au, pub inline_size: Au, pub margin_inline_start: Au, - pub margin_inline_end: Au + pub margin_inline_end: Au, } impl ISizeConstraintSolution { - pub fn new(inline_size: Au, margin_inline_start: Au, margin_inline_end: Au) - -> ISizeConstraintSolution { + pub fn new( + inline_size: Au, + margin_inline_start: Au, + margin_inline_end: Au, + ) -> ISizeConstraintSolution { ISizeConstraintSolution { inline_start: Au(0), inline_size: inline_size, @@ -2276,11 +2710,12 @@ impl ISizeConstraintSolution { } } - fn for_absolute_flow(inline_start: Au, - inline_size: Au, - margin_inline_start: Au, - margin_inline_end: Au) - -> ISizeConstraintSolution { + fn for_absolute_flow( + inline_start: Au, + inline_size: Au, + margin_inline_start: Au, + margin_inline_end: Au, + ) -> ISizeConstraintSolution { ISizeConstraintSolution { inline_start: inline_start, inline_size: inline_size, @@ -2296,54 +2731,57 @@ impl ISizeConstraintSolution { pub trait ISizeAndMarginsComputer { /// Instructs the fragment to compute its border and padding. fn compute_border_and_padding(&self, block: &mut BlockFlow, containing_block_inline_size: Au) { - block.fragment.compute_border_and_padding(containing_block_inline_size); + block + .fragment + .compute_border_and_padding(containing_block_inline_size); } /// Compute the inputs for the ISize constraint equation. /// /// This is called only once to compute the initial inputs. For calculations involving /// minimum and maximum inline-size, we don't need to recompute these. - fn compute_inline_size_constraint_inputs(&self, - block: &mut BlockFlow, - parent_flow_inline_size: Au, - shared_context: &SharedStyleContext) - -> ISizeConstraintInput { + fn compute_inline_size_constraint_inputs( + &self, + block: &mut BlockFlow, + parent_flow_inline_size: Au, + shared_context: &SharedStyleContext, + ) -> ISizeConstraintInput { let containing_block_inline_size = self.containing_block_inline_size(block, parent_flow_inline_size, shared_context); - block.fragment.compute_block_direction_margins(containing_block_inline_size); - block.fragment.compute_inline_direction_margins(containing_block_inline_size); + block + .fragment + .compute_block_direction_margins(containing_block_inline_size); + block + .fragment + .compute_inline_direction_margins(containing_block_inline_size); self.compute_border_and_padding(block, containing_block_inline_size); - let mut computed_inline_size = self.initial_computed_inline_size(block, - parent_flow_inline_size, - shared_context); + let mut computed_inline_size = + self.initial_computed_inline_size(block, parent_flow_inline_size, shared_context); let style = block.fragment.style(); match (computed_inline_size, style.get_position().box_sizing) { (MaybeAuto::Specified(size), BoxSizing::BorderBox) => { computed_inline_size = MaybeAuto::Specified(size - block.fragment.border_padding.inline_start_end()) - } - (MaybeAuto::Auto, BoxSizing::BorderBox) | - (_, BoxSizing::ContentBox) => {} + }, + (MaybeAuto::Auto, BoxSizing::BorderBox) | (_, BoxSizing::ContentBox) => {}, } let margin = style.logical_margin(); let position = style.logical_position(); - let available_inline_size = containing_block_inline_size - - block.fragment.border_padding.inline_start_end(); - ISizeConstraintInput::new(computed_inline_size, - MaybeAuto::from_style(margin.inline_start, - containing_block_inline_size), - MaybeAuto::from_style(margin.inline_end, - containing_block_inline_size), - MaybeAuto::from_style(position.inline_start, - containing_block_inline_size), - MaybeAuto::from_style(position.inline_end, - containing_block_inline_size), - style.get_inherited_text().text_align, - available_inline_size) + let available_inline_size = + containing_block_inline_size - block.fragment.border_padding.inline_start_end(); + ISizeConstraintInput::new( + computed_inline_size, + MaybeAuto::from_style(margin.inline_start, containing_block_inline_size), + MaybeAuto::from_style(margin.inline_end, containing_block_inline_size), + MaybeAuto::from_style(position.inline_start, containing_block_inline_size), + MaybeAuto::from_style(position.inline_end, containing_block_inline_size), + style.get_inherited_text().text_align, + available_inline_size, + ) } /// Set the used values for inline-size and margins from the relevant constraint equation. @@ -2355,9 +2793,11 @@ pub trait ISizeAndMarginsComputer { /// * Inline-start coordinate of this flow's box; /// * Inline-start coordinate of the flow with respect to its containing block (if this is an /// absolute flow). - fn set_inline_size_constraint_solutions(&self, - block: &mut BlockFlow, - solution: ISizeConstraintSolution) { + fn set_inline_size_constraint_solutions( + &self, + block: &mut BlockFlow, + solution: ISizeConstraintSolution, + ) { let inline_size; let extra_inline_size_from_margin; { @@ -2388,8 +2828,8 @@ pub trait ISizeAndMarginsComputer { // To calculate the total size of this block, we also need to account for any // additional size contribution from positive margins. Negative margins means the block // isn't made larger at all by the margin. - extra_inline_size_from_margin = max(Au(0), fragment.margin.inline_start) + - max(Au(0), fragment.margin.inline_end); + extra_inline_size_from_margin = + max(Au(0), fragment.margin.inline_start) + max(Au(0), fragment.margin.inline_end); } // We also resize the block itself, to ensure that overflow is not calculated @@ -2399,45 +2839,55 @@ pub trait ISizeAndMarginsComputer { } /// Set the inline coordinate of the given flow if it is absolutely positioned. - fn set_inline_position_of_flow_if_necessary(&self, - _: &mut BlockFlow, - _: ISizeConstraintSolution) {} - - /// Solve the inline-size and margins constraints for this block flow. - fn solve_inline_size_constraints(&self, - block: &mut BlockFlow, - input: &ISizeConstraintInput) - -> ISizeConstraintSolution; - - fn initial_computed_inline_size(&self, - block: &mut BlockFlow, - parent_flow_inline_size: Au, - shared_context: &SharedStyleContext) - -> MaybeAuto { - MaybeAuto::from_style(block.fragment().style().content_inline_size(), - self.containing_block_inline_size(block, - parent_flow_inline_size, - shared_context)) + fn set_inline_position_of_flow_if_necessary( + &self, + _: &mut BlockFlow, + _: ISizeConstraintSolution, + ) { } - fn containing_block_inline_size(&self, - _: &mut BlockFlow, - parent_flow_inline_size: Au, - _: &SharedStyleContext) - -> Au { + /// Solve the inline-size and margins constraints for this block flow. + fn solve_inline_size_constraints( + &self, + block: &mut BlockFlow, + input: &ISizeConstraintInput, + ) -> ISizeConstraintSolution; + + fn initial_computed_inline_size( + &self, + block: &mut BlockFlow, + parent_flow_inline_size: Au, + shared_context: &SharedStyleContext, + ) -> MaybeAuto { + MaybeAuto::from_style( + block.fragment().style().content_inline_size(), + self.containing_block_inline_size(block, parent_flow_inline_size, shared_context), + ) + } + + fn containing_block_inline_size( + &self, + _: &mut BlockFlow, + parent_flow_inline_size: Au, + _: &SharedStyleContext, + ) -> Au { parent_flow_inline_size } /// Compute the used value of inline-size, taking care of min-inline-size and max-inline-size. /// /// CSS Section 10.4: Minimum and Maximum inline-sizes - fn compute_used_inline_size(&self, - block: &mut BlockFlow, - shared_context: &SharedStyleContext, - parent_flow_inline_size: Au) { - let mut input = self.compute_inline_size_constraint_inputs(block, - parent_flow_inline_size, - shared_context); + fn compute_used_inline_size( + &self, + block: &mut BlockFlow, + shared_context: &SharedStyleContext, + parent_flow_inline_size: Au, + ) { + let mut input = self.compute_inline_size_constraint_inputs( + block, + parent_flow_inline_size, + shared_context, + ); let containing_block_inline_size = self.containing_block_inline_size(block, parent_flow_inline_size, shared_context); @@ -2447,19 +2897,27 @@ pub trait ISizeAndMarginsComputer { // If the tentative used inline-size is greater than 'max-inline-size', inline-size should // be recalculated, but this time using the computed value of 'max-inline-size' as the // computed value for 'inline-size'. - match block.fragment().style().max_inline_size().to_used_value(containing_block_inline_size) { + match block + .fragment() + .style() + .max_inline_size() + .to_used_value(containing_block_inline_size) + { Some(max_inline_size) if max_inline_size < solution.inline_size => { input.computed_inline_size = MaybeAuto::Specified(max_inline_size); solution = self.solve_inline_size_constraints(block, &input); - } - _ => {} + }, + _ => {}, } // If the resulting inline-size is smaller than 'min-inline-size', inline-size should be // recalculated, but this time using the value of 'min-inline-size' as the computed value // for 'inline-size'. - let computed_min_inline_size = - block.fragment().style().min_inline_size().to_used_value(containing_block_inline_size); + let computed_min_inline_size = block + .fragment() + .style() + .min_inline_size() + .to_used_value(containing_block_inline_size); if computed_min_inline_size > solution.inline_size { input.computed_inline_size = MaybeAuto::Specified(computed_min_inline_size); solution = self.solve_inline_size_constraints(block, &input); @@ -2477,15 +2935,17 @@ pub trait ISizeAndMarginsComputer { /// Constraint Equation: margin-inline-start + margin-inline-end + inline-size = /// available_inline-size /// where available_inline-size = CB inline-size - (horizontal border + padding) - fn solve_block_inline_size_constraints(&self, - block: &mut BlockFlow, - input: &ISizeConstraintInput) - -> ISizeConstraintSolution { - let (computed_inline_size, inline_start_margin, inline_end_margin, available_inline_size) = - (input.computed_inline_size, - input.inline_start_margin, - input.inline_end_margin, - input.available_inline_size); + fn solve_block_inline_size_constraints( + &self, + block: &mut BlockFlow, + input: &ISizeConstraintInput, + ) -> ISizeConstraintSolution { + let (computed_inline_size, inline_start_margin, inline_end_margin, available_inline_size) = ( + input.computed_inline_size, + input.inline_start_margin, + input.inline_end_margin, + input.available_inline_size, + ); // Check for direction of parent flow (NOT Containing Block) let block_mode = block.base.writing_mode; @@ -2504,11 +2964,14 @@ pub trait ISizeAndMarginsComputer { let inline_end = inline_end_margin.specified_or_zero(); if (inline_start + inline_end + inline_size) > available_inline_size { - (MaybeAuto::Specified(inline_start), MaybeAuto::Specified(inline_end)) + ( + MaybeAuto::Specified(inline_start), + MaybeAuto::Specified(inline_end), + ) } else { (inline_start_margin, inline_end_margin) } - } + }, }; // Invariant: inline-start_margin + inline-size + inline-end_margin == @@ -2516,9 +2979,11 @@ pub trait ISizeAndMarginsComputer { let (inline_start_margin, inline_size, inline_end_margin) = match (inline_start_margin, computed_inline_size, inline_end_margin) { // If all have a computed value other than 'auto', the system is over-constrained. - (MaybeAuto::Specified(margin_start), - MaybeAuto::Specified(inline_size), - MaybeAuto::Specified(margin_end)) => { + ( + MaybeAuto::Specified(margin_start), + MaybeAuto::Specified(inline_size), + MaybeAuto::Specified(margin_end), + ) => { // servo_left, servo_right, and servo_center are used to implement // the "align descendants" rule in HTML5 § 14.2. if block_align == TextAlign::ServoCenter { @@ -2533,52 +2998,66 @@ pub trait ISizeAndMarginsComputer { _ => parent_has_same_direction, }; if ignore_end_margin { - (margin_start, inline_size, available_inline_size - - (margin_start + inline_size)) + ( + margin_start, + inline_size, + available_inline_size - (margin_start + inline_size), + ) } else { - (available_inline_size - (margin_end + inline_size), - inline_size, - margin_end) + ( + available_inline_size - (margin_end + inline_size), + inline_size, + margin_end, + ) } } - } + }, // If exactly one value is 'auto', solve for it - (MaybeAuto::Auto, - MaybeAuto::Specified(inline_size), - MaybeAuto::Specified(margin_end)) => - (available_inline_size - (inline_size + margin_end), inline_size, margin_end), - (MaybeAuto::Specified(margin_start), - MaybeAuto::Auto, - MaybeAuto::Specified(margin_end)) => { - (margin_start, - available_inline_size - (margin_start + margin_end), - margin_end) - } - (MaybeAuto::Specified(margin_start), - MaybeAuto::Specified(inline_size), - MaybeAuto::Auto) => { - (margin_start, - inline_size, - available_inline_size - (margin_start + inline_size)) - } + ( + MaybeAuto::Auto, + MaybeAuto::Specified(inline_size), + MaybeAuto::Specified(margin_end), + ) => ( + available_inline_size - (inline_size + margin_end), + inline_size, + margin_end, + ), + ( + MaybeAuto::Specified(margin_start), + MaybeAuto::Auto, + MaybeAuto::Specified(margin_end), + ) => ( + margin_start, + available_inline_size - (margin_start + margin_end), + margin_end, + ), + ( + MaybeAuto::Specified(margin_start), + MaybeAuto::Specified(inline_size), + MaybeAuto::Auto, + ) => ( + margin_start, + inline_size, + available_inline_size - (margin_start + inline_size), + ), // If inline-size is set to 'auto', any other 'auto' value becomes '0', // and inline-size is solved for (MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Specified(margin_end)) => { (Au(0), available_inline_size - margin_end, margin_end) - } + }, (MaybeAuto::Specified(margin_start), MaybeAuto::Auto, MaybeAuto::Auto) => { (margin_start, available_inline_size - margin_start, Au(0)) - } + }, (MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Auto) => { (Au(0), available_inline_size, Au(0)) - } + }, // If inline-start and inline-end margins are auto, they become equal (MaybeAuto::Auto, MaybeAuto::Specified(inline_size), MaybeAuto::Auto) => { let margin = (available_inline_size - inline_size).scale_by(0.5); (margin, inline_size, margin) - } + }, }; ISizeConstraintSolution::new(inline_size, inline_start_margin, inline_end_margin) @@ -2609,10 +3088,11 @@ impl ISizeAndMarginsComputer for AbsoluteNonReplaced { /// [aka available inline-size] /// /// Return the solution for the equation. - fn solve_inline_size_constraints(&self, - block: &mut BlockFlow, - input: &ISizeConstraintInput) - -> ISizeConstraintSolution { + fn solve_inline_size_constraints( + &self, + block: &mut BlockFlow, + input: &ISizeConstraintInput, + ) -> ISizeConstraintSolution { let &ISizeConstraintInput { computed_inline_size, inline_start_margin, @@ -2639,14 +3119,16 @@ impl ISizeAndMarginsComputer for AbsoluteNonReplaced { // and inline-size Auto. // Set inline-end to zero to calculate inline-size. - let inline_size = - block.get_shrink_to_fit_inline_size(available_inline_size - - (margin_start + margin_end)); + let inline_size = block.get_shrink_to_fit_inline_size( + available_inline_size - (margin_start + margin_end), + ); (Au(0), inline_size, margin_start, margin_end) - } - (MaybeAuto::Specified(inline_start), - MaybeAuto::Specified(inline_end), - MaybeAuto::Specified(inline_size)) => { + }, + ( + MaybeAuto::Specified(inline_start), + MaybeAuto::Specified(inline_end), + MaybeAuto::Specified(inline_size), + ) => { match (inline_start_margin, inline_end_margin) { (MaybeAuto::Auto, MaybeAuto::Auto) => { let total_margin_val = @@ -2662,20 +3144,32 @@ impl ISizeAndMarginsComputer for AbsoluteNonReplaced { } } else { // Equal margins - (inline_start, - inline_size, - total_margin_val.scale_by(0.5), - total_margin_val.scale_by(0.5)) + ( + inline_start, + inline_size, + total_margin_val.scale_by(0.5), + total_margin_val.scale_by(0.5), + ) } - } + }, (MaybeAuto::Specified(margin_start), MaybeAuto::Auto) => { let sum = inline_start + inline_end + inline_size + margin_start; - (inline_start, inline_size, margin_start, available_inline_size - sum) - } + ( + inline_start, + inline_size, + margin_start, + available_inline_size - sum, + ) + }, (MaybeAuto::Auto, MaybeAuto::Specified(margin_end)) => { let sum = inline_start + inline_end + inline_size + margin_end; - (inline_start, inline_size, available_inline_size - sum, margin_end) - } + ( + inline_start, + inline_size, + available_inline_size - sum, + margin_end, + ) + }, (MaybeAuto::Specified(margin_start), MaybeAuto::Specified(margin_end)) => { // Values are over-constrained. let sum = inline_start + inline_size + margin_start + margin_end; @@ -2684,40 +3178,58 @@ impl ISizeAndMarginsComputer for AbsoluteNonReplaced { (inline_start, inline_size, margin_start, margin_end) } else { // Ignore value for 'inline-start' - (available_inline_size - sum, - inline_size, - margin_start, - margin_end) + ( + available_inline_size - sum, + inline_size, + margin_start, + margin_end, + ) } - } + }, } - } + }, // For the rest of the cases, auto values for margin are set to 0 // If only one is Auto, solve for it - (MaybeAuto::Auto, - MaybeAuto::Specified(inline_end), - MaybeAuto::Specified(inline_size)) => { + ( + MaybeAuto::Auto, + MaybeAuto::Specified(inline_end), + MaybeAuto::Specified(inline_size), + ) => { let margin_start = inline_start_margin.specified_or_zero(); let margin_end = inline_end_margin.specified_or_zero(); let sum = inline_end + inline_size + margin_start + margin_end; - (available_inline_size - sum, inline_size, margin_start, margin_end) - } - (MaybeAuto::Specified(inline_start), - MaybeAuto::Auto, - MaybeAuto::Specified(inline_size)) => { + ( + available_inline_size - sum, + inline_size, + margin_start, + margin_end, + ) + }, + ( + MaybeAuto::Specified(inline_start), + MaybeAuto::Auto, + MaybeAuto::Specified(inline_size), + ) => { let margin_start = inline_start_margin.specified_or_zero(); let margin_end = inline_end_margin.specified_or_zero(); (inline_start, inline_size, margin_start, margin_end) - } - (MaybeAuto::Specified(inline_start), - MaybeAuto::Specified(inline_end), - MaybeAuto::Auto) => { + }, + ( + MaybeAuto::Specified(inline_start), + MaybeAuto::Specified(inline_end), + MaybeAuto::Auto, + ) => { let margin_start = inline_start_margin.specified_or_zero(); let margin_end = inline_end_margin.specified_or_zero(); let sum = inline_start + inline_end + margin_start + margin_end; - (inline_start, available_inline_size - sum, margin_start, margin_end) - } + ( + inline_start, + available_inline_size - sum, + margin_start, + margin_end, + ) + }, // If inline-size is auto, then inline-size is shrink-to-fit. Solve for the // non-auto value. @@ -2725,21 +3237,26 @@ impl ISizeAndMarginsComputer for AbsoluteNonReplaced { let margin_start = inline_start_margin.specified_or_zero(); let margin_end = inline_end_margin.specified_or_zero(); // Set inline-end to zero to calculate inline-size - let inline_size = - block.get_shrink_to_fit_inline_size(available_inline_size - - (margin_start + margin_end)); + let inline_size = block.get_shrink_to_fit_inline_size( + available_inline_size - (margin_start + margin_end), + ); (inline_start, inline_size, margin_start, margin_end) - } + }, (MaybeAuto::Auto, MaybeAuto::Specified(inline_end), MaybeAuto::Auto) => { let margin_start = inline_start_margin.specified_or_zero(); let margin_end = inline_end_margin.specified_or_zero(); // Set inline-start to zero to calculate inline-size - let inline_size = - block.get_shrink_to_fit_inline_size(available_inline_size - - (margin_start + margin_end)); + let inline_size = block.get_shrink_to_fit_inline_size( + available_inline_size - (margin_start + margin_end), + ); let sum = inline_end + inline_size + margin_start + margin_end; - (available_inline_size - sum, inline_size, margin_start, margin_end) - } + ( + available_inline_size - sum, + inline_size, + margin_start, + margin_end, + ) + }, (MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Specified(inline_size)) => { let margin_start = inline_start_margin.specified_or_zero(); @@ -2747,28 +3264,39 @@ impl ISizeAndMarginsComputer for AbsoluteNonReplaced { // Setting 'inline-start' to static position because direction is 'ltr'. // TODO: Handle 'rtl' when it is implemented. (Au(0), inline_size, margin_start, margin_end) - } + }, }; - ISizeConstraintSolution::for_absolute_flow(inline_start, - inline_size, - margin_inline_start, - margin_inline_end) + ISizeConstraintSolution::for_absolute_flow( + inline_start, + inline_size, + margin_inline_start, + margin_inline_end, + ) } - fn containing_block_inline_size(&self, - block: &mut BlockFlow, - _: Au, - shared_context: &SharedStyleContext) - -> Au { + fn containing_block_inline_size( + &self, + block: &mut BlockFlow, + _: Au, + shared_context: &SharedStyleContext, + ) -> Au { let opaque_block = OpaqueFlow::from_flow(block); - block.containing_block_size(&shared_context.viewport_size(), opaque_block).inline + block + .containing_block_size(&shared_context.viewport_size(), opaque_block) + .inline } - fn set_inline_position_of_flow_if_necessary(&self, - block: &mut BlockFlow, - solution: ISizeConstraintSolution) { + fn set_inline_position_of_flow_if_necessary( + &self, + block: &mut BlockFlow, + solution: ISizeConstraintSolution, + ) { // Set the inline position of the absolute flow wrt to its containing block. - if !block.base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) { + if !block + .base + .flags + .contains(FlowFlags::INLINE_POSITION_IS_STATIC) + { block.base.position.start.i = solution.inline_start; } } @@ -2784,8 +3312,11 @@ impl ISizeAndMarginsComputer for AbsoluteReplaced { /// [aka available_inline-size] /// /// Return the solution for the equation. - fn solve_inline_size_constraints(&self, _: &mut BlockFlow, input: &ISizeConstraintInput) - -> ISizeConstraintSolution { + fn solve_inline_size_constraints( + &self, + _: &mut BlockFlow, + input: &ISizeConstraintInput, + ) -> ISizeConstraintSolution { let &ISizeConstraintInput { computed_inline_size, inline_start_margin, @@ -2803,9 +3334,11 @@ impl ISizeAndMarginsComputer for AbsoluteReplaced { let inline_size = match computed_inline_size { MaybeAuto::Specified(w) => w, - _ => panic!("{} {}", - "The used value for inline_size for absolute replaced flow", - "should have already been calculated by now.") + _ => panic!( + "{} {}", + "The used value for inline_size for absolute replaced flow", + "should have already been calculated by now." + ), }; let (inline_start, inline_size, margin_inline_start, margin_inline_end) = @@ -2814,86 +3347,115 @@ impl ISizeAndMarginsComputer for AbsoluteReplaced { let margin_start = inline_start_margin.specified_or_zero(); let margin_end = inline_end_margin.specified_or_zero(); (Au(0), inline_size, margin_start, margin_end) - } + }, // If only one is Auto, solve for it (MaybeAuto::Auto, MaybeAuto::Specified(inline_end)) => { let margin_start = inline_start_margin.specified_or_zero(); let margin_end = inline_end_margin.specified_or_zero(); let sum = inline_end + inline_size + margin_start + margin_end; - (available_inline_size - sum, inline_size, margin_start, margin_end) - } + ( + available_inline_size - sum, + inline_size, + margin_start, + margin_end, + ) + }, (MaybeAuto::Specified(inline_start), MaybeAuto::Auto) => { let margin_start = inline_start_margin.specified_or_zero(); let margin_end = inline_end_margin.specified_or_zero(); (inline_start, inline_size, margin_start, margin_end) - } + }, (MaybeAuto::Specified(inline_start), MaybeAuto::Specified(inline_end)) => { match (inline_start_margin, inline_end_margin) { (MaybeAuto::Auto, MaybeAuto::Auto) => { - let total_margin_val = available_inline_size - inline_start - - inline_end - inline_size; + let total_margin_val = + available_inline_size - inline_start - inline_end - inline_size; if total_margin_val < Au(0) { // margin-inline-start becomes 0 because direction is 'ltr'. (inline_start, inline_size, Au(0), total_margin_val) } else { // Equal margins - (inline_start, - inline_size, - total_margin_val.scale_by(0.5), - total_margin_val.scale_by(0.5)) + ( + inline_start, + inline_size, + total_margin_val.scale_by(0.5), + total_margin_val.scale_by(0.5), + ) } - } + }, (MaybeAuto::Specified(margin_start), MaybeAuto::Auto) => { let sum = inline_start + inline_end + inline_size + margin_start; - (inline_start, inline_size, margin_start, available_inline_size - sum) - } + ( + inline_start, + inline_size, + margin_start, + available_inline_size - sum, + ) + }, (MaybeAuto::Auto, MaybeAuto::Specified(margin_end)) => { let sum = inline_start + inline_end + inline_size + margin_end; - (inline_start, inline_size, available_inline_size - sum, margin_end) - } + ( + inline_start, + inline_size, + available_inline_size - sum, + margin_end, + ) + }, (MaybeAuto::Specified(margin_start), MaybeAuto::Specified(margin_end)) => { // Values are over-constrained. // Ignore value for 'inline-end' cos direction is 'ltr'. (inline_start, inline_size, margin_start, margin_end) - } + }, } - } + }, }; - ISizeConstraintSolution::for_absolute_flow(inline_start, - inline_size, - margin_inline_start, - margin_inline_end) + ISizeConstraintSolution::for_absolute_flow( + inline_start, + inline_size, + margin_inline_start, + margin_inline_end, + ) } /// Calculate used value of inline-size just like we do for inline replaced elements. - fn initial_computed_inline_size(&self, - block: &mut BlockFlow, - _: Au, - shared_context: &SharedStyleContext) - -> MaybeAuto { + fn initial_computed_inline_size( + &self, + block: &mut BlockFlow, + _: Au, + shared_context: &SharedStyleContext, + ) -> MaybeAuto { let opaque_block = OpaqueFlow::from_flow(block); - let containing_block_inline_size = - block.containing_block_size(&shared_context.viewport_size(), opaque_block).inline; + let containing_block_inline_size = block + .containing_block_size(&shared_context.viewport_size(), opaque_block) + .inline; let container_block_size = block.explicit_block_containing_size(shared_context); let fragment = block.fragment(); - fragment.assign_replaced_inline_size_if_necessary(containing_block_inline_size, container_block_size); + fragment.assign_replaced_inline_size_if_necessary( + containing_block_inline_size, + container_block_size, + ); // For replaced absolute flow, the rest of the constraint solving will // take inline-size to be specified as the value computed here. MaybeAuto::Specified(fragment.content_box().size.inline) } - fn containing_block_inline_size(&self, - block: &mut BlockFlow, - _: Au, - shared_context: &SharedStyleContext) - -> Au { + fn containing_block_inline_size( + &self, + block: &mut BlockFlow, + _: Au, + shared_context: &SharedStyleContext, + ) -> Au { let opaque_block = OpaqueFlow::from_flow(block); - block.containing_block_size(&shared_context.viewport_size(), opaque_block).inline + block + .containing_block_size(&shared_context.viewport_size(), opaque_block) + .inline } - fn set_inline_position_of_flow_if_necessary(&self, - block: &mut BlockFlow, - solution: ISizeConstraintSolution) { + fn set_inline_position_of_flow_if_necessary( + &self, + block: &mut BlockFlow, + solution: ISizeConstraintSolution, + ) { // Set the x-coordinate of the absolute flow wrt to its containing block. block.base.position.start.i = solution.inline_start; } @@ -2901,10 +3463,11 @@ impl ISizeAndMarginsComputer for AbsoluteReplaced { impl ISizeAndMarginsComputer for BlockNonReplaced { /// Compute inline-start and inline-end margins and inline-size. - fn solve_inline_size_constraints(&self, - block: &mut BlockFlow, - input: &ISizeConstraintInput) - -> ISizeConstraintSolution { + fn solve_inline_size_constraints( + &self, + block: &mut BlockFlow, + input: &ISizeConstraintInput, + ) -> ISizeConstraintSolution { self.solve_block_inline_size_constraints(block, input) } } @@ -2914,55 +3477,64 @@ impl ISizeAndMarginsComputer for BlockReplaced { /// /// ISize has already been calculated. We now calculate the margins just /// like for non-replaced blocks. - fn solve_inline_size_constraints(&self, - block: &mut BlockFlow, - input: &ISizeConstraintInput) - -> ISizeConstraintSolution { + fn solve_inline_size_constraints( + &self, + block: &mut BlockFlow, + input: &ISizeConstraintInput, + ) -> ISizeConstraintSolution { match input.computed_inline_size { MaybeAuto::Specified(_) => {}, MaybeAuto::Auto => { panic!("BlockReplaced: inline_size should have been computed by now") - } + }, }; self.solve_block_inline_size_constraints(block, input) } /// Calculate used value of inline-size just like we do for inline replaced elements. - fn initial_computed_inline_size(&self, - block: &mut BlockFlow, - parent_flow_inline_size: Au, - shared_context: &SharedStyleContext) - -> MaybeAuto { + fn initial_computed_inline_size( + &self, + block: &mut BlockFlow, + parent_flow_inline_size: Au, + shared_context: &SharedStyleContext, + ) -> MaybeAuto { let container_block_size = block.explicit_block_containing_size(shared_context); let fragment = block.fragment(); - fragment.assign_replaced_inline_size_if_necessary(parent_flow_inline_size, container_block_size); + fragment.assign_replaced_inline_size_if_necessary( + parent_flow_inline_size, + container_block_size, + ); // For replaced block flow, the rest of the constraint solving will // take inline-size to be specified as the value computed here. MaybeAuto::Specified(fragment.content_box().size.inline) } - } impl ISizeAndMarginsComputer for FloatNonReplaced { /// CSS Section 10.3.5 /// /// If inline-size is computed as 'auto', the used value is the 'shrink-to-fit' inline-size. - fn solve_inline_size_constraints(&self, - block: &mut BlockFlow, - input: &ISizeConstraintInput) - -> ISizeConstraintSolution { - let (computed_inline_size, inline_start_margin, inline_end_margin, available_inline_size) = - (input.computed_inline_size, - input.inline_start_margin, - input.inline_end_margin, - input.available_inline_size); + fn solve_inline_size_constraints( + &self, + block: &mut BlockFlow, + input: &ISizeConstraintInput, + ) -> ISizeConstraintSolution { + let (computed_inline_size, inline_start_margin, inline_end_margin, available_inline_size) = ( + input.computed_inline_size, + input.inline_start_margin, + input.inline_end_margin, + input.available_inline_size, + ); let margin_inline_start = inline_start_margin.specified_or_zero(); let margin_inline_end = inline_end_margin.specified_or_zero(); - let available_inline_size_float = available_inline_size - margin_inline_start - - margin_inline_end; + let available_inline_size_float = + available_inline_size - margin_inline_start - margin_inline_end; let shrink_to_fit = block.get_shrink_to_fit_inline_size(available_inline_size_float); let inline_size = computed_inline_size.specified_or_default(shrink_to_fit); - debug!("assign_inline_sizes_float -- inline_size: {:?}", inline_size); + debug!( + "assign_inline_sizes_float -- inline_size: {:?}", + inline_size + ); ISizeConstraintSolution::new(inline_size, margin_inline_start, margin_inline_end) } } @@ -2971,29 +3543,44 @@ impl ISizeAndMarginsComputer for FloatReplaced { /// CSS Section 10.3.5 /// /// If inline-size is computed as 'auto', the used value is the 'shrink-to-fit' inline-size. - fn solve_inline_size_constraints(&self, _: &mut BlockFlow, input: &ISizeConstraintInput) - -> ISizeConstraintSolution { - let (computed_inline_size, inline_start_margin, inline_end_margin) = - (input.computed_inline_size, input.inline_start_margin, input.inline_end_margin); + fn solve_inline_size_constraints( + &self, + _: &mut BlockFlow, + input: &ISizeConstraintInput, + ) -> ISizeConstraintSolution { + let (computed_inline_size, inline_start_margin, inline_end_margin) = ( + input.computed_inline_size, + input.inline_start_margin, + input.inline_end_margin, + ); let margin_inline_start = inline_start_margin.specified_or_zero(); let margin_inline_end = inline_end_margin.specified_or_zero(); let inline_size = match computed_inline_size { MaybeAuto::Specified(w) => w, - MaybeAuto::Auto => panic!("FloatReplaced: inline_size should have been computed by now") + MaybeAuto::Auto => { + panic!("FloatReplaced: inline_size should have been computed by now") + }, }; - debug!("assign_inline_sizes_float -- inline_size: {:?}", inline_size); + debug!( + "assign_inline_sizes_float -- inline_size: {:?}", + inline_size + ); ISizeConstraintSolution::new(inline_size, margin_inline_start, margin_inline_end) } /// Calculate used value of inline-size just like we do for inline replaced elements. - fn initial_computed_inline_size(&self, - block: &mut BlockFlow, - parent_flow_inline_size: Au, - shared_context: &SharedStyleContext) - -> MaybeAuto { + fn initial_computed_inline_size( + &self, + block: &mut BlockFlow, + parent_flow_inline_size: Au, + shared_context: &SharedStyleContext, + ) -> MaybeAuto { let container_block_size = block.explicit_block_containing_size(shared_context); let fragment = block.fragment(); - fragment.assign_replaced_inline_size_if_necessary(parent_flow_inline_size, container_block_size); + fragment.assign_replaced_inline_size_if_necessary( + parent_flow_inline_size, + container_block_size, + ); // For replaced block flow, the rest of the constraint solving will // take inline-size to be specified as the value computed here. MaybeAuto::Specified(fragment.content_box().size.inline) @@ -3002,18 +3589,17 @@ impl ISizeAndMarginsComputer for FloatReplaced { impl ISizeAndMarginsComputer for InlineBlockNonReplaced { /// Compute inline-start and inline-end margins and inline-size. - fn solve_inline_size_constraints(&self, - block: &mut BlockFlow, - input: &ISizeConstraintInput) - -> ISizeConstraintSolution { - let (computed_inline_size, - inline_start_margin, - inline_end_margin, - available_inline_size) = - (input.computed_inline_size, - input.inline_start_margin, - input.inline_end_margin, - input.available_inline_size); + fn solve_inline_size_constraints( + &self, + block: &mut BlockFlow, + input: &ISizeConstraintInput, + ) -> ISizeConstraintSolution { + let (computed_inline_size, inline_start_margin, inline_end_margin, available_inline_size) = ( + input.computed_inline_size, + input.inline_start_margin, + input.inline_end_margin, + input.available_inline_size, + ); // For inline-blocks, `auto` margins compute to 0. let inline_start_margin = inline_start_margin.specified_or_zero(); @@ -3022,10 +3608,9 @@ impl ISizeAndMarginsComputer for InlineBlockNonReplaced { // If inline-size is set to 'auto', and this is an inline block, use the // shrink to fit algorithm (see CSS 2.1 § 10.3.9) let inline_size = match computed_inline_size { - MaybeAuto::Auto => { - block.get_shrink_to_fit_inline_size(available_inline_size - (inline_start_margin + - inline_end_margin)) - } + MaybeAuto::Auto => block.get_shrink_to_fit_inline_size( + available_inline_size - (inline_start_margin + inline_end_margin), + ), MaybeAuto::Specified(inline_size) => inline_size, }; @@ -3038,23 +3623,22 @@ impl ISizeAndMarginsComputer for InlineBlockReplaced { /// /// ISize has already been calculated. We now calculate the margins just /// like for non-replaced blocks. - fn solve_inline_size_constraints(&self, - block: &mut BlockFlow, - input: &ISizeConstraintInput) - -> ISizeConstraintSolution { + fn solve_inline_size_constraints( + &self, + block: &mut BlockFlow, + input: &ISizeConstraintInput, + ) -> ISizeConstraintSolution { debug_assert!(match input.computed_inline_size { MaybeAuto::Specified(_) => true, MaybeAuto::Auto => false, }); - let (computed_inline_size, - inline_start_margin, - inline_end_margin, - available_inline_size) = - (input.computed_inline_size, - input.inline_start_margin, - input.inline_end_margin, - input.available_inline_size); + let (computed_inline_size, inline_start_margin, inline_end_margin, available_inline_size) = ( + input.computed_inline_size, + input.inline_start_margin, + input.inline_end_margin, + input.available_inline_size, + ); // For inline-blocks, `auto` margins compute to 0. let inline_start_margin = inline_start_margin.specified_or_zero(); @@ -3063,10 +3647,9 @@ impl ISizeAndMarginsComputer for InlineBlockReplaced { // If inline-size is set to 'auto', and this is an inline block, use the // shrink to fit algorithm (see CSS 2.1 § 10.3.9) let inline_size = match computed_inline_size { - MaybeAuto::Auto => { - block.get_shrink_to_fit_inline_size(available_inline_size - (inline_start_margin + - inline_end_margin)) - } + MaybeAuto::Auto => block.get_shrink_to_fit_inline_size( + available_inline_size - (inline_start_margin + inline_end_margin), + ), MaybeAuto::Specified(inline_size) => inline_size, }; @@ -3074,14 +3657,18 @@ impl ISizeAndMarginsComputer for InlineBlockReplaced { } /// Calculate used value of inline-size just like we do for inline replaced elements. - fn initial_computed_inline_size(&self, - block: &mut BlockFlow, - parent_flow_inline_size: Au, - shared_context: &SharedStyleContext) - -> MaybeAuto { + fn initial_computed_inline_size( + &self, + block: &mut BlockFlow, + parent_flow_inline_size: Au, + shared_context: &SharedStyleContext, + ) -> MaybeAuto { let container_block_size = block.explicit_block_containing_size(shared_context); let fragment = block.fragment(); - fragment.assign_replaced_inline_size_if_necessary(parent_flow_inline_size, container_block_size); + fragment.assign_replaced_inline_size_if_necessary( + parent_flow_inline_size, + container_block_size, + ); // For replaced block flow, the rest of the constraint solving will // take inline-size to be specified as the value computed here. MaybeAuto::Specified(fragment.content_box().size.inline) @@ -3091,23 +3678,30 @@ impl ISizeAndMarginsComputer for InlineBlockReplaced { impl ISizeAndMarginsComputer for InlineFlexItem { // Replace the default method directly to prevent recalculating and setting margins again // which has already been set by its parent. - fn compute_used_inline_size(&self, - block: &mut BlockFlow, - shared_context: &SharedStyleContext, - parent_flow_inline_size: Au) { + fn compute_used_inline_size( + &self, + block: &mut BlockFlow, + shared_context: &SharedStyleContext, + parent_flow_inline_size: Au, + ) { let container_block_size = block.explicit_block_containing_size(shared_context); - block.fragment.assign_replaced_inline_size_if_necessary(parent_flow_inline_size, - container_block_size); + block.fragment.assign_replaced_inline_size_if_necessary( + parent_flow_inline_size, + container_block_size, + ); } // The used inline size and margins are set by parent flex flow, do nothing here. - fn solve_inline_size_constraints(&self, - block: &mut BlockFlow, - _: &ISizeConstraintInput) - -> ISizeConstraintSolution { + fn solve_inline_size_constraints( + &self, + block: &mut BlockFlow, + _: &ISizeConstraintInput, + ) -> ISizeConstraintSolution { let fragment = block.fragment(); - ISizeConstraintSolution::new(fragment.border_box.size.inline, - fragment.margin.inline_start, - fragment.margin.inline_end) + ISizeConstraintSolution::new( + fragment.border_box.size.inline, + fragment.margin.inline_start, + fragment.margin.inline_end, + ) } } diff --git a/components/layout/construct.rs b/components/layout/construct.rs index 063b1ee710f..dd4ef419bbd 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -111,7 +111,12 @@ pub enum ConstructionItem { /// /// FIXME(emilio): How could whitespace have any PseudoElementType other /// than Normal? - Whitespace(OpaqueNode, PseudoElementType, ServoArc, RestyleDamage), + Whitespace( + OpaqueNode, + PseudoElementType, + ServoArc, + RestyleDamage, + ), /// TableColumn Fragment TableColumnFragment(Fragment), } @@ -182,15 +187,17 @@ impl InlineBlockSplit { let split = InlineBlockSplit { predecessors: mem::replace( fragment_accumulator, - InlineFragmentsAccumulator::from_inline_node( - node, - style_context, - )).to_intermediate_inline_fragments::(style_context), + InlineFragmentsAccumulator::from_inline_node(node, style_context), + ).to_intermediate_inline_fragments::(style_context), flow: flow, }; - fragment_accumulator.enclosing_node.as_mut().unwrap().flags.remove( - InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT); + fragment_accumulator + .enclosing_node + .as_mut() + .unwrap() + .flags + .remove(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT); split } @@ -220,7 +227,8 @@ impl IntermediateInlineFragments { fn push_all(&mut self, mut other: IntermediateInlineFragments) { self.fragments.append(&mut other.fragments); - self.absolute_descendants.push_descendants(other.absolute_descendants); + self.absolute_descendants + .push_descendants(other.absolute_descendants); } } @@ -256,8 +264,13 @@ impl InlineFragmentsAccumulator { } } - fn from_inline_node(node: &N, style_context: &SharedStyleContext) -> InlineFragmentsAccumulator - where N: ThreadSafeLayoutNode { + fn from_inline_node( + node: &N, + style_context: &SharedStyleContext, + ) -> InlineFragmentsAccumulator + where + N: ThreadSafeLayoutNode, + { InlineFragmentsAccumulator { fragments: IntermediateInlineFragments::new(), enclosing_node: Some(InlineFragmentNodeInfo { @@ -266,7 +279,7 @@ impl InlineFragmentsAccumulator { style: node.style(style_context), selected_style: node.selected_style(), flags: InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT | - InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT, + InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT, }), bidi_control_chars: None, restyle_damage: node.restyle_damage(), @@ -279,7 +292,9 @@ impl InlineFragmentsAccumulator { fn push_all(&mut self, mut fragments: IntermediateInlineFragments) { self.fragments.fragments.append(&mut fragments.fragments); - self.fragments.absolute_descendants.push_descendants(fragments.absolute_descendants); + self.fragments + .absolute_descendants + .push_descendants(fragments.absolute_descendants); } fn to_intermediate_inline_fragments( @@ -300,36 +315,42 @@ impl InlineFragmentsAccumulator { for (index, fragment) in fragments.fragments.iter_mut().enumerate() { let mut enclosing_node = enclosing_node.clone(); if index != 0 { - enclosing_node.flags.remove(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT) + enclosing_node + .flags + .remove(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT) } if index != fragment_count - 1 { - enclosing_node.flags.remove(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT) + enclosing_node + .flags + .remove(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT) } fragment.add_inline_context_style(enclosing_node); } // Control characters are later discarded in transform_text, so they don't affect the // is_first/is_last styles above. - enclosing_node.flags.remove(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT | - InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT); + enclosing_node.flags.remove( + InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT | + InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT, + ); if let Some((start, end)) = bidi_control_chars { - fragments.fragments.push_front( - control_chars_to_fragment::( + fragments + .fragments + .push_front(control_chars_to_fragment::( &enclosing_node, context, start, restyle_damage, - ) - ); - fragments.fragments.push_back( - control_chars_to_fragment::( + )); + fragments + .fragments + .push_back(control_chars_to_fragment::( &enclosing_node, context, end, restyle_damage, - ) - ); + )); } } fragments @@ -346,7 +367,8 @@ pub struct FlowConstructor<'a, N: ThreadSafeLayoutNode> { } impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> - FlowConstructor<'a, ConcreteThreadSafeLayoutNode> { + FlowConstructor<'a, ConcreteThreadSafeLayoutNode> +{ /// Creates a new flow constructor. pub fn new(layout_context: &'a LayoutContext<'a>) -> Self { FlowConstructor { @@ -361,9 +383,11 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> } #[inline] - fn set_flow_construction_result(&self, - node: &ConcreteThreadSafeLayoutNode, - result: ConstructionResult) { + fn set_flow_construction_result( + &self, + node: &ConcreteThreadSafeLayoutNode, + result: ConstructionResult, + ) { node.set_flow_construction_result(result); } @@ -372,44 +396,48 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> let specific_fragment_info = match node.type_id() { Some(LayoutNodeType::Element(LayoutElementType::HTMLIFrameElement)) => { SpecificFragmentInfo::Iframe(IframeFragmentInfo::new(node)) - } + }, Some(LayoutNodeType::Element(LayoutElementType::HTMLImageElement)) => { let image_info = Box::new(ImageFragmentInfo::new( - node.image_url(), node, &self.layout_context + node.image_url(), + node, + &self.layout_context, )); SpecificFragmentInfo::Image(image_info) - } + }, Some(LayoutNodeType::Element(LayoutElementType::HTMLObjectElement)) => { let image_info = Box::new(ImageFragmentInfo::new( - node.object_data(), node, &self.layout_context - )); + node.object_data(), + node, + &self.layout_context, + )); SpecificFragmentInfo::Image(image_info) - } + }, Some(LayoutNodeType::Element(LayoutElementType::HTMLTableElement)) => { SpecificFragmentInfo::TableWrapper - } + }, Some(LayoutNodeType::Element(LayoutElementType::HTMLTableColElement)) => { SpecificFragmentInfo::TableColumn(TableColumnFragmentInfo::new(node)) - } + }, Some(LayoutNodeType::Element(LayoutElementType::HTMLTableCellElement)) => { SpecificFragmentInfo::TableCell - } + }, Some(LayoutNodeType::Element(LayoutElementType::HTMLTableRowElement)) | Some(LayoutNodeType::Element(LayoutElementType::HTMLTableSectionElement)) => { SpecificFragmentInfo::TableRow - } + }, Some(LayoutNodeType::Element(LayoutElementType::HTMLCanvasElement)) => { let data = node.canvas_data().unwrap(); SpecificFragmentInfo::Canvas(Box::new(CanvasFragmentInfo::new(data))) - } + }, Some(LayoutNodeType::Element(LayoutElementType::SVGSVGElement)) => { let data = node.svg_data().unwrap(); SpecificFragmentInfo::Svg(Box::new(SvgFragmentInfo::new(data))) - } + }, _ => { // This includes pseudo-elements. SpecificFragmentInfo::Generic - } + }, }; Fragment::new(node, specific_fragment_info, self.layout_context) @@ -429,35 +457,33 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> legalizer: &mut Legalizer, node: &ConcreteThreadSafeLayoutNode, ) { - let mut fragments = - fragment_accumulator.to_intermediate_inline_fragments::( - self.style_context(), - ); + let mut fragments = fragment_accumulator + .to_intermediate_inline_fragments::(self.style_context()); if fragments.is_empty() { - return + return; }; strip_ignorable_whitespace_from_start(&mut fragments.fragments); strip_ignorable_whitespace_from_end(&mut fragments.fragments); if fragments.fragments.is_empty() { absolute_descendants.push_descendants(fragments.absolute_descendants); - return + return; } // Build a list of all the inline-block fragments before fragments is moved. - let mut inline_block_flows = vec!(); + let mut inline_block_flows = vec![]; for fragment in &fragments.fragments { match fragment.specific { SpecificFragmentInfo::InlineBlock(ref info) => { inline_block_flows.push(info.flow_ref.clone()) - } + }, SpecificFragmentInfo::InlineAbsoluteHypothetical(ref info) => { inline_block_flows.push(info.flow_ref.clone()) - } + }, SpecificFragmentInfo::InlineAbsolute(ref info) => { inline_block_flows.push(info.flow_ref.clone()) - } - _ => {} + }, + _ => {}, } } @@ -466,12 +492,15 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> // remain. In that case the inline flow will compute its ascent and descent to be zero. let scanned_fragments = with_thread_local_font_context(self.layout_context, |font_context| { - TextRunScanner::new().scan_for_runs(font_context, - mem::replace(&mut fragments.fragments, LinkedList::new())) + TextRunScanner::new().scan_for_runs( + font_context, + mem::replace(&mut fragments.fragments, LinkedList::new()), + ) }); - let mut inline_flow_ref = - FlowRef::new(Arc::new(InlineFlow::from_fragments(scanned_fragments, - node.style(self.style_context()).writing_mode))); + let mut inline_flow_ref = FlowRef::new(Arc::new(InlineFlow::from_fragments( + scanned_fragments, + node.style(self.style_context()).writing_mode, + ))); // Add all the inline-block fragments as children of the inline flow. for inline_block_flow in &inline_block_flows { @@ -498,7 +527,8 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> let inline_flow = FlowRef::deref_mut(&mut inline_flow_ref).as_mut_inline(); inline_flow.minimum_line_metrics = with_thread_local_font_context(self.layout_context, |font_context| { - inline_flow.minimum_line_metrics(font_context, &node.style(self.style_context())) + inline_flow + .minimum_line_metrics(font_context, &node.style(self.style_context())) }); } @@ -511,15 +541,16 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> } fn build_block_flow_using_construction_result_of_child( - &mut self, - flow: &mut FlowRef, - node: &ConcreteThreadSafeLayoutNode, - kid: ConcreteThreadSafeLayoutNode, - inline_fragment_accumulator: &mut InlineFragmentsAccumulator, - abs_descendants: &mut AbsoluteDescendants, - legalizer: &mut Legalizer) { + &mut self, + flow: &mut FlowRef, + node: &ConcreteThreadSafeLayoutNode, + kid: ConcreteThreadSafeLayoutNode, + inline_fragment_accumulator: &mut InlineFragmentsAccumulator, + abs_descendants: &mut AbsoluteDescendants, + legalizer: &mut Legalizer, + ) { match kid.get_construction_result() { - ConstructionResult::None => {} + ConstructionResult::None => {}, ConstructionResult::Flow(kid_flow, kid_abs_descendants) => { // If kid_flow is TableCaptionFlow, kid_flow should be added under // TableWrapperFlow. @@ -528,17 +559,24 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> ConstructionResult::Flow(kid_flow, AbsoluteDescendants::new()); self.set_flow_construction_result(&kid, construction_result) } else { - if !kid_flow.base().flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { + if !kid_flow + .base() + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { // Flush any inline fragments that we were gathering up. This allows us to // handle {ib} splits. - let old_inline_fragment_accumulator = - mem::replace(inline_fragment_accumulator, - InlineFragmentsAccumulator::new()); - self.flush_inline_fragments_to_flow(old_inline_fragment_accumulator, - flow, - abs_descendants, - legalizer, - node); + let old_inline_fragment_accumulator = mem::replace( + inline_fragment_accumulator, + InlineFragmentsAccumulator::new(), + ); + self.flush_inline_fragments_to_flow( + old_inline_fragment_accumulator, + flow, + abs_descendants, + legalizer, + node, + ); } legalizer.add_child::( self.style_context(), @@ -547,35 +585,41 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> ) } abs_descendants.push_descendants(kid_abs_descendants); - } + }, ConstructionResult::ConstructionItem(ConstructionItem::InlineFragments( - InlineFragmentsConstructionResult { - splits, - fragments: successor_fragments, - })) => { + InlineFragmentsConstructionResult { + splits, + fragments: successor_fragments, + }, + )) => { // Add any {ib} splits. for split in splits { // Pull apart the {ib} split object and push its predecessor fragments // onto the list. let InlineBlockSplit { predecessors, - flow: kid_flow + flow: kid_flow, } = split; inline_fragment_accumulator.push_all(predecessors); // Flush any inline fragments that we were gathering up. - debug!("flushing {} inline box(es) to flow A", - inline_fragment_accumulator.fragments.fragments.len()); - let old_inline_fragment_accumulator = - mem::replace(inline_fragment_accumulator, - InlineFragmentsAccumulator::new()); + debug!( + "flushing {} inline box(es) to flow A", + inline_fragment_accumulator.fragments.fragments.len() + ); + let old_inline_fragment_accumulator = mem::replace( + inline_fragment_accumulator, + InlineFragmentsAccumulator::new(), + ); let absolute_descendants = &mut inline_fragment_accumulator.fragments.absolute_descendants; - self.flush_inline_fragments_to_flow(old_inline_fragment_accumulator, - flow, - absolute_descendants, - legalizer, - node); + self.flush_inline_fragments_to_flow( + old_inline_fragment_accumulator, + flow, + absolute_descendants, + legalizer, + node, + ); // Push the flow generated by the {ib} split onto our list of flows. legalizer.add_child::( @@ -587,29 +631,35 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> // Add the fragments to the list we're maintaining. inline_fragment_accumulator.push_all(successor_fragments); - } + }, ConstructionResult::ConstructionItem(ConstructionItem::Whitespace( + whitespace_node, + whitespace_pseudo, + whitespace_style, + whitespace_damage, + )) => { + // Add whitespace results. They will be stripped out later on when + // between block elements, and retained when between inline elements. + let fragment_info = SpecificFragmentInfo::UnscannedText(Box::new( + UnscannedTextFragmentInfo::new(Box::::from(" "), None), + )); + let fragment = Fragment::from_opaque_node_and_style( whitespace_node, whitespace_pseudo, whitespace_style, - whitespace_damage)) => { - // Add whitespace results. They will be stripped out later on when - // between block elements, and retained when between inline elements. - let fragment_info = SpecificFragmentInfo::UnscannedText( - Box::new(UnscannedTextFragmentInfo::new(Box::::from(" "), None)) + node.selected_style(), + whitespace_damage, + fragment_info, ); - let fragment = Fragment::from_opaque_node_and_style(whitespace_node, - whitespace_pseudo, - whitespace_style, - node.selected_style(), - whitespace_damage, - fragment_info); - inline_fragment_accumulator.fragments.fragments.push_back(fragment); - } + inline_fragment_accumulator + .fragments + .fragments + .push_back(fragment); + }, ConstructionResult::ConstructionItem(ConstructionItem::TableColumnFragment(_)) => { // TODO: Implement anonymous table objects for missing parents // CSS 2.1 § 17.2.1, step 3-2 - } + }, } } @@ -617,15 +667,17 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> /// appending the construction results of children to the child list of the block flow. {ib} /// splits and absolutely-positioned descendants are handled correctly. fn build_flow_for_block_starting_with_fragments( - &mut self, - mut flow: FlowRef, - node: &ConcreteThreadSafeLayoutNode, - initial_fragments: IntermediateInlineFragments) - -> ConstructionResult { + &mut self, + mut flow: FlowRef, + node: &ConcreteThreadSafeLayoutNode, + initial_fragments: IntermediateInlineFragments, + ) -> ConstructionResult { // Gather up fragments for the inline flows we might need to create. let mut inline_fragment_accumulator = InlineFragmentsAccumulator::new(); - inline_fragment_accumulator.fragments.push_all(initial_fragments); + inline_fragment_accumulator + .fragments + .push_all(initial_fragments); // List of absolute descendants, in tree order. let mut abs_descendants = AbsoluteDescendants::new(); @@ -642,17 +694,20 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> kid, &mut inline_fragment_accumulator, &mut abs_descendants, - &mut legalizer); + &mut legalizer, + ); } } // Perform a final flush of any inline fragments that we were gathering up to handle {ib} // splits, after stripping ignorable whitespace. - self.flush_inline_fragments_to_flow(inline_fragment_accumulator, - &mut flow, - &mut abs_descendants, - &mut legalizer, - node); + self.flush_inline_fragments_to_flow( + inline_fragment_accumulator, + &mut flow, + &mut abs_descendants, + &mut legalizer, + node, + ); // The flow is done. legalizer.finish(&mut flow); @@ -664,7 +719,11 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> flow.set_absolute_descendants(abs_descendants); abs_descendants = AbsoluteDescendants::new(); - if flow.base().flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { + if flow + .base() + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { // This is now the only absolute flow in the subtree which hasn't yet // reached its CB. abs_descendants.push(flow.clone()); @@ -684,17 +743,23 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> /// /// FIXME(pcwalton): It is not clear to me that there isn't a cleaner way to handle /// ` + diff --git a/tests/wpt/web-platform-tests/css/css-scrollbars/textarea-scrollbar-width-none.html b/tests/wpt/web-platform-tests/css/css-scrollbars/textarea-scrollbar-width-none.html new file mode 100644 index 00000000000..dcfaf5b6270 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/css-scrollbars/textarea-scrollbar-width-none.html @@ -0,0 +1,18 @@ + + +CSS Test: scrollbar-width should apply on <textarea> + + + + + + + diff --git a/tests/wpt/web-platform-tests/css/css-shapes/parsing/shape-image-threshold-invalid.html b/tests/wpt/web-platform-tests/css/css-shapes/parsing/shape-image-threshold-invalid.html index eb60a2e4428..6299e2ecaad 100644 --- a/tests/wpt/web-platform-tests/css/css-shapes/parsing/shape-image-threshold-invalid.html +++ b/tests/wpt/web-platform-tests/css/css-shapes/parsing/shape-image-threshold-invalid.html @@ -8,7 +8,7 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + + diff --git a/tests/wpt/web-platform-tests/css/css-transitions/parsing/transition-delay-valid.html b/tests/wpt/web-platform-tests/css/css-transitions/parsing/transition-delay-valid.html new file mode 100644 index 00000000000..d6b42b9c059 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/css-transitions/parsing/transition-delay-valid.html @@ -0,0 +1,20 @@ + + + + +CSS Transitions: parsing transition-delay with valid values + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/css/css-transitions/parsing/transition-duration-invalid.html b/tests/wpt/web-platform-tests/css/css-transitions/parsing/transition-duration-invalid.html new file mode 100644 index 00000000000..fd0f341f407 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/css-transitions/parsing/transition-duration-invalid.html @@ -0,0 +1,19 @@ + + + + +CSS Transitions: parsing transition-duration with invalid values + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/css/css-transitions/parsing/transition-duration-valid.html b/tests/wpt/web-platform-tests/css/css-transitions/parsing/transition-duration-valid.html new file mode 100644 index 00000000000..311ca086695 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/css-transitions/parsing/transition-duration-valid.html @@ -0,0 +1,19 @@ + + + + +CSS Transitions: parsing transition-duration with valid values + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/css/css-transitions/parsing/transition-property-invalid.html b/tests/wpt/web-platform-tests/css/css-transitions/parsing/transition-property-invalid.html new file mode 100644 index 00000000000..903a206eac1 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/css-transitions/parsing/transition-property-invalid.html @@ -0,0 +1,19 @@ + + + + +CSS Transitions: parsing transition-property with invalid values + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/css/css-transitions/parsing/transition-property-valid.html b/tests/wpt/web-platform-tests/css/css-transitions/parsing/transition-property-valid.html new file mode 100644 index 00000000000..4e3894f5aa9 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/css-transitions/parsing/transition-property-valid.html @@ -0,0 +1,22 @@ + + + + +CSS Transitions: parsing transition-property with valid values + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/css/css-transitions/parsing/transition-timing-function-invalid.html b/tests/wpt/web-platform-tests/css/css-transitions/parsing/transition-timing-function-invalid.html new file mode 100644 index 00000000000..936defa6cce --- /dev/null +++ b/tests/wpt/web-platform-tests/css/css-transitions/parsing/transition-timing-function-invalid.html @@ -0,0 +1,24 @@ + + + + +CSS Animations: parsing transition-timing-function with invalid values + + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/css/css-transitions/parsing/transition-timing-function-valid.html b/tests/wpt/web-platform-tests/css/css-transitions/parsing/transition-timing-function-valid.html new file mode 100644 index 00000000000..e11ef0002e4 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/css-transitions/parsing/transition-timing-function-valid.html @@ -0,0 +1,31 @@ + + + + +CSS Transitions: parsing transition-timing-function with valid values + + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/css/css-transitions/transitions-animatable-properties-01.html b/tests/wpt/web-platform-tests/css/css-transitions/transitions-animatable-properties-01.html index 06143d3061d..534f81839ac 100644 --- a/tests/wpt/web-platform-tests/css/css-transitions/transitions-animatable-properties-01.html +++ b/tests/wpt/web-platform-tests/css/css-transitions/transitions-animatable-properties-01.html @@ -5,6 +5,7 @@ CSS Transitions: Animatable CSS properties + diff --git a/tests/wpt/web-platform-tests/css/css-typed-om/the-stylepropertymap/properties/color-interpolation.html b/tests/wpt/web-platform-tests/css/css-typed-om/the-stylepropertymap/properties/color-interpolation.html index 4713d90621d..d8324db22e2 100644 --- a/tests/wpt/web-platform-tests/css/css-typed-om/the-stylepropertymap/properties/color-interpolation.html +++ b/tests/wpt/web-platform-tests/css/css-typed-om/the-stylepropertymap/properties/color-interpolation.html @@ -15,8 +15,8 @@ runPropertyTests('color-interpolation', [ { syntax: 'auto' }, - { syntax: 'sRGB' }, - { syntax: 'linearRGB' }, + { syntax: 'srgb' }, + { syntax: 'linearrgb' }, ]); diff --git a/tests/wpt/web-platform-tests/css/css-ui/parsing/box-sizing-invalid.html b/tests/wpt/web-platform-tests/css/css-ui/parsing/box-sizing-invalid.html index 4ced38240f2..984475450a3 100644 --- a/tests/wpt/web-platform-tests/css/css-ui/parsing/box-sizing-invalid.html +++ b/tests/wpt/web-platform-tests/css/css-ui/parsing/box-sizing-invalid.html @@ -8,7 +8,7 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + diff --git a/tests/wpt/web-platform-tests/css/cssom/computed-style-set-property.html b/tests/wpt/web-platform-tests/css/cssom/computed-style-set-property.html index 65678526817..0a5e4cb0589 100644 --- a/tests/wpt/web-platform-tests/css/cssom/computed-style-set-property.html +++ b/tests/wpt/web-platform-tests/css/cssom/computed-style-set-property.html @@ -1,6 +1,5 @@ NoModificationAllowedError when mutating read only properties - diff --git a/tests/wpt/web-platform-tests/css/cssom/shorthand-serialization.html b/tests/wpt/web-platform-tests/css/cssom/shorthand-serialization.html index 2178ba37a95..44af6737e3e 100644 --- a/tests/wpt/web-platform-tests/css/cssom/shorthand-serialization.html +++ b/tests/wpt/web-platform-tests/css/cssom/shorthand-serialization.html @@ -58,6 +58,20 @@ assert_equals(testElem.style.margin, "20px"); assert_equals(testElem.style.cssText, "margin: 20px;") }, "Shorthand serialization after setting"); + + test(function() { + const testElem = document.getElementById("test"); + testElem.style.cssText = "margin: initial;"; + assert_equals(testElem.style.margin, "initial"); + assert_equals(testElem.style.cssText, "margin: initial;"); + }, "Shorthand serialization with 'initial' value."); + + test(function() { + const testElem = document.getElementById("test"); + testElem.style.setProperty("margin-top", "initial", "important"); + assert_equals(testElem.style.margin, ""); + assert_equals(testElem.style.cssText, "margin-top: initial !important; margin-right: initial; margin-bottom: initial; margin-left: initial;"); + }, "Shorthand serialization with 'initial' value, one longhand with important flag."); diff --git a/tests/wpt/web-platform-tests/css/filter-effects/parsing/color-interpolation-filters-parsing-invalid.html b/tests/wpt/web-platform-tests/css/filter-effects/parsing/color-interpolation-filters-parsing-invalid.html index 0cec437c627..6fdf647a43d 100644 --- a/tests/wpt/web-platform-tests/css/filter-effects/parsing/color-interpolation-filters-parsing-invalid.html +++ b/tests/wpt/web-platform-tests/css/filter-effects/parsing/color-interpolation-filters-parsing-invalid.html @@ -8,7 +8,7 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-16.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-16.xml deleted file mode 100644 index ea4c9849b8a..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-16.xml +++ /dev/null @@ -1,17 +0,0 @@ - - -Daniel Glazman -Ian Hickson - - - -p.test a { background-color : red } -p.test *:link { background-color : lime } - - -

-This link should have green background. -(Don't follow this link.) -

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-160.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-160.xml deleted file mode 100644 index 721d60af63f..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-160.xml +++ /dev/null @@ -1,16 +0,0 @@ - - -Ian Hickson - - - p { background: lime; } - p:subject { background: red; } /* this is not valid CSS, and if UAs - implemented the experimental :subject pseudo-class they should have - used the :-vnd-ident syntax. */ - - - -

This line should have a green background.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-162.xml-removed b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-162.xml-removed deleted file mode 100644 index b81ef952c64..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-162.xml-removed +++ /dev/null @@ -1,97 +0,0 @@ - - -Ian Hickson - - - - - - - - td > div { border: solid thick black; padding: 1em; line-height: 2; } - td > div > span { padding: 0.25em; } - - /* test version */ - .test > * { background: aqua; } - .test > div > ::selection { outline: solid thick green; } - .test > div > :nth-child(even)::selection { outline: solid thick yellow; } - .test > div > :empty::selection { outline: solid thick blue; background: red; } - .test > div *::selection { background: transparent; } /* applies to spans 4 to 6 and the strong */ - .test span:first-child::selection { background: white; } /* selects "Cascadable" */ - .test span[id=b]::selection { background: silver; } /* selects "Advanced" */ - .test #b + * + * { background: green; color: white; } /* affects "Selectors"'s span, whose selection inherits the background-color (next rule) */ - .test span[id=b] ~ ::selection { background: inherit; color: inherit; } /* selects "Tree", "Selectors" and "for CSS" but is overriden for "Tree" and "for CSS" */ - .test span[id=b] + ::selection { background: yellow; cursor: crosshair; } /* selects "Tree" */ - .test :not(#b):last-child::selection { background: transparent; } /* selects "for CSS" and "CSS" */ - .test ::selection { color: black; } /* applies to all spans and the strong */ - .test::selection { background: red ! important; } /* applies to the text in the cell and the div... so nothing. */ - .test::selection { color: red ! important; background: aqua; } /* should end up doing nothing - no text at that level and background is aqua is already the background */ - .test strong { color: red ! important; } /* should also end up doing nothing */ - - /* control version */ - .control ::selection { background: transparent; color: inherit; cursor: inherit; outline: none; } - .control > div { background: aqua; color: black; } - .control > div > span { padding: 0; margin: 0.25em; } - .control > div > span.a { background: white; } - .control > div > span.b { background: silver; } - .control > div > span.c { background: yellow; cursor: crosshair; } - .control > div > span.d { background: green; color: white; padding: 0.25em; margin: 0; } - .control > div > span.green { outline: solid thick green; } - .control > div > span.yellow { outline: solid thick yellow; } - .control > div > span.blue { outline: solid thick blue; background: red; } - - - - -
- -

Select everything in this document. The following two constructs - (in the thick black borders) should end up looking identical. You - should also check that the cursor is the same on equivalent parts - (in particular the cursor should either be a crosshair over "Tree" - and the default everywhere else, or the default everywhere).

- - - - - - -
- -
- Cascadable - Advanced - Tree - Selectors - - for CSS -
- -
- -
- Cascadable - Advanced - Tree - Selectors - - for CSS -
- -
-
-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-163.xml-disabled-contains-removed b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-163.xml-disabled-contains-removed deleted file mode 100644 index 88deffac63e..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-163.xml-disabled-contains-removed +++ /dev/null @@ -1,20 +0,0 @@ - - -Ian Hickson - - - - - .float { float: right; } - :hover ~ :contains('green') { background: green; } - - - -

TEST

-

TEST

-

TEST

-
TEST
-

While you hover over any of the four instances of the word TEST above, this paragraph should turn green.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-164.xml-removed b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-164.xml-removed deleted file mode 100644 index 2c26d874176..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-164.xml-removed +++ /dev/null @@ -1,38 +0,0 @@ - - -Ian Hickson - - - - - textarea { border: solid thick gray; } - textarea:focus { border: solid thick green; } - textarea::selection { background: silver; color: black; } - textarea:focus::selection { background: lime; color: black; } - - - -

- -

CONFORMANCE NOTE: If the UA - removes the selection when the focus leaves the text, which is also - valid behaviour, then the description above is inaccurate. In these - cases, the selection should disappear completely when the focus is - moved, and when the focus is returned, the selection should not be - in the same place as when focus was removed (typically, either the - selection will be non-existent, or everything will be selected -- - but what is selected is independent of what was selected when the - focus was removed).

- -

If the selection is - preserved, then the selection should NOT disappear when focus is - removed, it should instead turn silver as described.

- -
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-165.xml-removed b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-165.xml-removed deleted file mode 100644 index c2d16df2d79..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-165.xml-removed +++ /dev/null @@ -1,24 +0,0 @@ - - -Ian Hickson - - - - - p { border: solid thick gray; } - p:hover { border: solid thick green; } - p::selection { background: silver; color: black; } - p:hover::selection { background: lime; color: black; } - - - -

Select some of this - paragraph, then move your pointing device around. While it is above - the paragraph, the selection should be green. While the pointing - device is elsewhere, the selection should be silver. The - paragraph's border should at all times be a darker colour than the - selection's background. Repeat the test with everything - selected.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-166.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-166.xml deleted file mode 100644 index 2b5ede8f529..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-166.xml +++ /dev/null @@ -1,14 +0,0 @@ - - -Ian Hickson - - - p:first-letter { background-color: red; } - p::first-letter { background-color: lime; } - - - -

The first letter of this paragraph should have a green background.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-166a.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-166a.xml deleted file mode 100644 index 141d6cfa09f..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-166a.xml +++ /dev/null @@ -1,14 +0,0 @@ - - -Ian Hickson - - - p::first-letter { background-color: red; } - p:first-letter { background-color: lime; } - - - -

The first letter of this paragraph should have a green background.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-167.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-167.xml deleted file mode 100644 index 28809de1351..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-167.xml +++ /dev/null @@ -1,14 +0,0 @@ - - -Ian Hickson - - - p:first-line { background-color: red; } - p::first-line { background-color: lime; } - - - -

The first line of this paragraph should have a green background.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-167a.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-167a.xml deleted file mode 100644 index 1bff3b132ea..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-167a.xml +++ /dev/null @@ -1,14 +0,0 @@ - - -Ian Hickson - - - p::first-line { background-color: red; } - p:first-line { background-color: lime; } - - - -

The first line of this paragraph should have a green background.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-168.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-168.xml deleted file mode 100644 index 9cc9bbebb13..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-168.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Ian Hickson - - - span:before { background-color: red; content: 'FAILED'; } - span::before { background-color: lime; content: 'PASSED'; } - - - -

This test has .

-

(If the previous line just reads "This test has ." then this test has failed.)

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-168a.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-168a.xml deleted file mode 100644 index 8332c3345c5..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-168a.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Ian Hickson - - - span::before { background-color: red; content: 'FAILED'; } - span:before { background-color: lime; content: 'PASSED'; } - - - -

This test has .

-

(If the previous line just reads "This test has ." then this test has failed.)

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-169.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-169.xml deleted file mode 100644 index 0579bc96e60..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-169.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Ian Hickson - - - span:after { background-color: red; content: 'FAILED'; } - span::after { background-color: lime; content: 'PASSED'; } - - - -

This test has .

-

(If the previous line just reads "This test has ." then this test has failed.)

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-169a.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-169a.xml deleted file mode 100644 index f39e6b530bc..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-169a.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Ian Hickson - - - span::after { background-color: red; content: 'FAILED'; } - span:after { background-color: lime; content: 'PASSED'; } - - - -

This test has .

-

(If the previous line just reads "This test has ." then this test has failed.)

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-17.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-17.xml deleted file mode 100644 index 8203771cf1c..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-17.xml +++ /dev/null @@ -1,17 +0,0 @@ - - -Daniel Glazman -Ian Hickson - - - -p.test a { background-color : red } -p.test *:visited { background-color : lime } - - -

-You should see a green background assigned by the anchor. -(Note: You must have visited http://www.w3.org/ for this test to be valid.) -

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-171.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-171.xml deleted file mode 100644 index df876299aa3..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-171.xml +++ /dev/null @@ -1,16 +0,0 @@ - - -Ian Hickson - - - p { color: green; } - .fail { color: red; } - - - -

- This should be green. -

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-174a.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-174a.xml deleted file mode 100644 index 2593661e45d..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-174a.xml +++ /dev/null @@ -1,18 +0,0 @@ - - -Ian Hickson - - - tests, tests * { display: block; color: red; } - testA[*|attribute="pass"] { color: green; } - testB[*|attribute="pass"] { color: green; } - - - - - This should be green. - This should be green. - - - - diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-174b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-174b.xml deleted file mode 100644 index a8dddce2b52..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-174b.xml +++ /dev/null @@ -1,18 +0,0 @@ - - -Ian Hickson - - - tests, tests * { display: block; color: green } - testA:not([*|attribute="pass"]) { color: red; } - testB:not([*|attribute="pass"]) { color: red; } - - - - - This should be green. - This should be green. - - - - diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-175a.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-175a.xml deleted file mode 100644 index 6d74fd27a9d..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-175a.xml +++ /dev/null @@ -1,14 +0,0 @@ - - -Ian Hickson - - - p { color: green; } - .13 { color: red; } - - - -

This line should be green.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-175b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-175b.xml deleted file mode 100644 index ea136a0cef3..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-175b.xml +++ /dev/null @@ -1,14 +0,0 @@ - - -Ian Hickson - - - p { color: green; } - .\13 { color: red; } - - - -

This line should be green.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-175c.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-175c.xml deleted file mode 100644 index dabde06c883..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-175c.xml +++ /dev/null @@ -1,14 +0,0 @@ - - -Ian Hickson - - - p { color: red; } - .\31 \33 { color: green; } - - - -

This line should be green.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-176.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-176.xml deleted file mode 100644 index b56202954fd..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-176.xml +++ /dev/null @@ -1,21 +0,0 @@ - - -Ian Hickson - - -p { background: red; color: yellow; } -p:not(#other).class:not(.fail).test#id#id { background: green; color: white; } -div { background: green; color: white; } -div:not(#theid).class:not(.fail).test#theid#theid { background: red; color: yellow; } -div:not(#other).notclass:not(.fail).test#theid#theid { background: red; color: yellow; } -div:not(#other).class:not(.test).test#theid#theid { background: red; color: yellow; } -div:not(#other).class:not(.fail).nottest#theid#theid { background: red; color: yellow; } -div:not(#other).class:not(.fail).nottest#theid#other { background: red; color: yellow; } - - - -

This line should be green.

-
This line should be green.
-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-177a.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-177a.xml deleted file mode 100644 index 27b39e8f06d..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-177a.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Ian Hickson - - - - - p:selection { color: yellow; background: red; } - - - -

When you select this text, it shouldn't go red.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-177b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-177b.xml deleted file mode 100644 index fc78911553f..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-177b.xml +++ /dev/null @@ -1,16 +0,0 @@ - - -Ian Hickson - - - div { color: green; } - p::first-child { color: yellow; background: red; } - - - -
-

This line should be green.

-
-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-178.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-178.xml deleted file mode 100644 index fc37aedc761..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-178.xml +++ /dev/null @@ -1,17 +0,0 @@ - - -Ian Hickson - - - div { color: green; } - p:not(:first-line) { color: yellow; background: red; } - p:not(:after) { color: yellow; background: red; content: ' THIS TEST HAS FAILED! '; } - - - -
-

This line should be green.

-
-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-179.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-179.xml deleted file mode 100644 index d18dbbfc40d..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-179.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Ian Hickson - - - p { color: green; } - span:first-line { background: red; color: yellow; font-size: 4em; } - span::first-line { background: red; color: yellow; font-size: 4em; } - - - -

This line should be green.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-179a.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-179a.xml deleted file mode 100644 index ff4361ab1ad..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-179a.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Ian Hickson - - - p { color: green; } - p:first-line { background: red; color: yellow; font-size: 4em; } - p::first-line { background: red; color: yellow; font-size: 4em; } - - - -


This line should be green.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-180.xml-disabled-because-we-want-to-allow-for-expansion b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-180.xml-disabled-because-we-want-to-allow-for-expansion deleted file mode 100644 index 713e761b82f..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-180.xml-disabled-because-we-want-to-allow-for-expansion +++ /dev/null @@ -1,15 +0,0 @@ - - -Ian Hickson - - - p { color: green; } - span:first-letter { background: red; color: yellow; font-size: 4em; } - span::first-letter { background: red; color: yellow; font-size: 4em; } - - - -

This line should be green.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-180a.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-180a.xml deleted file mode 100644 index e76bb43776e..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-180a.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Ian Hickson - - - p { color: green; } - p:first-letter { background: red; color: yellow; font-size: 4em; } - p::first-letter { background: red; color: yellow; font-size: 4em; } - - - -


This line should be green.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-182.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-182.xml deleted file mode 100644 index f8212bf1cca..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-182.xml +++ /dev/null @@ -1,18 +0,0 @@ - - -Ian Hickson - - -p { color: green; } -foo\:bar { background: red; color: yellow; } - - - -

- -This text should be green. - -

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-183.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-183.xml deleted file mode 100644 index 03de4bcaec5..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-183.xml +++ /dev/null @@ -1,21 +0,0 @@ - - -Ian Hickson - - -p { color: green; } -..test { background: red; color: yellow; } -.foo..quux { background: red; color: yellow; } -.bar. { background: red; color: yellow; } - - - -

This text should be green.

-

This text should be green.

-

This text should be green.

-

This text should be green.

-

This text should be green.

-

This text should be green.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-184a.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-184a.xml deleted file mode 100644 index e6da5a1a984..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-184a.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Lachlan Hunt - - -p { color: lime; } -p[class$=""] { color: red; } - - - -

This text should be green.

-

This text should be green.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-184b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-184b.xml deleted file mode 100644 index b2230ede04e..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-184b.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Lachlan Hunt - - -p { color: lime; } -p[class^=""] { color: red; } - - - -

This text should be green.

-

This text should be green.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-184c.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-184c.xml deleted file mode 100644 index b04d4418510..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-184c.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Lachlan Hunt - - -p { color: lime; } -p[class*=""] { color: red; } - - - -

This text should be green.

-

This text should be green.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-184d.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-184d.xml deleted file mode 100644 index 4e38023ea42..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-184d.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Lachlan Hunt - - -p { color: red; } -p:not([class$=""]) { color: lime; } - - - -

This text should be green.

-

This text should be green.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-184e.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-184e.xml deleted file mode 100644 index 6f96b7f7765..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-184e.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Lachlan Hunt - - -p { color: red; } -p:not([class^=""]) { color: lime; } - - - -

This text should be green.

-

This text should be green.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-184f.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-184f.xml deleted file mode 100644 index a9593f8dc4f..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-184f.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Lachlan Hunt - - -p { color: red; } -p:not([class*=""]) { color: lime; } - - - -

This text should be green.

-

This text should be green.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-18a.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-18a.xml deleted file mode 100644 index 70b168a3a5b..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-18a.xml +++ /dev/null @@ -1,24 +0,0 @@ - - -Ian Hickson - - - - -p { color: navy; } - -.a a:hover { background: green; color: white; } - -.b a:hover { background: red; color: yellow; } -.b a:link { background: green; color: white; } - -.c :link { background: green; color: white; } -.c :visited:hover { background: red; color: yellow; } - - - -

The background color of this anchor (here) should turn to green when the pointing device hovers over it.

-

The background color of this anchor (here) should remain green when you hover it.

-

The background color of this anchor (here) should remain green when the pointing device hovers over it (do not follow that link).

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-18b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-18b.xml deleted file mode 100644 index b57cbfb25d0..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-18b.xml +++ /dev/null @@ -1,19 +0,0 @@ - - -Daniel Glazman -Ian Hickson - - - -div:hover > p:first-child { background-color : lime } - - -
-

The background color of this paragraph should turn to green when the mouse pointer hovers over any of the following:
This text.

-

This text.

-
This text.
This text.
This text.
-

This text.

-

...and anything else between the top of the first paragraph and the bottom of this paragraph.

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-18c.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-18c.xml deleted file mode 100644 index 3d28e24bfa2..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-18c.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Ian Hickson - - - - -:link, :visited { color: navy; text-decoration: none; } -:link:hover span { background-color : lime } - - - -

Hover here and the background of this text should go green.

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-19.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-19.xml deleted file mode 100644 index 5f348f242aa..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-19.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Daniel Glazman -Ian Hickson - - - -a:active { background-color : lime } - - -

The background color of the anchor - should turn to green when it is activated and come back to - normal when it is released.

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-19a.xml-removed b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-19a.xml-removed deleted file mode 100644 index 138c1fab508..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-19a.xml-removed +++ /dev/null @@ -1,13 +0,0 @@ - - -Ian Hickson - - - -p { color: navy; } -p:active { background: red; color: yellow; font-size: 2em; } - - -

Clicking this paragraph should have no effect.

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-19b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-19b.xml deleted file mode 100644 index 9c3683c327c..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-19b.xml +++ /dev/null @@ -1,12 +0,0 @@ - - -Ian Hickson - - - -button:active { background: green; color: white; } - - -

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-2.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-2.xml deleted file mode 100644 index e06740a7d53..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-2.xml +++ /dev/null @@ -1,11 +0,0 @@ - - -Daniel Glazman -Ian Hickson -address { background-color: lime } - - -
This address element should have a green background.
-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-20.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-20.xml deleted file mode 100644 index d6204affe15..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-20.xml +++ /dev/null @@ -1,16 +0,0 @@ - - -Daniel Glazman -Ian Hickson - - - -a:focus { background-color : lime } - - -

The background color of anchors - in this page should turn to green when they have the - focus.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-21.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-21.xml deleted file mode 100644 index 56b1a5f185e..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-21.xml +++ /dev/null @@ -1,22 +0,0 @@ - - -Daniel Glazman -Ian Hickson - - - -p:target { background-color : lime } - -

This paragraph should be unstyled. - The background of the following paragraph should become green when - you follow this link.

-

This paragraph should initially be unstyled. - It should become green when you select the link above. When you select - this link, it should return to being unstyled and the - background of the paragraph below should become green.

-

This paragraph should initially be unstyled. - It should become green when you select the link above. When you follow - this link, the three paragraphs - should all return to being unstyled.

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-21b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-21b.xml deleted file mode 100644 index fde26af08ac..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-21b.xml +++ /dev/null @@ -1,12 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -p { background-color: lime; } -p:target { background-color: red; } - -

This paragraph should be green.

-
-
- diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-21c.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-21c.xml deleted file mode 100644 index a62a1518b12..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-21c.xml +++ /dev/null @@ -1,12 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -:root { background-color: green; } -:target { background-color: red; } - -

This page should be green.

-
-
- diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-22.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-22.xml deleted file mode 100644 index 5996160912d..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-22.xml +++ /dev/null @@ -1,24 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -ul > li { background-color : red } -li:lang(en-GB) { background-color : lime } - - -
    -
  • This list item should be green because its language is - British English
  • -
  • This list item should be green because its language - is British English (Wales)
  • -
-
    -
  1. This list item should NOT be green because its language - is US English
  2. -
  3. This list item should NOT be green because its language is - French
  4. -
-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-23.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-23.xml deleted file mode 100644 index 9c10294fa6d..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-23.xml +++ /dev/null @@ -1,18 +0,0 @@ - - -Daniel Glazman -Ian Hickson -button { background-color : red } -input { background-color : red } -button:enabled { background-color : lime } -input:enabled { background-color : lime } - - -

- -
- -

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-24.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-24.xml deleted file mode 100644 index cd109dfea19..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-24.xml +++ /dev/null @@ -1,18 +0,0 @@ - - -Daniel Glazman -Ian Hickson -button { background-color : red } -input { background-color : red } -button:disabled { background-color : lime } -input:disabled { background-color : lime } - - -

- -
- -

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-25.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-25.xml deleted file mode 100644 index aea599d761b..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-25.xml +++ /dev/null @@ -1,14 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -input, span { background-color : red } -input:checked, input:checked + span { background-color : lime} - - - -

- Everything in this paragraph should have a green background

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-27.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-27.xml deleted file mode 100644 index 3d9f31b6f4d..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-27.xml +++ /dev/null @@ -1,10 +0,0 @@ - - -Daniel Glazman - -html { background-color : red } -*:root { background-color: lime } - -

The background of the document should be green

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-27b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-27b.xml deleted file mode 100644 index 7045d492b7d..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-27b.xml +++ /dev/null @@ -1,11 +0,0 @@ - - -Ian Hickson - -* html { background-color: red; } -* :root { background-color: red; } -p { color: green; } - -

This line should be green (there should be no red on this page).

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-28c.pl-draft b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-28c.pl-draft deleted file mode 100644 index f8601068c01..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-28c.pl-draft +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/perl -wT - -print "
\n"; -nest(0, 5, 5, 'span'); -print "
\n"; - -:nth-child(-1n+6) :nth-child(-2) :nth-child(-2n-2) - -sub nest { - my($indent, $remaining, $count, $element, @position) = @_; - ++$indent; - --$remaining; - for (my $index = 0; $index < $count; ++$index) { - if ($remaining > 1) { - print((' ' x $indent) . "<$element>\n"); - nest($indent, $remaining, $count, $element, @position, $index); - print((' ' x $indent) . "\n"); - } elsif ($remaining) { - print((' ' x $indent) . "<$element> "); - nest($indent, $remaining, $count, $element, @position, $index); - print "\n"; - } else { - my $class = tryToMatch(\@position, [nthChild(-1, 6), nthChild(0, -2), nthChild(-2, -2)]) ? 'match' : 'nomatch'; - print "<$element class="$class">Test "; - } - } -} - -sub nthChild { - my($position, $counts) = @_; - if -} diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-3.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-3.xml deleted file mode 100644 index 7dd22bd1f36..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-3.xml +++ /dev/null @@ -1,23 +0,0 @@ - - -Daniel Glazman -* { color : lime } -ul, p { color : red } -*.t1 { color : lime } - - - - - -

-This paragraph, and all textual contents in the document, - should be green. -

-
    -
  • This item should be green.
  • -
-And this element, part of a non-HTML namespace, - should be green too -
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-30.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-30.xml deleted file mode 100644 index 67ed015543f..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-30.xml +++ /dev/null @@ -1,30 +0,0 @@ - - -Daniel Glazman -.red { background-color : red } -p:nth-of-type(3) { background-color : lime } -dl > :nth-of-type(3n+1) { background-color : lime } - - - -

This paragraph is here only to fill space in the DOM

-
And this address too..
-

So does this paragraph !

-

But this one should have green background

-
-
First definition term that should have green background
-
First definition that should have green background
-
Second definition term
-
Second definition
-
Third definition term
-
Third definition
-
Fourth definition term that should have green background
-
Fourth definition that should have green background
-
Fifth definition term
-
Fifth definition
-
Sixth definition term
-
Sixth definition
-
-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-31.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-31.xml deleted file mode 100644 index e8b9e373430..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-31.xml +++ /dev/null @@ -1,30 +0,0 @@ - - -Daniel Glazman -.red { background-color : red } -p:nth-last-of-type(3) { background-color : lime } -dl > :nth-last-of-type(3n+1) { background-color : lime } - - - -

This paragraph should have green background

-
But this address is here only to fill space in the dom..
-

So does this paragraph !

-

And so does this one too.

-
-
First definition term
-
First definition
-
Second definition term
-
Second definition
-
Third definition term that should have green background
-
Third definition that should have green background
-
Fourth definition term
-
Fourth definition
-
Fifth definition term
-
Fifth definition
-
Sixth definition term that should have green background
-
Sixth definition that should have green background
-
-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-32.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-32.xml deleted file mode 100644 index 362a42a5da9..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-32.xml +++ /dev/null @@ -1,33 +0,0 @@ - - -Daniel Glazman -.red { background-color : red } -.t1 td:first-child { background-color : lime } -p > *:first-child { background-color : lime } - - - -
- - - - - - - - - - - - - - - - -
green cell1.21.3
green cell2.22.3
green cell3.23.3
-
-

This paragraph contains some text - and a span that should have a green background -

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-33.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-33.xml deleted file mode 100644 index 62b2398034b..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-33.xml +++ /dev/null @@ -1,33 +0,0 @@ - - -Daniel Glazman -.red { background-color : red } -.t1 td:last-child { background-color : lime } -p > *:last-child { background-color : lime } - - - -
- - - - - - - - - - - - - - - - -
1.11.2green cell
2.12.2green cell
3.13.2green cell
-
-

-This paragraph contains a span that should - have a green background and some text after it.

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-34.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-34.xml deleted file mode 100644 index 1fe467a4e03..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-34.xml +++ /dev/null @@ -1,16 +0,0 @@ - - -Daniel Glazman -.red { background-color : red } -address { margin-bottom : 1em ; margin-left : 1em } -address:first-of-type { background-color : lime } - - - -
This div contains 3 addresses: -
A first address that should have a green background
-
A second address with normal background
-
A third address with normal background
-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-35.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-35.xml deleted file mode 100644 index 91eba662245..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-35.xml +++ /dev/null @@ -1,17 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -.red { background-color : red } -address { margin-bottom : 1em ; margin-left : 1em } -address:last-of-type { background-color : lime } - - -
-
A first address with normal background
-
A second address with normal background
-
A third address that should have a green background
-This div contains 3 addresses above this sentence.
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-36.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-36.xml deleted file mode 100644 index 4873f209378..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-36.xml +++ /dev/null @@ -1,14 +0,0 @@ - - -Daniel Glazman -.red { background-color : red } -p:only-child { background-color : lime } -div.testText > div > p { margin-left : 1em } - - -

This paragraph should have normal background

-
This div contains only one paragraph -

This paragraph should have green background

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-37.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-37.xml deleted file mode 100644 index c660db6b789..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-37.xml +++ /dev/null @@ -1,14 +0,0 @@ - - -Daniel Glazman -.red { background-color : red } -.t1 :only-of-type { background-color : lime } - - -
-

This paragraph should have normal background

-
But this address should have green background
-

This paragraph should have normal background

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-38.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-38.xml deleted file mode 100644 index ad0515a1628..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-38.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Daniel Glazman -p:first-line { background-color : lime } - - -

This very long paragraph should have a - first line with green background. This very long paragraph should have a first - line with green background. This very long paragraph should have a first line - with green background. This very long paragraph should have a first line with - green background. This very long paragraph should have a first line with green - background. This very long paragraph should have a first line with green background. - This very long paragraph should have a first line with green background.

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-3a.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-3a.xml deleted file mode 100644 index 2737ccc6dbc..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-3a.xml +++ /dev/null @@ -1,20 +0,0 @@ - - -Daniel Glazman -Ian Hickson -* { color : lime } -ul, p { color : red } -*.t1 { color : lime } - - - -

-This paragraph, and all textual contents in the document, - should be green. -

-
    -
  • This item should be green.
  • -
-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-4.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-4.xml deleted file mode 100644 index 1f8c1187b73..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-4.xml +++ /dev/null @@ -1,11 +0,0 @@ - - -Daniel Glazman - -#foo { background-color : lime } -p { background-color : red } - - -

This paragraph should have a green background

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-40.xml-removed b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-40.xml-removed deleted file mode 100644 index 6422bfa4d33..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-40.xml-removed +++ /dev/null @@ -1,11 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -p::selection { background-color : lime } - - -

Any textual selection in this long paragraph should have green background. Any textual selection in this long paragraph should have green background. Any textual selection in this long paragraph should have green background.

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-41.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-41.xml deleted file mode 100644 index 1b54a0ad824..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-41.xml +++ /dev/null @@ -1,10 +0,0 @@ - - -Daniel Glazman - -p::before { background-color : lime ; content : "GENERATED CONTENT "} - - -

You should see before this paragraph the words GENERATED CONTENT over green background

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-41a.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-41a.xml deleted file mode 100644 index 9dda3c76ea1..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-41a.xml +++ /dev/null @@ -1,10 +0,0 @@ - - -Daniel Glazman - -p:before { background-color : lime ; content : "GENERATED CONTENT "} - - -

You should see before this paragraph the words GENERATED CONTENT over green background

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-42.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-42.xml deleted file mode 100644 index 226b3d9d33e..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-42.xml +++ /dev/null @@ -1,10 +0,0 @@ - - -Daniel Glazman - -p::after { background-color : lime ; content : "GENERATED CONTENT "} - - -

You should see after this paragraph the words GENERATED CONTENT over green background

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-42a.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-42a.xml deleted file mode 100644 index b7b68750ad5..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-42a.xml +++ /dev/null @@ -1,10 +0,0 @@ - - -Daniel Glazman - -p:after { background-color : lime ; content : "GENERATED CONTENT "} - - -

You should see after this paragraph the words GENERATED CONTENT over green background

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-43.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-43.xml deleted file mode 100644 index 8453553fb9b..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-43.xml +++ /dev/null @@ -1,32 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -.white { background-color: transparent ! important; } -.red { background-color: red; } -div.t1 p { background-color: lime; } - -
-

This paragraph should have a green background

- - - - - - -
-

This paragraph should have a green background

-
-
- - - - - - -
-

This paragraph should be unstyled.

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-43b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-43b.xml deleted file mode 100644 index 5707a2bb439..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-43b.xml +++ /dev/null @@ -1,32 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -.white { background-color: transparent ! important; } -.green { background-color: lime; } -div.t1 p { background-color: red; } - -
-

This paragraph should be unstyled

- - - - - - -
-

This paragraph should be unstyled

-
-
- - - - - - -
-

This paragraph should have a green background

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-44.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-44.xml deleted file mode 100644 index bedc9840168..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-44.xml +++ /dev/null @@ -1,27 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -.white { background-color: transparent ! important; } -.red { background-color: red; } -div > p.test { background-color: lime; } - - -
-

This paragraph should have a green background

-
-

This paragraph should have a green background

-
-
- - - - - - -
-

This paragraph should be unstyled.

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-44b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-44b.xml deleted file mode 100644 index d4df889b06d..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-44b.xml +++ /dev/null @@ -1,27 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -.white { background-color: transparent ! important; } -.green { background-color: lime; } -div > p.test { background-color: red; } - - -
-

This paragraph should be unstyled.

-
-

This paragraph should be unstyled.

-
-
- - - - - - -
-

This paragraph should have a green background.

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-44c.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-44c.xml deleted file mode 100644 index 90bc43abf7d..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-44c.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Ian Hickson - - - .fail > div { background: red; color: yellow; } - .control { background: green; color: white; } - - - -
This should be unstyled.
-
This should have a green background.
-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-44d.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-44d.xml deleted file mode 100644 index 882f74a48dd..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-44d.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Ian Hickson - - - #fail > div { background: red; } - p { background: green; } - - - -
This should be unstyled.
-

This should have a green background.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-45.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-45.xml deleted file mode 100644 index ed406c223ce..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-45.xml +++ /dev/null @@ -1,18 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -.red { background-color : red } -div.stub > p + p { background-color : lime } - - -
-

This paragraph should be unstyled.

-

But this one should have a green background.

-

And this one should also have a green background.

-
This address is only here to fill some space between two paragraphs.
-

This paragraph should be unstyled.

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-45b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-45b.xml deleted file mode 100644 index b1cc9bba4bc..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-45b.xml +++ /dev/null @@ -1,19 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -.green { background-color: lime; } -.white { background-color: transparent ! important; } -div.stub > p + p { background-color: red; } - - -
-

This paragraph should have a green background.

-

But this one should be unstyled.

-

And this one should also be unstyled.

-
This address is only here to fill some space between two paragraphs and should have a green background.
-

This paragraph should have a green background too.

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-45c.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-45c.xml deleted file mode 100644 index 47ec8819a41..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-45c.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Ian Hickson - - - .fail + div { background: red; } - .control { background: lime; } - - - -
This should be unstyled.
-
This should have a green background.
-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-46.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-46.xml deleted file mode 100644 index 15c8ae2370f..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-46.xml +++ /dev/null @@ -1,18 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -.red { background-color : red } -div.stub > p ~ p { background-color : lime } - - -
-

This paragraph should be unstyled.

-

But this one should have a green background

-

And this one should also have a green background

-
This address is only here to fill some space between two paragraphs
-

This paragraph should have a green background

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-46b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-46b.xml deleted file mode 100644 index da34d40f623..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-46b.xml +++ /dev/null @@ -1,18 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -.green { background-color : lime ! important } -div.stub > p ~ p { background-color : red } - - -
-

This paragraph should be unstyled.

-

But this one should have a green background

-

And this one should also have a green background

-
This address is only here to fill some space between two paragraphs
-

This paragraph should have a green background

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-47.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-47.xml deleted file mode 100644 index b3a30d36daa..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-47.xml +++ /dev/null @@ -1,21 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -div.stub span, div.stub address, div.stub *|q, div.stub *|r { background-color: red; } -address, *|q, *|r { display: block; margin: 1em; } -div.stub *:not(p) { background-color: lime; } - - -
-

- The text in this paragraph should have a green background -

-
This address should have a green background
- This element in another namespace should have a green background. - This element without a namespace should have a green background. -

This paragraph should be unstyled.

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-48.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-48.xml deleted file mode 100644 index eff468f1532..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-48.xml +++ /dev/null @@ -1,21 +0,0 @@ - - -Daniel Glazman - -@namespace html url(http://www.w3.org/1999/xhtml); -@namespace a url(http://www.example.org/a); -@namespace b url(http://www.example.org/b); -div.stub > *|* { background-color : lime ; display : block ; - margin-bottom : 1em } -div.stub > *|*:not(*) { background-color : red } -/* yes, the rule just above selects nothing... That's the point */ - - -
-
This address should have a green background
-This paragraph should have a green background -This paragraph should have a green background -This paragraph should have a green background -
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-49.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-49.xml deleted file mode 100644 index d55fbfc02a8..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-49.xml +++ /dev/null @@ -1,21 +0,0 @@ - - -Daniel Glazman - -@namespace html url(http://www.w3.org/1999/xhtml); -@namespace a url(http://www.example.org/a); -@namespace b url(http://www.example.org/b); -div.stub > *|* { background-color : lime ; display : block ; - margin-bottom : 1em } -div.stub > *|*:not() { background-color : red } -/* yes, the rule just above selects nothing... That's the point */ - - -
-
This address should have a green background
-This paragraph should have a green background -This paragraph should have a green background -This paragraph should have a green background -
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-5.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-5.xml deleted file mode 100644 index 69153646c01..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-5.xml +++ /dev/null @@ -1,12 +0,0 @@ - - -Daniel Glazman -p { background-color : red } -p[title] { background-color : lime } - - -

This paragraph should have a green background because its TITLE - attribute is set.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-50.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-50.xml deleted file mode 100644 index e437ecc6a2d..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-50.xml +++ /dev/null @@ -1,17 +0,0 @@ - - -Daniel Glazman - -@namespace a url(http://www.example.org/a); -a|* { color : red ; display : block ; margin-bottom : 1em } -div.stub *|*:not([test]) { color : lime } - - -
- - This text should be in green characters - -This text should be in green characters -
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-51.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-51.xml deleted file mode 100644 index c2476d13b94..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-51.xml +++ /dev/null @@ -1,20 +0,0 @@ - - -Daniel Glazman - -@namespace a url(http://www.example.org/a); -div.stub > p {color : red } -div.stub > a|* { color : red ; display : block ; margin-bottom : 1em } -div.stub *|*:not([test="1"]) { color : lime } - - -
- - This text should be - in green characters - -This text should be in green characters -

This text should be in green characters

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-52.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-52.xml deleted file mode 100644 index ef1ae777bb0..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-52.xml +++ /dev/null @@ -1,26 +0,0 @@ - - -Daniel Glazman - -@namespace a url(http://www.example.org/a); -@namespace b url(http://www.example.org/b); -div.stub p { color : red } -div.stub > a|*, div.stub > b|* { color : red ; display : block ; margin-bottom : 1em } -div.stub *|*:not([test~="foo"]) { color : lime } -div.stub *|p:not([class~="foo"]) { color : lime } -div.stub b|*[test~="foo2"] { color : lime } - - - -
- - This text should be - in green characters - -This text should be in green characters -This text should be in green characters -

This text should be in green characters

-This text should be in green characters -
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-53.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-53.xml deleted file mode 100644 index fa5ea77a07b..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-53.xml +++ /dev/null @@ -1,26 +0,0 @@ - - -Daniel Glazman - -@namespace a url(http://www.example.org/a); -@namespace b url(http://www.example.org/b); -div.stub p { color : red } -div.stub > a|*, div.stub > b|* { color : red ; display : block ; margin-bottom : 1em } -div.stub *|*:not([test|="foo-bar"]) { color : lime } -div.stub *|p:not([lang|="en-us"]) { color : lime } -div.stub b|*[test|="foo2-bar"] { color : lime } - - - -
- - This text should be - in green characters - -This text should be in green characters -This text should be in green characters -

This text should be in green characters

-This text should be in green characters -
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-54.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-54.xml deleted file mode 100644 index 09fba60bf87..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-54.xml +++ /dev/null @@ -1,18 +0,0 @@ - - -Daniel Glazman - -div.stub > * { color : red } -div.stub *:not([title^="si on"]) { color : lime } - - - -
-

This paragraph should be in green characters.

-

This paragraph should be in green characters.

-

- This paragraph should be in green characters. -

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-55.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-55.xml deleted file mode 100644 index 947352d7784..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-55.xml +++ /dev/null @@ -1,18 +0,0 @@ - - -Daniel Glazman - -div.stub > * { color : red } -div.stub *:not([title$="tait"]) { color : lime } - - - -
-

This paragraph should be in green characters.

-

This paragraph should be in green characters.

-

- This paragraph should be in green characters. -

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-56.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-56.xml deleted file mode 100644 index 34e3c845672..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-56.xml +++ /dev/null @@ -1,18 +0,0 @@ - - -Daniel Glazman - -div.stub > * { color : red } -div.stub *:not([title*=" on"]) { color : lime } - - - -
-

This paragraph should be in green characters.

-

This paragraph should be in green characters.

-

- This paragraph should be in green characters. -

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-57.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-57.xml deleted file mode 100644 index 89b824672b3..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-57.xml +++ /dev/null @@ -1,20 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -@namespace a url(http://www.example.org/a); -@namespace b url(http://www.example.org/b); -*|p, *|q, *|r { display : block ; margin-bottom : 1em } -*|p, *|r { background-color : red } -div.stub *:not([a|title]) {background-color : lime } - - - -
- This a:q element should be unstyled. -

This paragraph should have a green background.

- This b:r element should have a green background. -
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-57b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-57b.xml deleted file mode 100644 index 9f0e3f38d34..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-57b.xml +++ /dev/null @@ -1,20 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -@namespace a url(http://www.example.org/a); -@namespace b url(http://www.example.org/b); -*|p, *|q, *|r { display : block ; margin-bottom : 1em } -*|p, *|r { background-color : lime ! important } -div.stub *:not([a|title]) {background-color : red } - - - -
- This a:q element should be unstyled. -

This paragraph should have a green background.

- This b:r element should have a green background. -
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-58.xml-removed b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-58.xml-removed deleted file mode 100644 index 5e147c80a73..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-58.xml-removed +++ /dev/null @@ -1,15 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -form { background-color : red } -form:not([method]) { background-color : lime } - - - -
-

The paragraph should have a green background.

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-59.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-59.xml deleted file mode 100644 index b0aa032a2a9..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-59.xml +++ /dev/null @@ -1,18 +0,0 @@ - - -Daniel Glazman - -div.stub > * { color : red } -div.stub *:not(.foo) { color : lime } - - - -
-

This paragraph should be in green characters.

-

This paragraph should be in green characters.

-

- This paragraph should be in green characters. -

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-6.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-6.xml deleted file mode 100644 index 9a386de0297..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-6.xml +++ /dev/null @@ -1,17 +0,0 @@ - - -Daniel Glazman -Ian Hickson -address { background-color : red } -address[title="foo"] { background-color : lime } -span[title="a"] { background-color : red } - - -
-This line should - have a green background. - -
-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-60.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-60.xml deleted file mode 100644 index 882156d3223..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-60.xml +++ /dev/null @@ -1,18 +0,0 @@ - - -Daniel Glazman - -div.stub > * { color : red } -div.stub *:not(#foo) { color : lime } - - - -
-

This paragraph should be in green characters.

-

This paragraph should be in green characters.

-

- This paragraph should be in green characters. -

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-61.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-61.xml deleted file mode 100644 index aee3da868ca..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-61.xml +++ /dev/null @@ -1,17 +0,0 @@ - - -Daniel Glazman -Ian Hickson - - - -div.stub > * { background-color : red } -div.stub *:not(:link) { background-color : lime } - - -
-This anchor should have a green background -(Note: You must have visited http://www.w3.org/ for this test to be valid.) -
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-62.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-62.xml deleted file mode 100644 index 26e17595158..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-62.xml +++ /dev/null @@ -1,16 +0,0 @@ - - -Daniel Glazman - - - -div.stub > * { background-color : red } -div.stub *:not(:visited) { background-color : lime } - - -
-This anchor should have a green background -(Don't follow this link.) -
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-63.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-63.xml deleted file mode 100644 index 1215c119d66..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-63.xml +++ /dev/null @@ -1,17 +0,0 @@ - - -Daniel Glazman -Ian Hickson - - - -div.stub * { color: lime; text-decoration: none; } -div.stub > * > *:not(:hover) { color: black } - - -
-

The color of this text should be green when the pointing device hovers over it.

-

The color of this text should be green when the pointing device hovers over it.

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-64.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-64.xml deleted file mode 100644 index 87eb45bce9e..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-64.xml +++ /dev/null @@ -1,17 +0,0 @@ - - -Daniel Glazman -Ian Hickson - - - -div.stub * { color : lime } -div.stub > * > *:not(:active) { color : black } - - -
-

This text should turn green while it is active.

-

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-65.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-65.xml deleted file mode 100644 index 8fc8e954b36..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-65.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Daniel Glazman - - - -a:not(:focus) { background-color: transparent; } -a { background-color: lime; } - - -

The background color of all anchors - should become green when they have the - focus.

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-66.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-66.xml deleted file mode 100644 index 7d17bf525dd..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-66.xml +++ /dev/null @@ -1,23 +0,0 @@ - - -Daniel Glazman -Ian Hickson - - - -p { background-color: navy; color: white; } -p:not(:target) { background-color: white; color: black; } - -

This paragraph should be unstyled. - The background of the following paragraph should become blue when - you follow this link.

-

This paragraph should initially be unstyled. - It should become blue when you select the link above. When you select - this link, it should return to being unstyled and the - background of the paragraph below should become blue.

-

This paragraph should initially be unstyled. - It should become blue when you select the link above. When you follow - this link, the three paragraphs - should all return to being unstyled.

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-66b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-66b.xml deleted file mode 100644 index c3b40707733..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-66b.xml +++ /dev/null @@ -1,11 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -p { background-color: red; } -p:not(:target) { background-color: lime; } - -

This paragraph should be green.

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-67.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-67.xml deleted file mode 100644 index 533498fd904..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-67.xml +++ /dev/null @@ -1,20 +0,0 @@ - - -Daniel Glazman - -div.stub * { background-color : red } -div.stub *:not(:lang(fr)) { background-color : green } - - -
-

This paragraph should have a green background because the - enclosing div is in english.

-

This paragraph should have a green background because - it is in english.

-
-

This paragraph should have a green background - because it is in english.

-
-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-68.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-68.xml deleted file mode 100644 index 7c8afe60230..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-68.xml +++ /dev/null @@ -1,17 +0,0 @@ - - -Daniel Glazman -button { background-color : red } -input { background-color : red } -button:not(:enabled) { background-color : lime } -input:not(:enabled) { background-color : lime } - - -

- -
- -

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-69.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-69.xml deleted file mode 100644 index 8915eb2839e..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-69.xml +++ /dev/null @@ -1,17 +0,0 @@ - - -Daniel Glazman -button { background-color : red } -input { background-color : red } -button:not(:disabled) { background-color : lime } -input:not(:disabled) { background-color : lime } - - -

- -
- -

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-7.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-7.xml deleted file mode 100644 index bd5199ddffa..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-7.xml +++ /dev/null @@ -1,20 +0,0 @@ - - -Daniel Glazman -p { background-color : red } -p[class~="b"] { background-color : lime } -address { background-color : red } -address[title~="foo"] { background-color : lime } -span[class~="b"] { background-color : red } - - -

This paragraph should have green background because CLASS - contains "b"

-
-This address should also - have green background because the selector in the last - rule does not apply to the inner SPANs. -
-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-70.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-70.xml deleted file mode 100644 index cce76420397..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-70.xml +++ /dev/null @@ -1,12 +0,0 @@ - - -Daniel Glazman -Ian Hickson -input, span { background-color : red } -input:not(:checked), input:not(:checked) + span { background-color : lime} - - -

- Everything in this paragraph should have a green background

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-72.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-72.xml deleted file mode 100644 index cdf956b89c7..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-72.xml +++ /dev/null @@ -1,14 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -p:not(:root) { background-color: lime; } -div * { background-color: red; } - - -
-

This paragraph should have a green background and there should be no red anywhere.

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-72b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-72b.xml deleted file mode 100644 index 0d1f0d1a515..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-72b.xml +++ /dev/null @@ -1,14 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -html:not(:root), test:not(:root) { background-color: red; } -p { background-color: lime; } - - -
-

This paragraph should have a green background and there should be no red anywhere.

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-75.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-75.xml deleted file mode 100644 index 996af7b18f7..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-75.xml +++ /dev/null @@ -1,31 +0,0 @@ - - -Daniel Glazman -Ian Hickson -.red { background-color : red } -p:not(:nth-of-type(3)) { background-color : lime } -dl > *:not(:nth-of-type(3n+1)) { background-color : lime } - - - -

This paragraph should have green background

-
And this address should be unstyled.
-

This paragraph should also have green background!

-

But this one should be unstyled again.

-
-
First definition term
-
First definition
-
Second definition term that should have green background
-
Second definition that should have green background
-
Third definition term that should have green background
-
Third definition that should have green background
-
Fourth definition term
-
Fourth definition
-
Fifth definition term that should have green background
-
Fifth definition that should have green background
-
Sixth definition term that should have green background
-
Sixth definition that should have green background
-
-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-75b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-75b.xml deleted file mode 100644 index fae417ee013..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-75b.xml +++ /dev/null @@ -1,31 +0,0 @@ - - -Daniel Glazman -Ian Hickson -.green { background-color : lime ! important } -p:not(:nth-of-type(3)) { background-color : red } -dl > *:not(:nth-of-type(3n+1)) { background-color : red } - - - -

This paragraph should have green background

-
And this address should be unstyled.
-

This paragraph should also have green background!

-

But this one should be unstyled again.

-
-
First definition term
-
First definition
-
Second definition term that should have green background
-
Second definition that should have green background
-
Third definition term that should have green background
-
Third definition that should have green background
-
Fourth definition term
-
Fourth definition
-
Fifth definition term that should have green background
-
Fifth definition that should have green background
-
Sixth definition term that should have green background
-
Sixth definition that should have green background
-
-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-76.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-76.xml deleted file mode 100644 index 4c1caa7abe2..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-76.xml +++ /dev/null @@ -1,32 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -.red { background-color : red } -p:not(:nth-last-of-type(3)) { background-color : lime } -dl > *:not(:nth-last-of-type(3n+1)) { background-color : lime } - - - -

This paragraph should be unstyled.

-
This address should be unstyled.
-

This paragraph should have green background.

-

This paragraph should have green background.

-
-
First definition term that should have green background.
-
First definition that should also have a green background.
-
Second definition term that should have green background.
-
Second definition that should have green background.
-
Third definition term.
-
Third definition.
-
Fourth definition term that should have green background.
-
Fourth definition that should have green background.
-
Fifth definition term that should have green background.
-
Fifth definition that should have green background.
-
Sixth definition term.
-
Sixth definition.
-
-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-76b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-76b.xml deleted file mode 100644 index 089f673ecf4..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-76b.xml +++ /dev/null @@ -1,32 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -.green { background-color : lime ! important } -p:not(:nth-last-of-type(3)) { background-color : red } -dl > *:not(:nth-last-of-type(3n+1)) { background-color : red } - - - -

This paragraph should be unstyled.

-
This address should be unstyled.
-

This paragraph should have green background.

-

This paragraph should have green background.

-
-
First definition term that should have green background.
-
First definition that should also have a green background.
-
Second definition term that should have green background.
-
Second definition that should have green background.
-
Third definition term.
-
Third definition.
-
Fourth definition term that should have green background.
-
Fourth definition that should have green background.
-
Fifth definition term that should have green background.
-
Fifth definition that should have green background.
-
Sixth definition term.
-
Sixth definition.
-
-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-77.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-77.xml deleted file mode 100644 index e204565968d..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-77.xml +++ /dev/null @@ -1,33 +0,0 @@ - - -Daniel Glazman -Ian Hickson -.red { background-color : red } -.t1 td:not(:first-child) { background-color : lime } -p > *:not(:first-child) { background-color : lime } -table.t1 td { border : thin black solid } - - - -
- - - - - - - - - - - - - - - - -
1.1green cellgreen cell
2.1green cellgreen cell
3.1green cellgreen cell
-
-

This paragraph should be unstyled.

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-77b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-77b.xml deleted file mode 100644 index 77a6f9b7efd..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-77b.xml +++ /dev/null @@ -1,33 +0,0 @@ - - -Daniel Glazman -Ian Hickson -.green { background-color : lime ! important } -.t1 td:not(:first-child) { background-color : red } -p > *:not(:first-child) { background-color : red } -table.t1 td { border : thin black solid } - - - -
- - - - - - - - - - - - - - - - -
1.1green cellgreen cell
2.1green cellgreen cell
3.1green cellgreen cell
-
-

This paragraph should be unstyled.

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-78.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-78.xml deleted file mode 100644 index 42dd9ccaf3d..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-78.xml +++ /dev/null @@ -1,33 +0,0 @@ - - -Daniel Glazman -Ian Hickson -.red { background-color : red } -.t1 td:not(:last-child) { background-color : lime } -p > *:not(:last-child) { background-color : lime } -table.t1 td { border : thin black solid } - - - -
- - - - - - - - - - - - - - - - -
green cellgreen cell1.3
green cellgreen cell2.3
green cellgreen cell3.3
-
-

This paragraph should be unstyled.

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-78b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-78b.xml deleted file mode 100644 index 491dcaa7e99..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-78b.xml +++ /dev/null @@ -1,33 +0,0 @@ - - -Daniel Glazman -Ian Hickson -.green { background-color : lime ! important } -.t1 td:not(:last-child) { background-color : red } -p > *:not(:last-child) { background-color : red } -table.t1 td { border : thin black solid } - - - -
- - - - - - - - - - - - - - - - -
green cellgreen cell1.3
green cellgreen cell2.3
green cellgreen cell3.3
-
-

This paragraph should be unstyled.

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-79.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-79.xml deleted file mode 100644 index e0f664373a2..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-79.xml +++ /dev/null @@ -1,16 +0,0 @@ - - -Daniel Glazman -.red { background-color : red } -address { margin-bottom : 1em ; margin-left : 1em } -address:not(:first-of-type) { background-color : lime } - - - -
This div contains 3 addresses : -
A first address with normal background
-
A second address that should have a green background
-
A third address that should have a green background
-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-7b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-7b.xml deleted file mode 100644 index 51fcccb0ada..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-7b.xml +++ /dev/null @@ -1,18 +0,0 @@ - - -Ian Hickson - - -p { background: lime; } -[title~="hello world"] { background: red; } -/* Section 6.3.1: Represents the att attribute whose value is a -space-separated list of words, one of which is exactly "val". If this -selector is used, the words in the value must not contain spaces -(since they are separated by spaces). */ - - - -

This line should have a green background.

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-7c.xml-disabled-due-to-limitations-in-the-build-system b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-7c.xml-disabled-due-to-limitations-in-the-build-system deleted file mode 100644 index 68c5a9fe804..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-7c.xml-disabled-due-to-limitations-in-the-build-system +++ /dev/null @@ -1,29 +0,0 @@ - - -Ian Hickson - - -p { background: red; } -[title~="pass"] { background: lime; } -address { background: lime; } -[title~="fail"] { background: red; } - - - - - -

This line should have a green background.

-

This line should have a green background.

-

This line should have a green background.

- -

This line should have a green background.

- - -
This line should have a green background.
-
This line should have a green background.
-
This line should have a green background.
-
This line should have a green background.
-
This line should have a green background.
-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-7d.xml-disabled-due-to-limitations-in-the-build-system b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-7d.xml-disabled-due-to-limitations-in-the-build-system deleted file mode 100644 index 61faff54274..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-7d.xml-disabled-due-to-limitations-in-the-build-system +++ /dev/null @@ -1,30 +0,0 @@ - - - -Ian Hickson - - -p { background: red; } -[class~="pass"] { background: lime; } -address { background: lime; } -[class~="fail"] { background: red; } - - - - - -

This line should have a green background.

-

This line should have a green background.

-

This line should have a green background.

- -

This line should have a green background.

- - -
This line should have a green background.
-
This line should have a green background.
-
This line should have a green background.
-
This line should have a green background.
-
This line should have a green background.
-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-8.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-8.xml deleted file mode 100644 index 8ad15c3ed3f..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-8.xml +++ /dev/null @@ -1,19 +0,0 @@ - - -Daniel Glazman -p { background-color : red } -p[lang|="en"] { background-color : lime } -address { background-color : red } -address[lang="fi"] { background-color : lime } -span[lang|="fr"] { background-color : red } - - -

This paragraph should have green background because its language is "en-gb"

-
-This address should also - have green background because the language of the inner SPANs - is not French. -
-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-80.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-80.xml deleted file mode 100644 index 9199f4b5bd0..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-80.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Daniel Glazman -.red { background-color : red } -address { margin-bottom : 1em ; margin-left : 1em } -address:not(:last-of-type) { background-color : lime } - - -
-
A first address that should have a green background
-
A second address that should have a green background
-
A third address with normal background
-This div should have three addresses above it.
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-81.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-81.xml deleted file mode 100644 index 2e16fdb3b90..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-81.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Daniel Glazman -Ian Hickson -.red { background-color : red } -p:not(:only-child) { background-color : lime } -div.testText > div > p { margin-left : 1em } - - -

This paragraph should have a green background.

-
This div contains only one paragraph. -

This paragraph should be unstyled.

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-81b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-81b.xml deleted file mode 100644 index 3d70619eb95..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-81b.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Daniel Glazman -Ian Hickson -.green { background-color : lime ! important } -p:not(:only-child) { background-color : lime } -div.testText > div > p { margin-left : 1em } - - -

This paragraph should have a green background.

-
This div contains only one paragraph. -

This paragraph should be unstyled.

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-82.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-82.xml deleted file mode 100644 index 180aa135583..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-82.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Daniel Glazman -Ian Hickson -.red { background-color : red } -.t1 *:not(:only-of-type) { background-color : lime } - - -
-

This paragraph should have green background.

-
But this address should be unstyled.
-

This paragraph should have green background.

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-82b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-82b.xml deleted file mode 100644 index 388a7e0dbd5..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-82b.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -Daniel Glazman -Ian Hickson -.green { background-color : lime ! important } -.t1 *:not(:only-of-type) { background-color : red } - - -
-

This paragraph should have green background.

-
But this address should be unstyled.
-

This paragraph should have green background.

-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-83.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-83.xml deleted file mode 100644 index 07f6c1211b7..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-83.xml +++ /dev/null @@ -1,11 +0,0 @@ - - -Daniel Glazman - -p { background-color : lime } -p:not(:not(p)) { background-color : red } - - -

This paragraph should have a green background

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-84.xml-disabled-contains-removed b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-84.xml-disabled-contains-removed deleted file mode 100644 index 9a19e01f486..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-84.xml-disabled-contains-removed +++ /dev/null @@ -1,17 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -div.stub *:contains("agree") { background-color : lime } -.red { background-color : red } - - -
-

There is no disagreement over the fact that this paragraph should have a green background.

-
    -
  • All the text in this list should have a
  • green background throughout as well.
  • -
-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-84b.xml-disabled-contains-removed b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-84b.xml-disabled-contains-removed deleted file mode 100644 index fbb0f06a698..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-84b.xml-disabled-contains-removed +++ /dev/null @@ -1,18 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -.green { background-color : lime } -div.stub *:contains("agree") { background-color : red } - - -
-

This paragraph should have a green background.

-
    -
  • This list should also have a
  • -
  • green background throughout.
  • -
-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-85.xml-disabled-contains-removed b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-85.xml-disabled-contains-removed deleted file mode 100644 index 2021bd8fba6..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-85.xml-disabled-contains-removed +++ /dev/null @@ -1,18 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -div.stub *:not(:contains("red")) { background-color: lime; } -.red { background-color: red; } - - -
-

This paragraph should have a green background.

-
    -
  • All the text in this list should have a
  • -
  • green background throughout as well.
  • -
-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-86.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-86.xml deleted file mode 100644 index cb55d9fca49..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-86.xml +++ /dev/null @@ -1,17 +0,0 @@ - - -Daniel Glazman - -p { color: red; } -blockquote > div p { color: green; } - - -
-
-
-

This text should be green.

-
-
-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-87.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-87.xml deleted file mode 100644 index 377fbb601c4..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-87.xml +++ /dev/null @@ -1,14 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -p { color: red; } -blockquote + div ~ p { color: green; } - -
This text should be unstyled.
-
This text should be unstyled.
-
This text should be unstyled.
-

This text should be green.

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-87b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-87b.xml deleted file mode 100644 index 0e0861f17e1..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-87b.xml +++ /dev/null @@ -1,14 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -p { color: green ! important; } -blockquote + div ~ p { color: red; } - -
This text should be unstyled.
-
This text should be unstyled.
-
This text should be unstyled.
-

This text should be green.

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-88.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-88.xml deleted file mode 100644 index f9795eabf91..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-88.xml +++ /dev/null @@ -1,16 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -p { color: red; } -blockquote + div p { color: green; } - -
This text should be unstyled.
-
-
-

This text should be green.

-
-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-88b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-88b.xml deleted file mode 100644 index 97a8a654d93..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-88b.xml +++ /dev/null @@ -1,16 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -p { color: green ! important; } -blockquote + div p { color: red; } - -
This text should be unstyled.
-
-
-

This text should be green.

-
-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-89.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-89.xml deleted file mode 100644 index 48aca00df9e..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-89.xml +++ /dev/null @@ -1,16 +0,0 @@ - - -Daniel Glazman - -p { color: red; } -blockquote div > p { color: green; } - -
-
-
-

This text should be green.

-
-
-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-9.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-9.xml deleted file mode 100644 index 17c5faa589e..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-9.xml +++ /dev/null @@ -1,12 +0,0 @@ - - -Daniel Glazman -p { background-color : red } -p[title^="foo"] { background-color : lime } - - -

This paragraph should have a green background
-because its title attribute begins with "foo"

-
- -
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-90.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-90.xml deleted file mode 100644 index 3269a9c9397..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-90.xml +++ /dev/null @@ -1,14 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -p { color: red; } -blockquote ~ div + p { color: green; } - -
This text should be unstyled.
-
This text should be unstyled.
-
This text should be unstyled.
-

This text should be green.

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-90b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-90b.xml deleted file mode 100644 index cc6303e0e5b..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-90b.xml +++ /dev/null @@ -1,14 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -p { color: green ! important; } -blockquote ~ div + p { color: red; } - -
This text should be unstyled.
-
This text should be unstyled.
-
This text should be unstyled.
-

This text should be green.

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-91.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-91.xml deleted file mode 100644 index 64db9e8fd07..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-91.xml +++ /dev/null @@ -1,11 +0,0 @@ - - -Daniel Glazman - -@namespace test url(http://www.example.org/a); -testa { background-color : red } -test|testa { background-color : lime } - -This paragraph should have a green background - - diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-92.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-92.xml deleted file mode 100644 index 66995165f76..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-92.xml +++ /dev/null @@ -1,13 +0,0 @@ - -Daniel Glazman - -@namespace test url(http://www.example.org/b); -div.myTest * { background-color : red } -div.myTest *|testA { background-color : lime } - - -
-This paragraph should have a green background -
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-93.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-93.xml deleted file mode 100644 index d27bc764648..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-93.xml +++ /dev/null @@ -1,13 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -@namespace test url(http://www.example.org/b); -*|testA { background-color : red } -|testA {background-color : lime } - - -This paragraph has no declared namespace and should have a green background. - - diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-94.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-94.xml deleted file mode 100644 index 3182eedd5b9..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-94.xml +++ /dev/null @@ -1,18 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -@namespace a url(http://www.example.org/a); -@namespace b url(http://www.example.org/b); -p, q { display : block ; margin-bottom : 1em } -b|* { background-color : lime } - - -

This line should be unstyled.

-

This line should have a green background.

-This line should have a green background. -

This line should be unstyleed.

-

This line should have a green background.

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-94b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-94b.xml deleted file mode 100644 index 683af54fd62..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-94b.xml +++ /dev/null @@ -1,19 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -@namespace a url(http://www.example.org/a); -@namespace b url(http://www.example.org/b); -p, q { display : block ; margin-bottom : 1em } -b|* { background-color : red } -[test] { background-color: lime; } - - -

This line should be unstyled.

-

This line should have a green background.

-This line should have a green background. -

This line should be unstyled.

-

This line should have a green background.

-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-95.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-95.xml deleted file mode 100644 index c501fecd110..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-95.xml +++ /dev/null @@ -1,20 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -@namespace a url(http://www.example.org/a); -@namespace b url(http://www.example.org/b); -div.test * { background-color : red ; display : block ; margin-bottom : 1em } -div.test *|* { background-color : lime } - - -
-

This line should have a green background

-

This line should have a green background

- This line should have a green background -

This line should have a green background

- This line should have a green background -
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-96.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-96.xml deleted file mode 100644 index 3675657022f..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-96.xml +++ /dev/null @@ -1,24 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -@namespace a url(http://www.example.org/a); -@namespace b url(http://www.example.org/b); -div.green * { background-color : red } -div.test * { display : block ; margin-bottom : 1em } -div.test |* { background-color : lime } - - -
-

This line should be unstyled.

- This line should be unstyled. - This line should be unstyled. -
-

This line should have a green background

- This line should have a green background - This line should have a green background -
-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-96b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-96b.xml deleted file mode 100644 index 415115970c0..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-96b.xml +++ /dev/null @@ -1,24 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -@namespace a url(http://www.example.org/a); -@namespace b url(http://www.example.org/b); -div.green * { background-color : lime ! important } -div.test * { display : block ; margin-bottom : 1em } -div.test |* { background-color : red } - - -
-

This line should be unstyled.

- This line should be unstyled. - This line should be unstyled. -
-

This line should have a green background

- This line should have a green background - This line should have a green background -
-
-
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-97.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-97.xml deleted file mode 100644 index bcfddc6ff34..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-97.xml +++ /dev/null @@ -1,18 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -@namespace a url(http://www.example.org/a); -@namespace b url(http://www.example.org/b); -*|p, *|q, *|r { display : block ; margin-bottom : 1em } -*|q { background-color : red } -*[a|title] {background-color : lime } - - - -

This paragraph should be unstyled.

- This paragraph should have a green background. - This paragraph should be unstyled. -
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-97b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-97b.xml deleted file mode 100644 index 684b97e470c..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-97b.xml +++ /dev/null @@ -1,18 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -@namespace a url(http://www.example.org/a); -@namespace b url(http://www.example.org/b); -*|p, *|q, *|r { display : block ; margin-bottom : 1em } -*|q { background-color : lime ! important } -*[a|title] {background-color : red } - - - -

This paragraph should be unstyled.

- This paragraph should have a green background. - This paragraph should be unstyled. -
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-98.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-98.xml deleted file mode 100644 index f8a7ea055f5..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-98.xml +++ /dev/null @@ -1,21 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -@namespace a url(http://www.example.org/a); -@namespace b url(http://www.example.org/b); -*|p, *|q, *|r, *|s { display : block ; margin-bottom : 1em } -*|q, *|t { background-color : red } -*[a|title="foo"] {background-color : lime } -*[a|title=footwo] {background-color : lime } - - - -

This paragraph should be unstyled.

- This paragraph should have a green background - This paragraph should be unstyled. - This paragraph should be unstyled. - This paragraph should have a green background -
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-98b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-98b.xml deleted file mode 100644 index b9ac686f2d2..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-98b.xml +++ /dev/null @@ -1,19 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -@namespace a url(http://www.example.org/a); -@namespace b url(http://www.example.org/b); -*|p, *|q, *|r, *|s { display : block ; margin-bottom : 1em } -*|q { background-color : lime ! important } -*[a|title="foo"] {background-color : red } - - - -

This paragraph should be unstyled.

- This paragraph should have a green background - This paragraph should be unstyled. - This paragraph should be unstyled. -
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-99.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-99.xml deleted file mode 100644 index f5e88ecb543..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-99.xml +++ /dev/null @@ -1,21 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -@namespace a url(http://www.example.org/a); -@namespace b url(http://www.example.org/b); -@namespace html url(http://www.w3.org/1999/xhtml); -*|p, *|q, *|r, *|s { display : block ; margin-bottom : 1em } -*|p, *|r { background-color : red } -*|*[a|foo~="bar"], *|*[|class~="bar"] { background-color : lime } -*|*[html|class~="bar"] { background-color : red } - - - -

This paragraph should have a green background.

- This paragraph should be unstyled. - This paragraph should have a green background. - This paragraph should be unstyled. -
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-99b.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-99b.xml deleted file mode 100644 index 30fb0021bc1..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-99b.xml +++ /dev/null @@ -1,20 +0,0 @@ - - -Daniel Glazman -Ian Hickson - -@namespace a url(http://www.example.org/a); -@namespace b url(http://www.example.org/b); -@namespace html url(http://www.w3.org/1999/xhtml); -*|p, *|q, *|r, *|s { display : block ; margin-bottom : 1em } -*|p, *|r { background-color : lime ! important } -*|*[a|foo~="bar"], *|*[html|class~="bar"] { background-color : red } - - - -

This paragraph should have a green background.

- This paragraph should be unstyled. - This paragraph should have a green background. - This paragraph should be unstyled. -
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d1.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d1.xml deleted file mode 100644 index 06b98529876..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d1.xml +++ /dev/null @@ -1,34 +0,0 @@ - - -Ian Hickson - - - - - #test { background: red; display: block; padding: 1em; } - #test:not(:empty) { background: lime; } - - - - -
- - - -

The following bar should be green.

- -
- -
- -
- diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d2.xml b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d2.xml deleted file mode 100644 index 927c92c51ea..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d2.xml +++ /dev/null @@ -1,53 +0,0 @@ - - -Ian Hickson - - - - - #test { background: red; display: block; padding: 1em; } - #stub ~ div div + div > div { background: lime; } - - - - -
- - - - - - - - - -

The following bar should be green.

- -
-
-
- -
- -
- diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d5.xml-removed b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d5.xml-removed deleted file mode 100644 index 70c9e120091..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d5.xml-removed +++ /dev/null @@ -1,35 +0,0 @@ - - -Tantek Çelik -Ian Hickson - - - - - input, span { background:red } - input:indeterminate, input:indeterminate + span { background:green; } - - - - -
- - - -

Everything in this paragraph should have a green background.

- -
- -
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d5a.xml-removed b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d5a.xml-removed deleted file mode 100644 index e57f5e67914..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d5a.xml-removed +++ /dev/null @@ -1,35 +0,0 @@ - - -Tantek Çelik -Ian Hickson - - - - - input, span { background: green; } - input:checked, input:checked + span { background: red; } - - - - -
- - - -

Everything in this paragraph should have a green background.

- -
- -
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d5b.xml-removed b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d5b.xml-removed deleted file mode 100644 index b8114fabca6..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d5b.xml-removed +++ /dev/null @@ -1,36 +0,0 @@ - - -Tantek Çelik -Ian Hickson - - - - - input, span { background: red; } - input:not(:checked), input:not(:checked) + span { background: green; } - - - - -
- - - -

Everything in this paragraph should have a green background.

- -
- -
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d5c.xml-removed b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d5c.xml-removed deleted file mode 100644 index a568e301d51..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d5c.xml-removed +++ /dev/null @@ -1,37 +0,0 @@ - - -Tantek Çelik -Ian Hickson - - - - - input, span { background:red } - input:not(:indeterminate), input:not(:indeterminate) + span { background:green; } - - - - -
- - - -

Everything in this paragraph should have a green background.

- -
- -
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d5d.xml-removed b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d5d.xml-removed deleted file mode 100644 index a8343d6ab83..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d5d.xml-removed +++ /dev/null @@ -1,36 +0,0 @@ - - -Tantek Çelik -Ian Hickson - - - - - input, span { background: green; } - input:indeterminate:checked, input:indeterminate:checked + span { background: red; } - - - - -
- - - -

Everything in this paragraph should have a green background.

- -
- -
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d5e.xml-removed b/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d5e.xml-removed deleted file mode 100644 index ffe1b1a019b..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d5e.xml-removed +++ /dev/null @@ -1,33 +0,0 @@ - - -Tantek Çelik -Ian Hickson - - - - - input, span { background:red } - input:not(:indeterminate):not(:checked), input:not(:indeterminate):not(:checked) + span { background:green; } - - - - -
- - - -

Everything in this paragraph should have a green background.

- -
- -
-
diff --git a/tests/wpt/web-platform-tests/css/selectors/generate.pl b/tests/wpt/web-platform-tests/css/selectors/generate.pl deleted file mode 100644 index 812dd7a1126..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/generate.pl +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/perl -w -############################################################################## -# W3C Test Suite Generator # -############################################################################## -package main; -use strict; -use diagnostics; -use XML::Parser; # DEPENDENCY -use lib '.'; -use utils::parser; -use utils::helpers; -use utils::generators; - -# check arguments -# if argument 1 is '-v' then print out the value of second argument, which will be one of: -# - DESTINATION_TYPES -# - SHELL_TYPES -# - TEST_TYPES - -if (scalar(@ARGV) == 1 and ($ARGV[0] eq '-h' or $ARGV[0] eq '--help')) { - print "Syntax: generateTests.pl -v VARIABLE_NAME or generateTests.pl test1.xml test2,xml ...\n"; - return 0; -} elsif (scalar(@ARGV) > 0 and $ARGV[0] eq '-v') { - if (scalar(@ARGV) == 2) { - print $utils::helpers::types{$ARGV[1]}; - exit 0; - } else { - my @vars = keys(%utils::helpers::types); - local $" = '\', \''; - print "You must specify which variable to display in the form '-v VARIABLE_NAME',\nwhere VARIABLE_NAME is one of '@vars'.\n"; - exit 1; - } -} - -# otherwise, process arguments as filenames: -my %cache = %{&utils::helpers::readCache()}; -while (scalar(@ARGV)) { - # read file - local $/ = undef; - my $file = <>; - close(ARGV); - # print status - my $filename = $ARGV; - $filename =~ s/\.[a-z]+$//o; # remove extension - print "parsing $filename...\n"; - # process file - $cache{$filename} = XML::Parser->new(Style => 'utils::parser', Namespaces => 1, ErrorContext => 1)->parse($file); - die "$filename: modulename/number attributes wrong ('$cache{$filename}->{modulename}-$cache{$filename}->{number}')\n" if $filename ne "$cache{$filename}->{modulename}-$cache{$filename}->{number}"; -} -&utils::helpers::writeCache(\%cache); - -print "generating tests...\n"; -# ...and generate the tests -&utils::generators::generateTopIndex(\%cache); # points to mini test index and all test type indexes -foreach my $destinationType (split ' ', $utils::helpers::types{'DESTINATION_TYPES'}) { - my @destinationTests = &utils::helpers::shortlistTestsForDestination($destinationType, - [ sort { - my $na = $cache{$a}->{'number'}; - my $nb = $cache{$b}->{'number'}; - for my $n ($na, $nb) { - $n =~ m/^([0-9]*(?:\.[0-9]+)?)/o; - $n = $1; - } - if (($na ne '') and ($nb ne '')) { - return (($na <=> $nb) or ($cache{$a}->{'number'} cmp $cache{$b}->{'number'}) or ($a cmp $b)); - } else { - return (($cache{$a}->{'number'} cmp $cache{$b}->{'number'}) or ($a cmp $b)); - } - } keys(%cache) ], \%cache); - # generate primary index - &utils::generators::generateSubIndex($destinationType, \@destinationTests, \%cache); # points to mini test index and all test type indexes - # generate complete mini test index - &utils::generators::generateMiniTestIndex($destinationType, \@destinationTests, \%cache); # points to all mini tests - # generate mini tests - foreach my $testIndex (0..$#destinationTests) { - # generate mini test and CSS if needed - &utils::generators::generateMiniTest($destinationType, \@destinationTests, \%cache, $testIndex); - } - # generate flat tests and shells - foreach my $testType (split ' ', $utils::helpers::types{'TEST_TYPES'}) { - my @finalTestList = &utils::helpers::shortlistTestsForTypes($testType, \@destinationTests, \%cache); - # generate test type index - &utils::generators::generateTestTypeIndex($destinationType, $testType, \@finalTestList, \%cache); # points to flat test index and each shell index - # generate flat test index - &utils::generators::generateFlatTestIndex($destinationType, $testType, \@finalTestList, \%cache); # points to flat tests - foreach my $shell (split ' ', $utils::helpers::types{'SHELL_TYPES'}) { - # generate shell index - &utils::generators::generateShellTestIndex($destinationType, $testType, $shell, \@finalTestList, \%cache); # points to shell tests - } - foreach my $testIndex (0..$#finalTestList) { - # generate flat test - &utils::generators::generateFlatTest($destinationType, $testType, \@finalTestList, \%cache, $testIndex); - foreach my $shell (split ' ', $utils::helpers::types{'SHELL_TYPES'}) { - # generate shell - &utils::generators::generateShell($destinationType, $testType, $shell, \@finalTestList, \%cache, $testIndex); - } - } - } -} -# generate latest changes log -foreach my $test (sort { $a->{date} cmp $b->{date} } values %cache) { - print "$test->{date} ($test->{rev}): $test->{modulename}-$test->{number} - $test->{def}\n"; -} -print "done\n"; - -############################################################################## diff --git a/tests/wpt/web-platform-tests/css/selectors/historical-xmlid.xht b/tests/wpt/web-platform-tests/css/selectors/historical-xmlid.xht new file mode 100644 index 00000000000..7916d9c1203 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/historical-xmlid.xht @@ -0,0 +1,22 @@ + + + No xml:id support + + + + + + +

Test passes if there is a filled green square and no red.

+
+ + diff --git a/tests/wpt/web-platform-tests/css/selectors/htaccess b/tests/wpt/web-platform-tests/css/selectors/htaccess deleted file mode 100644 index c91ca1c3e52..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/htaccess +++ /dev/null @@ -1 +0,0 @@ -AddDefaultCharset utf-8 diff --git a/tests/wpt/web-platform-tests/css/selectors/html-full.css b/tests/wpt/web-platform-tests/css/selectors/html-full.css deleted file mode 100644 index fa306e5c535..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/html-full.css +++ /dev/null @@ -1,59 +0,0 @@ -/* same as xhtml.css minus namespace stuff */ - -pre.rules { - border : 1px solid black ; - padding : 5px -} - -.WARNING { - background-color: black; - color: white; - font-weight: bold; - margin-top: 1em; -} - -div.testSource { - border: thin black solid; - padding-left: 1em; - padding-right: 1em; -} - -div.testDescription { - border: thin black solid; - background-color: red; -} - -.testDescription { - margin-top: 1em; - width: 100%; - border: thin solid black; -} - -.testDescription th, -.testDescription td { - text-align: center; -} - -.testDescription th { - background-color: silver; -} - -.testDescription .a { - width: 25%; -} - -.testDescription .b { - width: 50%; -} - -.testDescription .c { - width: 100%; -} - -div.validator { - margin-top: 1em; -} - -div.validator img { - border-width : 0; -} diff --git a/tests/wpt/web-platform-tests/css/selectors/html-shell.css b/tests/wpt/web-platform-tests/css/selectors/html-shell.css deleted file mode 100644 index 1c23986cc7b..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/html-shell.css +++ /dev/null @@ -1,73 +0,0 @@ -/* same as xhtml.css minus namespace stuff */ - -pre.rules { - border : 1px solid black ; - padding : 5px -} - -.WARNING { - background-color: black; - color: white; - font-weight: bold; - margin-top: 1em; -} - -div.testSource { - border: thin black solid; - padding-left: 1em; - padding-right: 1em; -} - -div.testDescription { - border: thin black solid; - background-color: red; -} - -.testDescription { - margin-top: 1em; - width: 100%; - border: thin solid black; -} - -.testDescription th, -.testDescription td { - text-align: center; -} - -.testDescription th { - background-color: silver; -} - -.testDescription .a { - width: 25%; -} - -.testDescription .b { - width: 50%; -} - -.testDescription .c { - width: 100%; -} - -div.validator { - margin-top: 1em; -} - -div.validator img { - border-width : 0; -} - -iframe, object { - display: block; - position: fixed; - top: static-position; - left: 1em; - right: 1em; - bottom: 1em; - margin: 0; - width: auto; - height: auto; - padding: 0; - border: thin black solid; -} diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-1.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-1.xml new file mode 100644 index 00000000000..0ce55a4d99e --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-1.xml @@ -0,0 +1,17 @@ + + + + Groups of selectors + + + + + + +
    +
  • The background of this list item should be green
  • +
  • The background of this second list item should be also green
  • +
+

The background of this paragraph should be green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-10.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-10.xml new file mode 100644 index 00000000000..bb2f40f492e --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-10.xml @@ -0,0 +1,16 @@ + + + + Substring matching attribute selector (end) + + + + + + + +

This paragraph should have a green background because +its title attribute ends with "bar"

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-100.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-100.xml new file mode 100644 index 00000000000..57658b7013a --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-100.xml @@ -0,0 +1,22 @@ + + + Attribute dash-separated value selector with declared namespace + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should have a green background +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-100b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-100b.xml new file mode 100644 index 00000000000..8519170f151 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-100b.xml @@ -0,0 +1,22 @@ + + + Attribute dash-separated value selector with declared namespace + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should have a green background +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-101.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-101.xml new file mode 100644 index 00000000000..4d17096f436 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-101.xml @@ -0,0 +1,23 @@ + + + Substring matching attribute value selector on beginning with declared namespace + + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-101b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-101b.xml new file mode 100644 index 00000000000..23fc37b86ab --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-101b.xml @@ -0,0 +1,23 @@ + + + Substring matching attribute value selector on beginning with declared namespace + + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-102.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-102.xml new file mode 100644 index 00000000000..de597818519 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-102.xml @@ -0,0 +1,24 @@ + + + Substring matching attribute value selector on end with declared namespace + + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-102b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-102b.xml new file mode 100644 index 00000000000..cfd121ab71b --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-102b.xml @@ -0,0 +1,22 @@ + + + Substring matching attribute value selector on end with declared namespace + + + + + + + +

This paragraph should have a green background

+This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-103.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-103.xml new file mode 100644 index 00000000000..191533a5d38 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-103.xml @@ -0,0 +1,24 @@ + + + Substring matching attribute value selector on middle with declared namespace + + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-103b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-103b.xml new file mode 100644 index 00000000000..4cdd208fa47 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-103b.xml @@ -0,0 +1,23 @@ + + + Substring matching attribute value selector on middle with declared namespace + + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-104.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-104.xml new file mode 100644 index 00000000000..beed75ddaaf --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-104.xml @@ -0,0 +1,22 @@ + + + Attribute existence selector with universal namespace + + + + + + + +

This paragraph should have a green background

+This paragraph should be unstyled. +This paragraph should have a green background +This paragraph should have a green background + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-104b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-104b.xml new file mode 100644 index 00000000000..9a87d41fa3a --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-104b.xml @@ -0,0 +1,22 @@ + + + Attribute existence selector with universal namespace + + + + + + + +

This paragraph should have a green background

+This paragraph should be unstyled. +This paragraph should have a green background +This paragraph should have a green background + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-105.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-105.xml new file mode 100644 index 00000000000..51d511ee988 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-105.xml @@ -0,0 +1,24 @@ + + + Attribute value selector with universal namespace + + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should have a green background. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-105b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-105b.xml new file mode 100644 index 00000000000..3c3cd2ce4c7 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-105b.xml @@ -0,0 +1,24 @@ + + + Attribute value selector with universal namespace + + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should have a green background. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-106.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-106.xml new file mode 100644 index 00000000000..c806d6bf56c --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-106.xml @@ -0,0 +1,24 @@ + + + Attribute space-separated value selector with universal namespace + + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should have a green background. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-106b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-106b.xml new file mode 100644 index 00000000000..a76ec5a05fe --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-106b.xml @@ -0,0 +1,24 @@ + + + Attribute space-separated value selector with universal namespace + + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should have a green background. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-107.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-107.xml new file mode 100644 index 00000000000..260bdd40c60 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-107.xml @@ -0,0 +1,23 @@ + + + Attribute dash-separated value selector with universal namespace + + + + + + + +

This paragraph should have a green background

+This paragraph should be unstyled. +This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-107b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-107b.xml new file mode 100644 index 00000000000..ebdd2e009bd --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-107b.xml @@ -0,0 +1,23 @@ + + + Attribute dash-separated value selector with universal namespace + + + + + + + +

This paragraph should have a green background

+This paragraph should be unstyled. +This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-108.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-108.xml new file mode 100644 index 00000000000..30e354522d9 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-108.xml @@ -0,0 +1,23 @@ + + + Substring matching attribute selector on beginning with universal namespace + + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should have a green background. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-108b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-108b.xml new file mode 100644 index 00000000000..933aee9c141 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-108b.xml @@ -0,0 +1,23 @@ + + + Substring matching attribute selector on beginning with universal namespace + + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should have a green background. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-109.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-109.xml new file mode 100644 index 00000000000..9f8cee6a738 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-109.xml @@ -0,0 +1,23 @@ + + + Substring matching attribute selector on end with universal namespace + + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should have a green background. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-109b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-109b.xml new file mode 100644 index 00000000000..5e242f5d73e --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-109b.xml @@ -0,0 +1,23 @@ + + + Substring matching attribute selector on end with universal namespace + + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should have a green background. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-11.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-11.xml new file mode 100644 index 00000000000..5e4d827e4cc --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-11.xml @@ -0,0 +1,16 @@ + + + + Substring matching attribute selector (contains) + + + + + + + +

This paragraph should have a green background because +its title attribute contains "bar"

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-110.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-110.xml new file mode 100644 index 00000000000..8760fac79ab --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-110.xml @@ -0,0 +1,23 @@ + + + Substring matching attribute selector on middle with universal namespace + + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should have a green background. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-110b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-110b.xml new file mode 100644 index 00000000000..a20984ac412 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-110b.xml @@ -0,0 +1,23 @@ + + + Substring matching attribute selector on middle with universal namespace + + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should have a green background. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-111.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-111.xml new file mode 100644 index 00000000000..f834da54858 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-111.xml @@ -0,0 +1,20 @@ + + + Attribute existence selector without declared namespace + + + + + + + +

This paragraph should have a green background

+This paragraph should be unstyled. +This paragraph should have a green background + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-111b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-111b.xml new file mode 100644 index 00000000000..8d55801a244 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-111b.xml @@ -0,0 +1,20 @@ + + + Attribute existence selector without declared namespace + + + + + + + +

This paragraph should have a green background

+This paragraph should be unstyled. +This paragraph should have a green background + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-112.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-112.xml new file mode 100644 index 00000000000..f335eff311e --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-112.xml @@ -0,0 +1,23 @@ + + + Attribute value selector without declared namespace + + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-112b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-112b.xml new file mode 100644 index 00000000000..0b5b174b3a7 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-112b.xml @@ -0,0 +1,23 @@ + + + Attribute value selector without declared namespace + + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-113.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-113.xml new file mode 100644 index 00000000000..c779e14650e --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-113.xml @@ -0,0 +1,21 @@ + + + Attribute space-separated value selector without declared namespace + + + + + + + +

This paragraph should have a green background.

+
This address should be unstyled.
+This paragraph should have a green background. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-113b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-113b.xml new file mode 100644 index 00000000000..4cbfc6dfeed --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-113b.xml @@ -0,0 +1,21 @@ + + + Attribute space-separated value selector without declared namespace + + + + + + + +

This paragraph should have a green background.

+
This address should be unstyled.
+This paragraph should have a green background. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-114.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-114.xml new file mode 100644 index 00000000000..9a7f451ee8f --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-114.xml @@ -0,0 +1,22 @@ + + + Attribute dash-separated value selector without declared namespace + + + + + + + +

This paragraph should have a green background.

+
This address should be unstyled.
+
This address should be unstyled.
+This paragraph should have a green background. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-114b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-114b.xml new file mode 100644 index 00000000000..b5aab0d17d4 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-114b.xml @@ -0,0 +1,22 @@ + + + Attribute dash-separated value selector without declared namespace + + + + + + + +

This paragraph should have a green background.

+
This address should be unstyled.
+
This address should be unstyled.
+This paragraph should have a green background. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-115.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-115.xml new file mode 100644 index 00000000000..4c2492bd1b6 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-115.xml @@ -0,0 +1,23 @@ + + + Substring matching attribute selector on beginning without declared namespace + + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-115b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-115b.xml new file mode 100644 index 00000000000..9b37ed1ab8a --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-115b.xml @@ -0,0 +1,23 @@ + + + Substring matching attribute selector on beginning without declared namespace + + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-116.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-116.xml new file mode 100644 index 00000000000..e73d83db14f --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-116.xml @@ -0,0 +1,23 @@ + + + Substring matching attribute selector on end without declared namespace + + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-116b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-116b.xml new file mode 100644 index 00000000000..59a46a6362c --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-116b.xml @@ -0,0 +1,23 @@ + + + Substring matching attribute selector on end without declared namespace + + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-117.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-117.xml new file mode 100644 index 00000000000..5381cec147b --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-117.xml @@ -0,0 +1,23 @@ + + + Substring matching attribute selector on middle without declared namespace + + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-117b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-117b.xml new file mode 100644 index 00000000000..b88ac99a653 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-117b.xml @@ -0,0 +1,23 @@ + + + Substring matching attribute selector on middle without declared namespace + + + + + + + + +

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-118.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-118.xml new file mode 100644 index 00000000000..823c577031d --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-118.xml @@ -0,0 +1,26 @@ + + + NEGATED type element selector with declared namespace + + + + + + + +
+

This paragraph should have a green background.

+

This paragraph should have a green background.

+

This paragraph should have a green background.

+

+ This paragraph should have a green background. +

+
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-119.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-119.xml similarity index 54% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-119.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-119.xml index 17ca9382442..8a4eda34b41 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-119.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-119.xml @@ -1,19 +1,21 @@ - - -Daniel Glazman -Ian Hickson - -@namespace html url(http://www.w3.org/1999/xhtml); + + + NEGATED type element selector with universal namespace + + + + + + + +

This paragraph should have a green background.

This paragraph should have a green background.

@@ -25,5 +27,5 @@ div.stub > *:not(*|div) { background-color : lime } This paragraph should have a green background. This paragraph should have a green background.
- - + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-120.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-120.xml new file mode 100644 index 00000000000..4f233426b2f --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-120.xml @@ -0,0 +1,26 @@ + + + NEGATED type element selector without declared namespace + + + + + + +
+

This paragraph should have a green background

+

This paragraph should have a green background

+ +

This paragraph should have a + green background

+
+

This paragraph should have a green background

+
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-121.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-121.xml new file mode 100644 index 00000000000..4d666876cc8 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-121.xml @@ -0,0 +1,28 @@ + + + NEGATED universal selector with declared namespace + + + + + + + +
+
This address should be in green characters.
+This paragraph should be in green characters. +This paragraph should be in green characters. + +This paragraph should be in green characters. + +
+ + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-122.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-122.xml new file mode 100644 index 00000000000..23538313056 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-122.xml @@ -0,0 +1,25 @@ + + + NEGATED universal selector with universal namespace + + + + + + + +
+
This address should have a green background
+This paragraph should have a green background +This paragraph should have a green background +This paragraph should have a green background +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-123.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-123.xml new file mode 100644 index 00000000000..b9e577a0593 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-123.xml @@ -0,0 +1,24 @@ + + + NEGATED universal selector with declared namespace + + + + + + + +
+
This address should be in green characters.
+This paragraph should be in green characters. +This paragraph should be in green characters. +
+ + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-123b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-123b.xml new file mode 100644 index 00000000000..b6dcd3a97ee --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-123b.xml @@ -0,0 +1,22 @@ + + + NEGATED universal selector with declared namespace + + + + + + + +
+This paragraph should be in green characters. +
+ + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-124.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-124.xml new file mode 100644 index 00000000000..6c487f8af8c --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-124.xml @@ -0,0 +1,23 @@ + + + NEGATED Attribute value selector with declared namespace + + + + + + + +
+

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-124b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-124b.xml new file mode 100644 index 00000000000..a6fba323d29 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-124b.xml @@ -0,0 +1,23 @@ + + + NEGATED Attribute value selector with declared namespace + + + + + + + +
+

This paragraph should have a green background.

+This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-125.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-125.xml new file mode 100644 index 00000000000..10e3ec1d844 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-125.xml @@ -0,0 +1,24 @@ + + + NEGATED Attribute space-separated value selector with declared namespace + + + + + + + + +
+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-125b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-125b.xml new file mode 100644 index 00000000000..032a0eab06f --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-125b.xml @@ -0,0 +1,24 @@ + + + NEGATED Attribute space-separated value selector with declared namespace + + + + + + + + +
+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-126.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-126.xml new file mode 100644 index 00000000000..dca13bdbf70 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-126.xml @@ -0,0 +1,24 @@ + + + NEGATED Attribute dash-separated value selector with declared namespace + + + + + + + + +
+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-126b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-126b.xml new file mode 100644 index 00000000000..9dba3b1c725 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-126b.xml @@ -0,0 +1,24 @@ + + + NEGATED Attribute dash-separated value selector with declared namespace + + + + + + + + +
+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-127.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-127.xml new file mode 100644 index 00000000000..9ef8cd77a74 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-127.xml @@ -0,0 +1,24 @@ + + + NEGATED Substring matching attribute value selector on beginning with declared namespace + + + + + + + + +
+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-127b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-127b.xml new file mode 100644 index 00000000000..41e88ecf652 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-127b.xml @@ -0,0 +1,24 @@ + + + NEGATED Substring matching attribute value selector on beginning with declared namespace + + + + + + + + +
+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-128.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-128.xml new file mode 100644 index 00000000000..cb192739deb --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-128.xml @@ -0,0 +1,24 @@ + + + NEGATED Substring matching attribute value selector on end with declared namespace + + + + + + + + +
+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-128b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-128b.xml new file mode 100644 index 00000000000..26dbce728c1 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-128b.xml @@ -0,0 +1,24 @@ + + + NEGATED Substring matching attribute value selector on end with declared namespace + + + + + + + + +
+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-129.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-129.xml new file mode 100644 index 00000000000..c3dbdbaf6da --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-129.xml @@ -0,0 +1,24 @@ + + + NEGATED Substring matching attribute value selector on middle with declared namespace + + + + + + + + +
+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-129b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-129b.xml new file mode 100644 index 00000000000..407d6a91c53 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-129b.xml @@ -0,0 +1,24 @@ + + + NEGATED Substring matching attribute value selector on middle with declared namespace + + + + + + + + +
+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-13.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-13.xml new file mode 100644 index 00000000000..826e576ad41 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-13.xml @@ -0,0 +1,23 @@ + + + + Class selectors + + + + + + +
    +
  • This list item should have green background because its class is "t1"
  • +
  • This list item should have green background because its class is "t2"
  • +
  • +This list item should have green background because + the inner SPAN does not match SPAN.t3 +
  • +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-130.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-130.xml new file mode 100644 index 00000000000..e9a7672c53e --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-130.xml @@ -0,0 +1,23 @@ + + + NEGATED Attribute existence selector with universal namespace + + + + + + + +
+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should be unstyled. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-130b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-130b.xml new file mode 100644 index 00000000000..54c6c6a9c2c --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-130b.xml @@ -0,0 +1,23 @@ + + + NEGATED Attribute existence selector with universal namespace + + + + + + + +
+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should be unstyled. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-131.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-131.xml new file mode 100644 index 00000000000..f937a8094ad --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-131.xml @@ -0,0 +1,24 @@ + + + NEGATED Attribute value selector with universal namespace + + + + + + + +
+This paragraph should have a green background. +This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should be unstyled. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-131b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-131b.xml new file mode 100644 index 00000000000..05a7753eac6 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-131b.xml @@ -0,0 +1,24 @@ + + + NEGATED Attribute value selector with universal namespace + + + + + + + +
+This paragraph should have a green background. +This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should be unstyled. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-132.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-132.xml new file mode 100644 index 00000000000..f7080850ff9 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-132.xml @@ -0,0 +1,27 @@ + + + NEGATED Attribute space-separated value selector with universal namespace + + + + + + + +
+

This paragraph should be unstyled

+

This paragraph should have a green background.

+This paragraph should have a green background. +This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should be unstyled. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-132b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-132b.xml new file mode 100644 index 00000000000..8270be88ded --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-132b.xml @@ -0,0 +1,27 @@ + + + NEGATED Attribute space-separated value selector with universal namespace + + + + + + + +
+

This paragraph should be unstyled

+

This paragraph should have a green background.

+This paragraph should have a green background. +This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should be unstyled. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-133.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-133.xml new file mode 100644 index 00000000000..1c1b5baf575 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-133.xml @@ -0,0 +1,27 @@ + + + NEGATED Attribute dash-separated value selector with universal namespace + + + + + + + +
+

This paragraph should be unstyled.

+

This paragraph should have a green background.

+This paragraph should have a green background. +This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-133b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-133b.xml new file mode 100644 index 00000000000..6f67b88a179 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-133b.xml @@ -0,0 +1,27 @@ + + + NEGATED Attribute dash-separated value selector with universal namespace + + + + + + + +
+

This paragraph should be unstyled.

+

This paragraph should have a green background.

+This paragraph should have a green background. +This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-134.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-134.xml new file mode 100644 index 00000000000..20f42fda609 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-134.xml @@ -0,0 +1,26 @@ + + + NEGATED Substring matching attribute selector on beginning with universal namespace + + + + + + + + +
+

This paragraph should be unstyled.

+

This paragraph should have a green background.

+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should be unstyled. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-134b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-134b.xml new file mode 100644 index 00000000000..5a14b8f7334 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-134b.xml @@ -0,0 +1,26 @@ + + + NEGATED Substring matching attribute selector on beginning with universal namespace + + + + + + + + +
+

This paragraph should be unstyled.

+

This paragraph should have a green background.

+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should be unstyled. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-135.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-135.xml new file mode 100644 index 00000000000..842ff6573ae --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-135.xml @@ -0,0 +1,26 @@ + + + NEGATED Substring matching attribute selector on end with universal namespace + + + + + + + + +
+

This paragraph should be unstyled.

+

This paragraph should have a green background.

+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should be unstyled. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-135b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-135b.xml new file mode 100644 index 00000000000..9658c29253a --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-135b.xml @@ -0,0 +1,26 @@ + + + NEGATED Substring matching attribute selector on end with universal namespace + + + + + + + + +
+

This paragraph should be unstyled.

+

This paragraph should have a green background.

+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should be unstyled. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-136.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-136.xml new file mode 100644 index 00000000000..ca2a6ca22de --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-136.xml @@ -0,0 +1,27 @@ + + + NEGATED Substring matching attribute selector on middle with universal namespace + + + + + + + + +
+

This paragraph should be unstyled.

+

This paragraph should have a green background.

+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should be unstyled. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-136b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-136b.xml new file mode 100644 index 00000000000..94e8cb03d23 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-136b.xml @@ -0,0 +1,27 @@ + + + NEGATED Substring matching attribute selector on middle with universal namespace + + + + + + + + +
+

This paragraph should be unstyled.

+

This paragraph should have a green background.

+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should be unstyled. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-137.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-137.xml new file mode 100644 index 00000000000..fd17088d383 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-137.xml @@ -0,0 +1,21 @@ + + + NEGATED Attribute existence selector without declared namespace + + + + + + + +
+This paragraph should have a green background. +This paragraph should be unstyled. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-137b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-137b.xml new file mode 100644 index 00000000000..47d5dc7b200 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-137b.xml @@ -0,0 +1,21 @@ + + + NEGATED Attribute existence selector without declared namespace + + + + + + + +
+This paragraph should have a green background. +This paragraph should be unstyled. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-138.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-138.xml new file mode 100644 index 00000000000..9e8f8c0e2ef --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-138.xml @@ -0,0 +1,23 @@ + + + NEGATED Attribute value selector without declared namespace + + + + + + + +
+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-138b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-138b.xml new file mode 100644 index 00000000000..7cc16fd3c39 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-138b.xml @@ -0,0 +1,23 @@ + + + NEGATED Attribute value selector without declared namespace + + + + + + + +
+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-139.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-139.xml new file mode 100644 index 00000000000..ceebe6640b9 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-139.xml @@ -0,0 +1,23 @@ + + + NEGATED Attribute space-separated value selector without declared namespace + + + + + + + +
+

This paragraph should be unstyled.

+
This address should have a green background.
+This paragraph should be unstyled. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-139b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-139b.xml new file mode 100644 index 00000000000..4e727ea9c95 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-139b.xml @@ -0,0 +1,23 @@ + + + NEGATED Attribute space-separated value selector without declared namespace + + + + + + + +
+

This paragraph should be unstyled.

+
This address should have a green background.
+This paragraph should be unstyled. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-14.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-14.xml new file mode 100644 index 00000000000..5074fe0249c --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-14.xml @@ -0,0 +1,29 @@ + + + + More than one class selector + + + + + + + + +

This paragraph +should have a green background and a green thick solid border because +it carries both classes t1 and t2.

+ +
This line +should be green.
+ + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-140.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-140.xml new file mode 100644 index 00000000000..49c9e4bf743 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-140.xml @@ -0,0 +1,24 @@ + + + NEGATED Attribute dash-separated value selector without declared namespace + + + + + + + +
+

This paragraph should be unstyled.

+
This address should have a green background.
+
This address should have a green background.
+This paragraph should be unstyled. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-140b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-140b.xml new file mode 100644 index 00000000000..a39bd7d7730 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-140b.xml @@ -0,0 +1,24 @@ + + + NEGATED Attribute dash-separated value selector without declared namespace + + + + + + + +
+

This paragraph should be unstyled.

+
This address should have a green background.
+
This address should have a green background.
+This paragraph should be unstyled. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-141.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-141.xml new file mode 100644 index 00000000000..d69a2722fc6 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-141.xml @@ -0,0 +1,25 @@ + + + NEGATED Substring matching attribute selector on beginning without declared namespace + + + + + + + + +
+

This paragraph should be unstyled.

+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-141b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-141b.xml new file mode 100644 index 00000000000..184cb4e9dad --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-141b.xml @@ -0,0 +1,25 @@ + + + NEGATED Substring matching attribute selector on beginning without declared namespace + + + + + + + + +
+

This paragraph should be unstyled.

+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-142.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-142.xml new file mode 100644 index 00000000000..230f49032d0 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-142.xml @@ -0,0 +1,25 @@ + + + NEGATED Substring matching attribute selector on end without declared namespace + + + + + + + + +
+

This paragraph should be unstyled.

+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-142b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-142b.xml new file mode 100644 index 00000000000..a107e2a4eac --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-142b.xml @@ -0,0 +1,25 @@ + + + NEGATED Substring matching attribute selector on end without declared namespace + + + + + + + + +
+

This paragraph should be unstyled.

+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-143.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-143.xml new file mode 100644 index 00000000000..3bcd4f23c7f --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-143.xml @@ -0,0 +1,25 @@ + + + NEGATED Substring matching attribute selector on middle without declared namespace + + + + + + + + +
+

This paragraph should be unstyled.

+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-143b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-143b.xml new file mode 100644 index 00000000000..3c867296568 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-143b.xml @@ -0,0 +1,25 @@ + + + NEGATED Substring matching attribute selector on middle without declared namespace + + + + + + + + +
+

This paragraph should be unstyled.

+This paragraph should have a green background. +This paragraph should be unstyled. +This paragraph should have a green background. +This paragraph should have a green background. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-144.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-144.xml new file mode 100644 index 00000000000..7efde113c56 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-144.xml @@ -0,0 +1,16 @@ + + + + NEGATED :enabled:disabled pseudo-classes + + + + + + +
+

This paragraph should have a green background.

+
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-145a.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-145a.xml similarity index 71% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-145a.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-145a.xml index 7ad7011c1d3..ff15de6779a 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-145a.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-145a.xml @@ -1,15 +1,17 @@ - - -Ian Hickson - - + + + :nth-of-type() pseudo-class with hidden elements + + + + + + This line should be green. This line should be unstyled. @@ -27,5 +29,5 @@ This line should be unstyled. This line should be green. - - + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-145b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-145b.xml similarity index 71% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-145b.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-145b.xml index d55730b0652..fb57366b696 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-145b.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-145b.xml @@ -1,15 +1,17 @@ - - -Ian Hickson - - + + + :nth-of-type() pseudo-class with hidden elements + + + + + + This line should be green. This line should be unstyled. @@ -27,5 +29,5 @@ This line should be unstyled. This line should be green. - - + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-146a.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-146a.xml similarity index 75% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-146a.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-146a.xml index 2e2f822568c..8704f09e6dc 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-146a.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-146a.xml @@ -1,15 +1,17 @@ - - -Ian Hickson - - + + + :nth-child() pseudo-class with hidden elements + + + + + + This line should be unstyled. This line should be green. @@ -33,5 +35,5 @@ This line should be green. This line should be unstyled. - - + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-146b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-146b.xml similarity index 76% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-146b.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-146b.xml index b8ac8243969..a7b28b4e5c5 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-146b.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-146b.xml @@ -1,15 +1,17 @@ - - -Ian Hickson - - + + + :nth-child() pseudo-class with hidden elements + + + + + + This line should be unstyled. This line should be green. @@ -33,5 +35,5 @@ This line should be green. This line should be unstyled. - - + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-147a.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-147a.xml similarity index 75% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-147a.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-147a.xml index 70bab9788b9..dcf600bf805 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-147a.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-147a.xml @@ -1,15 +1,17 @@ - - -Ian Hickson - - + + + :nth-last-of-type() pseudo-class with collapsed elements + + + + + + This line should be unstyled. This line should be green. @@ -33,5 +35,5 @@ This line should be green. This line should be unstyled. - - + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-147b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-147b.xml similarity index 75% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-147b.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-147b.xml index 3791bdd4a7e..fdea6da4250 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-147b.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-147b.xml @@ -1,15 +1,17 @@ - - -Ian Hickson - - + + + :nth-last-of-type() pseudo-class with collapsed elements + + + + + + This line should be unstyled. This line should be green. @@ -33,5 +35,5 @@ This line should be green. This line should be unstyled. - - + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-148.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-148.xml new file mode 100644 index 00000000000..217ba53bbd0 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-148.xml @@ -0,0 +1,17 @@ + + + + :empty pseudo-class and text + + + + + + + +

This line should have a green background.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-149.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-149.xml new file mode 100644 index 00000000000..98fce81fac6 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-149.xml @@ -0,0 +1,19 @@ + + + + :empty pseudo-class and empty elements + + + + + + + +
+
This line should have a green background.
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-149b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-149b.xml new file mode 100644 index 00000000000..98fce81fac6 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-149b.xml @@ -0,0 +1,19 @@ + + + + :empty pseudo-class and empty elements + + + + + + + +
+
This line should have a green background.
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-14b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-14b.xml new file mode 100644 index 00000000000..0be061ee973 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-14b.xml @@ -0,0 +1,23 @@ + + + + More than one class selector + + + + + + + +

This line should be green.

+

This line should be green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-14c.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-14c.xml new file mode 100644 index 00000000000..0384f33280e --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-14c.xml @@ -0,0 +1,22 @@ + + + + More than one class selector + + + + + + +

This line should be green.

+
This line should be green.
+
This line should be green.
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-14d.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-14d.xml new file mode 100644 index 00000000000..37e057b517f --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-14d.xml @@ -0,0 +1,19 @@ + + + + NEGATED More than one class selector + + + + + + +

This line should be green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-14e.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-14e.xml new file mode 100644 index 00000000000..a8f8d756215 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-14e.xml @@ -0,0 +1,22 @@ + + + + NEGATED More than one class selector + + + + + + +

This line should be green.

+
This line should be green.
+
This line should be green.
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-15.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-15.xml new file mode 100644 index 00000000000..f3aa372602f --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-15.xml @@ -0,0 +1,22 @@ + + + + ID selectors + + + + + + + +
    +
  • This list item should have a green background. because its ID is "t1"
  • +
  • This list item should have a green background. because its ID is "t2"
  • +
  • This list item should have a green background. because the inner SPAN does not match "#t4"
  • +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-150.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-150.xml new file mode 100644 index 00000000000..b9fdca487ea --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-150.xml @@ -0,0 +1,19 @@ + + + + :empty pseudo-class and XML/SGML constructs + + + + + + +
+
This line should have a green background.
+

(Note: This test is based on unpublished errata.)

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-151.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-151.xml new file mode 100644 index 00000000000..a4bb1dd2017 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-151.xml @@ -0,0 +1,19 @@ + + + + :empty pseudo-class and whitespace + + + + + + + +
+
This line should have a green background.
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-152.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-152.xml new file mode 100644 index 00000000000..b39d5734634 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-152.xml @@ -0,0 +1,19 @@ + + + + :empty pseudo-class and elements + + + + + + + +
+
This line should have a green background.
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-153.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-153.xml new file mode 100644 index 00000000000..45f65fb5988 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-153.xml @@ -0,0 +1,18 @@ + + + :empty pseudo-class and CDATA + + + + + + +
+
This line should have a green background.
+

(Note: This test is based on unpublished errata.)

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-154.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-154.xml new file mode 100644 index 00000000000..f5f029542b7 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-154.xml @@ -0,0 +1,17 @@ + + + + Syntax and parsing + + + + + + + +

This line should have a green background.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-155.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-155.xml new file mode 100644 index 00000000000..961374d6994 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-155.xml @@ -0,0 +1,17 @@ + + + + Syntax and parsing + + + + + + + +

This line should have a green background.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-155a.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-155a.xml new file mode 100644 index 00000000000..1fca1916e4f --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-155a.xml @@ -0,0 +1,17 @@ + + + + Syntax and parsing + + + + + + + +

This line should have a green background.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-155b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-155b.xml new file mode 100644 index 00000000000..168f86523ee --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-155b.xml @@ -0,0 +1,22 @@ + + + + Syntax and parsing + + + + + + + +

This line should have a green background.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-155c.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-155c.xml new file mode 100644 index 00000000000..4fd0b48d6b7 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-155c.xml @@ -0,0 +1,17 @@ + + + + Syntax and parsing + + + + + + + +

This line should have a green background.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-155d.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-155d.xml new file mode 100644 index 00000000000..0c21d5f12ec --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-155d.xml @@ -0,0 +1,17 @@ + + + + Syntax and parsing + + + + + + + +

This line should have a green background.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-156.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-156.xml new file mode 100644 index 00000000000..fa0483e6455 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-156.xml @@ -0,0 +1,17 @@ + + + + Syntax and parsing + + + + + + + +

This line should have a green background.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-156b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-156b.xml new file mode 100644 index 00000000000..59d9f3b65c8 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-156b.xml @@ -0,0 +1,17 @@ + + + + Syntax and parsing + + + + + + + +

This line should have a green background.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-156c.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-156c.xml new file mode 100644 index 00000000000..2b9d445924c --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-156c.xml @@ -0,0 +1,17 @@ + + + + Syntax and parsing + + + + + + + +

This line should have a green background.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-157.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-157.xml new file mode 100644 index 00000000000..6a7e1d85ffd --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-157.xml @@ -0,0 +1,17 @@ + + + + Syntax and parsing + + + + + + + +

This line should have a green background.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-158.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-158.xml new file mode 100644 index 00000000000..9595b907936 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-158.xml @@ -0,0 +1,17 @@ + + + + Syntax and parsing + + + + + + + +

This line should have a green background.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-159.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-159.xml new file mode 100644 index 00000000000..3504398dbcf --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-159.xml @@ -0,0 +1,16 @@ + + + + Syntax and parsing of new pseudo-elements + + + + + + +

Try selecting some text in this document. It should be have a green background.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-15b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-15b.xml new file mode 100644 index 00000000000..b7e4205e0d4 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-15b.xml @@ -0,0 +1,22 @@ + + + + Multiple ID selectors + + + + + + + +

This line should be green.

+
This line should be green.
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-16.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-16.xml new file mode 100644 index 00000000000..48122c26d8a --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-16.xml @@ -0,0 +1,18 @@ + + + + :link pseudo-class + + + + + + + +

+This link should have green background. +(Don't follow this link.) +

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-160.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-160.xml new file mode 100644 index 00000000000..ec1de24cb28 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-160.xml @@ -0,0 +1,19 @@ + + + + Syntax and parsing of unknown pseudo-classes + + + + + + + +

This line should have a green background.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-161.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-161.xml similarity index 59% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-161.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-161.xml index 285b4d2938e..888c6f436b5 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-161.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-161.xml @@ -1,10 +1,8 @@ - - -Ian Hickson - - - - + + + + Syntax and parsing of unknown pseudo-classes and pseudo-elements + + + + + + +

This line should have a green background.

+

UAs may render the following element as a pop up menu. If so, please ensure the menu is unstyled (or green).

-
This line should have a green background (or it might be unstyled).
+
This line should have a green background (or it might be unstyled).
- - -
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-166.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-166.xml new file mode 100644 index 00000000000..5d4e31f9a5c --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-166.xml @@ -0,0 +1,16 @@ + + + + :first-letter with ::first-letter + + + + + + +

The first letter of this paragraph should have a green background.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-166a.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-166a.xml new file mode 100644 index 00000000000..55d36bb68c9 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-166a.xml @@ -0,0 +1,16 @@ + + + + :first-letter with ::first-letter + + + + + + +

The first letter of this paragraph should have a green background.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-167.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-167.xml new file mode 100644 index 00000000000..0fa9e6cdbb9 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-167.xml @@ -0,0 +1,16 @@ + + + + :first-line with ::first-line + + + + + + +

The first line of this paragraph should have a green background.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-167a.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-167a.xml new file mode 100644 index 00000000000..6dd9d8faac2 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-167a.xml @@ -0,0 +1,16 @@ + + + + :first-line with ::first-line + + + + + + +

The first line of this paragraph should have a green background.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-168.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-168.xml new file mode 100644 index 00000000000..431a41b159f --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-168.xml @@ -0,0 +1,18 @@ + + + + :before with ::before + + + + + + + +

This test has .

+

(If the previous line just reads "This test has ." then this test has failed.)

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-168a.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-168a.xml new file mode 100644 index 00000000000..d5ddad42b1d --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-168a.xml @@ -0,0 +1,18 @@ + + + + :before with ::before + + + + + + + +

This test has .

+

(If the previous line just reads "This test has ." then this test has failed.)

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-169.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-169.xml new file mode 100644 index 00000000000..eee2bef3573 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-169.xml @@ -0,0 +1,18 @@ + + + + :after with ::after + + + + + + + +

This test has .

+

(If the previous line just reads "This test has ." then this test has failed.)

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-169a.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-169a.xml new file mode 100644 index 00000000000..6254a520c31 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-169a.xml @@ -0,0 +1,18 @@ + + + + :after with ::after + + + + + + + +

This test has .

+

(If the previous line just reads "This test has ." then this test has failed.)

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-17.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-17.xml new file mode 100644 index 00000000000..e06fb70d588 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-17.xml @@ -0,0 +1,18 @@ + + + + :visited pseudo-class + + + + + + + +

+You should see a green background assigned by the anchor. +(Note: You must have visited http://www.w3.org/ for this test to be valid.) +

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-170.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-170.xml similarity index 90% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-170.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-170.xml index 2feb3cf9c49..c56ae2ac295 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-170.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-170.xml @@ -1,14 +1,17 @@ - - -Ian Hickson - - + + + + Long chains of selectors + + + + + + + +

This line should be green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-170a.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-170a.xml similarity index 92% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-170a.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-170a.xml index 749bb0709cd..1cde7071457 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-170a.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-170a.xml @@ -1,14 +1,17 @@ - - -Ian Hickson - - + + + + Long chains of selectors + + + + + + + +

This line should be green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-170b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-170b.xml similarity index 89% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-170b.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-170b.xml index c0f6887cf09..50b4fc0825b 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-170b.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-170b.xml @@ -1,14 +1,17 @@ - - -Ian Hickson - - + + + + Long chains of selectors + + + + + + + +

This line should be green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-170c.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-170c.xml similarity index 94% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-170c.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-170c.xml index b8c68bd6135..9e5cf375d6f 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-170c.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-170c.xml @@ -1,14 +1,17 @@ - - -Ian Hickson - - + + + + Long chains of selectors + + + + + + + +

This line should be green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-170d.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-170d.xml similarity index 95% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-170d.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-170d.xml index 5d79d1ff45e..371945a439f 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-170d.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-170d.xml @@ -1,14 +1,17 @@ - - -Ian Hickson - - + + + + Long chains of selectors + + + + + + + +

This line should be green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-171.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-171.xml new file mode 100644 index 00000000000..aa3b86e82fa --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-171.xml @@ -0,0 +1,17 @@ + + + Classes: XHTML global class attribute + + + + + + +

+ This should be green. +

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-172a.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-172a.xml similarity index 64% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-172a.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-172a.xml index a936ab7fdf0..fca9c6d4b7d 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-172a.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-172a.xml @@ -1,8 +1,7 @@ - - -Ian Hickson - - + + + Namespaced attribute selectors + + + + + + + This should be green. This should be green. @@ -23,6 +26,5 @@ This should be green. This should be green. - - - + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-172b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-172b.xml similarity index 65% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-172b.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-172b.xml index ea3f3b54ad5..ec93920fbb7 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-172b.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-172b.xml @@ -1,8 +1,7 @@ - - -Ian Hickson - - + + + Namespaced attribute selectors + + + + + + + This should be green. This should be green. @@ -24,6 +27,5 @@ This should be green. This should be green. - - - + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-173a.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-173a.xml similarity index 64% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-173a.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-173a.xml index ee0c48cc4b4..b75f8309c7d 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-173a.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-173a.xml @@ -1,8 +1,7 @@ - - -Ian Hickson - - + + + Namespaced attribute selectors + + + + + + + This should be green. This should be green. @@ -23,6 +26,5 @@ This should be green. This should be green. - - - + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-173b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-173b.xml similarity index 64% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-173b.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-173b.xml index 4520c7c8f60..7769701a9bd 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-173b.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-173b.xml @@ -1,8 +1,7 @@ - - -Ian Hickson - - + + + Namespaced attribute selectors + + + + + + + This should be green. This should be green. @@ -23,6 +26,5 @@ This should be green. This should be green. - - - + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-174a.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-174a.xml new file mode 100644 index 00000000000..25e23c5272c --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-174a.xml @@ -0,0 +1,19 @@ + + + Attribute selectors with multiple attributes + + + + + + + + This should be green. + This should be green. + + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-174b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-174b.xml new file mode 100644 index 00000000000..3a4d0a5e3a2 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-174b.xml @@ -0,0 +1,19 @@ + + + NEGATED Attribute selectors with multiple attributes + + + + + + + + This should be green. + This should be green. + + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-175a.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-175a.xml new file mode 100644 index 00000000000..ca91d681235 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-175a.xml @@ -0,0 +1,17 @@ + + + + Parsing: Numbers in classes + + + + + + + +

This line should be green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-175b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-175b.xml new file mode 100644 index 00000000000..135b8410279 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-175b.xml @@ -0,0 +1,17 @@ + + + + Parsing: Numbers in classes + + + + + + + +

This line should be green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-175c.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-175c.xml new file mode 100644 index 00000000000..7a93313e773 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-175c.xml @@ -0,0 +1,17 @@ + + + + Parsing: Numbers in classes + + + + + + + +

This line should be green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-176.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-176.xml new file mode 100644 index 00000000000..31482f08983 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-176.xml @@ -0,0 +1,24 @@ + + + + Combinations: classes and IDs + + + + + + + +

This line should be green.

+
This line should be green.
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-177a.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-177a.xml new file mode 100644 index 00000000000..09ea141d647 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-177a.xml @@ -0,0 +1,15 @@ + + + + Parsing : vs :: + + + + + + +

When you select this text, it shouldn't go red.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-177b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-177b.xml new file mode 100644 index 00000000000..1205619970a --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-177b.xml @@ -0,0 +1,19 @@ + + + + Parsing : vs :: + + + + + + + +
+

This line should be green.

+
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-178.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-178.xml new file mode 100644 index 00000000000..00f25827619 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-178.xml @@ -0,0 +1,20 @@ + + + + Parsing: :not and pseudo-elements + + + + + + + +
+

This line should be green.

+
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-179.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-179.xml new file mode 100644 index 00000000000..d58cbe961d0 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-179.xml @@ -0,0 +1,18 @@ + + + + ::first-line on inlines + + + + + + + +

This line should be green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-179a.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-179a.xml new file mode 100644 index 00000000000..184365703d3 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-179a.xml @@ -0,0 +1,17 @@ + + + + ::first-line after <br> + + + + + + +



This line should be green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-18.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-18.xml similarity index 50% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-18.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-18.xml index 72e8b4456cf..97443c66cfb 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-18.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-18.xml @@ -1,23 +1,24 @@ - - -Daniel Glazman -Ian Hickson - - - -p:hover { background-color : lime } + + + + :hover pseudo-class + + + + + + + +

The background color of this paragraph should turn to green when the mouse pointer hovers either its text (here) or its whitespace background, here:

-
The background color of this anchor (here) should turn to green when the pointing device hovers over it.
- +
The background color of this anchor (here) should turn to green when the pointing device hovers over it.
+
@@ -56,7 +57,5 @@ table { border-spacing: 5px; }
The cells in
- - -
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-180a.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-180a.xml new file mode 100644 index 00000000000..3661eb9c1f0 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-180a.xml @@ -0,0 +1,17 @@ + + + + ::first-letter after <br> + + + + + + +



This line should be green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-181.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-181.xml similarity index 55% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-181.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-181.xml index 3eca72a32ed..62465e4be54 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-181.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-181.xml @@ -1,8 +1,8 @@ - - -Ian Hickson - - + + + + Case sensitivity + + + + + + +
- -
-

This line should be green.

This line should be green.

This line should be green.

This line should be green.

-
- -
-

This line should be green.

-

This line should be green.

-

This line should be green.

-
-
-
-
- + +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-182.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-182.xml new file mode 100644 index 00000000000..293c11b780f --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-182.xml @@ -0,0 +1,19 @@ + + + Namespaces and \: in selectors + + + + + + +

+ +This text should be green. + +

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-183.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-183.xml new file mode 100644 index 00000000000..97412ddef6e --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-183.xml @@ -0,0 +1,23 @@ + + + + Syntax and parsing of class selectors + + + + + + +

This text should be green.

+

This text should be green.

+

This text should be green.

+

This text should be green.

+

This text should be green.

+

This text should be green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-184-ref.xht b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-184-ref.xht new file mode 100644 index 00000000000..8ffc002f9b0 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-184-ref.xht @@ -0,0 +1,13 @@ + + + + Ref: Two lime lines + + + +

This text should be green.

+

This text should be green.

+ + diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-184a.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-184a.xml new file mode 100644 index 00000000000..9777db1410e --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-184a.xml @@ -0,0 +1,18 @@ + + + + Ends-with attribute selector with empty value + + + + + + + +

This text should be green.

+

This text should be green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-184b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-184b.xml new file mode 100644 index 00000000000..2ea9ad9816d --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-184b.xml @@ -0,0 +1,18 @@ + + + + Starts-with attribute selector with empty value + + + + + + + +

This text should be green.

+

This text should be green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-184c.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-184c.xml new file mode 100644 index 00000000000..4e945506ce2 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-184c.xml @@ -0,0 +1,18 @@ + + + + Contains attribute selector with empty value + + + + + + + +

This text should be green.

+

This text should be green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-184d.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-184d.xml new file mode 100644 index 00000000000..73402386ae0 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-184d.xml @@ -0,0 +1,18 @@ + + + + NEGATED ends-with attribute selector with empty value + + + + + + + +

This text should be green.

+

This text should be green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-184e.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-184e.xml new file mode 100644 index 00000000000..418169b8cd0 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-184e.xml @@ -0,0 +1,18 @@ + + + + NEGATED starts-with attribute selector with empty value + + + + + + + +

This text should be green.

+

This text should be green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-184f.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-184f.xml new file mode 100644 index 00000000000..c28b61dabfb --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-184f.xml @@ -0,0 +1,18 @@ + + + + NEGATED contains attribute selector with empty value + + + + + + + +

This text should be green.

+

This text should be green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-18a.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-18a.xml new file mode 100644 index 00000000000..da5d12dc881 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-18a.xml @@ -0,0 +1,25 @@ + + + + :hover pseudo-class on links + + + + + + +

The background color of this anchor (here) should turn to green when the pointing device hovers over it.

+

The background color of this anchor (here) should remain green when you hover it.

+

The background color of this anchor (here) should remain green when the pointing device hovers over it (do not follow that link).

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-18b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-18b.xml new file mode 100644 index 00000000000..b8dc445f98e --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-18b.xml @@ -0,0 +1,20 @@ + + + + :hover pseudo-class + + + + + + + +
+

The background color of this paragraph should turn to green when the mouse pointer hovers over any of the following:

This text.

+

This text.

+
This text.
This text.
This text.
+

This text.

+

...and anything else between the top of the first paragraph and the bottom of this paragraph.

+
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-18c.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-18c.xml new file mode 100644 index 00000000000..77fba265b98 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-18c.xml @@ -0,0 +1,16 @@ + + + + :hover pseudo-class on links + + + + + + +

Hover here and the background of this text should go green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-19.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-19.xml new file mode 100644 index 00000000000..79f23a5084a --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-19.xml @@ -0,0 +1,16 @@ + + + + :active pseudo-class + + + + + + + +

The background color of the anchor + should turn to green when it is activated and come back to + normal when it is released.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-19b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-19b.xml new file mode 100644 index 00000000000..48ae456ca37 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-19b.xml @@ -0,0 +1,13 @@ + + + + :active pseudo-class on controls + + + + + + +

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-2.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-2.xml new file mode 100644 index 00000000000..09f84d60e98 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-2.xml @@ -0,0 +1,14 @@ + + + + Type element selectors + + + + + + + +
This address element should have a green background.
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-20.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-20.xml new file mode 100644 index 00000000000..7d1288c9f24 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-20.xml @@ -0,0 +1,16 @@ + + + + :focus pseudo-class + + + + + + + +

The background color of anchors + in this page should turn to green when they have the + focus.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-21.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-21.xml new file mode 100644 index 00000000000..5c530922475 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-21.xml @@ -0,0 +1,24 @@ + + + + :target pseudo-class + + + + + + + +

This paragraph should be unstyled. + The background of the following paragraph should become green when + you follow this link.

+

This paragraph should initially be unstyled. + It should become green when you select the link above. When you select + this link, it should return to being unstyled and the + background of the paragraph below should become green.

+

This paragraph should initially be unstyled. + It should become green when you select the link above. When you follow + this link, the three paragraphs + should all return to being unstyled.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-21b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-21b.xml new file mode 100644 index 00000000000..d97181d47dc --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-21b.xml @@ -0,0 +1,15 @@ + + + + :target pseudo-class + + + + + + + +

This paragraph should be green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-21c.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-21c.xml new file mode 100644 index 00000000000..e45074c9a09 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-21c.xml @@ -0,0 +1,15 @@ + + + + :target pseudo-class + + + + + + + +

This page should be green.

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-22.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-22.xml new file mode 100644 index 00000000000..098679c3689 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-22.xml @@ -0,0 +1,26 @@ + + + + :lang() pseudo-class + + + + + + + +
    +
  • This list item should be green because its language is + British English
  • +
  • This list item should be green because its language + is British English (Wales)
  • +
+
    +
  1. This list item should NOT be green because its language + is US English
  2. +
  3. This list item should NOT be green because its language is + French
  4. +
+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-23.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-23.xml new file mode 100644 index 00000000000..663ec09ef2c --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-23.xml @@ -0,0 +1,21 @@ + + + + :enabled pseudo-class + + + + + + + +

+ +

+ +

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-24.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-24.xml new file mode 100644 index 00000000000..d20a0116f74 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-24.xml @@ -0,0 +1,21 @@ + + + + :disabled pseudo-class + + + + + + + +

+ +

+ +

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-25.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-25.xml new file mode 100644 index 00000000000..ef1875fc89e --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-25.xml @@ -0,0 +1,17 @@ + + + + :checked pseudo-class + + + + + + + +

+ Everything in this paragraph should have a green background

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-27.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-27.xml new file mode 100644 index 00000000000..e20227755cb --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-27.xml @@ -0,0 +1,14 @@ + + + + :root pseudo-class + + + + + + +

The background of the document should be green

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-27a.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-27a.xml similarity index 51% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-27a.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-27a.xml index 9c8cad695b2..42736a39095 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-27a.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-27a.xml @@ -1,8 +1,8 @@ - - -Ian Hickson - - + + + + Impossible rules (:root:first-child, etc) + + + + + + +

This line should be green (there should be no red on this page).

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-27b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-27b.xml new file mode 100644 index 00000000000..8bfb356e50d --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-27b.xml @@ -0,0 +1,15 @@ + + + + Impossible rules (* html, * :root) + + + + + + +

This line should be green (there should be no red on this page).

+ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-28.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-28.xml similarity index 70% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-28.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-28.xml index 7972d5dfc0c..f73184d1cac 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-28.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-28.xml @@ -1,14 +1,18 @@ - - -Daniel Glazman -.red { background-color : red } -ul > li:nth-child(odd) { background-color : lime } -ol > li:nth-child(even) { background-color : lime } + + + + :nth-child() pseudo-class + + + + + + +
  • This first list item should have a green background
  • Second list item
  • This third list item should have a green background
  • @@ -16,7 +20,7 @@ table.t2 td:nth-child(3n+1) { background-color : lime }
  • This fifth list item should have a green background
  • Sixth list item
-
    +
    1. First list item
    2. This second list item should have a green background
    3. Third list item
    4. @@ -24,7 +28,7 @@ table.t2 td:nth-child(3n+1) { background-color : lime }
    5. Fifth list item
    6. This sixth list item should have a green background
    -
    +
    @@ -91,5 +95,5 @@ table.t2 td:nth-child(3n+1) { background-color : lime }
    Green row : 1.1
    - - + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-28b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-28b.xml similarity index 68% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-28b.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-28b.xml index 21a5a5479e0..dd3944a9288 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-28b.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-28b.xml @@ -1,16 +1,19 @@ - - -Daniel Glazman -Ian Hickson - -.green { background-color : lime ! important } -ul > li:nth-child(odd) { background-color : red } -ol > li:nth-child(even) { background-color : red } + + + + :nth-child() pseudo-class + + + + + + + +
    • This first list item should have a green background
    • Second list item
    • This third list item should have a green background
    • @@ -18,7 +21,7 @@ table.t2 td:nth-child(3n+1) { background-color : red }
    • This fifth list item should have a green background
    • Sixth list item
    -
      +
      1. First list item
      2. This second list item should have a green background
      3. Third list item
      4. @@ -26,7 +29,7 @@ table.t2 td:nth-child(3n+1) { background-color : red }
      5. Fifth list item
      6. This sixth list item should have a green background
      -
      +
      @@ -59,7 +62,7 @@ table.t2 td:nth-child(3n+1) { background-color : red }
      Green row : 1.1 6.3
      -

      +

      @@ -93,5 +96,5 @@ table.t2 td:nth-child(3n+1) { background-color : red }
      green cell
      - - + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-29.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-29.xml similarity index 68% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-29.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-29.xml index f98b97fd105..cfa23b50c54 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-29.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-29.xml @@ -1,16 +1,19 @@ - - -Daniel Glazman -Ian Hickson - -.red { background-color : red } -ul > li:nth-last-child(odd) { background-color : green } -ol > li:nth-last-child(even) { background-color : green } + + + + :nth-last-child() pseudo-class + + + + + + + +
      • First list item
      • This second list item should have a green background
      • Third list item
      • @@ -18,7 +21,7 @@ table.t2 td:nth-last-child(3n+1) { background-color : green }
      • Fifth list item
      • This sixth list item should have a green background
      -
        +
        1. This first list item should have a green background
        2. Second list item
        3. This third list item should have a green background
        4. @@ -26,7 +29,7 @@ table.t2 td:nth-last-child(3n+1) { background-color : green }
        5. This fifth list item should have a green background
        6. Sixth list item
        -
        +
        @@ -59,7 +62,7 @@ table.t2 td:nth-last-child(3n+1) { background-color : green }
        1.1 6.3
        -

        +

        @@ -93,5 +96,5 @@ table.t2 td:nth-last-child(3n+1) { background-color : green }
        1.1
        - - + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-29b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-29b.xml similarity index 68% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-29b.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-29b.xml index 31e75b5b42b..39227d21895 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-29b.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-29b.xml @@ -1,16 +1,19 @@ - - -Daniel Glazman -Ian Hickson - -.green { background-color : lime ! important } -ul > li:nth-last-child(odd) { background-color : red } -ol > li:nth-last-child(even) { background-color : red } + + + + :nth-last-child() pseudo-class + + + + + + + +
        • First list item
        • This second list item should have a green background
        • Third list item
        • @@ -18,7 +21,7 @@ table.t2 td:nth-last-child(3n+1) { background-color : red }
        • Fifth list item
        • This sixth list item should have a green background
        -
          +
          1. This first list item should have a green background
          2. Second list item
          3. This third list item should have a green background
          4. @@ -26,7 +29,7 @@ table.t2 td:nth-last-child(3n+1) { background-color : red }
          5. This fifth list item should have a green background
          6. Sixth list item
          -
          +
          @@ -59,7 +62,7 @@ table.t2 td:nth-last-child(3n+1) { background-color : red }
          1.1 6.3
          -

          +

          @@ -93,5 +96,5 @@ table.t2 td:nth-last-child(3n+1) { background-color : red }
          1.1
          - - + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-3.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-3.xml new file mode 100644 index 00000000000..7bcc09b947f --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-3.xml @@ -0,0 +1,23 @@ + + + Universal selector + + + + + + +

          +This paragraph, and all textual contents in the document, + should be green. +

          +
            +
          • This item should be green.
          • +
          +And this element, part of a non-HTML namespace, + should be green too + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-30.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-30.xml new file mode 100644 index 00000000000..facd83b7116 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-30.xml @@ -0,0 +1,33 @@ + + + + :nth-of-type() pseudo-class + + + + + + +

          This paragraph is here only to fill space in the DOM

          +
          And this address too..
          +

          So does this paragraph !

          +

          But this one should have green background

          +
          +
          First definition term that should have green background
          +
          First definition that should have green background
          +
          Second definition term
          +
          Second definition
          +
          Third definition term
          +
          Third definition
          +
          Fourth definition term that should have green background
          +
          Fourth definition that should have green background
          +
          Fifth definition term
          +
          Fifth definition
          +
          Sixth definition term
          +
          Sixth definition
          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-31.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-31.xml new file mode 100644 index 00000000000..dbf672bda05 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-31.xml @@ -0,0 +1,33 @@ + + + + :nth-last-of-type() pseudo-class + + + + + + +

          This paragraph should have green background

          +
          But this address is here only to fill space in the dom..
          +

          So does this paragraph !

          +

          And so does this one too.

          +
          +
          First definition term
          +
          First definition
          +
          Second definition term
          +
          Second definition
          +
          Third definition term that should have green background
          +
          Third definition that should have green background
          +
          Fourth definition term
          +
          Fourth definition
          +
          Fifth definition term
          +
          Fifth definition
          +
          Sixth definition term that should have green background
          +
          Sixth definition that should have green background
          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-32.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-32.xml new file mode 100644 index 00000000000..a5551b33f5f --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-32.xml @@ -0,0 +1,37 @@ + + + + :first-child pseudo-class + + + + + + +
          + + + + + + + + + + + + + + + + +
          green cell1.21.3
          green cell2.22.3
          green cell3.23.3
          +
          +

          This paragraph contains some text + and a span that should have a green background +

          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-33.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-33.xml new file mode 100644 index 00000000000..c3fc2731a93 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-33.xml @@ -0,0 +1,37 @@ + + + + :last-child pseudo-class + + + + + + +
          + + + + + + + + + + + + + + + + +
          1.11.2green cell
          2.12.2green cell
          3.13.2green cell
          +
          +

          +This paragraph contains a span that should + have a green background and some text after it.

          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-34.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-34.xml new file mode 100644 index 00000000000..6ea08bbae2f --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-34.xml @@ -0,0 +1,20 @@ + + + + :first-of-type pseudo-class + + + + + + +
          This div contains 3 addresses: +
          A first address that should have a green background
          +
          A second address with normal background
          +
          A third address with normal background
          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-35.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-35.xml new file mode 100644 index 00000000000..ac53300ad11 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-35.xml @@ -0,0 +1,21 @@ + + + + :last-of-type pseudo-class + + + + + + + +
          +
          A first address with normal background
          +
          A second address with normal background
          +
          A third address that should have a green background
          +This div contains 3 addresses above this sentence.
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-36.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-36.xml new file mode 100644 index 00000000000..393073a4be9 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-36.xml @@ -0,0 +1,19 @@ + + + + :only-child pseudo-class + + + + + + +

          This paragraph should have normal background

          +
          This div contains only one paragraph +

          This paragraph should have green background

          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-37.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-37.xml new file mode 100644 index 00000000000..2c805492f7e --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-37.xml @@ -0,0 +1,19 @@ + + + + :only-of-type pseudo-class + + + + + + +
          +

          This paragraph should have normal background

          +
          But this address should have green background
          +

          This paragraph should have normal background

          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-38.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-38.xml new file mode 100644 index 00000000000..ff60e4290d8 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-38.xml @@ -0,0 +1,20 @@ + + + + ::first-line pseudo-element + + + + + + +

          This very long paragraph should have a + first line with green background. This very long paragraph should have a first + line with green background. This very long paragraph should have a first line + with green background. This very long paragraph should have a first line with + green background. This very long paragraph should have a first line with green + background. This very long paragraph should have a first line with green background. + This very long paragraph should have a first line with green background.

          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-39.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-39.xml similarity index 63% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-39.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-39.xml index a262929ac20..bd0207a8f8b 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-39.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-39.xml @@ -1,12 +1,16 @@ - + + + + ::first-letter pseudo-element + + + + + + + -Daniel Glazman -Ian Hickson -p:first-letter { font-size : xx-large ; background-color : lime } - - - -

          This very long paragraph +

          This very long paragraph should have a big first letter T with a green background. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy @@ -28,5 +32,5 @@ text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text.

          -
          -
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-39a.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-39a.xml similarity index 61% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-39a.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-39a.xml index dcc1730d0ca..70746c18572 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-39a.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-39a.xml @@ -1,13 +1,17 @@ - + + + + ::first-letter pseudo-element with ::before pseudo-element + + + + + + + -Daniel Glazman -Ian Hickson -p:first-letter { color: lime; font-size: xx-large; } -p:before { color: red; content: 'T'; } - - - -

          his very long paragraph should +

          his very long paragraph should have a big green first letter T. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy @@ -29,5 +33,5 @@ text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text.

          -
          -
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-39b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-39b.xml similarity index 63% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-39b.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-39b.xml index fd1a787ce29..95b85d5efe3 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-39b.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-39b.xml @@ -1,13 +1,16 @@ - + + + + ::first-letter pseudo-element + + + + + + + -Daniel Glazman -Ian Hickson -p::first-letter { font-size : xx-large ; background-color : lime } - - - - -

          This very long paragraph +

          This very long paragraph should have a big first letter T with a green background. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy @@ -29,5 +32,5 @@ text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text.

          -
          -
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-39c.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-39c.xml similarity index 61% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-39c.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-39c.xml index 5832c074e54..4401b78fb6e 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-39c.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-39c.xml @@ -1,13 +1,17 @@ - + + + + ::first-letter pseudo-element with ::before pseudo-element + + + + + + + -Daniel Glazman -Ian Hickson -p::first-letter { color: lime; font-size: xx-large; } - p::before { color: red; content: 'T'; } - - - -

          his very long paragraph should +

          his very long paragraph should have a big green first letter T. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy @@ -29,6 +33,5 @@ text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text. Dummy text.

          -
          - -
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-3a.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-3a.xml new file mode 100644 index 00000000000..8ee5d04a994 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-3a.xml @@ -0,0 +1,23 @@ + + + + Universal selector (no namespaces) + + + + + + + +

          +This paragraph, and all textual contents in the document, + should be green. +

          +
            +
          • This item should be green.
          • +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-4.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-4.xml new file mode 100644 index 00000000000..4d38e6c2d51 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-4.xml @@ -0,0 +1,14 @@ + + + + Omitted universal selector + + + + + + +

          This paragraph should have a green background

          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-41.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-41.xml new file mode 100644 index 00000000000..8d0caef3112 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-41.xml @@ -0,0 +1,14 @@ + + + + ::before pseudo-element + + + + + + +

          You should see before this paragraph the words GENERATED CONTENT over green background

          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-41a.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-41a.xml new file mode 100644 index 00000000000..a010e28af73 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-41a.xml @@ -0,0 +1,14 @@ + + + + :before pseudo-element + + + + + + +

          You should see before this paragraph the words GENERATED CONTENT over green background

          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-42.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-42.xml new file mode 100644 index 00000000000..32617aee70b --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-42.xml @@ -0,0 +1,14 @@ + + + + ::after pseudo-element + + + + + + +

          You should see after this paragraph the words GENERATED CONTENT over green background

          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-42a.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-42a.xml new file mode 100644 index 00000000000..600e68138e3 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-42a.xml @@ -0,0 +1,14 @@ + + + + :after pseudo-element + + + + + + +

          You should see after this paragraph the words GENERATED CONTENT over green background

          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-43.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-43.xml new file mode 100644 index 00000000000..312c185510b --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-43.xml @@ -0,0 +1,36 @@ + + + + Descendant combinator + + + + + + + +
          +

          This paragraph should have a green background

          + + + + + + +
          +

          This paragraph should have a green background

          +
          +
          + + + + + + +
          +

          This paragraph should be unstyled.

          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-43b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-43b.xml new file mode 100644 index 00000000000..386b5994c78 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-43b.xml @@ -0,0 +1,36 @@ + + + + Descendant combinator + + + + + + + +
          +

          This paragraph should be unstyled

          + + + + + + +
          +

          This paragraph should be unstyled

          +
          +
          + + + + + + +
          +

          This paragraph should have a green background

          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-44.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-44.xml new file mode 100644 index 00000000000..3ba816eba4d --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-44.xml @@ -0,0 +1,30 @@ + + + + Child combinator + + + + + + + +
          +

          This paragraph should have a green background

          +
          +

          This paragraph should have a green background

          +
          +
          + + + + + + +
          +

          This paragraph should be unstyled.

          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-44b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-44b.xml new file mode 100644 index 00000000000..cdbf452c925 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-44b.xml @@ -0,0 +1,30 @@ + + + + Child combinator + + + + + + + +
          +

          This paragraph should be unstyled.

          +
          +

          This paragraph should be unstyled.

          +
          +
          + + + + + + +
          +

          This paragraph should have a green background.

          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-44c.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-44c.xml new file mode 100644 index 00000000000..9f5c8d25c17 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-44c.xml @@ -0,0 +1,17 @@ + + + + Child combinator and classes + + + + + + +
          This should be unstyled.
          +
          This should have a green background.
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-44d.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-44d.xml new file mode 100644 index 00000000000..8f448aba1bc --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-44d.xml @@ -0,0 +1,17 @@ + + + + Child combinatior and IDs + + + + + + +
          This should be unstyled.
          +

          This should have a green background.

          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-45.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-45.xml new file mode 100644 index 00000000000..7d29eeaab2b --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-45.xml @@ -0,0 +1,21 @@ + + + + Direct adjacent combinator + + + + + + + +
          +

          This paragraph should be unstyled.

          +

          But this one should have a green background.

          +

          And this one should also have a green background.

          +
          This address is only here to fill some space between two paragraphs.
          +

          This paragraph should be unstyled.

          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-45b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-45b.xml new file mode 100644 index 00000000000..7aa209e96f8 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-45b.xml @@ -0,0 +1,22 @@ + + + + Direct adjacent combinator + + + + + + + +
          +

          This paragraph should have a green background.

          +

          But this one should be unstyled.

          +

          And this one should also be unstyled.

          +
          This address is only here to fill some space between two paragraphs and should have a green background.
          +

          This paragraph should have a green background too.

          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-45c.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-45c.xml new file mode 100644 index 00000000000..4e139447cf7 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-45c.xml @@ -0,0 +1,17 @@ + + + + Direct adjacent combinator and classes + + + + + + +
          This should be unstyled.
          +
          This should have a green background.
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-46.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-46.xml new file mode 100644 index 00000000000..c826cc9675e --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-46.xml @@ -0,0 +1,21 @@ + + + + Indirect adjacent combinator + + + + + + + +
          +

          This paragraph should be unstyled.

          +

          But this one should have a green background

          +

          And this one should also have a green background

          +
          This address is only here to fill some space between two paragraphs
          +

          This paragraph should have a green background

          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-46b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-46b.xml new file mode 100644 index 00000000000..35b47b898a7 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-46b.xml @@ -0,0 +1,21 @@ + + + + Indirect adjacent combinator + + + + + + + +
          +

          This paragraph should be unstyled.

          +

          But this one should have a green background

          +

          And this one should also have a green background

          +
          This address is only here to fill some space between two paragraphs
          +

          This paragraph should have a green background

          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-47.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-47.xml new file mode 100644 index 00000000000..320490f2112 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-47.xml @@ -0,0 +1,23 @@ + + + NEGATED type element selector + + + + + + + +
          +

          + The text in this paragraph should have a green background +

          +
          This address should have a green background
          + This element in another namespace should have a green background. + This element without a namespace should have a green background. +

          This paragraph should be unstyled.

          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-48.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-48.xml new file mode 100644 index 00000000000..51484c8eac6 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-48.xml @@ -0,0 +1,25 @@ + + + NEGATED universal selector + + + + + + + +
          +
          This address should have a green background
          +This paragraph should have a green background +This paragraph should have a green background +This paragraph should have a green background +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-49.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-49.xml new file mode 100644 index 00000000000..40aa8315ce0 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-49.xml @@ -0,0 +1,25 @@ + + + NEGATED omitted universal selector is forbidden + + + + + + + +
          +
          This address should have a green background
          +This paragraph should have a green background +This paragraph should have a green background +This paragraph should have a green background +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-5.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-5.xml new file mode 100644 index 00000000000..cd559508ec4 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-5.xml @@ -0,0 +1,15 @@ + + + + Attribute existence selector + + + + + + +

          This paragraph should have a green background because its TITLE + attribute is set.

          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-50.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-50.xml new file mode 100644 index 00000000000..7b81eaec828 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-50.xml @@ -0,0 +1,19 @@ + + + NEGATED attribute existence selector + + + + + + +
          + + This text should be in green characters + +This text should be in green characters +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-51.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-51.xml new file mode 100644 index 00000000000..327bdca14d8 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-51.xml @@ -0,0 +1,22 @@ + + + NEGATED attribute value selector + + + + + + +
          + + This text should be + in green characters + +This text should be in green characters +

          This text should be in green characters

          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-52.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-52.xml new file mode 100644 index 00000000000..3320e3d2c0a --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-52.xml @@ -0,0 +1,28 @@ + + + NEGATED attribute space-separated value selector + + + + + + +
          + + This text should be + in green characters + +This text should be in green characters +This text should be in green characters +

          This text should be in green characters

          +This text should be in green characters +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-53.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-53.xml new file mode 100644 index 00000000000..bb9118688b6 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-53.xml @@ -0,0 +1,28 @@ + + + NEGATED attribute dash-separated value selector + + + + + + +
          + + This text should be + in green characters + +This text should be in green characters +This text should be in green characters +

          This text should be in green characters

          +This text should be in green characters +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-54.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-54.xml new file mode 100644 index 00000000000..6e5327a9c26 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-54.xml @@ -0,0 +1,22 @@ + + + + NEGATED substring matching attribute selector on beginning + + + + + + + +
          +

          This paragraph should be in green characters.

          +

          This paragraph should be in green characters.

          +

          + This paragraph should be in green characters. +

          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-55.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-55.xml new file mode 100644 index 00000000000..acc6dcd7290 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-55.xml @@ -0,0 +1,22 @@ + + + + NEGATED substring matching attribute selector on end + + + + + + + +
          +

          This paragraph should be in green characters.

          +

          This paragraph should be in green characters.

          +

          + This paragraph should be in green characters. +

          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-56.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-56.xml new file mode 100644 index 00000000000..27ae88d296b --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-56.xml @@ -0,0 +1,22 @@ + + + + NEGATED substring matching attribute selector on middle + + + + + + + +
          +

          This paragraph should be in green characters.

          +

          This paragraph should be in green characters.

          +

          + This paragraph should be in green characters. +

          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-57.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-57.xml new file mode 100644 index 00000000000..4539b0a9ec2 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-57.xml @@ -0,0 +1,22 @@ + + + NEGATED Attribute existence selector with declared namespace + + + + + + + +
          + This a:q element should be unstyled. +

          This paragraph should have a green background.

          + This b:r element should have a green background. +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-57b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-57b.xml new file mode 100644 index 00000000000..baf4a38b2ec --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-57b.xml @@ -0,0 +1,22 @@ + + + NEGATED Attribute existence selector with declared namespace + + + + + + + +
          + This a:q element should be unstyled. +

          This paragraph should have a green background.

          + This b:r element should have a green background. +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-59.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-59.xml new file mode 100644 index 00000000000..543123eba56 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-59.xml @@ -0,0 +1,22 @@ + + + + NEGATED class selector + + + + + + + +
          +

          This paragraph should be in green characters.

          +

          This paragraph should be in green characters.

          +

          + This paragraph should be in green characters. +

          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-6.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-6.xml new file mode 100644 index 00000000000..98c87228926 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-6.xml @@ -0,0 +1,20 @@ + + + + Attribute value selector + + + + + + + +
          +This line should + have a green background. + +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-60.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-60.xml new file mode 100644 index 00000000000..eec66ac79aa --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-60.xml @@ -0,0 +1,22 @@ + + + + NEGATED ID selector + + + + + + + +
          +

          This paragraph should be in green characters.

          +

          This paragraph should be in green characters.

          +

          + This paragraph should be in green characters. +

          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-61.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-61.xml new file mode 100644 index 00000000000..cb3c2df6fcd --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-61.xml @@ -0,0 +1,19 @@ + + + + NEGATED :link pseudo-class + + + + + + + +
          +This anchor should have a green background +(Note: You must have visited http://www.w3.org/ for this test to be valid.) +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-62.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-62.xml new file mode 100644 index 00000000000..ffaea5d44a6 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-62.xml @@ -0,0 +1,18 @@ + + + + NEGATED :visited pseudo-class + + + + + + +
          +This anchor should have a green background +(Don't follow this link.) +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-63.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-63.xml new file mode 100644 index 00000000000..7c4a34a9b29 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-63.xml @@ -0,0 +1,19 @@ + + + + NEGATED :hover pseudo-class + + + + + + + +
          +

          The color of this text should be green when the pointing device hovers over it.

          +

          The color of this text should be green when the pointing device hovers over it.

          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-64.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-64.xml new file mode 100644 index 00000000000..b1f00e49095 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-64.xml @@ -0,0 +1,19 @@ + + + + NEGATED :active pseudo-class + + + + + + + +
          +

          This text should turn green while it is active.

          +

          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-65.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-65.xml new file mode 100644 index 00000000000..384c6bcd18b --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-65.xml @@ -0,0 +1,17 @@ + + + + NEGATED :focus pseudo-class + + + + + + +

          The background color of all anchors + should become green when they have the + focus.

          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-66.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-66.xml new file mode 100644 index 00000000000..e7b9562ea35 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-66.xml @@ -0,0 +1,25 @@ + + + + NEGATED :target pseudo-class + + + + + + + +

          This paragraph should be unstyled. + The background of the following paragraph should become blue when + you follow this link.

          +

          This paragraph should initially be unstyled. + It should become blue when you select the link above. When you select + this link, it should return to being unstyled and the + background of the paragraph below should become blue.

          +

          This paragraph should initially be unstyled. + It should become blue when you select the link above. When you follow + this link, the three paragraphs + should all return to being unstyled.

          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-66b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-66b.xml new file mode 100644 index 00000000000..91fc0d324f9 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-66b.xml @@ -0,0 +1,15 @@ + + + + NEGATED :target pseudo-class + + + + + + + +

          This paragraph should be green.

          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-67.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-67.xml new file mode 100644 index 00000000000..4fbffc211f1 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-67.xml @@ -0,0 +1,23 @@ + + + + NEGATED :lang() pseudo-class + + + + + + +
          +

          This paragraph should have a green background because the + enclosing div is in english.

          +

          This paragraph should have a green background because + it is in english.

          +
          +

          This paragraph should have a green background + because it is in english.

          +
          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-68.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-68.xml new file mode 100644 index 00000000000..99c28261381 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-68.xml @@ -0,0 +1,20 @@ + + + + NEGATED :enabled pseudo-class + + + + + + +

          + +

          + +

          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-69.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-69.xml new file mode 100644 index 00000000000..3da2a7f43c5 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-69.xml @@ -0,0 +1,20 @@ + + + + NEGATED :disabled pseudo-class + + + + + + +

          + +

          + +

          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-7.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-7.xml new file mode 100644 index 00000000000..a464ccdb771 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-7.xml @@ -0,0 +1,23 @@ + + + + Attribute multivalue selector + + + + + + +

          This paragraph should have green background because CLASS + contains "b"

          +
          +This address should also + have green background because the selector in the last + rule does not apply to the inner SPANs. +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-70.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-70.xml new file mode 100644 index 00000000000..1c18a1e9526 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-70.xml @@ -0,0 +1,16 @@ + + + + NEGATED :checked pseudo-class + + + + + + + +

          + Everything in this paragraph should have a green background

          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-72.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-72.xml new file mode 100644 index 00000000000..72bf8bc1077 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-72.xml @@ -0,0 +1,18 @@ + + + + NEGATED :root pseudo-class + + + + + + + +
          +

          This paragraph should have a green background and there should be no red anywhere.

          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-72b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-72b.xml new file mode 100644 index 00000000000..ce912f0b701 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-72b.xml @@ -0,0 +1,18 @@ + + + + NEGATED :root pseudo-class + + + + + + + +
          +

          This paragraph should have a green background and there should be no red anywhere.

          +
          + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-73.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-73.xml similarity index 71% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-73.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-73.xml index 54dafec9b36..84954c80f19 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-73.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-73.xml @@ -1,15 +1,19 @@ - - -Daniel Glazman -.red { background-color : red } -ul > li:not(:nth-child(odd)) { background-color : lime } -ol > li:not(:nth-child(even)) { background-color : lime } + + + + NEGATED :nth-child() pseudo-class + + + + + + +
          • First list item
          • This second list item should have a green background
          • Third list
          • @@ -17,7 +21,7 @@ table.t1 td, table.t2 td { border : thin black solid }
          • Fifth list item
          • This sixth list item should have a green background
          -
            +
            1. This first list item should have a green background
            2. Second list item
            3. This third list item should have a green background
            4. @@ -25,7 +29,7 @@ table.t1 td, table.t2 td { border : thin black solid }
            5. This fifth list item should have a green background
            6. Sixth list item
            -
            +
            @@ -58,7 +62,7 @@ table.t1 td, table.t2 td { border : thin black solid }
            1.1 6.3
            -

            +

            @@ -92,5 +96,5 @@ table.t1 td, table.t2 td { border : thin black solid }
            1.1
            - - + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-73b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-73b.xml similarity index 69% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-73b.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-73b.xml index b5657a1189b..d7e476c916c 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-73b.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-73b.xml @@ -1,16 +1,20 @@ - - -Daniel Glazman -Ian Hickson -.green { background-color : lime ! important; } -ul > li:not(:nth-child(odd)) { background-color : red } -ol > li:not(:nth-child(even)) { background-color : red } + + + + NEGATED :nth-child() pseudo-class + + + + + + + +
            • First list item
            • This second list item should have a green background
            • Third list
            • @@ -18,7 +22,7 @@ table.t1 td, table.t2 td { border : thin black solid }
            • Fifth list item
            • This sixth list item should have a green background
            -
              +
              1. This first list item should have a green background
              2. Second list item
              3. This third list item should have a green background
              4. @@ -26,7 +30,7 @@ table.t1 td, table.t2 td { border : thin black solid }
              5. This fifth list item should have a green background
              6. Sixth list item
              -
              +
              @@ -59,7 +63,7 @@ table.t1 td, table.t2 td { border : thin black solid }
              1.1 6.3
              -

              +

              @@ -93,5 +97,5 @@ table.t1 td, table.t2 td { border : thin black solid }
              1.1
              - - + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-74.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-74.xml similarity index 73% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-74.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-74.xml index cb3efc99cd8..aff2e9b33c7 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-74.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-74.xml @@ -1,16 +1,20 @@ - - -Daniel Glazman -.red { background-color : red } -ul > li:not(:nth-last-child(odd)) { background-color : lime } -ol > li:not(:nth-last-child(even)) { background-color : lime } + + + + NEGATED :nth-last-child() pseudo-class + + + + + + +
              • This first list item should have a green background
              • Second list item
              • This third list item should have a green background
              • @@ -18,7 +22,7 @@ table.t1 td, table.t2 td { border : thin black solid }
              • This fifth list item should have a green background
              • Sixth list item
              -
                +
                1. First list item
                2. This second list item should have a green background
                3. Third list item
                4. @@ -26,7 +30,7 @@ table.t1 td, table.t2 td { border : thin black solid }
                5. Fifth list item
                6. This sixth list item should have a green background
                -
                +
                @@ -59,7 +63,7 @@ table.t1 td, table.t2 td { border : thin black solid }
                Green row : 1.16.3
                -

                +

                @@ -93,5 +97,5 @@ table.t1 td, table.t2 td { border : thin black solid }
                green cell
                - - + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-74b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-74b.xml similarity index 71% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-74b.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-74b.xml index ed7f2086846..82cf0051f96 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-74b.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-74b.xml @@ -1,18 +1,21 @@ - - -Daniel Glazman -Ian Hickson - -.green { background-color : lime ! important; } -ul > li:not(:nth-last-child(odd)) { background-color : red } -ol > li:not(:nth-last-child(even)) { background-color : red } + + + + NEGATED :nth-last-child() pseudo-class + + + + + + + +
                • This first list item should have a green background
                • Second list item
                • This third list item should have a green background
                • @@ -20,7 +23,7 @@ table.t1 td, table.t2 td { border : thin black solid }
                • This fifth list item should have a green background
                • Sixth list item
                -
                  +
                  1. First list item
                  2. This second list item should have a green background
                  3. Third list item
                  4. @@ -28,7 +31,7 @@ table.t1 td, table.t2 td { border : thin black solid }
                  5. Fifth list item
                  6. This sixth list item should have a green background
                  -
                  +
                  @@ -61,7 +64,7 @@ table.t1 td, table.t2 td { border : thin black solid }
                  Green row : 1.16.3
                  -

                  +

                  @@ -95,5 +98,5 @@ table.t1 td, table.t2 td { border : thin black solid }
                  green cell
                  - - + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-75.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-75.xml new file mode 100644 index 00000000000..235183445ac --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-75.xml @@ -0,0 +1,34 @@ + + + + NEGATED :nth-of-type() pseudo-class + + + + + + + +

                  This paragraph should have green background

                  +
                  And this address should be unstyled.
                  +

                  This paragraph should also have green background!

                  +

                  But this one should be unstyled again.

                  +
                  +
                  First definition term
                  +
                  First definition
                  +
                  Second definition term that should have green background
                  +
                  Second definition that should have green background
                  +
                  Third definition term that should have green background
                  +
                  Third definition that should have green background
                  +
                  Fourth definition term
                  +
                  Fourth definition
                  +
                  Fifth definition term that should have green background
                  +
                  Fifth definition that should have green background
                  +
                  Sixth definition term that should have green background
                  +
                  Sixth definition that should have green background
                  +
                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-75b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-75b.xml new file mode 100644 index 00000000000..6d6345e6543 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-75b.xml @@ -0,0 +1,34 @@ + + + + NEGATED :nth-of-type() pseudo-class + + + + + + + +

                  This paragraph should have green background

                  +
                  And this address should be unstyled.
                  +

                  This paragraph should also have green background!

                  +

                  But this one should be unstyled again.

                  +
                  +
                  First definition term
                  +
                  First definition
                  +
                  Second definition term that should have green background
                  +
                  Second definition that should have green background
                  +
                  Third definition term that should have green background
                  +
                  Third definition that should have green background
                  +
                  Fourth definition term
                  +
                  Fourth definition
                  +
                  Fifth definition term that should have green background
                  +
                  Fifth definition that should have green background
                  +
                  Sixth definition term that should have green background
                  +
                  Sixth definition that should have green background
                  +
                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-76.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-76.xml new file mode 100644 index 00000000000..d1181a4aaee --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-76.xml @@ -0,0 +1,34 @@ + + + + NEGATED :nth-last-of-type() pseudo-class + + + + + + + +

                  This paragraph should be unstyled.

                  +
                  This address should be unstyled.
                  +

                  This paragraph should have green background.

                  +

                  This paragraph should have green background.

                  +
                  +
                  First definition term that should have green background.
                  +
                  First definition that should also have a green background.
                  +
                  Second definition term that should have green background.
                  +
                  Second definition that should have green background.
                  +
                  Third definition term.
                  +
                  Third definition.
                  +
                  Fourth definition term that should have green background.
                  +
                  Fourth definition that should have green background.
                  +
                  Fifth definition term that should have green background.
                  +
                  Fifth definition that should have green background.
                  +
                  Sixth definition term.
                  +
                  Sixth definition.
                  +
                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-76b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-76b.xml new file mode 100644 index 00000000000..7ba99cc2ce0 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-76b.xml @@ -0,0 +1,34 @@ + + + + NEGATED :nth-last-of-type() pseudo-class + + + + + + + +

                  This paragraph should be unstyled.

                  +
                  This address should be unstyled.
                  +

                  This paragraph should have green background.

                  +

                  This paragraph should have green background.

                  +
                  +
                  First definition term that should have green background.
                  +
                  First definition that should also have a green background.
                  +
                  Second definition term that should have green background.
                  +
                  Second definition that should have green background.
                  +
                  Third definition term.
                  +
                  Third definition.
                  +
                  Fourth definition term that should have green background.
                  +
                  Fourth definition that should have green background.
                  +
                  Fifth definition term that should have green background.
                  +
                  Fifth definition that should have green background.
                  +
                  Sixth definition term.
                  +
                  Sixth definition.
                  +
                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-77.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-77.xml new file mode 100644 index 00000000000..c99fa70543a --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-77.xml @@ -0,0 +1,37 @@ + + + + NEGATED :first-child pseudo-class + + + + + + + +
                  + + + + + + + + + + + + + + + + +
                  1.1green cellgreen cell
                  2.1green cellgreen cell
                  3.1green cellgreen cell
                  +
                  +

                  This paragraph should be unstyled.

                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-77b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-77b.xml new file mode 100644 index 00000000000..073579042b6 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-77b.xml @@ -0,0 +1,37 @@ + + + + NEGATED :first-child pseudo-class + + + + + + + +
                  + + + + + + + + + + + + + + + + +
                  1.1green cellgreen cell
                  2.1green cellgreen cell
                  3.1green cellgreen cell
                  +
                  +

                  This paragraph should be unstyled.

                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-78.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-78.xml new file mode 100644 index 00000000000..8e265200c65 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-78.xml @@ -0,0 +1,37 @@ + + + + NEGATED :last-child pseudo-class + + + + + + + +
                  + + + + + + + + + + + + + + + + +
                  green cellgreen cell1.3
                  green cellgreen cell2.3
                  green cellgreen cell3.3
                  +
                  +

                  This paragraph should be unstyled.

                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-78b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-78b.xml new file mode 100644 index 00000000000..2983d0ee2ac --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-78b.xml @@ -0,0 +1,37 @@ + + + + NEGATED :last-child pseudo-class + + + + + + + +
                  + + + + + + + + + + + + + + + + +
                  green cellgreen cell1.3
                  green cellgreen cell2.3
                  green cellgreen cell3.3
                  +
                  +

                  This paragraph should be unstyled.

                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-79.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-79.xml new file mode 100644 index 00000000000..4edac8d622b --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-79.xml @@ -0,0 +1,20 @@ + + + + NEGATED :first-of-type pseudo-class + + + + + + +
                  This div contains 3 addresses : +
                  A first address with normal background
                  +
                  A second address that should have a green background
                  +
                  A third address that should have a green background
                  +
                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-7b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-7b.xml new file mode 100644 index 00000000000..e1ad8d766d5 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-7b.xml @@ -0,0 +1,21 @@ + + + + Attribute multivalue selector + + + + + + + +

                  This line should have a green background.

                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-8.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-8.xml new file mode 100644 index 00000000000..ce5a68ffec6 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-8.xml @@ -0,0 +1,22 @@ + + + + Attribute value selectors (hyphen-separated attributes) + + + + + + +

                  This paragraph should have green background because its language is "en-gb"

                  +
                  +This address should also + have green background because the language of the inner SPANs + is not French. +
                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-80.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-80.xml new file mode 100644 index 00000000000..b7c08e54cf1 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-80.xml @@ -0,0 +1,20 @@ + + + + NEGATED :last-of-type pseudo-class + + + + + + +
                  +
                  A first address that should have a green background
                  +
                  A second address that should have a green background
                  +
                  A third address with normal background
                  +This div should have three addresses above it.
                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-81.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-81.xml new file mode 100644 index 00000000000..d27e3161095 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-81.xml @@ -0,0 +1,20 @@ + + + + NEGATED :only-child pseudo-class + + + + + + + +

                  This paragraph should have a green background.

                  +
                  This div contains only one paragraph. +

                  This paragraph should be unstyled.

                  +
                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-81b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-81b.xml new file mode 100644 index 00000000000..305cf9b63f7 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-81b.xml @@ -0,0 +1,20 @@ + + + + NEGATED :only-child pseudo-class + + + + + + + +

                  This paragraph should have a green background.

                  +
                  This div contains only one paragraph. +

                  This paragraph should be unstyled.

                  +
                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-82.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-82.xml new file mode 100644 index 00000000000..5b2202696a3 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-82.xml @@ -0,0 +1,20 @@ + + + + NEGATED :only-of-type pseudo-class + + + + + + + +
                  +

                  This paragraph should have green background.

                  +
                  But this address should be unstyled.
                  +

                  This paragraph should have green background.

                  +
                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-82b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-82b.xml new file mode 100644 index 00000000000..1aafc549ea7 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-82b.xml @@ -0,0 +1,20 @@ + + + + NEGATED :only-of-type pseudo-class + + + + + + + +
                  +

                  This paragraph should have green background.

                  +
                  But this address should be unstyled.
                  +

                  This paragraph should have green background.

                  +
                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-83-ref.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-83-ref.xml new file mode 100644 index 00000000000..6ab85b3239e --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-83-ref.xml @@ -0,0 +1,10 @@ + + + + This paragraph green background red + + + +

                  This paragraph should have a green background

                  + + diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-83.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-83.xml new file mode 100644 index 00000000000..b5f10122624 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-83.xml @@ -0,0 +1,14 @@ + + + + Negation pseudo-class can be an argument of itself + + + + + + +

                  This paragraph should have a green background

                  + + diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-86.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-86.xml new file mode 100644 index 00000000000..5d2355f7f70 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-86.xml @@ -0,0 +1,21 @@ + + + + Nondeterministic matching of descendant and child combinators + + + + + + +
                  +
                  +
                  +

                  This text should be green.

                  +
                  +
                  +
                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-87.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-87.xml new file mode 100644 index 00000000000..da5adca13ad --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-87.xml @@ -0,0 +1,19 @@ + + + + Nondeterministic matching of direct and indirect adjacent combinators + + + + + + + + +
                  This text should be unstyled.
                  +
                  This text should be unstyled.
                  +
                  This text should be unstyled.
                  +

                  This text should be green.

                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-87b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-87b.xml new file mode 100644 index 00000000000..efdcb019b00 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-87b.xml @@ -0,0 +1,19 @@ + + + + Nondeterministic matching of direct and indirect adjacent combinators + + + + + + + + +
                  This text should be unstyled.
                  +
                  This text should be unstyled.
                  +
                  This text should be unstyled.
                  +

                  This text should be green.

                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-88.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-88.xml new file mode 100644 index 00000000000..f354cf21a3d --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-88.xml @@ -0,0 +1,20 @@ + + + + Nondeterministic matching of descendant and direct adjacent combinators + + + + + + + +
                  This text should be unstyled.
                  +
                  +
                  +

                  This text should be green.

                  +
                  +
                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-88b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-88b.xml new file mode 100644 index 00000000000..2c10a61fd48 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-88b.xml @@ -0,0 +1,20 @@ + + + + Nondeterministic matching of descendant and direct adjacent combinators + + + + + + + +
                  This text should be unstyled.
                  +
                  +
                  +

                  This text should be green.

                  +
                  +
                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-89.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-89.xml new file mode 100644 index 00000000000..22ac828a827 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-89.xml @@ -0,0 +1,20 @@ + + + + Simple combination of descendant and child combinators + + + + + + +
                  +
                  +
                  +

                  This text should be green.

                  +
                  +
                  +
                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-9.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-9.xml new file mode 100644 index 00000000000..e7eeba381c8 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-9.xml @@ -0,0 +1,15 @@ + + + + Substring matching attribute selector (beginning) + + + + + + +

                  This paragraph should have a green background

                  +because its title attribute begins with "foo"

                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-90.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-90.xml new file mode 100644 index 00000000000..03973b90c43 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-90.xml @@ -0,0 +1,19 @@ + + + + Simple combination of direct and indirect adjacent combinators + + + + + + + + +
                  This text should be unstyled.
                  +
                  This text should be unstyled.
                  +
                  This text should be unstyled.
                  +

                  This text should be green.

                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-90b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-90b.xml new file mode 100644 index 00000000000..15e06bcfa40 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-90b.xml @@ -0,0 +1,19 @@ + + + + Simple combination of direct and indirect adjacent combinators + + + + + + + + +
                  This text should be unstyled.
                  +
                  This text should be unstyled.
                  +
                  This text should be unstyled.
                  +

                  This text should be green.

                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-91.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-91.xml new file mode 100644 index 00000000000..2fc2ed6d730 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-91.xml @@ -0,0 +1,14 @@ + + + Type element selector with declared namespace + + + + + + +This paragraph should have a green background + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-92.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-92.xml new file mode 100644 index 00000000000..16883a4a423 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-92.xml @@ -0,0 +1,16 @@ + + + Type element selector with universal namespace + + + + + + +
                  +This paragraph should have a green background +
                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-93.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-93.xml new file mode 100644 index 00000000000..47f802396c3 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-93.xml @@ -0,0 +1,15 @@ + + + Type element selector without declared namespace + + + + + + + +This paragraph has no declared namespace and should have a green background. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-94.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-94.xml new file mode 100644 index 00000000000..4bebf5303c5 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-94.xml @@ -0,0 +1,20 @@ + + + Universal selector with declared namespace + + + + + + + +

                  This line should be unstyled.

                  +

                  This line should have a green background.

                  +This line should have a green background. +

                  This line should be unstyleed.

                  +

                  This line should have a green background.

                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-94b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-94b.xml new file mode 100644 index 00000000000..d2ab44d297a --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-94b.xml @@ -0,0 +1,21 @@ + + + Universal selector with declared namespace + + + + + + + +

                  This line should be unstyled.

                  +

                  This line should have a green background.

                  +This line should have a green background. +

                  This line should be unstyled.

                  +

                  This line should have a green background.

                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-95.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-95.xml new file mode 100644 index 00000000000..9ba5dd0e8f0 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-95.xml @@ -0,0 +1,22 @@ + + + Universal selector with universal namespace + + + + + + + +
                  +

                  This line should have a green background

                  +

                  This line should have a green background

                  + This line should have a green background +

                  This line should have a green background

                  + This line should have a green background +
                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-96.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-96.xml new file mode 100644 index 00000000000..8d62a81ea8c --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-96.xml @@ -0,0 +1,26 @@ + + + Universal selector without declared namespace + + + + + + + +
                  +

                  This line should be unstyled.

                  + This line should be unstyled. + This line should be unstyled. +
                  +

                  This line should have a green background

                  + This line should have a green background + This line should have a green background +
                  +
                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-96b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-96b.xml new file mode 100644 index 00000000000..5c85d67f15b --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-96b.xml @@ -0,0 +1,26 @@ + + + Universal selector without declared namespace + + + + + + + +
                  +

                  This line should be unstyled.

                  + This line should be unstyled. + This line should be unstyled. +
                  +

                  This line should have a green background

                  + This line should have a green background + This line should have a green background +
                  +
                  + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-97.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-97.xml new file mode 100644 index 00000000000..a254bafb555 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-97.xml @@ -0,0 +1,20 @@ + + + Attribute existence selector with declared namespace + + + + + + + +

                  This paragraph should be unstyled.

                  + This paragraph should have a green background. + This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-97b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-97b.xml new file mode 100644 index 00000000000..71e3467f27c --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-97b.xml @@ -0,0 +1,20 @@ + + + Attribute existence selector with declared namespace + + + + + + + +

                  This paragraph should be unstyled.

                  + This paragraph should have a green background. + This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-98.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-98.xml new file mode 100644 index 00000000000..9d68a22d6b5 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-98.xml @@ -0,0 +1,23 @@ + + + Attribute value selector with declared namespace + + + + + + + +

                  This paragraph should be unstyled.

                  + This paragraph should have a green background + This paragraph should be unstyled. + This paragraph should be unstyled. + This paragraph should have a green background + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-98b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-98b.xml new file mode 100644 index 00000000000..bf416abf82a --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-98b.xml @@ -0,0 +1,21 @@ + + + Attribute value selector with declared namespace + + + + + + + +

                  This paragraph should be unstyled.

                  + This paragraph should have a green background + This paragraph should be unstyled. + This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-99.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-99.xml new file mode 100644 index 00000000000..2d385fe6f47 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-99.xml @@ -0,0 +1,24 @@ + + + Attribute space-separated value selector with declared namespace + + + + + + + + +

                  This paragraph should have a green background.

                  + This paragraph should be unstyled. + This paragraph should have a green background. + This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-99b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-99b.xml new file mode 100644 index 00000000000..f8aff417ef0 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-99b.xml @@ -0,0 +1,23 @@ + + + Attribute space-separated value selector with declared namespace + + + + + + + + +

                  This paragraph should have a green background.

                  + This paragraph should be unstyled. + This paragraph should have a green background. + This paragraph should be unstyled. + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-d1.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-d1.xml new file mode 100644 index 00000000000..144cf0e0fd8 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-d1.xml @@ -0,0 +1,35 @@ + + + + NEGATED Dynamic handling of :empty + + + + + + + +
                  + + + +

                  The following bar should be green.

                  + +
                  + +
                  + + + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d1b.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-d1b.xml similarity index 50% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-d1b.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-d1b.xml index caf7ae8a8ad..f4583f843ca 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d1b.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-d1b.xml @@ -1,19 +1,20 @@ - - -Ian Hickson - - - - + + + + Dynamic handling of :empty + + + + + + - - -
                  +
                  + + + + +

                  The following bar should be green.

                  + +
                  +
                  +
                  + +
                  + + + diff --git a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d3.xml b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-d3.xml similarity index 53% rename from tests/wpt/web-platform-tests/css/selectors/css3-modsel-d3.xml rename to tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-d3.xml index ba8956cc82c..e8b15e96143 100644 --- a/tests/wpt/web-platform-tests/css/selectors/css3-modsel-d3.xml +++ b/tests/wpt/web-platform-tests/css/selectors/old-tests/css3-modsel-d3.xml @@ -1,17 +1,17 @@ - - -Ian Hickson - - - - + + + Dynamic handling of attribute selectors + + + + + + - - -
                  +
                  + + + +
                  + + diff --git a/tests/wpt/web-platform-tests/css/selectors/x-pseudo-element.html b/tests/wpt/web-platform-tests/css/selectors/x-pseudo-element.html new file mode 100644 index 00000000000..80ec44f9def --- /dev/null +++ b/tests/wpt/web-platform-tests/css/selectors/x-pseudo-element.html @@ -0,0 +1,22 @@ + +CSS Test: 'x-' prefixed pseudo-elements don't parse correctly + + + + + + +

                  Should be green + diff --git a/tests/wpt/web-platform-tests/css/selectors/xhtml-full.css b/tests/wpt/web-platform-tests/css/selectors/xhtml-full.css deleted file mode 100644 index 6d965486792..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/xhtml-full.css +++ /dev/null @@ -1,65 +0,0 @@ -@namespace url(http://www.w3.org/1999/xhtml); - -pre.rules { - border : 1px solid black ; - padding : 5px -} - -.WARNING { - background-color: black; - color: white; - font-weight: bold; - margin-top: 1em; -} - -div.testText { - background: white; - color: black; -} - -div.testSource { - border: thin black solid; - padding-left: 1em; - padding-right: 1em; -} - -div.testDescription { - border: thin black solid; - background-color: red; -} - -.testDescription { - margin-top: 1em; - width: 100%; - border: thin solid black; - margin-bottom: 1em; -} - -.testDescription th, -.testDescription td { - text-align: center; -} - -.testDescription th { - background-color: silver; -} - -.testDescription .a { - width: 25%; -} - -.testDescription .b { - width: 50%; -} - -.testDescription .c { - width: 100%; -} - -div.validator { - margin-top: 1em; -} - -div.validator img { - border-width : 0; -} diff --git a/tests/wpt/web-platform-tests/css/selectors/xhtml-shell.css b/tests/wpt/web-platform-tests/css/selectors/xhtml-shell.css deleted file mode 100644 index 957da843bb8..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/xhtml-shell.css +++ /dev/null @@ -1,74 +0,0 @@ -@namespace url(http://www.w3.org/1999/xhtml); - -pre.rules { - border : 1px solid black ; - padding : 5px -} - -.WARNING { - background-color: black; - color: white; - font-weight: bold; - margin-top: 1em; -} - -div.testSource { - border: thin black solid; - padding-left: 1em; - padding-right: 1em; -} - -div.testDescription { - border: thin black solid; - background-color: red; -} - -.testDescription { - margin-top: 1em; - width: 100%; - border: thin solid black; - margin-bottom: 1em; -} - -.testDescription th, -.testDescription td { - text-align: center; -} - -.testDescription th { - background-color: silver; -} - -.testDescription .a { - width: 25%; -} - -.testDescription .b { - width: 50%; -} - -.testDescription .c { - width: 100%; -} - -div.validator { - margin-top: 1em; -} - -div.validator img { - border-width : 0; -} - -iframe, object { - display: block; - position: fixed; - top: static-position; - left: 1em; - right: 1em; - bottom: 1em; - margin: 0; - width: auto; - height: auto; - padding: 0; - border: thin black solid; -} diff --git a/tests/wpt/web-platform-tests/css/selectors/xml-full.css b/tests/wpt/web-platform-tests/css/selectors/xml-full.css deleted file mode 100644 index b4176074f4b..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/xml-full.css +++ /dev/null @@ -1,15 +0,0 @@ -test { display: block; background: white; color: black; } - title { display: block; border-bottom: solid; margin: 0 0 0.5em 0; padding: 0.5em 1em 0 1em; font-size: 1.5em; } - author { display: none; } - metadata { display: table; border-spacing: 1em 0.4em; } - item { display: table-row; } - name { display: table-cell; } - data { display: table-cell; } - data:link { color: blue; text-decoration: underline; } - data:visited { color: navy; text-decoration: underline; } - requirement { display: block; margin: 1em; background: black; color: white; } - content { display: block; border: solid; margin: 1em; padding: 1em; } - source { display: block; font-family: monospace; } - css { display: block; white-space: pre; border: solid; margin: 1em; padding: 1em; } - xml { display: block; white-space: pre; border: solid; margin: 1em; padding: 1em; } - diff --git a/tests/wpt/web-platform-tests/css/selectors/xml-shell.css b/tests/wpt/web-platform-tests/css/selectors/xml-shell.css deleted file mode 100644 index b4176074f4b..00000000000 --- a/tests/wpt/web-platform-tests/css/selectors/xml-shell.css +++ /dev/null @@ -1,15 +0,0 @@ -test { display: block; background: white; color: black; } - title { display: block; border-bottom: solid; margin: 0 0 0.5em 0; padding: 0.5em 1em 0 1em; font-size: 1.5em; } - author { display: none; } - metadata { display: table; border-spacing: 1em 0.4em; } - item { display: table-row; } - name { display: table-cell; } - data { display: table-cell; } - data:link { color: blue; text-decoration: underline; } - data:visited { color: navy; text-decoration: underline; } - requirement { display: block; margin: 1em; background: black; color: white; } - content { display: block; border: solid; margin: 1em; padding: 1em; } - source { display: block; font-family: monospace; } - css { display: block; white-space: pre; border: solid; margin: 1em; padding: 1em; } - xml { display: block; white-space: pre; border: solid; margin: 1em; padding: 1em; } - diff --git a/tests/wpt/web-platform-tests/css/compositing/parsing/support/parsing-testcommon.js b/tests/wpt/web-platform-tests/css/support/parsing-testcommon.js similarity index 100% rename from tests/wpt/web-platform-tests/css/compositing/parsing/support/parsing-testcommon.js rename to tests/wpt/web-platform-tests/css/support/parsing-testcommon.js diff --git a/tests/wpt/web-platform-tests/docs/_writing-tests/h2tests.md b/tests/wpt/web-platform-tests/docs/_writing-tests/h2tests.md new file mode 100644 index 00000000000..0d19f7de19c --- /dev/null +++ b/tests/wpt/web-platform-tests/docs/_writing-tests/h2tests.md @@ -0,0 +1,155 @@ +# Writing H2 Tests +> Important: The HTTP/2.0 server requires you to have Python 2.7.10+ +and OpenSSL 1.0.2+. This is because HTTP/2.0 is negotiated using the +[TLS ALPN](https://tools.ietf.org/html/rfc7301) extension, which is only supported in [OpenSSL 1.0.2](https://www.openssl.org/news/openssl-1.0.2-notes.html) and up. + +These instructions assume you are already familiar with the testing +infrastructure and know how to write a standard HTTP/1.1 test. + +On top of the standard `main` handler that the H1 server offers, the +H2 server also offers support for specific frame handlers in the Python +scripts. Currently there is support for for `handle_headers` and `handle_data`. +Unlike the `main` handler, these are run whenever the server receives a +HEADERS frame (RequestReceived event) or a DATA frame (DataReceived event). +`main` can still be used, but it will be run after the server has received +the request in its entirety. + +Here is what a Python script for a test might look like: +```python +def handle_headers(frame, request, response): + if request.headers["test"] == "pass": + response.status = 200 + response.headers.update([('test', 'passed')]) + response.write_status_headers() + else: + response.status = 403 + response.headers.update([('test', 'failed')]) + response.write_status_headers() + response.writer.end_stream() + +def handle_data(frame, request, response): + response.writer.write_data(frame.data[::-1]) + +def main(request, response): + response.writer.write_data('\nEnd of File', last=True) +``` + +The above script is fairly simple: +1. Upon receiving the HEADERS frame, `handle_headers` is run. + - This checks for a header called 'test' and checks if it is set to 'pass'. + If true, it will immediately send a response header, otherwise it responds + with a 403 and ends the stream. +2. Any DATA frames received will then be handled by `handle_data`. This will +simply reverse the data and send it back. +3. Once the request has been fully received, `main` is run which will send +one last DATA frame and signal its the end of the stream. + +## Response Writer API ## + +The H2Response API is pretty much the same as the H1 variant, the main API +difference lies in the H2ResponseWriter which is accessed through `response.writer` + +--- + +#### `write_headers(self, headers, status_code, status_message=None, stream_id=None, last=False):` +Write a HEADER frame using the H2 Connection object, will only work if the +stream is in a state to send HEADER frames. This will automatically format +the headers so that pseudo headers are at the start of the list and correctly +prefixed with ':'. Since this using the H2 Connection object, it requires that +the stream is in the correct state to be sending this frame. + +> Note: Will raise ProtocolErrors if pseudo headers are missing. + +- Parameters + + - headers: List of (header, value) tuples + - status_code: The HTTP status code of the response + - stream_id: Id of stream to send frame on. Will use the request stream ID if None + - last: Flag to signal if this is the last frame in stream. + +--- + +#### `write_data(self, item, last=False, stream_id=None):` +Write a DATA frame using the H2 Connection object, will only work if the +stream is in a state to send DATA frames. Uses flow control to split data +into multiple data frames if it exceeds the size that can be in a single frame. +Since this using the H2 Connection object, it requires that the stream is in +the correct state to be sending this frame. + +- Parameters + + - item: The content of the DATA frame + - last: Flag to signal if this is the last frame in stream. + - stream_id: Id of stream to send frame on. Will use the request stream ID if None + +--- + +#### `write_push(self, promise_headers, push_stream_id=None, status=None, response_headers=None, response_data=None):` +This will write a push promise to the request stream. If you do not provide +headers and data for the response, then no response will be pushed, and you +should send them yourself using the ID returned from this function. + +- Parameters + - promise_headers: A list of header tuples that matches what the client would use to + request the pushed response + - push_stream_id: The ID of the stream the response should be pushed to. If none given, will + use the next available id. + - status: The status code of the response, REQUIRED if response_headers given + - response_headers: The headers of the response + - response_data: The response data. + +- Returns: The ID of the push stream + +--- + +#### `write_raw_header_frame(self, headers, stream_id=None, end_stream=False, end_headers=False, frame_cls=HeadersFrame):` +Unlike `write_headers`, this does not check to see if a stream is in the +correct state to have HEADER frames sent through to it. It also won't force +the order of the headers or make sure pseudo headers are prefixed with ':'. +It will build a HEADER frame and send it without using the H2 Connection +object other than to HPACK encode the headers. + +> Note: The `frame_cls` parameter is so that this class can be reused +by `write_raw_continuation_frame`, as their construction is identical. + +- Parameters + - headers: List of (header, value) tuples + - stream_id: Id of stream to send frame on. Will use the request stream ID if None + - end_stream: Set to `True` to add END_STREAM flag to frame + - end_headers: Set to `True` to add END_HEADERS flag to frame + +--- + +#### `write_raw_data_frame(self, data, stream_id=None, end_stream=False):` +Unlike `write_data`, this does not check to see if a stream is in the correct +state to have DATA frames sent through to it. It will build a DATA frame and +send it without using the H2 Connection object. It will not perform any flow control checks. + +- Parameters + - data: The data to be sent in the frame + - stream_id: Id of stream to send frame on. Will use the request stream ID if None + - end_stream: Set to True to add END_STREAM flag to frame + +--- + +#### `write_raw_continuation_frame(self, headers, stream_id=None, end_headers=False):` +This provides the ability to create and write a CONTINUATION frame to the +stream, which is not exposed by `write_headers` as the h2 library handles +the split between HEADER and CONTINUATION internally. Will perform HPACK +encoding on the headers. It also ignores the state of the stream. + +This calls `write_raw_data_frame` with `frame_cls=ContinuationFrame` since +the HEADER and CONTINUATION frames are constructed in the same way. + +- Parameters: + - headers: List of (header, value) tuples + - stream_id: Id of stream to send frame on. Will use the request stream ID if None + - end_headers: Set to True to add END_HEADERS flag to frame + +--- + +#### `end_stream(self, stream_id=None):` +Ends the stream with the given ID, or the one that request was made on if no ID given. + +- Parameters + - stream_id: Id of stream to send frame on. Will use the request stream ID if None \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/docs/_writing-tests/server-features.md b/tests/wpt/web-platform-tests/docs/_writing-tests/server-features.md index a3cd4174d27..8798c2e6bdd 100644 --- a/tests/wpt/web-platform-tests/docs/_writing-tests/server-features.md +++ b/tests/wpt/web-platform-tests/docs/_writing-tests/server-features.md @@ -94,4 +94,17 @@ of the response. For details see the [wptserve documentation](https://wptserve.readthedocs.org). +### Writing tests for HTTP/2.0 + +The server now has a prototype HTTP/2.0 server which gives you access to +some of the HTTP/2.0 specific functionality. Currently, the server is off +by default and needs to be run using `./wpt serve --h2` in order to enable it. +The HTTP/2.0 server supports handlers that work per-frame; these, along with the +API are documented in [Writing H2 Tests][h2tests] + +> Important: The HTTP/2.0 server requires you to have Python 2.7.10+ +and OpenSSL 1.0.2+. This is because HTTP/2.0 is negotiated using the +[TLS ALPN](https://tools.ietf.org/html/rfc7301) extension, which is only supported in [OpenSSL 1.0.2](https://www.openssl.org/news/openssl-1.0.2-notes.html) and up. + [file names]: {{ site.baseurl }}{% link _writing-tests/file-names.md %} +[h2tests]: {{ site.baseurl }}{% link _writing-tests/h2tests.md %} diff --git a/tests/wpt/web-platform-tests/docs/_writing-tests/testdriver.md b/tests/wpt/web-platform-tests/docs/_writing-tests/testdriver.md index a934e3278f1..eb9b9fb0413 100644 --- a/tests/wpt/web-platform-tests/docs/_writing-tests/testdriver.md +++ b/tests/wpt/web-platform-tests/docs/_writing-tests/testdriver.md @@ -18,9 +18,11 @@ the global scope. NB: presently, testdriver.js only works in the top-level test browsing context (and not therefore in any frame or window opened from it). -### `test_driver.bless(intent, action)` -#### `intent: a string describing the motivation for this invocation` -#### `action: an optional function` +### bless + +Usage: `test_driver.bless(intent, action)` + * `intent`: a string describing the motivation for this invocation + * `action`: an optional function This function simulates [activation][activation], allowing tests to perform privileged operations that require user interaction. For @@ -44,8 +46,10 @@ test_driver.bless('initiate media playback', function () { }); ``` -### `test_driver.click(element)` -#### `element: a DOM Element object` +### click + +Usage: `test_driver.click(element)` + * `element`: a DOM Element object This function causes a click to occur on the target element (an `Element` object), potentially scrolling the document to make it @@ -57,9 +61,11 @@ Note that if the element to be clicked does not have a unique ID, the document must not have any DOM mutations made between the function being called and the promise settling. -### `test_driver.send_keys(element, keys)` -#### `element: a DOM Element object` -#### `keys: string to send to the element` +### send_keys + +Usage: `test_driver.send_keys(element, keys)` + * `element`: a DOM Element object + * `keys`: string to send to the element This function causes the string `keys` to be send to the target element (an `Element` object), potentially scrolling the document to diff --git a/tests/wpt/web-platform-tests/docs/_writing-tests/testharness-api.md b/tests/wpt/web-platform-tests/docs/_writing-tests/testharness-api.md index bb552453291..952c8365fb7 100644 --- a/tests/wpt/web-platform-tests/docs/_writing-tests/testharness-api.md +++ b/tests/wpt/web-platform-tests/docs/_writing-tests/testharness-api.md @@ -161,9 +161,9 @@ Test is finished. promise_test(test_function, name, properties) ``` -`test_function` is a function that receives a test as an argument and returns a -promise. The test completes when the returned promise resolves. The test fails -if the returned promise rejects. +`test_function` is a function that receives a test as an argument. It must +return a promise. The test completes when the returned promise resolves. The +test fails if the returned promise rejects. E.g.: diff --git a/tests/wpt/web-platform-tests/docs/_writing-tests/testharness.md b/tests/wpt/web-platform-tests/docs/_writing-tests/testharness.md index e91302f1d21..9c21452607e 100644 --- a/tests/wpt/web-platform-tests/docs/_writing-tests/testharness.md +++ b/tests/wpt/web-platform-tests/docs/_writing-tests/testharness.md @@ -24,7 +24,7 @@ with testharness.js. See also the [general guidelines][] for all test types. A test file can have multiple variants by including `meta` elements, for example: -``` +```html ``` @@ -36,7 +36,7 @@ There are two utility scripts in that work well together with variants, a test that would otherwise have too many tests to be useful can be split up in ranges of subtests. For example: -``` +```html Testing variants @@ -60,7 +60,7 @@ With `subsetTestByKey`, the key is given as the first argument, and the query string can include or exclude a key (will be matched as a regular expression). -``` +```html Testing variants by key @@ -103,13 +103,15 @@ JavaScript file with the `.js` removed. For example, one could write a test for the `FileReaderSync` API by creating a `FileAPI/FileReaderSync.worker.js` as follows: - importScripts("/resources/testharness.js"); - test(function () { - var blob = new Blob(["Hello"]); - var fr = new FileReaderSync(); - assert_equals(fr.readAsText(blob), "Hello"); - }, "FileReaderSync#readAsText."); - done(); +```js +importScripts("/resources/testharness.js"); +test(function () { + var blob = new Blob(["Hello"]); + var fr = new FileReaderSync(); + assert_equals(fr.readAsText(blob), "Hello"); +}, "FileReaderSync#readAsText."); +done(); +``` This test could then be run from `FileAPI/FileReaderSync.worker.html`. @@ -124,29 +126,33 @@ By default, the test runs in a window scope and a dedicated worker scope. For example, one could write a test for the `Blob` constructor by creating a `FileAPI/Blob-constructor.any.js` as follows: - test(function () { - var blob = new Blob(); - assert_equals(blob.size, 0); - assert_equals(blob.type, ""); - assert_false(blob.isClosed); - }, "The Blob constructor."); +```js +test(function () { + var blob = new Blob(); + assert_equals(blob.size, 0); + assert_equals(blob.type, ""); + assert_false(blob.isClosed); +}, "The Blob constructor."); +``` This test could then be run from `FileAPI/Blob-constructor.any.worker.html` as well as `FileAPI/Blob-constructor.any.html`. It is possible to customize the set of scopes with a metadata comment, such as - // META: global=sharedworker - // ==> would run in the default window and dedicated worker scopes, - // as well as the shared worker scope - // META: global=!default,serviceworker - // ==> would only run in the service worker scope - // META: global=!window - // ==> would run in the default dedicated worker scope, but not the - // window scope - // META: global=worker - // ==> would run in the default window scope, as well as in the - // dedicated, shared and service worker scopes +``` +// META: global=sharedworker +// ==> would run in the default window and dedicated worker scopes, +// as well as the shared worker scope +// META: global=!default,serviceworker +// ==> would only run in the service worker scope +// META: global=!window +// ==> would run in the default dedicated worker scope, but not the +// window scope +// META: global=worker +// ==> would run in the default window scope, as well as in the +// dedicated, shared and service worker scopes +``` For a test file x.any.js, the available scope keywords are: @@ -172,8 +178,10 @@ Use `// META: title=This is the title of the test` at the beginning of the resou Use `// META: script=link/to/resource.js` at the beginning of the resource. For example, - // META: script=/common/utils.js - // META: script=resources/utils.js +``` +// META: script=/common/utils.js +// META: script=resources/utils.js +``` can be used to include both the global and a local `utils.js` in a test. @@ -185,8 +193,10 @@ Use `// META: timeout=long` at the beginning of the resource. Use `// META: variant=url-suffix` at the beginning of the resource. For example, - // META: variant= - // META: variant=?wss +``` +// META: variant= +// META: variant=?wss +``` [general guidelines]: {{ site.baseurl }}{% link _writing-tests/general-guidelines.md %} diff --git a/tests/wpt/web-platform-tests/dom/nodes/selectors.js b/tests/wpt/web-platform-tests/dom/nodes/selectors.js index 587779b7da0..c4e87330b44 100644 --- a/tests/wpt/web-platform-tests/dom/nodes/selectors.js +++ b/tests/wpt/web-platform-tests/dom/nodes/selectors.js @@ -534,11 +534,13 @@ var scopedSelectors = [ {name: ":root pseudo-class selector, not matching document root element", selector: ":root", ctx: "#html", expect: [] /*no matches*/, exclude: ["fragment", "detached"], level: 3, testType: TEST_FIND}, // - :nth-child(n) (Level 3) - {name: ":nth-child selector, matching the third child element", selector: ":nth-child(3)", ctx: "#pseudo-nth-table1", expect: ["pseudo-nth-td3", "pseudo-nth-td9", "pseudo-nth-tr3", "pseudo-nth-td15"], level: 3, testType: TEST_FIND | TEST_MATCH}, - {name: ":nth-child selector, matching every third child element", selector: "li:nth-child(3n)", ctx: "#pseudo-nth", expect: ["pseudo-nth-li3", "pseudo-nth-li6", "pseudo-nth-li9", "pseudo-nth-li12"], level: 3, testType: TEST_FIND | TEST_MATCH}, - {name: ":nth-child selector, matching every second child element, starting from the fourth", selector: "li:nth-child(2n+4)", ctx: "#pseudo-nth", expect: ["pseudo-nth-li4", "pseudo-nth-li6", "pseudo-nth-li8", "pseudo-nth-li10", "pseudo-nth-li12"], level: 3, testType: TEST_FIND | TEST_MATCH}, - {name: ":nth-child selector, matching every fourth child element, starting from the third", selector: ":nth-child(4n-1)", ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-em2", "pseudo-nth-span3"], level: 3, testType: TEST_FIND | TEST_MATCH}, - {name: ":nth-child selector used twice, matching ", selector: ":nth-child(1) :nth-child(1)", ctx: "#pseudo-nth", expect: ["pseudo-nth-table1", "pseudo-nth-tr1"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":nth-child selector, matching the third child element", selector: ":nth-child(3)", ctx: "#pseudo-nth-table1", expect: ["pseudo-nth-td3", "pseudo-nth-td9", "pseudo-nth-tr3", "pseudo-nth-td15"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":nth-child selector, matching every third child element", selector: "li:nth-child(3n)", ctx: "#pseudo-nth", expect: ["pseudo-nth-li3", "pseudo-nth-li6", "pseudo-nth-li9", "pseudo-nth-li12"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":nth-child selector, matching every second child element, starting from the fourth", selector: "li:nth-child(2n+4)", ctx: "#pseudo-nth", expect: ["pseudo-nth-li4", "pseudo-nth-li6", "pseudo-nth-li8", "pseudo-nth-li10", "pseudo-nth-li12"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":nth-child selector, matching every second child element, starting from the fourth, with whitespace", selector: "li:nth-child(2n \t\r\n+ \t\r\n4)", ctx: "#pseudo-nth", expect: ["pseudo-nth-li4", "pseudo-nth-li6", "pseudo-nth-li8", "pseudo-nth-li10", "pseudo-nth-li12"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":nth-child selector, matching every fourth child element, starting from the third", selector: ":nth-child(4n-1)", ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-em2", "pseudo-nth-span3"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":nth-child selector, matching every fourth child element, starting from the third, with whitespace", selector: ":nth-child(4n \t\r\n- \t\r\n1)", ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-em2", "pseudo-nth-span3"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":nth-child selector used twice, matching ", selector: ":nth-child(1) :nth-child(1)", ctx: "#pseudo-nth", expect: ["pseudo-nth-table1", "pseudo-nth-tr1"], level: 3, testType: TEST_FIND | TEST_MATCH}, // - :nth-last-child (Level 3) {name: ":nth-last-child selector, matching the third last child element", selector: ":nth-last-child(3)", ctx: "#pseudo-nth-table1", expect: ["pseudo-nth-tr1", "pseudo-nth-td4", "pseudo-nth-td10", "pseudo-nth-td16"], level: 3, testType: TEST_FIND | TEST_MATCH}, diff --git a/tests/wpt/web-platform-tests/editing/run/backcolor.html b/tests/wpt/web-platform-tests/editing/run/backcolor.html index 3d337785efe..5911de309d0 100644 --- a/tests/wpt/web-platform-tests/editing/run/backcolor.html +++ b/tests/wpt/web-platform-tests/editing/run/backcolor.html @@ -1,5 +1,6 @@ + backcolor - HTML editing conformance tests diff --git a/tests/wpt/web-platform-tests/editing/run/bold.html b/tests/wpt/web-platform-tests/editing/run/bold.html index b439a11fdd8..390d6810d85 100644 --- a/tests/wpt/web-platform-tests/editing/run/bold.html +++ b/tests/wpt/web-platform-tests/editing/run/bold.html @@ -1,5 +1,6 @@ + diff --git a/tests/wpt/web-platform-tests/editing/run/createlink.html b/tests/wpt/web-platform-tests/editing/run/createlink.html index 98261697b35..b67357e684a 100644 --- a/tests/wpt/web-platform-tests/editing/run/createlink.html +++ b/tests/wpt/web-platform-tests/editing/run/createlink.html @@ -1,5 +1,6 @@ + createlink - HTML editing conformance tests diff --git a/tests/wpt/web-platform-tests/editing/run/delete-list-items-in-table-cell.html b/tests/wpt/web-platform-tests/editing/run/delete-list-items-in-table-cell.html index 409a844fc96..b765bc4b977 100644 --- a/tests/wpt/web-platform-tests/editing/run/delete-list-items-in-table-cell.html +++ b/tests/wpt/web-platform-tests/editing/run/delete-list-items-in-table-cell.html @@ -1,5 +1,6 @@ + delete list items in table cells - HTML editing conformance tests diff --git a/tests/wpt/web-platform-tests/editing/run/delete.html b/tests/wpt/web-platform-tests/editing/run/delete.html index 592c7bb9974..6d7a7c8f0c5 100644 --- a/tests/wpt/web-platform-tests/editing/run/delete.html +++ b/tests/wpt/web-platform-tests/editing/run/delete.html @@ -1,5 +1,6 @@ + diff --git a/tests/wpt/web-platform-tests/editing/run/fontname.html b/tests/wpt/web-platform-tests/editing/run/fontname.html index 491fbe55015..53800c540c4 100644 --- a/tests/wpt/web-platform-tests/editing/run/fontname.html +++ b/tests/wpt/web-platform-tests/editing/run/fontname.html @@ -1,5 +1,6 @@ + diff --git a/tests/wpt/web-platform-tests/editing/run/fontsize.html b/tests/wpt/web-platform-tests/editing/run/fontsize.html index 35ef7015664..66ae99ebc10 100644 --- a/tests/wpt/web-platform-tests/editing/run/fontsize.html +++ b/tests/wpt/web-platform-tests/editing/run/fontsize.html @@ -1,5 +1,6 @@ + diff --git a/tests/wpt/web-platform-tests/editing/run/forecolor.html b/tests/wpt/web-platform-tests/editing/run/forecolor.html index 4dd42bf6762..8594e061c14 100644 --- a/tests/wpt/web-platform-tests/editing/run/forecolor.html +++ b/tests/wpt/web-platform-tests/editing/run/forecolor.html @@ -1,5 +1,6 @@ + diff --git a/tests/wpt/web-platform-tests/editing/run/formatblock.html b/tests/wpt/web-platform-tests/editing/run/formatblock.html index f117e77d7bf..5c97c08e732 100644 --- a/tests/wpt/web-platform-tests/editing/run/formatblock.html +++ b/tests/wpt/web-platform-tests/editing/run/formatblock.html @@ -1,5 +1,6 @@ + diff --git a/tests/wpt/web-platform-tests/editing/run/forwarddelete.html b/tests/wpt/web-platform-tests/editing/run/forwarddelete.html index 50850d13077..e17190053ac 100644 --- a/tests/wpt/web-platform-tests/editing/run/forwarddelete.html +++ b/tests/wpt/web-platform-tests/editing/run/forwarddelete.html @@ -1,5 +1,6 @@ + diff --git a/tests/wpt/web-platform-tests/editing/run/hilitecolor.html b/tests/wpt/web-platform-tests/editing/run/hilitecolor.html index e2de0d960ff..cd9e5528e56 100644 --- a/tests/wpt/web-platform-tests/editing/run/hilitecolor.html +++ b/tests/wpt/web-platform-tests/editing/run/hilitecolor.html @@ -1,5 +1,6 @@ + hilitecolor - HTML editing conformance tests diff --git a/tests/wpt/web-platform-tests/editing/run/indent.html b/tests/wpt/web-platform-tests/editing/run/indent.html index bf753e6efa2..13e98f5ea64 100644 --- a/tests/wpt/web-platform-tests/editing/run/indent.html +++ b/tests/wpt/web-platform-tests/editing/run/indent.html @@ -1,5 +1,6 @@ + indent - HTML editing conformance tests diff --git a/tests/wpt/web-platform-tests/editing/run/insert-list-items-in-table-cell.html b/tests/wpt/web-platform-tests/editing/run/insert-list-items-in-table-cell.html index 60b396dd347..8d08f8c3eb9 100644 --- a/tests/wpt/web-platform-tests/editing/run/insert-list-items-in-table-cell.html +++ b/tests/wpt/web-platform-tests/editing/run/insert-list-items-in-table-cell.html @@ -1,5 +1,6 @@ + Insert list items in table cells - HTML editing conformance tests diff --git a/tests/wpt/web-platform-tests/editing/run/inserthorizontalrule.html b/tests/wpt/web-platform-tests/editing/run/inserthorizontalrule.html index 5569e8f9a6b..6e3e5490a60 100644 --- a/tests/wpt/web-platform-tests/editing/run/inserthorizontalrule.html +++ b/tests/wpt/web-platform-tests/editing/run/inserthorizontalrule.html @@ -1,5 +1,6 @@ + inserthorizontalrule - HTML editing conformance tests diff --git a/tests/wpt/web-platform-tests/editing/run/inserthtml.html b/tests/wpt/web-platform-tests/editing/run/inserthtml.html index 59eaf4c59f1..f83102e6a9b 100644 --- a/tests/wpt/web-platform-tests/editing/run/inserthtml.html +++ b/tests/wpt/web-platform-tests/editing/run/inserthtml.html @@ -1,5 +1,6 @@ + inserthtml - HTML editing conformance tests diff --git a/tests/wpt/web-platform-tests/editing/run/insertimage.html b/tests/wpt/web-platform-tests/editing/run/insertimage.html index f34cad0d1f1..7a1f7b92266 100644 --- a/tests/wpt/web-platform-tests/editing/run/insertimage.html +++ b/tests/wpt/web-platform-tests/editing/run/insertimage.html @@ -1,5 +1,6 @@ + insertimage - HTML editing conformance tests diff --git a/tests/wpt/web-platform-tests/editing/run/insertlinebreak.html b/tests/wpt/web-platform-tests/editing/run/insertlinebreak.html index eb3df9dc523..ddab665084b 100644 --- a/tests/wpt/web-platform-tests/editing/run/insertlinebreak.html +++ b/tests/wpt/web-platform-tests/editing/run/insertlinebreak.html @@ -1,5 +1,6 @@ + insertlinebreak - HTML editing conformance tests diff --git a/tests/wpt/web-platform-tests/editing/run/insertorderedlist.html b/tests/wpt/web-platform-tests/editing/run/insertorderedlist.html index 53a9ababb23..68772355c24 100644 --- a/tests/wpt/web-platform-tests/editing/run/insertorderedlist.html +++ b/tests/wpt/web-platform-tests/editing/run/insertorderedlist.html @@ -1,5 +1,6 @@ + insertorderedlist - HTML editing conformance tests diff --git a/tests/wpt/web-platform-tests/editing/run/insertparagraph.html b/tests/wpt/web-platform-tests/editing/run/insertparagraph.html index 549878a08a5..173c5aea40b 100644 --- a/tests/wpt/web-platform-tests/editing/run/insertparagraph.html +++ b/tests/wpt/web-platform-tests/editing/run/insertparagraph.html @@ -1,5 +1,6 @@ + diff --git a/tests/wpt/web-platform-tests/editing/run/inserttext.html b/tests/wpt/web-platform-tests/editing/run/inserttext.html index 1a13919124e..a01293fcae0 100644 --- a/tests/wpt/web-platform-tests/editing/run/inserttext.html +++ b/tests/wpt/web-platform-tests/editing/run/inserttext.html @@ -1,5 +1,6 @@ + diff --git a/tests/wpt/web-platform-tests/editing/run/insertunorderedlist.html b/tests/wpt/web-platform-tests/editing/run/insertunorderedlist.html index 24e4d00e3fb..b1f636b1095 100644 --- a/tests/wpt/web-platform-tests/editing/run/insertunorderedlist.html +++ b/tests/wpt/web-platform-tests/editing/run/insertunorderedlist.html @@ -1,5 +1,6 @@ + insertunorderedlist - HTML editing conformance tests diff --git a/tests/wpt/web-platform-tests/editing/run/italic.html b/tests/wpt/web-platform-tests/editing/run/italic.html index 1b363c28003..6185d553d02 100644 --- a/tests/wpt/web-platform-tests/editing/run/italic.html +++ b/tests/wpt/web-platform-tests/editing/run/italic.html @@ -1,5 +1,6 @@ + diff --git a/tests/wpt/web-platform-tests/editing/run/justifycenter.html b/tests/wpt/web-platform-tests/editing/run/justifycenter.html index 68ade6b6e35..4902a302cca 100644 --- a/tests/wpt/web-platform-tests/editing/run/justifycenter.html +++ b/tests/wpt/web-platform-tests/editing/run/justifycenter.html @@ -1,6 +1,6 @@ - + diff --git a/tests/wpt/web-platform-tests/editing/run/justifyfull.html b/tests/wpt/web-platform-tests/editing/run/justifyfull.html index 5d2dad5e68e..c11befaf893 100644 --- a/tests/wpt/web-platform-tests/editing/run/justifyfull.html +++ b/tests/wpt/web-platform-tests/editing/run/justifyfull.html @@ -1,5 +1,6 @@ + diff --git a/tests/wpt/web-platform-tests/editing/run/justifyleft.html b/tests/wpt/web-platform-tests/editing/run/justifyleft.html index 37554844fec..f6b28185389 100644 --- a/tests/wpt/web-platform-tests/editing/run/justifyleft.html +++ b/tests/wpt/web-platform-tests/editing/run/justifyleft.html @@ -1,5 +1,6 @@ + diff --git a/tests/wpt/web-platform-tests/editing/run/justifyright.html b/tests/wpt/web-platform-tests/editing/run/justifyright.html index ca69e328762..edd30b7f5f0 100644 --- a/tests/wpt/web-platform-tests/editing/run/justifyright.html +++ b/tests/wpt/web-platform-tests/editing/run/justifyright.html @@ -1,5 +1,6 @@ + diff --git a/tests/wpt/web-platform-tests/editing/run/misc.html b/tests/wpt/web-platform-tests/editing/run/misc.html index 2ebd68cda6e..5bf52682292 100644 --- a/tests/wpt/web-platform-tests/editing/run/misc.html +++ b/tests/wpt/web-platform-tests/editing/run/misc.html @@ -1,5 +1,6 @@ + misc - HTML editing conformance tests diff --git a/tests/wpt/web-platform-tests/editing/run/multitest.html b/tests/wpt/web-platform-tests/editing/run/multitest.html index 2c4b6611687..813b9edc034 100644 --- a/tests/wpt/web-platform-tests/editing/run/multitest.html +++ b/tests/wpt/web-platform-tests/editing/run/multitest.html @@ -11,7 +11,7 @@ - + multitest - HTML editing conformance tests

                  diff --git a/tests/wpt/web-platform-tests/editing/run/outdent.html b/tests/wpt/web-platform-tests/editing/run/outdent.html index 0329b6eb44a..f1f9fb491aa 100644 --- a/tests/wpt/web-platform-tests/editing/run/outdent.html +++ b/tests/wpt/web-platform-tests/editing/run/outdent.html @@ -1,5 +1,6 @@ + diff --git a/tests/wpt/web-platform-tests/editing/run/removeformat.html b/tests/wpt/web-platform-tests/editing/run/removeformat.html index fb38a4457e8..0c38ff915fb 100644 --- a/tests/wpt/web-platform-tests/editing/run/removeformat.html +++ b/tests/wpt/web-platform-tests/editing/run/removeformat.html @@ -1,5 +1,6 @@ + removeformat - HTML editing conformance tests diff --git a/tests/wpt/web-platform-tests/editing/run/strikethrough.html b/tests/wpt/web-platform-tests/editing/run/strikethrough.html index ed0781fd16e..cb06c10d0c2 100644 --- a/tests/wpt/web-platform-tests/editing/run/strikethrough.html +++ b/tests/wpt/web-platform-tests/editing/run/strikethrough.html @@ -1,5 +1,6 @@ + diff --git a/tests/wpt/web-platform-tests/editing/run/subscript.html b/tests/wpt/web-platform-tests/editing/run/subscript.html index 1655a822fdf..e0071d7a080 100644 --- a/tests/wpt/web-platform-tests/editing/run/subscript.html +++ b/tests/wpt/web-platform-tests/editing/run/subscript.html @@ -1,5 +1,6 @@ + subscript - HTML editing conformance tests diff --git a/tests/wpt/web-platform-tests/editing/run/superscript.html b/tests/wpt/web-platform-tests/editing/run/superscript.html index 4c1f04763b6..0c3519b288e 100644 --- a/tests/wpt/web-platform-tests/editing/run/superscript.html +++ b/tests/wpt/web-platform-tests/editing/run/superscript.html @@ -1,5 +1,6 @@ + superscript - HTML editing conformance tests diff --git a/tests/wpt/web-platform-tests/editing/run/underline.html b/tests/wpt/web-platform-tests/editing/run/underline.html index 61f85a1fa82..f53add984bd 100644 --- a/tests/wpt/web-platform-tests/editing/run/underline.html +++ b/tests/wpt/web-platform-tests/editing/run/underline.html @@ -1,5 +1,6 @@ + diff --git a/tests/wpt/web-platform-tests/editing/run/unlink.html b/tests/wpt/web-platform-tests/editing/run/unlink.html index 26d6e2d83ec..7cd0be939f1 100644 --- a/tests/wpt/web-platform-tests/editing/run/unlink.html +++ b/tests/wpt/web-platform-tests/editing/run/unlink.html @@ -1,5 +1,6 @@ + unlink - HTML editing conformance tests diff --git a/tests/wpt/web-platform-tests/encoding/streams/backpressure.any.js b/tests/wpt/web-platform-tests/encoding/streams/backpressure.any.js new file mode 100644 index 00000000000..f17e149ed9e --- /dev/null +++ b/tests/wpt/web-platform-tests/encoding/streams/backpressure.any.js @@ -0,0 +1,60 @@ +// META: global=worker + +'use strict'; + +const classes = [ + { + constructor: TextDecoderStream, + input: new Uint8Array([65]) + }, + { + constructor: TextEncoderStream, + input: 'A' + } +]; + +const microtasksRun = () => new Promise(resolve => step_timeout(resolve, 0)); + +for (const streamClass of classes) { + promise_test(async () => { + const stream = new streamClass.constructor(); + const writer = stream.writable.getWriter(); + const reader = stream.readable.getReader(); + const events = []; + await microtasksRun(); + const writePromise = writer.write(streamClass.input); + writePromise.then(() => events.push('write')); + await microtasksRun(); + events.push('paused'); + await reader.read(); + events.push('read'); + await writePromise; + assert_array_equals(events, ['paused', 'read', 'write'], + 'write should happen after read'); + }, 'write() should not complete until read relieves backpressure for ' + + `${streamClass.constructor.name}`); + + promise_test(async () => { + const stream = new streamClass.constructor(); + const writer = stream.writable.getWriter(); + const reader = stream.readable.getReader(); + const events = []; + await microtasksRun(); + const readPromise1 = reader.read(); + readPromise1.then(() => events.push('read1')); + const writePromise1 = writer.write(streamClass.input); + const writePromise2 = writer.write(streamClass.input); + writePromise1.then(() => events.push('write1')); + writePromise2.then(() => events.push('write2')); + await microtasksRun(); + events.push('paused'); + const readPromise2 = reader.read(); + readPromise2.then(() => events.push('read2')); + await Promise.all([writePromise1, writePromise2, + readPromise1, readPromise2]); + assert_array_equals(events, ['read1', 'write1', 'paused', 'read2', + 'write2'], + 'writes should not happen before read2'); + }, 'additional writes should wait for backpressure to be relieved for ' + + `class ${streamClass.constructor.name}`); +} diff --git a/tests/wpt/web-platform-tests/encoding/streams/decode-attributes.any.js b/tests/wpt/web-platform-tests/encoding/streams/decode-attributes.any.js new file mode 100644 index 00000000000..21b70201271 --- /dev/null +++ b/tests/wpt/web-platform-tests/encoding/streams/decode-attributes.any.js @@ -0,0 +1,71 @@ +// META: global=worker + +'use strict'; + +// Verify that constructor arguments are correctly reflected in the attributes. + +// Mapping of the first argument to TextDecoderStream to the expected value of +// the encoding attribute. We assume that if this subset works correctly, the +// rest probably work too. +const labelToName = { + 'unicode-1-1-utf-8': 'utf-8', + 'iso-8859-2': 'iso-8859-2', + 'ascii': 'windows-1252', + 'utf-16': 'utf-16le' +}; + +for (const label of Object.keys(labelToName)) { + test(() => { + const stream = new TextDecoderStream(label); + assert_equals(stream.encoding, labelToName[label], 'encoding should match'); + }, `encoding attribute should have correct value for '${label}'`); +} + +for (const falseValue of [false, 0, '', undefined, null]) { + test(() => { + const stream = new TextDecoderStream('utf-8', { fatal: falseValue }); + assert_false(stream.fatal, 'fatal should be false'); + }, `setting fatal to '${falseValue}' should set the attribute to false`); + + test(() => { + const stream = new TextDecoderStream('utf-8', { ignoreBOM: falseValue }); + assert_false(stream.ignoreBOM, 'ignoreBOM should be false'); + }, `setting ignoreBOM to '${falseValue}' should set the attribute to false`); +} + +for (const trueValue of [true, 1, {}, [], 'yes']) { + test(() => { + const stream = new TextDecoderStream('utf-8', { fatal: trueValue }); + assert_true(stream.fatal, 'fatal should be true'); + }, `setting fatal to '${trueValue}' should set the attribute to true`); + + test(() => { + const stream = new TextDecoderStream('utf-8', { ignoreBOM: trueValue }); + assert_true(stream.ignoreBOM, 'ignoreBOM should be true'); + }, `setting ignoreBOM to '${trueValue}' should set the attribute to true`); +} + +test(() => { + assert_throws(new RangeError(), () => new TextDecoderStream(''), + 'the constructor should throw'); +}, 'constructing with an invalid encoding should throw'); + +test(() => { + assert_throws(new TypeError(), () => new TextDecoderStream({ + toString() { return {}; } + }), 'the constructor should throw'); +}, 'constructing with a non-stringifiable encoding should throw'); + +test(() => { + assert_throws(new Error(), + () => new TextDecoderStream('utf-8', { + get fatal() { throw new Error(); } + }), 'the constructor should throw'); +}, 'a throwing fatal member should cause the constructor to throw'); + +test(() => { + assert_throws(new Error(), + () => new TextDecoderStream('utf-8', { + get ignoreBOM() { throw new Error(); } + }), 'the constructor should throw'); +}, 'a throwing ignoreBOM member should cause the constructor to throw'); diff --git a/tests/wpt/web-platform-tests/encoding/streams/decode-bad-chunks.any.js b/tests/wpt/web-platform-tests/encoding/streams/decode-bad-chunks.any.js new file mode 100644 index 00000000000..101fb3aeb61 --- /dev/null +++ b/tests/wpt/web-platform-tests/encoding/streams/decode-bad-chunks.any.js @@ -0,0 +1,72 @@ +// META: global=worker + +'use strict'; + +const badChunks = [ + { + name: 'undefined', + value: undefined + }, + { + name: 'null', + value: null + }, + { + name: 'numeric', + value: 3.14 + }, + { + name: 'object, not BufferSource', + value: {} + }, + { + name: 'array', + value: [65] + }, + { + name: 'detached ArrayBufferView', + value: (() => { + const u8 = new Uint8Array([65]); + const ab = u8.buffer; + const mc = new MessageChannel(); + mc.port1.postMessage(ab, [ab]); + return u8; + })() + }, + { + name: 'detached ArrayBuffer', + value: (() => { + const u8 = new Uint8Array([65]); + const ab = u8.buffer; + const mc = new MessageChannel(); + mc.port1.postMessage(ab, [ab]); + return ab; + })() + }, + { + name: 'SharedArrayBuffer', + // Use a getter to postpone construction so that all tests don't fail where + // SharedArrayBuffer is not yet implemented. + get value() { + return new SharedArrayBuffer(); + } + }, + { + name: 'shared Uint8Array', + get value() { + new Uint8Array(new SharedArrayBuffer()) + } + } +]; + +for (const chunk of badChunks) { + promise_test(async t => { + const tds = new TextDecoderStream(); + const reader = tds.readable.getReader(); + const writer = tds.writable.getWriter(); + const writePromise = writer.write(chunk.value); + const readPromise = reader.read(); + await promise_rejects(t, new TypeError(), writePromise, 'write should reject'); + await promise_rejects(t, new TypeError(), readPromise, 'read should reject'); + }, `chunk of type ${chunk.name} should error the stream`); +} diff --git a/tests/wpt/web-platform-tests/encoding/streams/decode-ignore-bom.any.js b/tests/wpt/web-platform-tests/encoding/streams/decode-ignore-bom.any.js new file mode 100644 index 00000000000..cbe26d71b13 --- /dev/null +++ b/tests/wpt/web-platform-tests/encoding/streams/decode-ignore-bom.any.js @@ -0,0 +1,38 @@ +// META: global=worker +// META: script=resources/readable-stream-from-array.js +// META: script=resources/readable-stream-to-array.js + +const cases = [ + {encoding: 'utf-8', bytes: [0xEF, 0xBB, 0xBF, 0x61, 0x62, 0x63]}, + {encoding: 'utf-16le', bytes: [0xFF, 0xFE, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00]}, + {encoding: 'utf-16be', bytes: [0xFE, 0xFF, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63]} +]; +const BOM = '\uFEFF'; + +// |inputChunks| is an array of chunks, each represented by an array of +// integers. |ignoreBOM| is true or false. The result value is the output of the +// pipe, concatenated into a single string. +async function pipeAndAssemble(inputChunks, encoding, ignoreBOM) { + const chunksAsUint8 = inputChunks.map(values => new Uint8Array(values)); + const readable = readableStreamFromArray(chunksAsUint8); + const outputArray = await readableStreamToArray(readable.pipeThrough( + new TextDecoderStream(encoding, {ignoreBOM}))); + return outputArray.join(''); +} + +for (const testCase of cases) { + for (let splitPoint = 0; splitPoint < 4; ++splitPoint) { + promise_test(async () => { + const inputChunks = [testCase.bytes.slice(0, splitPoint), + testCase.bytes.slice(splitPoint)]; + const withIgnoreBOM = + await pipeAndAssemble(inputChunks, testCase.encoding, true); + assert_equals(withIgnoreBOM, BOM + 'abc', 'BOM should be preserved'); + + const withoutIgnoreBOM = + await pipeAndAssemble(inputChunks, testCase.encoding, false); + assert_equals(withoutIgnoreBOM, 'abc', 'BOM should be stripped') + }, `ignoreBOM should work for encoding ${testCase.encoding}, split at ` + + `character ${splitPoint}`); + } +} diff --git a/tests/wpt/web-platform-tests/encoding/streams/decode-incomplete-input.any.js b/tests/wpt/web-platform-tests/encoding/streams/decode-incomplete-input.any.js new file mode 100644 index 00000000000..80dd016d491 --- /dev/null +++ b/tests/wpt/web-platform-tests/encoding/streams/decode-incomplete-input.any.js @@ -0,0 +1,24 @@ +// META: global=worker +// META: script=resources/readable-stream-from-array.js +// META: script=resources/readable-stream-to-array.js + +'use strict'; + +const inputBytes = [229]; + +promise_test(async () => { + const input = readableStreamFromArray([new Uint8Array(inputBytes)]); + const output = input.pipeThrough(new TextDecoderStream()); + const array = await readableStreamToArray(output); + assert_array_equals(array, ['\uFFFD'], 'array should have one element'); +}, 'incomplete input with error mode "replacement" should end with a ' + + 'replacement character'); + +promise_test(async t => { + const input = readableStreamFromArray([new Uint8Array(inputBytes)]); + const output = input.pipeThrough(new TextDecoderStream( + 'utf-8', {fatal: true})); + const reader = output.getReader(); + await promise_rejects(t, new TypeError(), reader.read(), + 'read should reject'); +}, 'incomplete input with error mode "fatal" should error the stream'); diff --git a/tests/wpt/web-platform-tests/encoding/streams/decode-non-utf8.any.js b/tests/wpt/web-platform-tests/encoding/streams/decode-non-utf8.any.js new file mode 100644 index 00000000000..7f39cdc04ca --- /dev/null +++ b/tests/wpt/web-platform-tests/encoding/streams/decode-non-utf8.any.js @@ -0,0 +1,77 @@ +// META: global=worker + +'use strict'; + +// The browser is assumed to use the same implementation as for TextDecoder, so +// this file don't replicate the exhaustive checks it has. It is just a smoke +// test that non-UTF-8 encodings work at all. + +const encodings = [ + { + name: 'UTF-16BE', + value: [108, 52], + expected: "\u{6c34}", + invalid: [0xD8, 0x00] + }, + { + name: 'UTF-16LE', + value: [52, 108], + expected: "\u{6c34}", + invalid: [0x00, 0xD8] + }, + { + name: 'Shift_JIS', + value: [144, 133], + expected: "\u{6c34}", + invalid: [255] + }, + { + name: 'ISO-8859-14', + value: [100, 240, 114], + expected: "d\u{0175}r", + invalid: undefined // all bytes are treated as valid + } +]; + +for (const encoding of encodings) { + promise_test(async () => { + const stream = new TextDecoderStream(encoding.name); + const reader = stream.readable.getReader(); + const writer = stream.writable.getWriter(); + const writePromise = writer.write(new Uint8Array(encoding.value)); + const {value, done} = await reader.read(); + assert_false(done, 'readable should not be closed'); + assert_equals(value, encoding.expected, 'chunk should match expected'); + await writePromise; + }, `TextDecoderStream should be able to decode ${encoding.name}`); + + if (!encoding.invalid) + continue; + + promise_test(async t => { + const stream = new TextDecoderStream(encoding.name); + const reader = stream.readable.getReader(); + const writer = stream.writable.getWriter(); + const writePromise = writer.write(new Uint8Array(encoding.invalid)); + const closePromise = writer.close(); + const {value, done} = await reader.read(); + assert_false(done, 'readable should not be closed'); + assert_equals(value, '\u{FFFD}', 'output should be replacement character'); + await Promise.all([writePromise, closePromise]); + }, `TextDecoderStream should be able to decode invalid sequences in ` + + `${encoding.name}`); + + promise_test(async t => { + const stream = new TextDecoderStream(encoding.name, {fatal: true}); + const reader = stream.readable.getReader(); + const writer = stream.writable.getWriter(); + const writePromise = writer.write(new Uint8Array(encoding.invalid)); + const closePromise = writer.close(); + await promise_rejects(t, new TypeError(), reader.read(), + 'readable should be errored'); + await promise_rejects(t, new TypeError(), + Promise.all([writePromise, closePromise]), + 'writable should be errored'); + }, `TextDecoderStream should be able to reject invalid sequences in ` + + `${encoding.name}`); +} diff --git a/tests/wpt/web-platform-tests/encoding/streams/decode-split-character.any.js b/tests/wpt/web-platform-tests/encoding/streams/decode-split-character.any.js new file mode 100644 index 00000000000..6c022697da6 --- /dev/null +++ b/tests/wpt/web-platform-tests/encoding/streams/decode-split-character.any.js @@ -0,0 +1,50 @@ +// META: global=worker +// META: script=resources/readable-stream-from-array.js +// META: script=resources/readable-stream-to-array.js + +'use strict'; + +const inputBytes = [73, 32, 240, 159, 146, 153, 32, 115, 116, 114, 101, + 97, 109, 115]; +for (const splitPoint of [2, 3, 4, 5]) { + promise_test(async () => { + const input = readableStreamFromArray( + [new Uint8Array(inputBytes.slice(0, splitPoint)), + new Uint8Array(inputBytes.slice(splitPoint))]); + const expectedOutput = ['I ', '\u{1F499} streams']; + const output = input.pipeThrough(new TextDecoderStream()); + const array = await readableStreamToArray(output); + assert_array_equals(array, expectedOutput, + 'the split code point should be in the second chunk ' + + 'of the output'); + }, 'a code point split between chunks should not be emitted until all ' + + 'bytes are available; split point = ' + splitPoint); +} + +promise_test(async () => { + const splitPoint = 6; + const input = readableStreamFromArray( + [new Uint8Array(inputBytes.slice(0, splitPoint)), + new Uint8Array(inputBytes.slice(splitPoint))]); + const output = input.pipeThrough(new TextDecoderStream()); + const array = await readableStreamToArray(output); + assert_array_equals(array, ['I \u{1F499}', ' streams'], + 'the multibyte character should be in the first chunk ' + + 'of the output'); +}, 'a code point should be emitted as soon as all bytes are available'); + +for (let splitPoint = 1; splitPoint < 7; ++splitPoint) { + promise_test(async () => { + const input = readableStreamFromArray( + [new Uint8Array(inputBytes.slice(0, splitPoint)), + new Uint8Array([]), + new Uint8Array(inputBytes.slice(splitPoint))]); + const concatenatedOutput = 'I \u{1F499} streams'; + const output = input.pipeThrough(new TextDecoderStream()); + const array = await readableStreamToArray(output); + assert_equals(array.length, 2, 'two chunks should be output'); + assert_equals(array[0].concat(array[1]), concatenatedOutput, + 'output should be unchanged by the empty chunk'); + }, 'an empty chunk inside a code point split between chunks should not ' + + 'change the output; split point = ' + splitPoint); +} diff --git a/tests/wpt/web-platform-tests/encoding/streams/decode-utf8.any.js b/tests/wpt/web-platform-tests/encoding/streams/decode-utf8.any.js new file mode 100644 index 00000000000..34fa764bf0a --- /dev/null +++ b/tests/wpt/web-platform-tests/encoding/streams/decode-utf8.any.js @@ -0,0 +1,41 @@ +// META: global=worker +// META: script=resources/readable-stream-from-array.js +// META: script=resources/readable-stream-to-array.js + +'use strict'; + +const emptyChunk = new Uint8Array([]); +const inputChunk = new Uint8Array([73, 32, 240, 159, 146, 153, 32, 115, 116, + 114, 101, 97, 109, 115]); +const expectedOutputString = 'I \u{1F499} streams'; + +promise_test(async () => { + const input = readableStreamFromArray([inputChunk]); + const output = input.pipeThrough(new TextDecoderStream()); + const array = await readableStreamToArray(output); + assert_array_equals(array, [expectedOutputString], + 'the output should be in one chunk'); +}, 'decoding one UTF-8 chunk should give one output string'); + +promise_test(async () => { + const input = readableStreamFromArray([emptyChunk]); + const output = input.pipeThrough(new TextDecoderStream()); + const array = await readableStreamToArray(output); + assert_array_equals(array, [], 'no chunks should be output'); +}, 'decoding an empty chunk should give no output chunks'); + +promise_test(async () => { + const input = readableStreamFromArray([emptyChunk, inputChunk]); + const output = input.pipeThrough(new TextDecoderStream()); + const array = await readableStreamToArray(output); + assert_array_equals(array, [expectedOutputString], + 'the output should be in one chunk'); +}, 'an initial empty chunk should be ignored'); + +promise_test(async () => { + const input = readableStreamFromArray([inputChunk, emptyChunk]); + const output = input.pipeThrough(new TextDecoderStream()); + const array = await readableStreamToArray(output); + assert_array_equals(array, [expectedOutputString], + 'the output should be in one chunk'); +}, 'a trailing empty chunk should be ignored'); diff --git a/tests/wpt/web-platform-tests/encoding/streams/encode-bad-chunks.any.js b/tests/wpt/web-platform-tests/encoding/streams/encode-bad-chunks.any.js new file mode 100644 index 00000000000..868e34b7342 --- /dev/null +++ b/tests/wpt/web-platform-tests/encoding/streams/encode-bad-chunks.any.js @@ -0,0 +1,63 @@ +// META: global=worker +// META: script=resources/readable-stream-from-array.js +// META: script=resources/readable-stream-to-array.js + +'use strict'; + +const error1 = new Error('error1'); +error1.name = 'error1'; + +promise_test(t => { + const ts = new TextEncoderStream(); + const writer = ts.writable.getWriter(); + const reader = ts.readable.getReader(); + const writePromise = writer.write({ + toString() { throw error1; } + }); + const readPromise = reader.read(); + return Promise.all([ + promise_rejects(t, error1, readPromise, 'read should reject with error1'), + promise_rejects(t, error1, writePromise, 'write should reject with error1'), + promise_rejects(t, error1, reader.closed, 'readable should be errored with error1'), + promise_rejects(t, error1, writer.closed, 'writable should be errored with error1'), + ]); +}, 'a chunk that cannot be converted to a string should error the streams'); + +const oddInputs = [ + { + name: 'undefined', + value: undefined, + expected: 'undefined' + }, + { + name: 'null', + value: null, + expected: 'null' + }, + { + name: 'numeric', + value: 3.14, + expected: '3.14' + }, + { + name: 'object', + value: {}, + expected: '[object Object]' + }, + { + name: 'array', + value: ['hi'], + expected: 'hi' + } +]; + +for (const input of oddInputs) { + promise_test(async () => { + const outputReadable = readableStreamFromArray([input.value]) + .pipeThrough(new TextEncoderStream()) + .pipeThrough(new TextDecoderStream()); + const output = await readableStreamToArray(outputReadable); + assert_equals(output.length, 1, 'output should contain one chunk'); + assert_equals(output[0], input.expected, 'output should be correct'); + }, `input of type ${input.name} should be converted correctly to string`); +} diff --git a/tests/wpt/web-platform-tests/encoding/streams/encode-utf8.any.js b/tests/wpt/web-platform-tests/encoding/streams/encode-utf8.any.js new file mode 100644 index 00000000000..74d1860e82b --- /dev/null +++ b/tests/wpt/web-platform-tests/encoding/streams/encode-utf8.any.js @@ -0,0 +1,144 @@ +// META: global=worker +// META: script=resources/readable-stream-from-array.js +// META: script=resources/readable-stream-to-array.js + +'use strict'; +const inputString = 'I \u{1F499} streams'; +const expectedOutputBytes = [0x49, 0x20, 0xf0, 0x9f, 0x92, 0x99, 0x20, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73]; +// This is a character that must be represented in two code units in a string, +// ie. it is not in the Basic Multilingual Plane. +const astralCharacter = '\u{1F499}'; // BLUE HEART +const astralCharacterEncoded = [0xf0, 0x9f, 0x92, 0x99]; +const leading = astralCharacter[0]; +const trailing = astralCharacter[1]; +const replacementEncoded = [0xef, 0xbf, 0xbd]; + +// These tests assume that the implementation correctly classifies leading and +// trailing surrogates and treats all the code units in each set equivalently. + +const testCases = [ + { + input: [inputString], + output: [expectedOutputBytes], + description: 'encoding one string of UTF-8 should give one complete chunk' + }, + { + input: [leading, trailing], + output: [astralCharacterEncoded], + description: 'a character split between chunks should be correctly encoded' + }, + { + input: [leading, trailing + astralCharacter], + output: [astralCharacterEncoded.concat(astralCharacterEncoded)], + description: 'a character following one split between chunks should be ' + + 'correctly encoded' + }, + { + input: [leading, trailing + leading, trailing], + output: [astralCharacterEncoded, astralCharacterEncoded], + description: 'two consecutive astral characters each split down the ' + + 'middle should be correctly reassembled' + }, + { + input: [leading, trailing + leading + leading, trailing], + output: [astralCharacterEncoded.concat(replacementEncoded), astralCharacterEncoded], + description: 'two consecutive astral characters each split down the ' + + 'middle with an invalid surrogate in the middle should be correctly ' + + 'encoded' + }, + { + input: [leading], + output: [replacementEncoded], + description: 'a stream ending in a leading surrogate should emit a ' + + 'replacement character as a final chunk' + }, + { + input: [leading, astralCharacter], + output: [replacementEncoded.concat(astralCharacterEncoded)], + description: 'an unmatched surrogate at the end of a chunk followed by ' + + 'an astral character in the next chunk should be replaced with ' + + 'the replacement character at the start of the next output chunk' + }, + { + input: [leading, 'A'], + output: [replacementEncoded.concat([65])], + description: 'an unmatched surrogate at the end of a chunk followed by ' + + 'an ascii character in the next chunk should be replaced with ' + + 'the replacement character at the start of the next output chunk' + }, + { + input: [leading, leading, trailing], + output: [replacementEncoded, astralCharacterEncoded], + description: 'an unmatched surrogate at the end of a chunk followed by ' + + 'a plane 1 character split into two chunks should result in ' + + 'the encoded plane 1 character appearing in the last output chunk' + }, + { + input: [leading, leading], + output: [replacementEncoded, replacementEncoded], + description: 'two leading chunks should result in two replacement ' + + 'characters' + }, + { + input: [leading + leading, trailing], + output: [replacementEncoded, astralCharacterEncoded], + description: 'a non-terminal unpaired leading surrogate should ' + + 'immediately be replaced' + }, + { + input: [trailing, astralCharacter], + output: [replacementEncoded, astralCharacterEncoded], + description: 'a terminal unpaired trailing surrogate should ' + + 'immediately be replaced' + }, + { + input: [leading, '', trailing], + output: [astralCharacterEncoded], + description: 'a leading surrogate chunk should be carried past empty chunks' + }, + { + input: [leading, ''], + output: [replacementEncoded], + description: 'a leading surrogate chunk should error when it is clear ' + + 'it didn\'t form a pair' + }, + { + input: [''], + output: [], + description: 'an empty string should result in no output chunk' + }, + { + input: ['', inputString], + output: [expectedOutputBytes], + description: 'a leading empty chunk should be ignored' + }, + { + input: [inputString, ''], + output: [expectedOutputBytes], + description: 'a trailing empty chunk should be ignored' + }, + { + input: ['A'], + output: [[65]], + description: 'a plain ASCII chunk should be converted' + }, + { + input: ['\xff'], + output: [[195, 191]], + description: 'characters in the ISO-8859-1 range should be encoded correctly' + }, +]; + +for (const {input, output, description} of testCases) { + promise_test(async () => { + const inputStream = readableStreamFromArray(input); + const outputStream = inputStream.pipeThrough(new TextEncoderStream()); + const chunkArray = await readableStreamToArray(outputStream); + assert_equals(chunkArray.length, output.length, + 'number of chunks should match'); + for (let i = 0; i < output.length; ++i) { + assert_array_equals(chunkArray[i], output[i], `chunk ${i} should match`); + } + }, description); +} diff --git a/tests/wpt/web-platform-tests/encoding/streams/readable-writable-properties.any.js b/tests/wpt/web-platform-tests/encoding/streams/readable-writable-properties.any.js new file mode 100644 index 00000000000..ad7cde32f68 --- /dev/null +++ b/tests/wpt/web-platform-tests/encoding/streams/readable-writable-properties.any.js @@ -0,0 +1,22 @@ +// META: global=worker + +// This just tests that the "readable" and "writable" properties pass the brand +// checks. All other relevant attributes are covered by the IDL tests. + +'use strict'; + +test(() => { + const te = new TextEncoderStream(); + assert_equals(typeof ReadableStream.prototype.getReader.call(te.readable), + 'object', 'readable property must pass brand check'); + assert_equals(typeof WritableStream.prototype.getWriter.call(te.writable), + 'object', 'writable property must pass brand check'); +}, 'TextEncoderStream readable and writable properties must pass brand checks'); + +test(() => { + const td = new TextDecoderStream(); + assert_equals(typeof ReadableStream.prototype.getReader.call(td.readable), + 'object', 'readable property must pass brand check'); + assert_equals(typeof WritableStream.prototype.getWriter.call(td.writable), + 'object', 'writable property must pass brand check'); +}, 'TextDecoderStream readable and writable properties must pass brand checks'); diff --git a/tests/wpt/web-platform-tests/encoding/streams/realms.window.js b/tests/wpt/web-platform-tests/encoding/streams/realms.window.js new file mode 100644 index 00000000000..b1cc13e0b80 --- /dev/null +++ b/tests/wpt/web-platform-tests/encoding/streams/realms.window.js @@ -0,0 +1,347 @@ +'use strict'; + +// Test that objects created by the TextEncoderStream and TextDecoderStream APIs +// are created in the correct realm. The tests work by creating an iframe for +// each realm and then posting Javascript to them to be evaluated. Inputs and +// outputs are passed around via global variables in each realm's scope. + +// Async setup is required before creating any tests, so require done() to be +// called. +setup({explicit_done: true}); + +function createRealm() { + let iframe = document.createElement('iframe'); + const scriptEndTag = '<' + '/script>'; + iframe.srcdoc = ` + + + + diff --git a/tests/wpt/web-platform-tests/feature-policy/experimental-features/intrinsicSize-without-unsized-media.tentative.https.sub.html b/tests/wpt/web-platform-tests/feature-policy/experimental-features/intrinsicSize-without-unsized-media.tentative.https.sub.html new file mode 100644 index 00000000000..4a3526425d7 --- /dev/null +++ b/tests/wpt/web-platform-tests/feature-policy/experimental-features/intrinsicSize-without-unsized-media.tentative.https.sub.html @@ -0,0 +1,100 @@ + + + + + + diff --git a/tests/wpt/web-platform-tests/feature-policy/experimental-features/intrinsicsize-without-unsized-media.tentative.https.sub.html.headers b/tests/wpt/web-platform-tests/feature-policy/experimental-features/intrinsicsize-without-unsized-media.tentative.https.sub.html.headers new file mode 100644 index 00000000000..4fbf3f5addd --- /dev/null +++ b/tests/wpt/web-platform-tests/feature-policy/experimental-features/intrinsicsize-without-unsized-media.tentative.https.sub.html.headers @@ -0,0 +1 @@ +Feature-Policy: unsized-media * diff --git a/tests/wpt/web-platform-tests/feature-policy/reporting/camera-reporting.https.html b/tests/wpt/web-platform-tests/feature-policy/reporting/camera-reporting.https.html new file mode 100644 index 00000000000..14b2ed1d37c --- /dev/null +++ b/tests/wpt/web-platform-tests/feature-policy/reporting/camera-reporting.https.html @@ -0,0 +1,30 @@ + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/feature-policy/reporting/camera-reporting.https.html.headers b/tests/wpt/web-platform-tests/feature-policy/reporting/camera-reporting.https.html.headers new file mode 100644 index 00000000000..2adc5e237fc --- /dev/null +++ b/tests/wpt/web-platform-tests/feature-policy/reporting/camera-reporting.https.html.headers @@ -0,0 +1 @@ +Feature-Policy: camera 'none' diff --git a/tests/wpt/web-platform-tests/feature-policy/reporting/document-write-reporting.html b/tests/wpt/web-platform-tests/feature-policy/reporting/document-write-reporting.html new file mode 100644 index 00000000000..cb08b8d72d1 --- /dev/null +++ b/tests/wpt/web-platform-tests/feature-policy/reporting/document-write-reporting.html @@ -0,0 +1,32 @@ + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/feature-policy/reporting/document-write-reporting.html.headers b/tests/wpt/web-platform-tests/feature-policy/reporting/document-write-reporting.html.headers new file mode 100644 index 00000000000..57102d5ee7c --- /dev/null +++ b/tests/wpt/web-platform-tests/feature-policy/reporting/document-write-reporting.html.headers @@ -0,0 +1 @@ +Feature-Policy: document-write 'none' diff --git a/tests/wpt/web-platform-tests/feature-policy/reporting/fullscreen-reporting.html b/tests/wpt/web-platform-tests/feature-policy/reporting/fullscreen-reporting.html new file mode 100644 index 00000000000..83d97c91fab --- /dev/null +++ b/tests/wpt/web-platform-tests/feature-policy/reporting/fullscreen-reporting.html @@ -0,0 +1,29 @@ + + + + + + + +
                  + + + diff --git a/tests/wpt/web-platform-tests/feature-policy/reporting/fullscreen-reporting.html.headers b/tests/wpt/web-platform-tests/feature-policy/reporting/fullscreen-reporting.html.headers new file mode 100644 index 00000000000..d35e48ba40d --- /dev/null +++ b/tests/wpt/web-platform-tests/feature-policy/reporting/fullscreen-reporting.html.headers @@ -0,0 +1 @@ +Feature-Policy: fullscreen 'none' diff --git a/tests/wpt/web-platform-tests/feature-policy/reporting/geolocation-reporting.https.html b/tests/wpt/web-platform-tests/feature-policy/reporting/geolocation-reporting.https.html new file mode 100644 index 00000000000..22e258563b7 --- /dev/null +++ b/tests/wpt/web-platform-tests/feature-policy/reporting/geolocation-reporting.https.html @@ -0,0 +1,30 @@ + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/feature-policy/reporting/geolocation-reporting.https.html.headers b/tests/wpt/web-platform-tests/feature-policy/reporting/geolocation-reporting.https.html.headers new file mode 100644 index 00000000000..7e75481ea6d --- /dev/null +++ b/tests/wpt/web-platform-tests/feature-policy/reporting/geolocation-reporting.https.html.headers @@ -0,0 +1 @@ +Feature-Policy: geolocation 'none' diff --git a/tests/wpt/web-platform-tests/feature-policy/reporting/image.jpg b/tests/wpt/web-platform-tests/feature-policy/reporting/image.jpg new file mode 100644 index 00000000000..c059b96d97f Binary files /dev/null and b/tests/wpt/web-platform-tests/feature-policy/reporting/image.jpg differ diff --git a/tests/wpt/web-platform-tests/feature-policy/reporting/microphone-reporting.https.html b/tests/wpt/web-platform-tests/feature-policy/reporting/microphone-reporting.https.html new file mode 100644 index 00000000000..7347a2332bc --- /dev/null +++ b/tests/wpt/web-platform-tests/feature-policy/reporting/microphone-reporting.https.html @@ -0,0 +1,30 @@ + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/feature-policy/reporting/microphone-reporting.https.html.headers b/tests/wpt/web-platform-tests/feature-policy/reporting/microphone-reporting.https.html.headers new file mode 100644 index 00000000000..a86e0a07785 --- /dev/null +++ b/tests/wpt/web-platform-tests/feature-policy/reporting/microphone-reporting.https.html.headers @@ -0,0 +1 @@ +Feature-Policy: microphone 'none' diff --git a/tests/wpt/web-platform-tests/feature-policy/reporting/midi-reporting.html b/tests/wpt/web-platform-tests/feature-policy/reporting/midi-reporting.html new file mode 100644 index 00000000000..8303b7adce4 --- /dev/null +++ b/tests/wpt/web-platform-tests/feature-policy/reporting/midi-reporting.html @@ -0,0 +1,32 @@ + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/feature-policy/reporting/midi-reporting.html.headers b/tests/wpt/web-platform-tests/feature-policy/reporting/midi-reporting.html.headers new file mode 100644 index 00000000000..0e145978a01 --- /dev/null +++ b/tests/wpt/web-platform-tests/feature-policy/reporting/midi-reporting.html.headers @@ -0,0 +1 @@ +Feature-Policy: midi 'none' diff --git a/tests/wpt/web-platform-tests/feature-policy/reporting/payment-reporting.https.html b/tests/wpt/web-platform-tests/feature-policy/reporting/payment-reporting.https.html new file mode 100644 index 00000000000..03eaebea58f --- /dev/null +++ b/tests/wpt/web-platform-tests/feature-policy/reporting/payment-reporting.https.html @@ -0,0 +1,35 @@ + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/feature-policy/reporting/payment-reporting.https.html.headers b/tests/wpt/web-platform-tests/feature-policy/reporting/payment-reporting.https.html.headers new file mode 100644 index 00000000000..a2836778bc5 --- /dev/null +++ b/tests/wpt/web-platform-tests/feature-policy/reporting/payment-reporting.https.html.headers @@ -0,0 +1 @@ +Feature-Policy: payment 'none' diff --git a/tests/wpt/web-platform-tests/feature-policy/reporting/sync-xhr-reporting.html b/tests/wpt/web-platform-tests/feature-policy/reporting/sync-xhr-reporting.html new file mode 100644 index 00000000000..2c76390847b --- /dev/null +++ b/tests/wpt/web-platform-tests/feature-policy/reporting/sync-xhr-reporting.html @@ -0,0 +1,34 @@ + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/feature-policy/reporting/sync-xhr-reporting.html.headers b/tests/wpt/web-platform-tests/feature-policy/reporting/sync-xhr-reporting.html.headers new file mode 100644 index 00000000000..21a909e1fb6 --- /dev/null +++ b/tests/wpt/web-platform-tests/feature-policy/reporting/sync-xhr-reporting.html.headers @@ -0,0 +1 @@ +Feature-Policy: sync-xhr 'none' diff --git a/tests/wpt/web-platform-tests/feature-policy/reporting/unsized-media-reporting.html b/tests/wpt/web-platform-tests/feature-policy/reporting/unsized-media-reporting.html new file mode 100644 index 00000000000..8bd79318950 --- /dev/null +++ b/tests/wpt/web-platform-tests/feature-policy/reporting/unsized-media-reporting.html @@ -0,0 +1,24 @@ + + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/feature-policy/reporting/unsized-media-reporting.html.headers b/tests/wpt/web-platform-tests/feature-policy/reporting/unsized-media-reporting.html.headers new file mode 100644 index 00000000000..db2dcbc1929 --- /dev/null +++ b/tests/wpt/web-platform-tests/feature-policy/reporting/unsized-media-reporting.html.headers @@ -0,0 +1 @@ +Feature-Policy: unsized-media 'none' diff --git a/tests/wpt/web-platform-tests/feature-policy/reporting/usb-reporting.https.html b/tests/wpt/web-platform-tests/feature-policy/reporting/usb-reporting.https.html new file mode 100644 index 00000000000..f90c602e449 --- /dev/null +++ b/tests/wpt/web-platform-tests/feature-policy/reporting/usb-reporting.https.html @@ -0,0 +1,30 @@ + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/feature-policy/reporting/usb-reporting.https.html.headers b/tests/wpt/web-platform-tests/feature-policy/reporting/usb-reporting.https.html.headers new file mode 100644 index 00000000000..4fd1e269362 --- /dev/null +++ b/tests/wpt/web-platform-tests/feature-policy/reporting/usb-reporting.https.html.headers @@ -0,0 +1 @@ +Feature-Policy: usb 'none' diff --git a/tests/wpt/web-platform-tests/fetch/api/basic/header-value-null-byte.any.js b/tests/wpt/web-platform-tests/fetch/api/basic/header-value-null-byte.any.js new file mode 100644 index 00000000000..9c223740c78 --- /dev/null +++ b/tests/wpt/web-platform-tests/fetch/api/basic/header-value-null-byte.any.js @@ -0,0 +1,5 @@ +// META: global=window,worker + +promise_test(t => { + return promise_rejects(t, new TypeError(), fetch("../../../xhr/resources/parse-headers.py?my-custom-header="+encodeURIComponent("x\0x"))); +}, "Ensure fetch() rejects null bytes in headers"); diff --git a/tests/wpt/web-platform-tests/fetch/api/request/request-init-stream.any.js b/tests/wpt/web-platform-tests/fetch/api/request/request-init-stream.any.js new file mode 100644 index 00000000000..22e3f41bc2d --- /dev/null +++ b/tests/wpt/web-platform-tests/fetch/api/request/request-init-stream.any.js @@ -0,0 +1,51 @@ +// META: global=window,worker + +"use strict"; + +async function assert_request(input, init) { + assert_throws(new TypeError(), () => new Request(input, init), "new Request()"); + assert_throws(new TypeError(), async () => await fetch(input, init), "fetch()"); +} + +promise_test(async () => { + const stream = new ReadableStream(); + stream.getReader(); + await assert_request("...", { method:"POST", body: stream }); +}, "Constructing a Request with a stream on which getReader() is called"); + +promise_test(async () => { + const stream = new ReadableStream(); + stream.getReader().read(); + await assert_request("...", { method:"POST", body: stream }); +}, "Constructing a Request with a stream on which read() is called"); + +promise_test(async () => { + const stream = new ReadableStream({ pull: c => c.enqueue(new Uint8Array()) }), + reader = stream.getReader(); + await reader.read(); + reader.releaseLock(); + await assert_request("...", { method:"POST", body: stream }); +}, "Constructing a Request with a stream on which read() and releaseLock() are called"); + +promise_test(async () => { + const request = new Request("...", { method: "POST", body: "..." }); + request.body.getReader(); + await assert_request(request); + assert_class_string(new Request(request, { body: "..." }), "Request"); +}, "Constructing a Request with a Request on which body.getReader() is called"); + +promise_test(async () => { + const request = new Request("...", { method: "POST", body: "..." }); + request.body.getReader().read(); + await assert_request(request); + assert_class_string(new Request(request, { body: "..." }), "Request"); +}, "Constructing a Request with a Request on which body.getReader().read() is called"); + +promise_test(async () => { + const request = new Request("...", { method: "POST", body: "..." }), + reader = request.body.getReader(); + await reader.read(); + reader.releaseLock(); + await assert_request(request); + assert_class_string(new Request(request, { body: "..." }), "Request"); +}, "Constructing a Request with a Request on which read() and releaseLock() are called"); diff --git a/tests/wpt/web-platform-tests/fetch/api/response/response-from-stream.any.js b/tests/wpt/web-platform-tests/fetch/api/response/response-from-stream.any.js new file mode 100644 index 00000000000..93b29b42867 --- /dev/null +++ b/tests/wpt/web-platform-tests/fetch/api/response/response-from-stream.any.js @@ -0,0 +1,23 @@ +// META: global=window,worker + +"use strict"; + +test(() => { + const stream = new ReadableStream(); + stream.getReader(); + assert_throws(new TypeError(), () => new Response(stream)); +}, "Constructing a Response with a stream on which getReader() is called"); + +test(() => { + const stream = new ReadableStream(); + stream.getReader().read(); + assert_throws(new TypeError(), () => new Response(stream)); +}, "Constructing a Response with a stream on which read() is called"); + +promise_test(async () => { + const stream = new ReadableStream({ pull: c => c.enqueue(new Uint8Array()) }), + reader = stream.getReader(); + await reader.read(); + reader.releaseLock(); + assert_throws(new TypeError(), () => new Response(stream)); +}, "Constructing a Response with a stream on which read() and releaseLock() are called"); diff --git a/tests/wpt/web-platform-tests/fetch/sec-metadata/font.tentative.https.sub.html b/tests/wpt/web-platform-tests/fetch/sec-metadata/font.tentative.https.sub.html index 65432b5bacf..0a75531c405 100644 --- a/tests/wpt/web-platform-tests/fetch/sec-metadata/font.tentative.https.sub.html +++ b/tests/wpt/web-platform-tests/fetch/sec-metadata/font.tentative.https.sub.html @@ -1,5 +1,5 @@ - + @@ -43,62 +43,42 @@ + diff --git a/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/cross-site-redirect.tentative.https.sub.html b/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/cross-site-redirect.tentative.https.sub.html new file mode 100644 index 00000000000..9f497a9b62b --- /dev/null +++ b/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/cross-site-redirect.tentative.https.sub.html @@ -0,0 +1,86 @@ + + + + + + + + diff --git a/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/cross-site/cross-site.tentative.https.sub.html b/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/cross-site/cross-site.tentative.https.sub.html deleted file mode 100644 index e25fd3f61d5..00000000000 --- a/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/cross-site/cross-site.tentative.https.sub.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - diff --git a/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/cross-site/same-origin.tentative.https.sub.html b/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/cross-site/same-origin.tentative.https.sub.html deleted file mode 100644 index ac5982d8956..00000000000 --- a/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/cross-site/same-origin.tentative.https.sub.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - diff --git a/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/cross-site/same-site.tentative.https.sub.html b/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/cross-site/same-site.tentative.https.sub.html deleted file mode 100644 index 5b3b965f5e9..00000000000 --- a/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/cross-site/same-site.tentative.https.sub.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - diff --git a/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/multiple-redirect-cross-site.tentative.https.sub.html b/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/multiple-redirect-cross-site.tentative.https.sub.html new file mode 100644 index 00000000000..fdd8733ba6d --- /dev/null +++ b/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/multiple-redirect-cross-site.tentative.https.sub.html @@ -0,0 +1,37 @@ + + + + + + + + diff --git a/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/multiple-redirect-same-site.tentative.https.sub.html b/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/multiple-redirect-same-site.tentative.https.sub.html new file mode 100644 index 00000000000..8fdc943f4c9 --- /dev/null +++ b/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/multiple-redirect-same-site.tentative.https.sub.html @@ -0,0 +1,37 @@ + + + + + + + + diff --git a/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-origin-redirect.tentative.https.sub.html b/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-origin-redirect.tentative.https.sub.html new file mode 100644 index 00000000000..dea71c3f67d --- /dev/null +++ b/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-origin-redirect.tentative.https.sub.html @@ -0,0 +1,89 @@ + + + + + + + + diff --git a/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-origin/cross-site.tentative.https.sub.html b/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-origin/cross-site.tentative.https.sub.html deleted file mode 100644 index ea6b167673f..00000000000 --- a/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-origin/cross-site.tentative.https.sub.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - diff --git a/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-origin/same-origin.tentative.https.sub.html b/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-origin/same-origin.tentative.https.sub.html deleted file mode 100644 index 430990a57c4..00000000000 --- a/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-origin/same-origin.tentative.https.sub.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - diff --git a/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-origin/same-site.tentative.https.sub.html b/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-origin/same-site.tentative.https.sub.html deleted file mode 100644 index 591cf67d181..00000000000 --- a/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-origin/same-site.tentative.https.sub.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - diff --git a/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-site-redirect.tentative.https.sub.html b/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-site-redirect.tentative.https.sub.html new file mode 100644 index 00000000000..a71163a1bfc --- /dev/null +++ b/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-site-redirect.tentative.https.sub.html @@ -0,0 +1,89 @@ + + + + + + + + diff --git a/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-site/cross-site.tentative.https.sub.html b/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-site/cross-site.tentative.https.sub.html deleted file mode 100644 index 8592d02c269..00000000000 --- a/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-site/cross-site.tentative.https.sub.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - diff --git a/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-site/same-origin.tentative.https.sub.html b/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-site/same-origin.tentative.https.sub.html deleted file mode 100644 index 191dbaa7f77..00000000000 --- a/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-site/same-origin.tentative.https.sub.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - diff --git a/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-site/same-site.tentative.https.sub.html b/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-site/same-site.tentative.https.sub.html deleted file mode 100644 index 11d60473981..00000000000 --- a/tests/wpt/web-platform-tests/fetch/sec-metadata/redirect/same-site/same-site.tentative.https.sub.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - diff --git a/tests/wpt/web-platform-tests/fetch/sec-metadata/resources/helper.js b/tests/wpt/web-platform-tests/fetch/sec-metadata/resources/helper.js index cbd96d06863..55e36d49fac 100644 --- a/tests/wpt/web-platform-tests/fetch/sec-metadata/resources/helper.js +++ b/tests/wpt/web-platform-tests/fetch/sec-metadata/resources/helper.js @@ -17,10 +17,3 @@ function assert_header_equals(value, expected) { assert_equals(result.target, expected.target, "target"); assert_equals(result.site, expected.site, "site"); } - -function verify_response(xhr, test, expected){ - if (xhr.readyState === 4) { - assert_header_equals(xhr.responseText, expected); - test.done(); - } -} diff --git a/tests/wpt/web-platform-tests/fetch/sec-metadata/resources/post-to-owner.py b/tests/wpt/web-platform-tests/fetch/sec-metadata/resources/post-to-owner.py index fe08cd1cbca..5472aa5b47e 100644 --- a/tests/wpt/web-platform-tests/fetch/sec-metadata/resources/post-to-owner.py +++ b/tests/wpt/web-platform-tests/fetch/sec-metadata/resources/post-to-owner.py @@ -12,5 +12,5 @@ def main(request, response): if (window.top != window) window.top.postMessage(data, "*"); - """ % json.dumps(request.headers["sec-metadata"]) + """ % json.dumps(request.headers.get("Sec-Metadata", "")) return headers, body diff --git a/tests/wpt/web-platform-tests/fetch/sec-metadata/resources/record-header.py b/tests/wpt/web-platform-tests/fetch/sec-metadata/resources/record-header.py index 06157e4cd8b..4c30d1e52ac 100644 --- a/tests/wpt/web-platform-tests/fetch/sec-metadata/resources/record-header.py +++ b/tests/wpt/web-platform-tests/fetch/sec-metadata/resources/record-header.py @@ -21,20 +21,23 @@ def main(request, response): if 'retrieve' in request.GET: response.writer.write_status(200) response.writer.end_headers() - header_value = request.server.stash.take(testId) - if header_value != None: + try: + header_value = request.server.stash.take(testId) response.writer.write(header_value) + except (KeyError, ValueError) as e: + response.writer.write("No header has been recorded") + pass response.close_connection = True ## Record incoming Sec-Metadata header value else: - ## Return empty string as a default value ## - header = request.headers.get("Sec-Metadata", "") try: + ## Return empty string as a default value ## + header = request.headers.get("Sec-Metadata", "") request.server.stash.put(testId, header) except KeyError: - ## The header is already recorded + ## The header is already recorded or it doesn't exist pass ## Prevent the browser from caching returned responses and allow CORS ## @@ -61,6 +64,7 @@ def main(request, response): ## Return a valid font content and Content-Type ## if key.startswith("font"): + response.headers.set("Content-Type", "application/x-font-ttf") file = open("fonts/Ahem.ttf", "r") font = file.read() file.close() diff --git a/tests/wpt/web-platform-tests/fetch/sec-metadata/serviceworker.tentative.https.sub.html b/tests/wpt/web-platform-tests/fetch/sec-metadata/serviceworker.tentative.https.sub.html index 9d1fe2a3449..cefabb20aaa 100644 --- a/tests/wpt/web-platform-tests/fetch/sec-metadata/serviceworker.tentative.https.sub.html +++ b/tests/wpt/web-platform-tests/fetch/sec-metadata/serviceworker.tentative.https.sub.html @@ -8,7 +8,7 @@ diff --git a/tests/wpt/web-platform-tests/fetch/sec-metadata/sharedworker.tentative.https.sub.html b/tests/wpt/web-platform-tests/fetch/sec-metadata/sharedworker.tentative.https.sub.html index aa118e04239..09017ccbb3a 100644 --- a/tests/wpt/web-platform-tests/fetch/sec-metadata/sharedworker.tentative.https.sub.html +++ b/tests/wpt/web-platform-tests/fetch/sec-metadata/sharedworker.tentative.https.sub.html @@ -23,22 +23,18 @@ } function test_same_origin(){ - var same_origin_test = async_test("Same-Origin sharedworker"); - same_origin_test.step(function () { - key = "sharedworker-same-origin"; - expected_same_origin = {"destination":"sharedworker", "site":"same-origin"}; + promise_test(t => { + return new Promise((resolve, reject) => { + let key = "sharedworker-same-origin"; + let expected = {"destination":"sharedworker", "site":"same-origin"}; - // Requests from the server the saved value of the Sec-Metadata header - same_origin_xhr = new XMLHttpRequest(); - same_origin_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key); - - // Async test step triggered when the response is loaded - same_origin_xhr.onreadystatechange = same_origin_test.step_func(function () { - verify_response(same_origin_xhr, same_origin_test, expected_same_origin) - }); - same_origin_xhr.send(); - }); + fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key) + .then(response => response.text()) + .then(text => assert_header_equals(text, expected)) + .then(_ => resolve()) + .catch(e => reject(e)); + }) + }, "Same-Origin sharedworker") } - diff --git a/tests/wpt/web-platform-tests/fetch/sec-metadata/style.tentative.https.sub.html b/tests/wpt/web-platform-tests/fetch/sec-metadata/style.tentative.https.sub.html index 78fac567b43..609d5764f08 100644 --- a/tests/wpt/web-platform-tests/fetch/sec-metadata/style.tentative.https.sub.html +++ b/tests/wpt/web-platform-tests/fetch/sec-metadata/style.tentative.https.sub.html @@ -1,75 +1,70 @@ - + + - - - - - - - - - - + diff --git a/tests/wpt/web-platform-tests/fullscreen/api/element-ready-check-containing-iframe-manual.html b/tests/wpt/web-platform-tests/fullscreen/api/element-ready-check-containing-iframe-manual.html index 66f99688f14..8ba2ab71b15 100644 --- a/tests/wpt/web-platform-tests/fullscreen/api/element-ready-check-containing-iframe-manual.html +++ b/tests/wpt/web-platform-tests/fullscreen/api/element-ready-check-containing-iframe-manual.html @@ -13,9 +13,12 @@ async_test(function(t) trusted_request(t, iframes[0].contentDocument.body, document.body); iframes[0].contentDocument.onfullscreenchange = t.step_func(function() { + assert_equals(document.fullscreenElement, iframes[0]); trusted_request(t, iframes[1].contentDocument.body, iframes[0].contentDocument.body); - iframes[1].contentDocument.onfullscreenchange = t.unreached_func("fullscreenchange event"); - iframes[1].contentDocument.onfullscreenerror = t.step_func_done(); + iframes[1].contentDocument.onfullscreenchange = t.step_func_done(function() { + assert_equals(document.fullscreenElement, iframes[1]); + }); + iframes[1].contentDocument.onfullscreenerror = t.unreached_func("fullscreenchange error"); }); }); diff --git a/tests/wpt/web-platform-tests/fullscreen/api/element-ready-check-fullscreen-element-sibling-manual.html b/tests/wpt/web-platform-tests/fullscreen/api/element-ready-check-fullscreen-element-sibling-manual.html index dc0c28c78e1..f800093ec8e 100644 --- a/tests/wpt/web-platform-tests/fullscreen/api/element-ready-check-fullscreen-element-sibling-manual.html +++ b/tests/wpt/web-platform-tests/fullscreen/api/element-ready-check-fullscreen-element-sibling-manual.html @@ -13,10 +13,12 @@ async_test(function(t) var b = document.getElementById("b"); document.onfullscreenchange = t.step_func(function() { - assert_equals(document.fullscreenElement, a, "fullscreen element"); + assert_equals(document.fullscreenElement, a, "fullscreen element is a"); trusted_request(t, b, a); - document.onfullscreenchange = t.unreached_func("second fullscreenchange event"); - document.onfullscreenerror = t.step_func_done(); + document.onfullscreenchange = t.step_func_done(function() { + assert_equals(document.fullscreenElement, b, "fullscreen element is b"); + }); + document.onfullscreenerror = t.unreached_func("second fullscreenchange event"); }); trusted_request(t, a); }); diff --git a/tests/wpt/web-platform-tests/fullscreen/api/element-request-fullscreen-non-top-manual.html b/tests/wpt/web-platform-tests/fullscreen/api/element-request-fullscreen-non-top-manual.html index 06c4c1b0367..0764e9c8423 100644 --- a/tests/wpt/web-platform-tests/fullscreen/api/element-request-fullscreen-non-top-manual.html +++ b/tests/wpt/web-platform-tests/fullscreen/api/element-request-fullscreen-non-top-manual.html @@ -21,7 +21,9 @@ async_test(function(t) { assert_equals(document.fullscreenElement, last); trusted_request(t, first, last); - document.onfullscreenerror = t.step_func_done(); + document.onfullscreenchange = t.step_func_done(function() { + assert_equals(document.fullscreenElement, first); + }); }); }); }); diff --git a/tests/wpt/web-platform-tests/fullscreen/api/element-request-fullscreen-two-elements-manual.html b/tests/wpt/web-platform-tests/fullscreen/api/element-request-fullscreen-two-elements-manual.html index 9611c816566..3291664c63a 100644 --- a/tests/wpt/web-platform-tests/fullscreen/api/element-request-fullscreen-two-elements-manual.html +++ b/tests/wpt/web-platform-tests/fullscreen/api/element-request-fullscreen-two-elements-manual.html @@ -19,8 +19,11 @@ async_test(t => { assert_in_array(document.fullscreenElement, [a, b]); order.push(document.fullscreenElement.id); if (order.length == 2) { - assert_array_equals(order, ['b', 'a'], - 'fullscreenElement IDs in fullscreenchange events'); + // Since fullscreenchange event occurs at animation frame timing we might + // have not seen the transition from null -> 'b' but just see the + // resulting 'a' transition twice. + assert_true(order[0] == 'a' || order[0] == 'b', 'first id seen is a or b'); + assert_true(order[1] == 'a', 'second id seen is b'); t.done(); } }); diff --git a/tests/wpt/web-platform-tests/fullscreen/api/element-request-fullscreen-two-iframes-manual.html b/tests/wpt/web-platform-tests/fullscreen/api/element-request-fullscreen-two-iframes-manual.html index 99a7672e71c..94b38c0302a 100644 --- a/tests/wpt/web-platform-tests/fullscreen/api/element-request-fullscreen-two-iframes-manual.html +++ b/tests/wpt/web-platform-tests/fullscreen/api/element-request-fullscreen-two-iframes-manual.html @@ -21,8 +21,11 @@ async_test(t => { assert_in_array(document.fullscreenElement, [a, b]); order.push(document.fullscreenElement.id); if (order.length == 2) { - assert_array_equals(order, ['b', 'a'], - 'fullscreenElement IDs in fullscreenchange events'); + // Since fullscreenchange event occurs at animation frame timing we might + // have not seen the transition from null -> 'b' but just see the + // resulting 'a' transition twice. + assert_true(order[0] == 'a' || order[0] == 'b', 'first id seen is a or b'); + assert_true(order[1] == 'a', 'second id seen is b'); t.done(); } }); diff --git a/tests/wpt/web-platform-tests/fullscreen/rendering/fullscreen-root-block-scroll-manual.html b/tests/wpt/web-platform-tests/fullscreen/rendering/fullscreen-root-block-scroll-manual.html new file mode 100644 index 00000000000..ae57d8a9f23 --- /dev/null +++ b/tests/wpt/web-platform-tests/fullscreen/rendering/fullscreen-root-block-scroll-manual.html @@ -0,0 +1,26 @@ + + +fullscreen root block scrolling + + + + +
                  This page tests that entering fullscreen doesn't adjust the scroll offset
                  + diff --git a/tests/wpt/web-platform-tests/fullscreen/rendering/fullscreen-root-block-size-manual.html b/tests/wpt/web-platform-tests/fullscreen/rendering/fullscreen-root-block-size-manual.html new file mode 100644 index 00000000000..989a85d91c4 --- /dev/null +++ b/tests/wpt/web-platform-tests/fullscreen/rendering/fullscreen-root-block-size-manual.html @@ -0,0 +1,28 @@ + + +fullscreen root block sizing + + + + + + diff --git a/tests/wpt/web-platform-tests/hr-time/resources/unload-a.html b/tests/wpt/web-platform-tests/hr-time/resources/unload-a.html new file mode 100644 index 00000000000..40c1d061830 --- /dev/null +++ b/tests/wpt/web-platform-tests/hr-time/resources/unload-a.html @@ -0,0 +1,13 @@ + + + + Helper page for ../unload-manual.html + + + + + + + diff --git a/tests/wpt/web-platform-tests/hr-time/resources/unload-b.html b/tests/wpt/web-platform-tests/hr-time/resources/unload-b.html new file mode 100644 index 00000000000..7c2d90df275 --- /dev/null +++ b/tests/wpt/web-platform-tests/hr-time/resources/unload-b.html @@ -0,0 +1,13 @@ + + + + Helper page for ../unload-manual.html + + + + + + + diff --git a/tests/wpt/web-platform-tests/hr-time/resources/unload-c.html b/tests/wpt/web-platform-tests/hr-time/resources/unload-c.html new file mode 100644 index 00000000000..731da9db758 --- /dev/null +++ b/tests/wpt/web-platform-tests/hr-time/resources/unload-c.html @@ -0,0 +1,13 @@ + + + + Helper page for ../unload-manual.html + + + + + + + diff --git a/tests/wpt/web-platform-tests/hr-time/resources/unload.js b/tests/wpt/web-platform-tests/hr-time/resources/unload.js new file mode 100644 index 00000000000..ab6b121c2b5 --- /dev/null +++ b/tests/wpt/web-platform-tests/hr-time/resources/unload.js @@ -0,0 +1,51 @@ +const syncDelay = ms => { + const start = performance.now(); + let elapsedTime; + do { + elapsedTime = performance.now() - start; + } while (elapsedTime < ms); +}; + +const markTime = (docName, lifecycleEventName) => { + // Calculating these values before the below `mark` invocation ensures that delays in + // reaching across to the other window object doesn't interfere with the correctness + // of the test. + const dateNow = Date.now(); + const performanceNow = performance.now(); + + window.opener.mark({ + docName, + lifecycleEventName, + performanceNow: performanceNow, + dateNow: dateNow + }); +}; + +const setupUnloadPrompt = (docName, msg) => { + window.addEventListener("beforeunload", ev => { + markTime(docName, "beforeunload"); + return ev.returnValue = msg || "Click OK to continue test." + }); +}; + +const setupListeners = (docName, nextDocument) => { + window.addEventListener("load", () => { + markTime(docName, "load"); + document.getElementById("proceed").addEventListener("click", ev => { + ev.preventDefault(); + if (nextDocument) { + document.location = nextDocument; + } else { + window.close(); + } + }) + }); + + setupUnloadPrompt(docName); + + window.addEventListener("unload", () => { + markTime(docName, "unload"); + if (docName !== "c") { syncDelay(1000); } + }); +}; + diff --git a/tests/wpt/web-platform-tests/hr-time/unload-manual.html b/tests/wpt/web-platform-tests/hr-time/unload-manual.html new file mode 100644 index 00000000000..18c4e0dc327 --- /dev/null +++ b/tests/wpt/web-platform-tests/hr-time/unload-manual.html @@ -0,0 +1,73 @@ + + + + time origin value manual test + + + + + + + + + + +

                  Description

                  +

                  This test validates the behavior of performance.now() with respect to its time origin.

                  +
                  +

                  Manual Test Steps

                  +
                    +
                  1. Click here +
                  +
                  + + diff --git a/tests/wpt/web-platform-tests/html/META.yml b/tests/wpt/web-platform-tests/html/META.yml index d491c94e30c..636b42b68c1 100644 --- a/tests/wpt/web-platform-tests/html/META.yml +++ b/tests/wpt/web-platform-tests/html/META.yml @@ -5,6 +5,5 @@ suggested_reviewers: - foolip - jdm - jgraham - - sideshowbarker - zcorpan - zqzhang diff --git a/tests/wpt/web-platform-tests/html/editing/focus/inert/inert-does-not-match-disabled-selector.html b/tests/wpt/web-platform-tests/html/editing/focus/inert/inert-does-not-match-disabled-selector.html deleted file mode 100644 index defc7cd6c49..00000000000 --- a/tests/wpt/web-platform-tests/html/editing/focus/inert/inert-does-not-match-disabled-selector.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - inert does not match :disabled selector - - - - - - - - - - diff --git a/tests/wpt/web-platform-tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/sharedworker-failure.js b/tests/wpt/web-platform-tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/sharedworker-failure.js index a11ccbc1f30..8472318abd5 100644 --- a/tests/wpt/web-platform-tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/sharedworker-failure.js +++ b/tests/wpt/web-platform-tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/sharedworker-failure.js @@ -1,16 +1,17 @@ let state = "send-sw-failure" onconnect = initialE => { - initialE.source.postMessage(state) - initialE.source.onmessage = e => { + let port = initialE.source; + port.postMessage(state) + port.onmessage = e => { if(state === "" && e.data === "send-window-failure") { - e.postMessage(new SharedArrayBuffer()) + port.postMessage(new SharedArrayBuffer()) } else { - e.postMessage("failure") + port.postMessage("failure") } } - initialE.source.onmessageerror = e => { + port.onmessageerror = e => { if(state === "send-sw-failure") { - e.postMessage("send-sw-failure-success") + port.postMessage("send-sw-failure-success") state = "" } } diff --git a/tests/wpt/web-platform-tests/html/editing/focus/composed.window.js b/tests/wpt/web-platform-tests/html/interaction/focus/composed.window.js similarity index 100% rename from tests/wpt/web-platform-tests/html/editing/focus/composed.window.js rename to tests/wpt/web-platform-tests/html/interaction/focus/composed.window.js diff --git a/tests/wpt/web-platform-tests/html/editing/focus/document-level-focus-apis/document-level-apis.html b/tests/wpt/web-platform-tests/html/interaction/focus/document-level-focus-apis/document-level-apis.html similarity index 100% rename from tests/wpt/web-platform-tests/html/editing/focus/document-level-focus-apis/document-level-apis.html rename to tests/wpt/web-platform-tests/html/interaction/focus/document-level-focus-apis/document-level-apis.html diff --git a/tests/wpt/web-platform-tests/html/editing/focus/document-level-focus-apis/test.html b/tests/wpt/web-platform-tests/html/interaction/focus/document-level-focus-apis/test.html similarity index 100% rename from tests/wpt/web-platform-tests/html/editing/focus/document-level-focus-apis/test.html rename to tests/wpt/web-platform-tests/html/interaction/focus/document-level-focus-apis/test.html diff --git a/tests/wpt/web-platform-tests/html/editing/focus/focus-01.html b/tests/wpt/web-platform-tests/html/interaction/focus/focus-01.html similarity index 100% rename from tests/wpt/web-platform-tests/html/editing/focus/focus-01.html rename to tests/wpt/web-platform-tests/html/interaction/focus/focus-01.html diff --git a/tests/wpt/web-platform-tests/html/editing/focus/focus-02.html b/tests/wpt/web-platform-tests/html/interaction/focus/focus-02.html similarity index 100% rename from tests/wpt/web-platform-tests/html/editing/focus/focus-02.html rename to tests/wpt/web-platform-tests/html/interaction/focus/focus-02.html diff --git a/tests/wpt/web-platform-tests/html/editing/focus/focus-management/focus-event-targets-simple.html b/tests/wpt/web-platform-tests/html/interaction/focus/focus-management/focus-event-targets-simple.html similarity index 100% rename from tests/wpt/web-platform-tests/html/editing/focus/focus-management/focus-event-targets-simple.html rename to tests/wpt/web-platform-tests/html/interaction/focus/focus-management/focus-event-targets-simple.html diff --git a/tests/wpt/web-platform-tests/html/editing/focus/focus-management/focus-events.html b/tests/wpt/web-platform-tests/html/interaction/focus/focus-management/focus-events.html similarity index 100% rename from tests/wpt/web-platform-tests/html/editing/focus/focus-management/focus-events.html rename to tests/wpt/web-platform-tests/html/interaction/focus/focus-management/focus-events.html diff --git a/tests/wpt/web-platform-tests/html/editing/focus/processing-model/focus-fixup-rule-one-no-dialogs.html b/tests/wpt/web-platform-tests/html/interaction/focus/processing-model/focus-fixup-rule-one-no-dialogs.html similarity index 100% rename from tests/wpt/web-platform-tests/html/editing/focus/processing-model/focus-fixup-rule-one-no-dialogs.html rename to tests/wpt/web-platform-tests/html/interaction/focus/processing-model/focus-fixup-rule-one-no-dialogs.html diff --git a/tests/wpt/web-platform-tests/html/interaction/focus/processing-model/legend-focusable.html b/tests/wpt/web-platform-tests/html/interaction/focus/processing-model/legend-focusable.html new file mode 100644 index 00000000000..c9209d3cf62 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/interaction/focus/processing-model/legend-focusable.html @@ -0,0 +1,17 @@ + +legend focusable + + + +
                  + + legend + + + +
                  + diff --git a/tests/wpt/web-platform-tests/html/interaction/focus/processing-model/legend.html b/tests/wpt/web-platform-tests/html/interaction/focus/processing-model/legend.html new file mode 100644 index 00000000000..b53839374df --- /dev/null +++ b/tests/wpt/web-platform-tests/html/interaction/focus/processing-model/legend.html @@ -0,0 +1,20 @@ + +legend + + + +
                  + + legend + + + +
                  + diff --git a/tests/wpt/web-platform-tests/html/editing/focus/processing-model/preventScroll.html b/tests/wpt/web-platform-tests/html/interaction/focus/processing-model/preventScroll.html similarity index 100% rename from tests/wpt/web-platform-tests/html/editing/focus/processing-model/preventScroll.html rename to tests/wpt/web-platform-tests/html/interaction/focus/processing-model/preventScroll.html diff --git a/tests/wpt/web-platform-tests/html/editing/focus/processing-model/support/preventScroll-helper.html b/tests/wpt/web-platform-tests/html/interaction/focus/processing-model/support/preventScroll-helper.html similarity index 100% rename from tests/wpt/web-platform-tests/html/editing/focus/processing-model/support/preventScroll-helper.html rename to tests/wpt/web-platform-tests/html/interaction/focus/processing-model/support/preventScroll-helper.html diff --git a/tests/wpt/web-platform-tests/html/editing/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-default-value.html b/tests/wpt/web-platform-tests/html/interaction/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-default-value.html similarity index 100% rename from tests/wpt/web-platform-tests/html/editing/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-default-value.html rename to tests/wpt/web-platform-tests/html/interaction/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-default-value.html diff --git a/tests/wpt/web-platform-tests/html/editing/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-negative.html b/tests/wpt/web-platform-tests/html/interaction/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-negative.html similarity index 100% rename from tests/wpt/web-platform-tests/html/editing/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-negative.html rename to tests/wpt/web-platform-tests/html/interaction/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-negative.html diff --git a/tests/wpt/web-platform-tests/html/editing/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-order.html b/tests/wpt/web-platform-tests/html/interaction/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-order.html similarity index 100% rename from tests/wpt/web-platform-tests/html/editing/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-order.html rename to tests/wpt/web-platform-tests/html/interaction/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-order.html diff --git a/tests/wpt/web-platform-tests/html/editing/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-positive.html b/tests/wpt/web-platform-tests/html/interaction/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-positive.html similarity index 100% rename from tests/wpt/web-platform-tests/html/editing/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-positive.html rename to tests/wpt/web-platform-tests/html/interaction/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-positive.html diff --git a/tests/wpt/web-platform-tests/html/editing/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-zero.html b/tests/wpt/web-platform-tests/html/interaction/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-zero.html similarity index 100% rename from tests/wpt/web-platform-tests/html/editing/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-zero.html rename to tests/wpt/web-platform-tests/html/interaction/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-zero.html diff --git a/tests/wpt/web-platform-tests/html/editing/focus/tabindex-focus-flag.html b/tests/wpt/web-platform-tests/html/interaction/focus/tabindex-focus-flag.html similarity index 100% rename from tests/wpt/web-platform-tests/html/editing/focus/tabindex-focus-flag.html rename to tests/wpt/web-platform-tests/html/interaction/focus/tabindex-focus-flag.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/META.yml b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/META.yml new file mode 100644 index 00000000000..f5b533c3771 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/META.yml @@ -0,0 +1,4 @@ +suggested_reviewers: + - emilio + - mstensho + - zcorpan diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-block-formatting-context.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-block-formatting-context.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-block-formatting-context.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-block-formatting-context.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-border-gap-ref.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-gap-ref.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-border-gap-ref.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-gap-ref.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-border-gap.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-gap.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-border-gap.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-gap.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-radius-hittest.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-radius-hittest.html new file mode 100644 index 00000000000..9ab10159d8c --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-radius-hittest.html @@ -0,0 +1,14 @@ + +fieldset, border-radius and hit testing + + + +
                  +
                  + diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-containing-block-ref.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-containing-block-ref.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-containing-block-ref.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-containing-block-ref.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-containing-block.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-containing-block.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-containing-block.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-containing-block.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-content-before-legend.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-content-before-legend.html new file mode 100644 index 00000000000..4abd9ce533d --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-content-before-legend.html @@ -0,0 +1,20 @@ + +fieldset content before legend + + +
                  + X + legend + Y +
                  +
                  + legend + X Y +
                  + diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-default-style.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-default-style.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-default-style.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-default-style.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-display.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-display.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-display.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-display.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-div-display-contents.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-div-display-contents.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-div-display-contents.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-div-display-contents.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-flexbox.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-flexbox.html similarity index 54% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-flexbox.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-flexbox.html index d2b1d30d8cc..07c73554e59 100644 --- a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-flexbox.html +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-flexbox.html @@ -11,9 +11,13 @@ border: none } #test-inline, #ref-inline { display: inline-flex } +legend { + float: left; /* Makes it not the "rendered legend" */ + padding: 0; +}
                  -
                  1
                  + 1
                  2
                  3
                  4
                  @@ -25,7 +29,7 @@

                  -
                  1
                  + 1
                  2
                  3
                  4
                  @@ -37,7 +41,7 @@

                  -
                  1
                  + 1
                  2
                  3
                  4
                  @@ -60,12 +64,21 @@
                  diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-foo-ref.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-foo-ref.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-foo-ref.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-foo-ref.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-grid.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-grid.html similarity index 56% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-grid.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-grid.html index 7e9cf3643d0..bbb71dfa702 100644 --- a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-grid.html +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-grid.html @@ -12,9 +12,13 @@ border: none } #test-inline, #ref-inline { display: inline-grid } +legend { + float: left; /* Makes it not the "rendered legend" */ + padding: 0; +}
                  -
                  1
                  + 1
                  2
                  3
                  4
                  @@ -38,7 +42,7 @@

                  -
                  1
                  + 1
                  2
                  3
                  4
                  @@ -61,12 +65,21 @@
                  diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-list-item-ref.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-list-item-ref.html new file mode 100644 index 00000000000..05b8ca4770b --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-list-item-ref.html @@ -0,0 +1,9 @@ + +Reference for fieldset and dipslay: list-item + +

                  There should be no bullet points below.

                  +
                  + X +
                  diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-list-item.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-list-item.html new file mode 100644 index 00000000000..7726947beca --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-list-item.html @@ -0,0 +1,10 @@ + +fieldset and dipslay: list-item + + +

                  There should be no bullet points below.

                  +
                  + X +
                  diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-multicol.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-multicol.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-multicol.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-multicol.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-overflow-hidden-ref.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-hidden-ref.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-overflow-hidden-ref.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-hidden-ref.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-overflow-hidden.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-hidden.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-overflow-hidden.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-hidden.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-ref.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-ref.html new file mode 100644 index 00000000000..d9b36e530b4 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-ref.html @@ -0,0 +1,23 @@ + +Reference for fieldset overflow + +

                  There should be no red.

                  +
                  +
                  +
                  diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow.html new file mode 100644 index 00000000000..2599f2f0fa2 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow.html @@ -0,0 +1,33 @@ + +fieldset overflow + + +

                  There should be no red.

                  +
                  + +
                  +
                  +
                  + diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-painting-order-ref.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-painting-order-ref.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-painting-order-ref.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-painting-order-ref.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-painting-order.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-painting-order.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-painting-order.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-painting-order.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-shadow-dom.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-shadow-dom.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-shadow-dom.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-shadow-dom.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-transform-translatez-ref.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-transform-translatez-ref.html similarity index 81% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-transform-translatez-ref.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-transform-translatez-ref.html index c0db2d7c71a..8200e671944 100644 --- a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-transform-translatez-ref.html +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-transform-translatez-ref.html @@ -1,7 +1,7 @@ Reference for Fieldset and transform: translateZ(0)

                  It should say PASS below without anything obscuring the text.

                  diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-transform-translatez.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-transform-translatez.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/fieldset-transform-translatez.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-transform-translatez.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-vertical-ref.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-vertical-ref.html new file mode 100644 index 00000000000..29c28ea5f89 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-vertical-ref.html @@ -0,0 +1,25 @@ + +Reference for fieldset vertical + +

                  vertical-lr +

                  +
                  foo bar
                  normal
                  +
                  foo bar
                  dir=rtl
                  +
                  foo bar
                  dir=rtl align=left
                  +
                  foo bar
                  dir=rtl align=center
                  +
                  foo bar
                  dir=rtl align=right
                  +
                  foo bar
                  align=left
                  +
                  foo bar
                  align=center
                  +
                  foo bar
                  align=right
                  +
                  +
                  +

                  vertical-rl +

                  +
                  foo bar
                  normal
                  +
                  foo bar
                  dir=rtl
                  +
                  foo bar
                  dir=rtl align=left
                  +
                  foo bar
                  dir=rtl align=center
                  +
                  foo bar
                  dir=rtl align=right
                  +
                  foo bar
                  align=left
                  +
                  foo bar
                  align=center
                  +
                  foo bar
                  align=right
                  diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-vertical.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-vertical.html new file mode 100644 index 00000000000..c11b4666696 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-vertical.html @@ -0,0 +1,27 @@ + +fieldset vertical + + +

                  vertical-lr +

                  +
                  foo barnormal
                  +
                  foo bardir=rtl
                  +
                  foo bardir=rtl align=left
                  +
                  foo bardir=rtl align=center
                  +
                  foo bardir=rtl align=right
                  +
                  foo baralign=left
                  +
                  foo baralign=center
                  +
                  foo baralign=right
                  +
                  +
                  +

                  vertical-rl +

                  +
                  foo barnormal
                  +
                  foo bardir=rtl
                  +
                  foo bardir=rtl align=left
                  +
                  foo bardir=rtl align=center
                  +
                  foo bardir=rtl align=right
                  +
                  foo baralign=left
                  +
                  foo baralign=center
                  +
                  foo baralign=right
                  +
                  diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-align-text-align.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-align-text-align.html new file mode 100644 index 00000000000..01483bf8ad3 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-align-text-align.html @@ -0,0 +1,27 @@ + +legend align does not map to text-align + + + + +
                  foo bar abcdefghijklmnopqrstuvwxyz
                  +
                  foo bar abcdefghijklmnopqrstuvwxyz
                  +
                  foo bar abcdefghijklmnopqrstuvwxyz
                  +
                  foo bar abcdefghijklmnopqrstuvwxyz
                  +
                  foo bar abcdefghijklmnopqrstuvwxyz
                  + diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-align.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-align.html new file mode 100644 index 00000000000..e7745998194 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-align.html @@ -0,0 +1,50 @@ + +legend align + + +
                  x
                  +
                  x
                  +
                  x
                  +
                  x
                  +
                  +
                  x
                  +
                  +
                  +
                  x
                  +
                  +
                  +
                  x
                  +
                  +
                  +
                  x
                  +
                  +
                  +
                  x
                  +
                  +
                  +
                  x
                  +
                  +
                  x
                  +
                  x
                  +
                  x
                  +
                  x
                  + diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-auto-margins-ref.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-auto-margins-ref.html new file mode 100644 index 00000000000..8b1258727fc --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-auto-margins-ref.html @@ -0,0 +1,37 @@ + + + +legend inline auto margins + + + + +
                  +
                  +
                  +
                  +
                  + + diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-auto-margins.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-auto-margins.html new file mode 100644 index 00000000000..dd1964ba251 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-auto-margins.html @@ -0,0 +1,32 @@ + + + +legend inline auto margins + + + + + +
                  +
                  +
                  +
                  +
                  + + diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/legend-block-formatting-context.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-formatting-context.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/legend-block-formatting-context.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-formatting-context.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none-rendering-ref.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none-rendering-ref.html new file mode 100644 index 00000000000..e6eff47e53c --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none-rendering-ref.html @@ -0,0 +1,7 @@ + +Reference for Rendering of display: none legend + +

                  There should be a green box below.

                  +
                  diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none-rendering.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none-rendering.html new file mode 100644 index 00000000000..abf3c45df71 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none-rendering.html @@ -0,0 +1,11 @@ + +Rendering of display: none legend + + +

                  There should be a green box below.

                  +
                  + FAIL +
                  diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none.html new file mode 100644 index 00000000000..689454ac493 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none.html @@ -0,0 +1,16 @@ + +legend display: none + + + +
                  + Foo +
                  + diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/legend-display.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/legend-display.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-dynamic-update.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-dynamic-update.html new file mode 100644 index 00000000000..5dc68244fe0 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-dynamic-update.html @@ -0,0 +1,19 @@ + + +legend and dynamic update + +

                  There should be a normal fieldset below with the legend "Foo".

                  +
                  + F +
                  + diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/legend-float-abspos.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-float-abspos.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/legend-float-abspos.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-float-abspos.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/legend-float-ref.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-float-ref.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/legend-float-ref.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-float-ref.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/legend-float.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-float.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/legend-float.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-float.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/legend-grid-flex-multicol.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-grid-flex-multicol.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/legend-grid-flex-multicol.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-grid-flex-multicol.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-ref.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-ref.html new file mode 100644 index 00000000000..ee76e93b64e --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-ref.html @@ -0,0 +1,7 @@ + +Reference for legend and dipslay: list-item + +

                  There should be a bullet point below.

                  +
                  X
                  diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item.html new file mode 100644 index 00000000000..c26b50ce662 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item.html @@ -0,0 +1,11 @@ + +legend and dipslay: list-item + + +

                  There should be a bullet point below.

                  +
                  + X +
                  diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/legend-position-relative-ref.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-position-relative-ref.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/legend-position-relative-ref.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-position-relative-ref.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/legend-position-relative.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-position-relative.html similarity index 82% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/legend-position-relative.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-position-relative.html index efd55ab22db..99383612614 100644 --- a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/legend-position-relative.html +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-position-relative.html @@ -3,7 +3,7 @@

                  There should be no red.

                  diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/legend-sans-fieldset-display.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-sans-fieldset-display.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/legend-sans-fieldset-display.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-sans-fieldset-display.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/legend.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/legend.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/min-inline-size.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/min-inline-size.html similarity index 100% rename from tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-element-0/min-inline-size.html rename to tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/min-inline-size.html diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/resources/fieldset-vertical.css b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/resources/fieldset-vertical.css new file mode 100644 index 00000000000..b358d925a76 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/resources/fieldset-vertical.css @@ -0,0 +1,18 @@ +body > div { display: inline-block } +fieldset, .fieldset { padding: 0; height:10em; width:2em; border:1em groove; margin: 0em; line-height:1 } +legend, .legend { padding: 0; width: 1em } +.legend { + background: white; /* overlap the border to emulate the border not being painted */ + display: table; /* shrink-wrap */ +} + +[style="writing-mode: vertical-lr"] .legend { + margin-left: -1em; +} +[style="writing-mode: vertical-rl"] .legend { + margin-right: -1em; +} +.top { margin-bottom: auto } +.center { margin-top: auto; margin-bottom: auto } +.bottom { margin-top: auto } +.rtl { direction: rtl } diff --git a/tests/wpt/web-platform-tests/html/rendering/the-details-element/details-display-property-is-ignored-ref.html b/tests/wpt/web-platform-tests/html/rendering/the-details-element/details-display-property-is-ignored-ref.html new file mode 100644 index 00000000000..6ebed6075de --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/the-details-element/details-display-property-is-ignored-ref.html @@ -0,0 +1,21 @@ + + + +From html.spec.whatwg.org: + +
                  +The details element is expected to render as a block box. The element's shadow +tree is expected to take the element's first summary element child, if any, and +place it in a first block box container, and then take the element's remaining +descendants, if any, and place them in a second block box container. +
                  + +<details display:flex> should be ignored. Otherwise details would render as +something other than a block box. +
                  + +
                  + This is the summary. +
                  thing 1
                  + thing 2 +
                  diff --git a/tests/wpt/web-platform-tests/html/rendering/the-details-element/details-display-property-is-ignored.html b/tests/wpt/web-platform-tests/html/rendering/the-details-element/details-display-property-is-ignored.html new file mode 100644 index 00000000000..445b4e483d0 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/the-details-element/details-display-property-is-ignored.html @@ -0,0 +1,26 @@ + + + + + + + + +From html.spec.whatwg.org: + +
                  +The details element is expected to render as a block box. The element's shadow +tree is expected to take the element's first summary element child, if any, and +place it in a first block box container, and then take the element's remaining +descendants, if any, and place them in a second block box container. +
                  + +<details display:flex> should be ignored. Otherwise details would render as +something other than a block box. +
                  + +
                  + This is the summary. +
                  thing 1
                  + thing 2 +
                  diff --git a/tests/wpt/web-platform-tests/feature-policy/autoplay-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html b/tests/wpt/web-platform-tests/html/semantics/embedded-content/media-elements/autoplay-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html similarity index 100% rename from tests/wpt/web-platform-tests/feature-policy/autoplay-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html rename to tests/wpt/web-platform-tests/html/semantics/embedded-content/media-elements/autoplay-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html diff --git a/tests/wpt/web-platform-tests/feature-policy/autoplay-allowed-by-feature-policy-attribute.https.sub.html b/tests/wpt/web-platform-tests/html/semantics/embedded-content/media-elements/autoplay-allowed-by-feature-policy-attribute.https.sub.html similarity index 100% rename from tests/wpt/web-platform-tests/feature-policy/autoplay-allowed-by-feature-policy-attribute.https.sub.html rename to tests/wpt/web-platform-tests/html/semantics/embedded-content/media-elements/autoplay-allowed-by-feature-policy-attribute.https.sub.html diff --git a/tests/wpt/web-platform-tests/feature-policy/autoplay-allowed-by-feature-policy.https.sub.html b/tests/wpt/web-platform-tests/html/semantics/embedded-content/media-elements/autoplay-allowed-by-feature-policy.https.sub.html similarity index 100% rename from tests/wpt/web-platform-tests/feature-policy/autoplay-allowed-by-feature-policy.https.sub.html rename to tests/wpt/web-platform-tests/html/semantics/embedded-content/media-elements/autoplay-allowed-by-feature-policy.https.sub.html diff --git a/tests/wpt/web-platform-tests/feature-policy/autoplay-allowed-by-feature-policy.https.sub.html.headers b/tests/wpt/web-platform-tests/html/semantics/embedded-content/media-elements/autoplay-allowed-by-feature-policy.https.sub.html.headers similarity index 100% rename from tests/wpt/web-platform-tests/feature-policy/autoplay-allowed-by-feature-policy.https.sub.html.headers rename to tests/wpt/web-platform-tests/html/semantics/embedded-content/media-elements/autoplay-allowed-by-feature-policy.https.sub.html.headers diff --git a/tests/wpt/web-platform-tests/feature-policy/autoplay-default-feature-policy.https.sub.html b/tests/wpt/web-platform-tests/html/semantics/embedded-content/media-elements/autoplay-default-feature-policy.https.sub.html similarity index 100% rename from tests/wpt/web-platform-tests/feature-policy/autoplay-default-feature-policy.https.sub.html rename to tests/wpt/web-platform-tests/html/semantics/embedded-content/media-elements/autoplay-default-feature-policy.https.sub.html diff --git a/tests/wpt/web-platform-tests/feature-policy/autoplay-disabled-by-feature-policy.https.sub.html b/tests/wpt/web-platform-tests/html/semantics/embedded-content/media-elements/autoplay-disabled-by-feature-policy.https.sub.html similarity index 100% rename from tests/wpt/web-platform-tests/feature-policy/autoplay-disabled-by-feature-policy.https.sub.html rename to tests/wpt/web-platform-tests/html/semantics/embedded-content/media-elements/autoplay-disabled-by-feature-policy.https.sub.html diff --git a/tests/wpt/web-platform-tests/feature-policy/autoplay-disabled-by-feature-policy.https.sub.html.headers b/tests/wpt/web-platform-tests/html/semantics/embedded-content/media-elements/autoplay-disabled-by-feature-policy.https.sub.html.headers similarity index 100% rename from tests/wpt/web-platform-tests/feature-policy/autoplay-disabled-by-feature-policy.https.sub.html.headers rename to tests/wpt/web-platform-tests/html/semantics/embedded-content/media-elements/autoplay-disabled-by-feature-policy.https.sub.html.headers diff --git a/tests/wpt/web-platform-tests/html/semantics/embedded-content/the-img-element/environment-changes/viewport-change.html b/tests/wpt/web-platform-tests/html/semantics/embedded-content/the-img-element/environment-changes/viewport-change.html index 21624712cf9..f6ae65708c6 100644 --- a/tests/wpt/web-platform-tests/html/semantics/embedded-content/the-img-element/environment-changes/viewport-change.html +++ b/tests/wpt/web-platform-tests/html/semantics/embedded-content/the-img-element/environment-changes/viewport-change.html @@ -39,7 +39,7 @@ onload = function() { var expected = {wide:resolve(img.dataset.wide), narrow:resolve(img.dataset.narrow)}; var current = iframe.className; var next = current === 'wide' ? 'narrow' : 'wide'; - var expect_change = expected[next].indexOf('broken.png') !== 0 && !('noChange' in img.dataset); + var expect_change = expected[next].indexOf('broken.png') === -1 && !('noChange' in img.dataset); test(function() { assert_equals(img.currentSrc, expected[current]); diff --git a/tests/wpt/web-platform-tests/html/semantics/embedded-content/the-img-element/img.complete.html b/tests/wpt/web-platform-tests/html/semantics/embedded-content/the-img-element/img.complete.html index 771b8e1b80e..4be8d4db848 100644 --- a/tests/wpt/web-platform-tests/html/semantics/embedded-content/the-img-element/img.complete.html +++ b/tests/wpt/web-platform-tests/html/semantics/embedded-content/the-img-element/img.complete.html @@ -38,8 +38,9 @@ assert_false(loaded); loaded = true; assert_true(document.getElementById("imgTestTag3").complete); - var currentSrc = document.getElementById("imgTestTag3").currentSrc - assert_equals(new URL(window.location.origin + "/" + currentSrc).pathname, "/3.jpg"); + var currentSrc = document.getElementById("imgTestTag3").currentSrc; + var expectedUrl = new URL("3.jpg", window.location); + assert_equals(new URL(currentSrc).pathname, expectedUrl.pathname); }, "Only one onload, despite setting the src twice"); document.getElementById("imgTestTag3").src = 'test' + Math.random(); diff --git a/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/common/accesskey.js b/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/common/accesskey.js new file mode 100644 index 00000000000..f08761be8c1 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/common/accesskey.js @@ -0,0 +1,36 @@ +setup({explicit_done: true, explicit_timeout: true}); + +const NOTRUN = 3; +let status = NOTRUN; +function notrun() { + return status === NOTRUN; +} +add_completion_callback(tests => { + status = tests[0].status; +}); + +function pass() { + // Wait a couple of frames in case fail() is also called. + requestAnimationFrame(() => { + requestAnimationFrame(() => { + if (notrun()) { + test(() => {}); + done(); + } + }); + }); +} + +function fail(msg) { + if (notrun()) { + test(() => { assert_unreached(msg); }); + done(); + } +} + +document.addEventListener('DOMContentLoaded', () => { + const accessKeyElement = document.querySelector('[accesskey]'); + if (accessKeyElement.accessKeyLabel) { + document.querySelector('kbd').textContent = accessKeyElement.accessKeyLabel; + } +}); diff --git a/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/first-input-after-legend-manual.html b/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/first-input-after-legend-manual.html new file mode 100644 index 00000000000..521b4bb9755 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/first-input-after-legend-manual.html @@ -0,0 +1,10 @@ + +First input after the legend + + + +

                  Press the access key combination for "a".

                  +
                  + legend + +
                  diff --git a/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/first-input-before-legend-manual.html b/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/first-input-before-legend-manual.html new file mode 100644 index 00000000000..1c40cc7b81e --- /dev/null +++ b/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/first-input-before-legend-manual.html @@ -0,0 +1,13 @@ + +First input before the legend + + + +

                  Press the access key combination for "a".

                  +
                  + + legend + + + +
                  diff --git a/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/first-input-inside-legend-manual.html b/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/first-input-inside-legend-manual.html new file mode 100644 index 00000000000..abd3a3b2dfe --- /dev/null +++ b/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/first-input-inside-legend-manual.html @@ -0,0 +1,12 @@ + +First input inside the legend + + + +

                  Press the access key combination for "a".

                  +
                  + legend + + + +
                  diff --git a/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/focusable-legend-manual.html b/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/focusable-legend-manual.html new file mode 100644 index 00000000000..e2880a77bf9 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/focusable-legend-manual.html @@ -0,0 +1,14 @@ + +Focusable legend + + + +

                  Press the access key combination for "a".

                  +
                  + + legend + + + +
                  diff --git a/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/focusable-legend-sibling-manual.html b/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/focusable-legend-sibling-manual.html new file mode 100644 index 00000000000..49dcaaf7d54 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/focusable-legend-sibling-manual.html @@ -0,0 +1,17 @@ + +Focusable legend sibling + + + +

                  Press the access key combination for "a".

                  +
                  + first legend + second legend +
                  + diff --git a/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/input-outside-fieldset-manual.html b/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/input-outside-fieldset-manual.html new file mode 100644 index 00000000000..dc6af48323e --- /dev/null +++ b/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/input-outside-fieldset-manual.html @@ -0,0 +1,17 @@ + +Input outside fieldset + + + +

                  Press the access key combination for "a".

                  +
                  + legend +
                  + + diff --git a/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/label-sibling-manual.html b/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/label-sibling-manual.html new file mode 100644 index 00000000000..8a7b20565f7 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/label-sibling-manual.html @@ -0,0 +1,18 @@ + +Label sibling + + + +

                  Press the access key combination for "a".

                  + +
                  + legend + +
                  + diff --git a/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/no-fieldset-parent-manual.html b/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/no-fieldset-parent-manual.html new file mode 100644 index 00000000000..e7abb71454a --- /dev/null +++ b/tests/wpt/web-platform-tests/html/semantics/interactive-elements/commands/legend/no-fieldset-parent-manual.html @@ -0,0 +1,18 @@ + +No fieldset parent + + + +

                  Press the access key combination for "a".

                  + + legend + + + + diff --git a/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/goal-parameter.htm b/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/goal-parameter.htm new file mode 100644 index 00000000000..fe4d6759b91 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/goal-parameter.htm @@ -0,0 +1,138 @@ + + + + Goal Parameter on JavaScript MIME + + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/is-module-goal.mjs b/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/is-module-goal.mjs new file mode 100644 index 00000000000..b533fc2e906 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/is-module-goal.mjs @@ -0,0 +1 @@ +import "./serve-with-content-type.py?fn=is-module-goal.mjs&ct=text%2Fjavascript%3Bgoal=module"; \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/is-script-goal.js b/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/is-script-goal.js new file mode 100644 index 00000000000..069363dd400 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/is-script-goal.js @@ -0,0 +1,3 @@ +with ({}) { + ; +}; \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/load-error-events-2.html b/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/load-error-events-2.html index cefa053e754..0748b459092 100644 --- a/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/load-error-events-2.html +++ b/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/load-error-events-2.html @@ -11,7 +11,7 @@ var test5_load = event_test('no src, parser-inserted, has style sheets blocking scripts, script nesting level == 1', false, false); - + diff --git a/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/load-error-events-3.html b/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/load-error-events-3.html index c2cf0dbdd98..83a752ce2cd 100644 --- a/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/load-error-events-3.html +++ b/tests/wpt/web-platform-tests/html/semantics/scripting-1/the-script-element/load-error-events-3.html @@ -13,7 +13,7 @@ var test6_load = event_test('no src, parser-inserted, has style sheets blocking false, false); document.write( - ` + ` - + diff --git a/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/010-1.html b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/010-1.html deleted file mode 100644 index 317e13691d4..00000000000 --- a/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/010-1.html +++ /dev/null @@ -1,2 +0,0 @@ - -010-1 diff --git a/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/010-2.html b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/010-2.html deleted file mode 100644 index ea537fcd601..00000000000 --- a/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/010-2.html +++ /dev/null @@ -1,5 +0,0 @@ - -010-2 - diff --git a/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/010.html b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/010.html deleted file mode 100644 index d83d24f2414..00000000000 --- a/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/010.html +++ /dev/null @@ -1,22 +0,0 @@ - -Salvagability of document.opened document - - -
                  - - diff --git a/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/016-1.html b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/016-1.html index 12990a56070..ceeeb64df63 100644 --- a/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/016-1.html +++ b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/016-1.html @@ -11,7 +11,7 @@ onload = function() { setTimeout(function() { parent.tests[0].step(function() { - parent.assert_equals(test_prop, 1, "Global scope from original window timeout"); + parent.assert_equals(test_prop, 2, "Global scope from original window timeout"); parent.assert_equals(window.test_prop, 2, "Window property from original window timeout") }); parent.tests[1].step(function() { @@ -23,7 +23,7 @@ onload = function() { window.setTimeout(function() { parent.tests[2].step(function() { - parent.assert_equals(test_prop, 1, "Global scope from original window timeout"); + parent.assert_equals(test_prop, 2, "Global scope from original window timeout"); parent.assert_equals(window.test_prop, 2, "Window property from original window timeout") }); parent.tests[3].step(function() { diff --git a/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-refresh-immediate.window.js b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-refresh-immediate.window.js new file mode 100644 index 00000000000..8d045b9e0ab --- /dev/null +++ b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-refresh-immediate.window.js @@ -0,0 +1,119 @@ +// The following tests deal with the pragma and the +// `Refresh` header. The spec is still hazy on the precise behavior in those +// cases but we use https://github.com/whatwg/html/issues/4003 as a guideline. + +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + frame.onload = null; + + const client = new frame.contentWindow.XMLHttpRequest(); + client.open("GET", "/common/blank.html"); + client.onabort = t.step_func_done(); + client.send(); + + frame.contentDocument.open(); + }); + frame.src = "resources/meta-refresh.py?0"; +}, "document.open() aborts documents that are queued for navigation through refresh with timeout 0 (XMLHttpRequest)"); + +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + frame.onload = null; + + frame.contentWindow.fetch("/common/blank.html").then( + t.unreached_func("Fetch should have been aborted"), + t.step_func_done()); + + frame.contentDocument.open(); + }); + frame.src = "resources/meta-refresh.py?0"; +}, "document.open() aborts documents that are queued for navigation through refresh with timeout 0 (fetch())"); + +// We cannot test for img element's error event for this test, as Firefox does +// not fire the event if the fetch is aborted while Chrome does. +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + frame.onload = null; + + let happened = false; + const img = frame.contentDocument.createElement("img"); + img.src = new URL("resources/slow-png.py", document.URL); + img.onload = t.unreached_func("Image loading should not have succeeded"); + // The image fetch starts in a microtask, so let's be sure to test after + // the fetch has started. + t.step_timeout(() => { + frame.contentDocument.open(); + happened = true; + }); + // If 3 seconds have passed and the image has still not loaded, we consider + // it aborted. slow-png.py only sleeps for 2 wallclock seconds. + t.step_timeout(t.step_func_done(() => { + assert_true(happened); + }), 3000); + }); + frame.src = "resources/meta-refresh.py?0"; +}, "document.open() aborts documents that are queued for navigation through refresh with timeout 0 (image loading)"); + +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + frame.onload = null; + + const client = new frame.contentWindow.XMLHttpRequest(); + client.open("GET", "/common/blank.html"); + client.onabort = t.step_func_done(); + client.send(); + + frame.contentDocument.open(); + }); + frame.src = "resources/http-refresh.py?0"; +}, "document.open() aborts documents that are queued for navigation through Refresh header with timeout 0 (XMLHttpRequest)"); + +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + frame.onload = null; + + frame.contentWindow.fetch("/common/blank.html").then( + t.unreached_func("Fetch should have been aborted"), + t.step_func_done()); + + frame.contentDocument.open(); + }); + frame.src = "resources/http-refresh.py?0"; +}, "document.open() aborts documents that are queued for navigation through Refresh header with timeout 0 (fetch())"); + +// We cannot test for img element's error event for this test, as Firefox does +// not fire the event if the fetch is aborted while Chrome does. +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + frame.onload = null; + + let happened = false; + const img = frame.contentDocument.createElement("img"); + img.src = new URL("resources/slow-png.py", document.URL); + img.onload = t.unreached_func("Image loading should not have succeeded"); + // The image fetch starts in a microtask, so let's be sure to test after + // the fetch has started. + t.step_timeout(() => { + frame.contentDocument.open(); + happened = true; + }); + // If 3 seconds have passed and the image has still not loaded, we consider + // it aborted. slow-png.py only sleeps for 2 wallclock seconds. + t.step_timeout(t.step_func_done(() => { + assert_true(happened); + }), 3000); + }); + frame.src = "resources/http-refresh.py?0"; +}, "document.open() aborts documents that are queued for navigation through Refresh header with timeout 0 (image loading)"); diff --git a/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-refresh-multisecond-header.window.js b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-refresh-multisecond-header.window.js new file mode 100644 index 00000000000..8c6c1267c4e --- /dev/null +++ b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-refresh-multisecond-header.window.js @@ -0,0 +1,69 @@ +// The following tests deal with the pragma and the +// `Refresh` header. The spec is still hazy on the precise behavior in those +// cases but we use https://github.com/whatwg/html/issues/4003 as a guideline. +// +// This is separate from abort-refresh-multisecond-meta.window.js to avoid +// browser interventions that limit the number of connections in a tab. + +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + frame.onload = null; + let happened = false; + + const client = new frame.contentWindow.XMLHttpRequest(); + client.open("GET", "/common/blank.html"); + client.onload = t.step_func_done(() => { + assert_true(happened); + }); + client.onerror = t.unreached_func("XMLHttpRequest should have succeeded"); + client.onabort = t.unreached_func("XMLHttpRequest should have succeeded"); + client.ontimeout = t.unreached_func("XMLHttpRequest should have succeeded"); + client.send(); + + frame.contentDocument.open(); + happened = true; + }); + frame.src = "resources/http-refresh.py?1"; +}, "document.open() does NOT abort documents that are queued for navigation through Refresh header with 1-sec timeout (XMLHttpRequest)"); + +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + frame.onload = null; + let happened = false; + frame.contentWindow.fetch("/common/blank.html").then( + t.step_func_done(() => { + assert_true(happened); + }), + t.unreached_func("Fetch should have succeeded") + ); + frame.contentDocument.open(); + happened = true; + }); + frame.src = "resources/http-refresh.py?1"; +}, "document.open() does NOT abort documents that are queued for navigation through Refresh header with 1-sec timeout (fetch())"); + +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + frame.onload = null; + let happened = false; + const img = frame.contentDocument.createElement("img"); + img.src = new URL("resources/slow-png.py", document.URL); + img.onload = t.step_func_done(() => { + assert_true(happened); + }); + img.onerror = t.unreached_func("Image loading should not have errored"); + // The image fetch starts in a microtask, so let's be sure to test after + // the fetch has started. + t.step_timeout(() => { + frame.contentDocument.open(); + happened = true; + }); + }); + frame.src = "resources/http-refresh.py?4"; +}, "document.open() does NOT abort documents that are queued for navigation through Refresh header with 4-sec timeout (image loading)"); diff --git a/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-refresh-multisecond-meta.window.js b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-refresh-multisecond-meta.window.js new file mode 100644 index 00000000000..2895f959e55 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-refresh-multisecond-meta.window.js @@ -0,0 +1,69 @@ +// The following tests deal with the pragma and the +// `Refresh` header. The spec is still hazy on the precise behavior in those +// cases but we use https://github.com/whatwg/html/issues/4003 as a guideline. +// +// This is separate from abort-refresh-multisecond-header.window.js to avoid +// browser interventions that limit the number of connections in a tab. + +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + frame.onload = null; + let happened = false; + + const client = new frame.contentWindow.XMLHttpRequest(); + client.open("GET", "/common/blank.html"); + client.onload = t.step_func_done(() => { + assert_true(happened); + }); + client.onerror = t.unreached_func("XMLHttpRequest should have succeeded"); + client.onabort = t.unreached_func("XMLHttpRequest should have succeeded"); + client.ontimeout = t.unreached_func("XMLHttpRequest should have succeeded"); + client.send(); + + frame.contentDocument.open(); + happened = true; + }); + frame.src = "resources/meta-refresh.py?1"; +}, "document.open() does NOT abort documents that are queued for navigation through refresh with 1-sec timeout (XMLHttpRequest)"); + +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + frame.onload = null; + let happened = false; + frame.contentWindow.fetch("/common/blank.html").then( + t.step_func_done(() => { + assert_true(happened); + }), + t.unreached_func("Fetch should have succeeded") + ); + frame.contentDocument.open(); + happened = true; + }); + frame.src = "resources/meta-refresh.py?1"; +}, "document.open() does NOT abort documents that are queued for navigation through refresh with 1-sec timeout (fetch())"); + +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + frame.onload = null; + let happened = false; + const img = frame.contentDocument.createElement("img"); + img.src = new URL("resources/slow-png.py", document.URL); + img.onload = t.step_func_done(() => { + assert_true(happened); + }); + img.onerror = t.unreached_func("Image loading should not have errored"); + // The image fetch starts in a microtask, so let's be sure to test after + // the fetch has started. + t.step_timeout(() => { + frame.contentDocument.open(); + happened = true; + }); + }); + frame.src = "resources/meta-refresh.py?4"; +}, "document.open() does NOT abort documents that are queued for navigation through refresh with 4-sec timeout (image loading)"); diff --git a/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-while-navigating.window.js b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-while-navigating.window.js new file mode 100644 index 00000000000..e3efeffb8b3 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-while-navigating.window.js @@ -0,0 +1,179 @@ +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + frame.onload = null; + const client = new frame.contentWindow.XMLHttpRequest(); + client.open("GET", "/common/blank.html"); + // The abort event handler is called synchronously in Chrome but + // asynchronously in Firefox. See https://crbug.com/879620. + client.onabort = t.step_func_done(); + client.send(); + frame.contentWindow.location.href = new URL("resources/dummy.html", document.URL); + frame.contentDocument.open(); + }); + frame.src = "/common/blank.html"; +}, "document.open() aborts documents that are navigating through Location (XMLHttpRequest)"); + +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + frame.onload = null; + let happened = false; + frame.contentWindow.fetch("/common/blank.html").then( + t.unreached_func("Fetch should have been aborted"), + t.step_func_done(() => { + assert_true(happened); + })); + frame.contentWindow.location.href = new URL("resources/dummy.html", document.URL); + frame.contentDocument.open(); + happened = true; + }); + frame.src = "/common/blank.html"; +}, "document.open() aborts documents that are navigating through Location (fetch())"); + +// We cannot test for img element's error event for this test, as Firefox does +// not fire the event if the fetch is aborted while Chrome does. +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + frame.onload = null; + let happened = false; + const img = frame.contentDocument.createElement("img"); + img.src = new URL("resources/slow-png.py", document.URL); + img.onload = t.unreached_func("Image loading should not have succeeded"); + // The image fetch starts in a microtask, so let's be sure to test after + // the fetch has started. + t.step_timeout(() => { + frame.contentWindow.location.href = new URL("resources/dummy.html", document.URL); + frame.contentDocument.open(); + happened = true; + }); + // If 3 seconds have passed and the image has still not loaded, we consider + // it aborted. slow-png.py only sleeps for 2 wallclock seconds. + t.step_timeout(t.step_func_done(() => { + assert_true(happened); + }), 3000); + }); + frame.src = "/common/blank.html"; +}, "document.open() aborts documents that are navigating through Location (image loading)"); + +async_test(t => { + const div = document.body.appendChild(document.createElement("div")); + t.add_cleanup(() => div.remove()); + div.innerHTML = ""; + const frame = div.childNodes[0]; + const client = new frame.contentWindow.XMLHttpRequest(); + client.open("GET", "/common/blank.html"); + client.onabort = t.step_func_done(); + client.send(); + frame.contentDocument.open(); +}, "document.open() aborts documents that are navigating through iframe loading (XMLHttpRequest)"); + +async_test(t => { + const div = document.body.appendChild(document.createElement("div")); + t.add_cleanup(() => div.remove()); + div.innerHTML = ""; + const frame = div.childNodes[0]; + frame.contentWindow.fetch("/common/blank.html").then( + t.unreached_func("Fetch should have been aborted"), + t.step_func_done()); + frame.contentDocument.open(); +}, "document.open() aborts documents that are navigating through iframe loading (fetch())"); + +// We cannot test for img element's error event for this test, as Firefox does +// not fire the event if the fetch is aborted while Chrome does. +// +// We use /common/slow.py here as the source of the iframe, to prevent the +// situation where when document.open() is called the initial about:blank +// document has already become inactive. +async_test(t => { + const div = document.body.appendChild(document.createElement("div")); + t.add_cleanup(() => div.remove()); + div.innerHTML = ""; + const frame = div.childNodes[0]; + let happened = false; + const img = frame.contentDocument.createElement("img"); + img.src = new URL("resources/slow-png.py", document.URL); + img.onload = t.unreached_func("Image loading should not have succeeded"); + // The image fetch starts in a microtask, so let's be sure to test after + // the fetch has started. + t.step_timeout(() => { + frame.contentDocument.open(); + happened = true; + }); + // If 3 seconds have passed and the image has still not loaded, we consider + // it aborted. slow-png.py only sleeps for 2 wallclock seconds. + t.step_timeout(t.step_func_done(() => { + assert_true(happened); + }), 3000); +}, "document.open() aborts documents that are navigating through iframe loading (image loading)"); + +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + frame.onload = null; + const link = frame.contentDocument.body.appendChild(frame.contentDocument.createElement("a")); + link.href = new URL("resources/dummy.html", document.URL); + + const client = new frame.contentWindow.XMLHttpRequest(); + client.open("GET", "/common/blank.html"); + client.onabort = t.step_func_done(); + client.send(); + + link.click(); + frame.contentDocument.open(); + }); + frame.src = "/common/blank.html"; +}, "document.open() aborts documents that are queued for navigation through .click() (XMLHttpRequest)"); + +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + frame.onload = null; + const link = frame.contentDocument.body.appendChild(frame.contentDocument.createElement("a")); + link.href = new URL("resources/dummy.html", document.URL); + + frame.contentWindow.fetch("/common/blank.html").then( + t.unreached_func("Fetch should have been aborted"), + t.step_func_done()); + + link.click(); + frame.contentDocument.open(); + }); + frame.src = "/common/blank.html"; +}, "document.open() aborts documents that are queued for navigation through .click() (fetch())"); + +// We cannot test for img element's error event for this test, as Firefox does +// not fire the event if the fetch is aborted while Chrome does. +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + frame.onload = null; + const link = frame.contentDocument.body.appendChild(frame.contentDocument.createElement("a")); + link.href = new URL("resources/dummy.html", document.URL); + + let happened = false; + const img = frame.contentDocument.createElement("img"); + img.src = new URL("resources/slow-png.py", document.URL); + img.onload = t.unreached_func("Image loading should not have succeeded"); + // The image fetch starts in a microtask, so let's be sure to test after + // the fetch has started. + t.step_timeout(() => { + link.click(); + frame.contentDocument.open(); + happened = true; + }); + // If 3 seconds have passed and the image has still not loaded, we consider + // it aborted. slow-png.py only sleeps for 2 wallclock seconds. + t.step_timeout(t.step_func_done(() => { + assert_true(happened); + }), 3000); + }); + frame.src = "/common/blank.html"; +}, "document.open() aborts documents that are queued for navigation through .click() (image loading)"); diff --git a/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort.sub.window.js b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort.sub.window.js new file mode 100644 index 00000000000..b2f05cf056d --- /dev/null +++ b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort.sub.window.js @@ -0,0 +1,104 @@ +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + frame.onload = null; + let happened = false; + const client = new frame.contentWindow.XMLHttpRequest(); + client.open("GET", "/common/blank.html"); + client.onload = t.step_func_done(e => { + assert_true(happened); + }); + client.onerror = t.unreached_func("XMLHttpRequest should have succeeded"); + client.onabort = t.unreached_func("XMLHttpRequest should have succeeded"); + client.ontimeout = t.unreached_func("XMLHttpRequest should have succeeded"); + client.send(); + frame.contentDocument.open(); + happened = true; + }); + frame.src = "/common/blank.html"; +}, "document.open() does not abort documents that are not navigating (XMLHttpRequest)"); + +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + frame.onload = null; + let happened = false; + frame.contentWindow.fetch("/common/blank.html").then( + t.step_func_done(() => { + assert_true(happened); + }), + t.unreached_func("Fetch should have succeeded") + ); + frame.contentDocument.open(); + happened = true; + }); + frame.src = "/common/blank.html"; +}, "document.open() does not abort documents that are not navigating (fetch())"); + +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + frame.onload = null; + let happened = false; + const img = frame.contentDocument.createElement("img"); + img.src = new URL("resources/slow-png.py", document.URL); + img.onload = t.step_func_done(() => { + assert_true(happened); + }); + img.onerror = t.unreached_func("Image loading should not have errored"); + // The image fetch starts in a microtask, so let's be sure to test after + // the fetch has started. + t.step_timeout(() => { + frame.contentDocument.open(); + happened = true; + }); + }); + frame.src = "/common/blank.html"; +}, "document.open() does not abort documents that are not navigating (image loading)"); + +async_test(t => { + const __SERVER__NAME = "{{host}}"; + const __PORT = {{ports[ws][0]}}; + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + frame.onload = null; + let happened = false; + const ws = new frame.contentWindow.WebSocket(`ws://${__SERVER__NAME}:${__PORT}/echo`); + ws.onopen = t.step_func_done(() => { + assert_true(happened); + }); + ws.onclose = t.unreached_func("WebSocket fetch should have succeeded"); + ws.onerror = t.unreached_func("WebSocket should have no error"); + frame.contentDocument.open(); + happened = true; + }); + frame.src = "/common/blank.html"; +}, "document.open() does not abort documents that are not navigating (establish a WebSocket connection)"); + +// An already established WebSocket connection shouldn't be terminated during +// an "abort a document" anyway. Test just for completeness. +async_test(t => { + const __SERVER__NAME = "{{host}}"; + const __PORT = {{ports[ws][0]}}; + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + frame.onload = null; + let happened = false; + const ws = new frame.contentWindow.WebSocket(`ws://${__SERVER__NAME}:${__PORT}/echo`); + ws.onopen = t.step_func(() => { + t.step_timeout(t.step_func_done(() => { + assert_true(happened); + }), 100); + frame.contentDocument.open(); + happened = true; + }); + ws.onclose = t.unreached_func("WebSocket should not be closed"); + ws.onerror = t.unreached_func("WebSocket should have no error"); + }); + frame.src = "/common/blank.html"; +}, "document.open() does not abort documents that are not navigating (already established WebSocket connection)"); diff --git a/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/active.window.js b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/active.window.js new file mode 100644 index 00000000000..f96710999ad --- /dev/null +++ b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/active.window.js @@ -0,0 +1,98 @@ +function assertOpenIsEffective(doc, initialNodeCount) { + assert_equals(doc.childNodes.length, initialNodeCount); + + // Test direct document.open() call. + assert_equals(doc.open(), doc); + assert_equals(doc.childNodes.length, 0, "after open: no nodes in document"); + doc.write(""); + assert_equals(doc.childNodes.length, 1, "after write: doctype node in document"); + doc.close(); + assert_equals(doc.childNodes.length, 2, "after parser close: doctype node and an html element in document"); + + // Test implicit document.open() call through write(). Since we called + // doc.close() above, which sets the insertion point of the parser to + // undefined, document.write() will run the document open steps. + doc.write(); + assert_equals(doc.childNodes.length, 0, "after implicit open: no nodes in document"); + doc.write(""); + assert_equals(doc.childNodes.length, 1, "after write: doctype node in document"); + doc.close(); + assert_equals(doc.childNodes.length, 2, "after parser close: doctype node and an html element in document"); +} + +test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + assertOpenIsEffective(frame.contentDocument, 1); +}, "document.open() removes the document's children (fully active document)"); + +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + const childFrame = frame.contentDocument.querySelector("iframe"); + const childDoc = childFrame.contentDocument; + const childWin = childFrame.contentWindow; + + // Right now childDoc is still fully active. + + frame.onload = t.step_func_done(() => { + // Now childDoc is still active but no longer fully active. + assertOpenIsEffective(childDoc, 1); + }); + frame.src = "/common/blank.html"; + }); + frame.src = "resources/page-with-frame.html"; +}, "document.open() removes the document's children (active but not fully active document)"); + +test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + const doc = frame.contentDocument; + + // Right now the frame is connected and it has an active document. + frame.remove(); + + // Now the frame is no longer connected. Its document is no longer active. + assertOpenIsEffective(doc, 1); +}, "document.open() removes the document's children (non-active document with an associated Window object; frame is removed)"); + +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.src = "resources/dummy.html"; + + frame.onload = t.step_func(() => { + const firstDocument = frame.contentDocument; + // Right now the frame is connected and it has an active document. + + frame.onload = t.step_func_done(() => { + // Now even though the frame is still connected, its document is no + // longer active. + assert_not_equals(frame.contentDocument, firstDocument); + assertOpenIsEffective(firstDocument, 2); + }); + + frame.src = "/common/blank.html"; + }); +}, "document.open() removes the document's children (non-active document with an associated Window object; navigated away)"); + +test(t => { + const doc = document.implementation.createHTMLDocument(); + assertOpenIsEffective(doc, 2); +}, "document.open() removes the document's children (non-active document without an associated Window object; createHTMLDocument)"); + +test(t => { + const doc = new DOMParser().parseFromString("", "text/html"); + assertOpenIsEffective(doc, 1); +}, "document.open() removes the document's children (non-active document without an associated Window object; DOMParser)"); + +async_test(t => { + const xhr = new XMLHttpRequest(); + xhr.onload = t.step_func_done(() => { + assert_equals(xhr.status, 200); + assertOpenIsEffective(xhr.responseXML, 2); + }); + xhr.responseType = "document"; + xhr.open("GET", "resources/dummy.html"); + xhr.send(); +}, "document.open() removes the document's children (non-active document without an associated Window object; XMLHttpRequest)"); diff --git a/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/event-listeners.window.js b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/event-listeners.window.js index 58ec08f9ff1..df07124d811 100644 --- a/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/event-listeners.window.js +++ b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/event-listeners.window.js @@ -1,3 +1,7 @@ +// Many of the active-related test cases in this file came from +// active.window.js. However, we cannot test the "navigated away" non-active +// case right now due to https://github.com/whatwg/html/issues/3997. + test(t => { const frame = document.body.appendChild(document.createElement("iframe")), body = frame.contentDocument.body; @@ -36,6 +40,130 @@ test(t => { frame.contentDocument.close(); }, "Standard event listeners are to be removed from Window"); +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + const childFrame = frame.contentDocument.querySelector("iframe"); + const childWin = childFrame.contentWindow; + const childDoc = childFrame.contentDocument; + const childBody = childDoc.body; + + // Right now childDoc is still fully active. + + frame.onload = t.step_func_done(() => { + // Focus on the current window so that the frame's window is blurred. + window.focus(); + // Now childDoc is still active but no longer fully active. + childWin.addEventListener("focus", t.unreached_func("window event listener not removed")); + childBody.onfocus = t.unreached_func("body event listener not removed"); + + childDoc.open(); + assert_equals(childBody.onfocus, null); + + // Now try to fire the focus event two different ways. + childWin.focus(); + const focusEvent = new FocusEvent("focus"); + childWin.dispatchEvent(focusEvent); + childDoc.close(); + }); + frame.src = "/common/blank.html"; + }); + frame.src = "resources/page-with-frame.html"; +}, "Standard event listeners are to be removed from Window for an active but not fully active document"); + +test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + const win = frame.contentWindow; + const doc = frame.contentDocument; + const body = doc.body; + + // Right now the frame is connected and it has an active document. + frame.remove(); + + win.addEventListener("focus", t.unreached_func("window event listener not removed")); + body.onfocus = t.unreached_func("body event listener not removed"); + doc.open(); + assert_equals(body.onfocus, null); + + // Now try to fire the focus event two different ways. + win.focus(); + const focusEvent = new FocusEvent("focus"); + win.dispatchEvent(focusEvent); + doc.close(); +}, "Standard event listeners are to be removed from Window for a non-active document that is the associated Document of a Window (frame is removed)"); + +test(t => { + let winHappened = 0; + const winListener = t.step_func(() => { winHappened++; }); + window.addEventListener("focus", winListener); + t.add_cleanup(() => { window.removeEventListener("focus", winListener); }); + + let bodyHappened = 0; + const bodyListener = t.step_func(() => { bodyHappened++; }); + document.body.onfocus = bodyListener; + t.add_cleanup(() => { document.body.onfocus = null; }); + + const doc = document.implementation.createHTMLDocument(); + doc.open(); + + const focusEvent = new FocusEvent("focus"); + window.dispatchEvent(focusEvent); + + assert_equals(winHappened, 1); + assert_equals(bodyHappened, 1); +}, "Standard event listeners are NOT to be removed from Window for a Window-less document (createHTMLDocument)"); + +test(t => { + let winHappened = 0; + const winListener = t.step_func(() => { winHappened++; }); + window.addEventListener("focus", winListener); + t.add_cleanup(() => { window.removeEventListener("focus", winListener); }); + + let bodyHappened = 0; + const bodyListener = t.step_func(() => { bodyHappened++; }); + document.body.onfocus = bodyListener; + t.add_cleanup(() => { document.body.onfocus = null; }); + + const doc = new DOMParser().parseFromString("", "text/html"); + doc.open(); + + const focusEvent = new FocusEvent("focus"); + window.dispatchEvent(focusEvent); + + assert_equals(winHappened, 1); + assert_equals(bodyHappened, 1); +}, "Standard event listeners are NOT to be removed from Window for a Window-less document (DOMParser)"); + +async_test(t => { + const xhr = new XMLHttpRequest(); + xhr.onload = t.step_func_done(() => { + assert_equals(xhr.status, 200); + const doc = xhr.responseXML; + + let winHappened = 0; + const winListener = t.step_func(() => { winHappened++; }); + window.addEventListener("focus", winListener); + t.add_cleanup(() => { window.removeEventListener("focus", winListener); }); + + let bodyHappened = 0; + const bodyListener = t.step_func(() => { bodyHappened++; }); + document.body.onfocus = bodyListener; + t.add_cleanup(() => { document.body.onfocus = null; }); + + doc.open(); + + const focusEvent = new FocusEvent("focus"); + window.dispatchEvent(focusEvent); + + assert_equals(winHappened, 1); + assert_equals(bodyHappened, 1); + }); + xhr.responseType = "document"; + xhr.open("GET", "resources/dummy.html"); + xhr.send(); +}, "Standard event listeners are NOT to be removed from Window for a Window-less document (XMLHttpRequest)"); + test(t => { const frame = document.body.appendChild(document.createElement("iframe")); t.add_cleanup(() => frame.remove()); @@ -45,6 +173,76 @@ test(t => { frame.contentDocument.close(); }, "Custom event listeners are to be removed from Window"); +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func(() => { + const childFrame = frame.contentDocument.querySelector("iframe"); + const childDoc = childFrame.contentDocument; + const childWin = childFrame.contentWindow; + + // Right now childDoc is still fully active. + + frame.onload = t.step_func_done(() => { + // Now childDoc is still active but no longer fully active. + childWin.addEventListener("x", t.unreached_func("window event listener not removed")); + childDoc.open(); + childWin.dispatchEvent(new Event("x")); + childDoc.close(); + }); + frame.src = "/common/blank.html"; + }); + frame.src = "resources/page-with-frame.html"; +}, "Custom event listeners are to be removed from Window for an active but not fully active document"); + +test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + const win = frame.contentWindow; + const doc = frame.contentDocument; + + // Right now the frame is connected and it has an active document. + frame.remove(); + + win.addEventListener("x", t.unreached_func("window event listener not removed")); + doc.open(); + win.dispatchEvent(new Event("x")); + doc.close(); +}, "Custom event listeners are to be removed from Window for a non-active document that is the associated Document of a Window (frame is removed)"); + +test(t => { + const doc = document.implementation.createHTMLDocument(); + let happened = false; + window.addEventListener("createHTMLDocumentTest", t.step_func(() => { happened = true; })); + doc.open(); + window.dispatchEvent(new Event("createHTMLDocumentTest")); + assert_true(happened); +}, "Custom event listeners are NOT to be removed from Window for a Window-less document (createHTMLDocument)"); + +test(t => { + const doc = new DOMParser().parseFromString("", "text/html"); + let happened = false; + window.addEventListener("DOMParserTest", t.step_func(() => { happened = true; })); + doc.open(); + window.dispatchEvent(new Event("DOMParserTest")); + assert_true(happened); +}, "Custom event listeners are NOT to be removed from Window for a Window-less document (DOMParser)"); + +async_test(t => { + const xhr = new XMLHttpRequest(); + xhr.onload = t.step_func_done(() => { + assert_equals(xhr.status, 200); + const doc = xhr.responseXML; + let happened = false; + window.addEventListener("XHRTest", t.step_func(() => { happened = true; })); + doc.open(); + window.dispatchEvent(new Event("XHRTest")); + assert_true(happened); + }); + xhr.responseType = "document"; + xhr.open("GET", "resources/dummy.html"); + xhr.send(); +}, "Custom event listeners are NOT to be removed from Window for a Window-less document (XMLHttpRequest)"); + test(t => { const frame = document.body.appendChild(document.createElement("iframe")), body = frame.contentDocument.body; diff --git a/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/history.window.js b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/history.window.js new file mode 100644 index 00000000000..0134da24f07 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/history.window.js @@ -0,0 +1,29 @@ +// Historically, document.open() created an entry in the session history so +// that the original page could be seen by going back. Test that this behavior +// no longer occurs. +// +// This test uses window.open() for variety, as most other tests in this +// directory use document.open(). An diff --git a/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/slow-png.py b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/slow-png.py new file mode 100644 index 00000000000..5fa2fd9a9d8 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/slow-png.py @@ -0,0 +1,8 @@ +from base64 import decodestring +import time + +png_response = decodestring('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVR4nGNiAAAABgADNjd8qAAAAABJRU5ErkJggg==') + +def main(request, response): + time.sleep(2) + return 200, [], png_response diff --git a/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/url-frame.html b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/url-frame.html new file mode 100644 index 00000000000..be483ff0aea --- /dev/null +++ b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/url-frame.html @@ -0,0 +1,9 @@ + diff --git a/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/url-fragment.window.js b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/url-fragment.window.js new file mode 100644 index 00000000000..0c528935b52 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/url-fragment.window.js @@ -0,0 +1,26 @@ +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")), + urlSansHash = document.URL; + t.add_cleanup(() => { frame.remove(); }); + assert_equals(frame.contentDocument.URL, "about:blank"); + assert_equals(frame.contentWindow.location.href, "about:blank"); + self.onhashchange = t.step_func_done(() => { + frame.contentDocument.open(); + assert_equals(frame.contentDocument.URL, urlSansHash); + assert_equals(frame.contentWindow.location.href, urlSansHash); + }); + self.location.hash = "heya"; +}, "document.open() and document's URL containing a fragment (entry is not relevant)"); + +window.testDone = undefined; +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")) + t.add_cleanup(() => { frame.remove(); }); + frame.src = "resources/url-frame.html#heya"; + window.testDone = t.step_func_done((beforeURL, afterURL) => { + assert_equals(beforeURL, frame.src); + assert_equals(afterURL, frame.src); + assert_equals(frame.contentDocument.URL, frame.src); + assert_equals(frame.contentWindow.location.href, frame.src); + }); +}, "document.open() and document's URL containing a fragment (entry is relevant)"); diff --git a/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/url.window.js b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/url.window.js index 282e58e9c38..4e7c649f453 100644 --- a/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/url.window.js +++ b/tests/wpt/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/url.window.js @@ -3,7 +3,7 @@ test(t => { t.add_cleanup(() => frame.remove()); assert_equals(frame.contentDocument.URL, "about:blank"); assert_equals(frame.contentWindow.location.href, "about:blank"); - frame.contentDocument.open(); + assert_equals(frame.contentDocument.open(), frame.contentDocument); assert_equals(frame.contentDocument.URL, document.URL); assert_equals(frame.contentWindow.location.href, document.URL); }, "document.open() changes document's URL (fully active document)"); @@ -26,7 +26,7 @@ async_test(t => { frame.onload = t.step_func_done(() => { // Now childDoc is still active but no longer fully active. - childDoc.open(); + assert_equals(childDoc.open(), childDoc); assert_equals(childDoc.URL, blankURL); assert_equals(childWin.location.href, blankURL); }); @@ -40,6 +40,9 @@ test(t => { t.add_cleanup(() => frame.remove()); const doc = frame.contentDocument; + // We do not test for win.location.href in this test due to + // https://github.com/whatwg/html/issues/3959. + // Right now the frame is connected and it has an active document. assert_equals(doc.URL, "about:blank"); @@ -55,6 +58,9 @@ async_test(t => { const frame = document.createElement("iframe"); t.add_cleanup(() => frame.remove()); + // We do not test for win.location.href in this test due to + // https://github.com/whatwg/html/issues/3959. + frame.onload = t.step_func(() => { const doc = frame.contentDocument; // Right now the frame is connected and it has an active document. diff --git a/tests/wpt/web-platform-tests/dom/inert/inert-does-not-match-disabled-selector.html b/tests/wpt/web-platform-tests/inert/inert-does-not-match-disabled-selector.tentative.html similarity index 100% rename from tests/wpt/web-platform-tests/dom/inert/inert-does-not-match-disabled-selector.html rename to tests/wpt/web-platform-tests/inert/inert-does-not-match-disabled-selector.tentative.html diff --git a/tests/wpt/web-platform-tests/html/editing/focus/inert/inert-in-shadow-dom.html b/tests/wpt/web-platform-tests/inert/inert-in-shadow-dom.tentative.html similarity index 100% rename from tests/wpt/web-platform-tests/html/editing/focus/inert/inert-in-shadow-dom.html rename to tests/wpt/web-platform-tests/inert/inert-in-shadow-dom.tentative.html diff --git a/tests/wpt/web-platform-tests/html/editing/focus/inert/inert-inlines.html b/tests/wpt/web-platform-tests/inert/inert-inlines.tentative.html similarity index 100% rename from tests/wpt/web-platform-tests/html/editing/focus/inert/inert-inlines.html rename to tests/wpt/web-platform-tests/inert/inert-inlines.tentative.html diff --git a/tests/wpt/web-platform-tests/html/editing/focus/inert/inert-label-focus.html b/tests/wpt/web-platform-tests/inert/inert-label-focus.tentative.html similarity index 100% rename from tests/wpt/web-platform-tests/html/editing/focus/inert/inert-label-focus.html rename to tests/wpt/web-platform-tests/inert/inert-label-focus.tentative.html diff --git a/tests/wpt/web-platform-tests/html/editing/focus/inert/inert-node-is-uneditable.html b/tests/wpt/web-platform-tests/inert/inert-node-is-uneditable.tentative.html similarity index 100% rename from tests/wpt/web-platform-tests/html/editing/focus/inert/inert-node-is-uneditable.html rename to tests/wpt/web-platform-tests/inert/inert-node-is-uneditable.tentative.html diff --git a/tests/wpt/web-platform-tests/html/editing/focus/inert/inert-node-is-unfocusable.html b/tests/wpt/web-platform-tests/inert/inert-node-is-unfocusable.tentative.html similarity index 100% rename from tests/wpt/web-platform-tests/html/editing/focus/inert/inert-node-is-unfocusable.html rename to tests/wpt/web-platform-tests/inert/inert-node-is-unfocusable.tentative.html diff --git a/tests/wpt/web-platform-tests/html/editing/focus/inert/inert-node-is-unselectable.html b/tests/wpt/web-platform-tests/inert/inert-node-is-unselectable.tentative.html similarity index 100% rename from tests/wpt/web-platform-tests/html/editing/focus/inert/inert-node-is-unselectable.html rename to tests/wpt/web-platform-tests/inert/inert-node-is-unselectable.tentative.html diff --git a/tests/wpt/web-platform-tests/infrastructure/META.yml b/tests/wpt/web-platform-tests/infrastructure/META.yml index 59b44af3351..c1d3b0c9ec4 100644 --- a/tests/wpt/web-platform-tests/infrastructure/META.yml +++ b/tests/wpt/web-platform-tests/infrastructure/META.yml @@ -2,4 +2,3 @@ suggested_reviewers: - gsnedders - jgraham - jugglinmike - - kereliuk diff --git a/tests/wpt/web-platform-tests/infrastructure/reftest/reftest_and_mismatch.html b/tests/wpt/web-platform-tests/infrastructure/reftest/reftest_and_mismatch.html new file mode 100644 index 00000000000..b6b4847473d --- /dev/null +++ b/tests/wpt/web-platform-tests/infrastructure/reftest/reftest_and_mismatch.html @@ -0,0 +1,5 @@ +Reftest chain with mismatch and mismatch + + diff --git a/tests/wpt/web-platform-tests/infrastructure/reftest/reftest_and_mismatch_0.html b/tests/wpt/web-platform-tests/infrastructure/reftest/reftest_and_mismatch_0.html new file mode 100644 index 00000000000..f84ce6a13aa --- /dev/null +++ b/tests/wpt/web-platform-tests/infrastructure/reftest/reftest_and_mismatch_0.html @@ -0,0 +1,5 @@ +Reftest chain with mismatch and mismatch + + diff --git a/tests/wpt/web-platform-tests/infrastructure/reftest/reftest_and_mismatch_1.html b/tests/wpt/web-platform-tests/infrastructure/reftest/reftest_and_mismatch_1.html new file mode 100644 index 00000000000..05e905adafc --- /dev/null +++ b/tests/wpt/web-platform-tests/infrastructure/reftest/reftest_and_mismatch_1.html @@ -0,0 +1,4 @@ +Reftest chain with match and mismatch + diff --git a/tests/wpt/web-platform-tests/input-device-capabilities/idlharness.window.js b/tests/wpt/web-platform-tests/input-device-capabilities/idlharness.window.js new file mode 100644 index 00000000000..a57ae829936 --- /dev/null +++ b/tests/wpt/web-platform-tests/input-device-capabilities/idlharness.window.js @@ -0,0 +1,14 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +'use strict'; + +idl_test( + ['InputDeviceCapabilities'], + ['uievents', 'dom'], + idl_array => { + idl_array.add_objects({ + InputDeviceCapabilities: ["new InputDeviceCapabilities"], + }); + } +); diff --git a/tests/wpt/web-platform-tests/input-device-capabilities/interfaces.html b/tests/wpt/web-platform-tests/input-device-capabilities/interfaces.html deleted file mode 100644 index 178ce5aa892..00000000000 --- a/tests/wpt/web-platform-tests/input-device-capabilities/interfaces.html +++ /dev/null @@ -1,24 +0,0 @@ - -Input Device Capabilities IDL tests - - - - - - diff --git a/tests/wpt/web-platform-tests/interfaces/background-fetch.idl b/tests/wpt/web-platform-tests/interfaces/background-fetch.idl index 6957604e7df..130d5d825a5 100644 --- a/tests/wpt/web-platform-tests/interfaces/background-fetch.idl +++ b/tests/wpt/web-platform-tests/interfaces/background-fetch.idl @@ -19,11 +19,10 @@ interface BackgroundFetchManager { Promise fetch(DOMString id, (RequestInfo or sequence) requests, optional BackgroundFetchOptions options); Promise get(DOMString id); Promise> getIds(); - // TODO: in future this should become an async iterator for BackgroundFetchRegistration objects }; dictionary BackgroundFetchUIOptions { - sequence icons = []; + sequence icons = []; DOMString title = ""; }; @@ -31,14 +30,6 @@ dictionary BackgroundFetchOptions : BackgroundFetchUIOptions { unsigned long long downloadTotal = 0; }; -// This is taken from https://w3c.github.io/manifest/#icons-member. -// This definition should probably be moved somewhere more general. -dictionary IconDefinition { - DOMString src; - DOMString sizes = ""; - DOMString type = ""; -}; - [Exposed=(Window,Worker)] interface BackgroundFetchRegistration : EventTarget { readonly attribute DOMString id; @@ -46,8 +37,9 @@ interface BackgroundFetchRegistration : EventTarget { readonly attribute unsigned long long uploaded; readonly attribute unsigned long long downloadTotal; readonly attribute unsigned long long downloaded; - readonly attribute BackgroundFetchState state; + readonly attribute BackgroundFetchResult result; readonly attribute BackgroundFetchFailureReason failureReason; + readonly attribute boolean recordsAvailable; attribute EventHandler onprogress; @@ -56,9 +48,10 @@ interface BackgroundFetchRegistration : EventTarget { Promise> matchAll(optional RequestInfo request, optional CacheQueryOptions options); }; -enum BackgroundFetchState { "pending", "success", "failure" }; +enum BackgroundFetchResult { "", "success", "failure" }; enum BackgroundFetchFailureReason { + // The background fetch has not completed yet, or was successful. "", // The operation was aborted by the user, or abort() was called. "aborted", @@ -70,14 +63,13 @@ enum BackgroundFetchFailureReason { // Storage quota was reached during the operation. "quota-exceeded", // The provided downloadTotal was exceeded. - "total-download-exceeded" + "download-total-exceeded" }; [Exposed=(Window,Worker)] interface BackgroundFetchRecord { readonly attribute Request request; readonly attribute Promise responseReady; - // TODO: In future this will include a fetch observer }; [Constructor(DOMString type, BackgroundFetchEventInit init), Exposed=ServiceWorker] diff --git a/tests/wpt/web-platform-tests/interfaces/cookie-store.idl b/tests/wpt/web-platform-tests/interfaces/cookie-store.idl index 454da38b182..d872b7aadb2 100644 --- a/tests/wpt/web-platform-tests/interfaces/cookie-store.idl +++ b/tests/wpt/web-platform-tests/interfaces/cookie-store.idl @@ -1,48 +1,31 @@ -// https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md +// GENERATED CONTENT - DO NOT EDIT +// Content was automatically extracted by Reffy into reffy-reports +// (https://github.com/tidoust/reffy-reports) +// Source: Cookie Store API (https://wicg.github.io/cookie-store/) -enum CookieSameSite { - "strict", - "lax", - "unrestricted" -}; +[Exposed=(ServiceWorker,Window), + SecureContext] +interface CookieStore : EventTarget { + Promise get(USVString name); + Promise get(optional CookieStoreGetOptions options); -dictionary CookieListItem { - required USVString name; - USVString value; - USVString? domain = null; - USVString path = "/"; - DOMTimeStamp? expires = null; - boolean secure = true; - CookieSameSite sameSite = "strict"; -}; + Promise getAll(USVString name); + Promise getAll(optional CookieStoreGetOptions options); -typedef sequence CookieList; + Promise set(USVString name, USVString value, + optional CookieStoreSetOptions options); + Promise set(CookieStoreSetExtraOptions options); -dictionary CookieChangeEventInit : EventInit { - CookieList changed; - CookieList deleted; -}; + Promise delete(USVString name); + Promise delete(CookieStoreDeleteOptions options); -[ - Exposed=Window, - SecureContext, - Constructor(DOMString type, optional CookieChangeEventInit eventInitDict) -] interface CookieChangeEvent : Event { - readonly attribute CookieList changed; - readonly attribute CookieList deleted; -}; + [Exposed=ServiceWorker] + Promise subscribeToChanges(sequence subscriptions); -dictionary ExtendableCookieChangeEventInit : ExtendableEventInit { - CookieList changed; - CookieList deleted; -}; + [Exposed=ServiceWorker] + Promise> getChangeSubscriptions(); -[ - Exposed=ServiceWorker, - Constructor(DOMString type, optional ExtendableCookieChangeEventInit eventInitDict) -] interface ExtendableCookieChangeEvent : ExtendableEvent { - readonly attribute CookieList changed; - readonly attribute CookieList deleted; + attribute EventHandler onchange; }; enum CookieMatchType { @@ -50,20 +33,18 @@ enum CookieMatchType { "starts-with" }; -dictionary CookieStoreDeleteOptions { - required USVString name; - USVString? domain = null; - USVString path = "/"; - boolean secure = true; - CookieSameSite sameSite = "strict"; -}; - dictionary CookieStoreGetOptions { USVString name; USVString url; CookieMatchType matchType = "equals"; }; +enum CookieSameSite { + "strict", + "lax", + "unrestricted" +}; + dictionary CookieStoreSetOptions { DOMTimeStamp? expires = null; USVString? domain = null; @@ -77,27 +58,35 @@ dictionary CookieStoreSetExtraOptions : CookieStoreSetOptions { required USVString value; }; -[ - Exposed=(ServiceWorker,Window), - SecureContext -] interface CookieStore : EventTarget { - Promise get(USVString name); - Promise get(optional CookieStoreGetOptions options); +dictionary CookieStoreDeleteOptions { + required USVString name; + USVString? domain = null; + USVString path = "/"; +}; - Promise getAll(USVString name); - Promise getAll(optional CookieStoreGetOptions options); +dictionary CookieListItem { + required USVString name; + USVString value; + USVString? domain = null; + USVString path = "/"; + DOMTimeStamp? expires = null; + boolean secure = true; + CookieSameSite sameSite = "strict"; +}; - Promise set(USVString name, USVString value, optional CookieStoreSetOptions options); - Promise set(CookieStoreSetExtraOptions options); +typedef sequence CookieList; - Promise delete(USVString name); - Promise delete(CookieStoreDeleteOptions options); +[Exposed=(ServiceWorker,Window), + SecureContext, + Constructor(DOMString type, optional CookieChangeEventInit eventInitDict)] +interface CookieChangeEvent : Event { + readonly attribute CookieList changed; + readonly attribute CookieList deleted; +}; - [Exposed=ServiceWorker] Promise subscribeToChanges(sequence subscriptions); - - [Exposed=ServiceWorker] Promise> getChangeSubscriptions(); - - [Exposed=Window] attribute EventHandler onchange; +dictionary CookieChangeEventInit : EventInit { + CookieList changed; + CookieList deleted; }; [SecureContext] @@ -107,5 +96,6 @@ partial interface Window { partial interface ServiceWorkerGlobalScope { [Replaceable, SameObject] readonly attribute CookieStore cookieStore; + attribute EventHandler oncookiechange; }; diff --git a/tests/wpt/web-platform-tests/interfaces/cssom-view.idl b/tests/wpt/web-platform-tests/interfaces/cssom-view.idl index 0213a4090c7..2b5b381dfa4 100644 --- a/tests/wpt/web-platform-tests/interfaces/cssom-view.idl +++ b/tests/wpt/web-platform-tests/interfaces/cssom-view.idl @@ -3,7 +3,7 @@ // (https://github.com/tidoust/reffy-reports) // Source: CSSOM View Module (https://drafts.csswg.org/cssom-view/) -enum ScrollBehavior { "auto", "instant", "smooth" }; +enum ScrollBehavior { "auto", "smooth" }; dictionary ScrollOptions { ScrollBehavior behavior = "auto"; diff --git a/tests/wpt/web-platform-tests/interfaces/encoding.idl b/tests/wpt/web-platform-tests/interfaces/encoding.idl index 7d55ce7e190..b805363c534 100644 --- a/tests/wpt/web-platform-tests/interfaces/encoding.idl +++ b/tests/wpt/web-platform-tests/interfaces/encoding.idl @@ -3,6 +3,12 @@ // (https://github.com/tidoust/reffy-reports) // Source: Encoding Standard (https://encoding.spec.whatwg.org/) +interface mixin TextDecoderCommon { + readonly attribute DOMString encoding; + readonly attribute boolean fatal; + readonly attribute boolean ignoreBOM; +}; + dictionary TextDecoderOptions { boolean fatal = false; boolean ignoreBOM = false; @@ -15,14 +21,36 @@ dictionary TextDecodeOptions { [Constructor(optional DOMString label = "utf-8", optional TextDecoderOptions options), Exposed=(Window,Worker)] interface TextDecoder { - readonly attribute DOMString encoding; - readonly attribute boolean fatal; - readonly attribute boolean ignoreBOM; USVString decode(optional BufferSource input, optional TextDecodeOptions options); }; +TextDecoder includes TextDecoderCommon; + +interface mixin TextEncoderCommon { + readonly attribute DOMString encoding; +}; + [Constructor, Exposed=(Window,Worker)] interface TextEncoder { - readonly attribute DOMString encoding; [NewObject] Uint8Array encode(optional USVString input = ""); }; +TextEncoder includes TextEncoderCommon; + +interface mixin GenericTransformStream { + readonly attribute ReadableStream readable; + readonly attribute WritableStream writable; +}; + +[Constructor(optional DOMString label = "utf-8", optional TextDecoderOptions options), + Exposed=(Window,Worker)] +interface TextDecoderStream { +}; +TextDecoderStream includes TextDecoderCommon; +TextDecoderStream includes GenericTransformStream; + +[Constructor, + Exposed=(Window,Worker)] +interface TextEncoderStream { +}; +TextEncoderStream includes TextEncoderCommon; +TextEncoderStream includes GenericTransformStream; diff --git a/tests/wpt/web-platform-tests/interfaces/intersection-observer.idl b/tests/wpt/web-platform-tests/interfaces/intersection-observer.idl index b48e1cbab37..ffda8f5c64d 100644 --- a/tests/wpt/web-platform-tests/interfaces/intersection-observer.idl +++ b/tests/wpt/web-platform-tests/interfaces/intersection-observer.idl @@ -20,7 +20,7 @@ interface IntersectionObserver { [Constructor(IntersectionObserverEntryInit intersectionObserverEntryInit)] interface IntersectionObserverEntry { readonly attribute DOMHighResTimeStamp time; - readonly attribute DOMRectReadOnly rootBounds; + readonly attribute DOMRectReadOnly? rootBounds; readonly attribute DOMRectReadOnly boundingClientRect; readonly attribute DOMRectReadOnly intersectionRect; readonly attribute boolean isIntersecting; @@ -30,7 +30,7 @@ interface IntersectionObserverEntry { dictionary IntersectionObserverEntryInit { required DOMHighResTimeStamp time; - required DOMRectInit rootBounds; + required DOMRectInit? rootBounds; required DOMRectInit boundingClientRect; required DOMRectInit intersectionRect; required boolean isIntersecting; diff --git a/tests/wpt/web-platform-tests/interfaces/payment-handler.idl b/tests/wpt/web-platform-tests/interfaces/payment-handler.idl index 9f10d7e7019..b19a7302dba 100644 --- a/tests/wpt/web-platform-tests/interfaces/payment-handler.idl +++ b/tests/wpt/web-platform-tests/interfaces/payment-handler.idl @@ -46,7 +46,6 @@ interface CanMakePaymentEvent : ExtendableEvent { readonly attribute USVString topOrigin; readonly attribute USVString paymentRequestOrigin; readonly attribute FrozenArray methodData; - readonly attribute FrozenArray modifiers; void respondWith(Promise canMakePaymentResponse); }; @@ -54,7 +53,6 @@ dictionary CanMakePaymentEventInit : ExtendableEventInit { USVString topOrigin; USVString paymentRequestOrigin; sequence methodData; - sequence modifiers; }; partial interface ServiceWorkerGlobalScope { diff --git a/tests/wpt/web-platform-tests/interfaces/payment-request.idl b/tests/wpt/web-platform-tests/interfaces/payment-request.idl index 3717d79476d..05790c7d76d 100644 --- a/tests/wpt/web-platform-tests/interfaces/payment-request.idl +++ b/tests/wpt/web-platform-tests/interfaces/payment-request.idl @@ -18,6 +18,7 @@ interface PaymentRequest : EventTarget { readonly attribute DOMString? shippingOption; readonly attribute PaymentShippingType? shippingType; + attribute EventHandler onmerchantvalidation; attribute EventHandler onshippingaddresschange; attribute EventHandler onshippingoptionchange; attribute EventHandler onpaymentmethodchange; @@ -89,6 +90,7 @@ interface PaymentAddress { readonly attribute DOMString city; readonly attribute DOMString country; readonly attribute DOMString dependentLocality; + // "languageCode" is a feature at risk readonly attribute DOMString languageCode; readonly attribute DOMString organization; readonly attribute DOMString phone; @@ -177,6 +179,17 @@ dictionary PayerErrorFields { DOMString phone; }; +[Constructor(DOMString type, optional MerchantValidationEventInit eventInitDict), +SecureContext, Exposed=Window] +interface MerchantValidationEvent : Event { + readonly attribute USVString validationURL; + void complete(Promise merchantSessionPromise); +}; + +dictionary MerchantValidationEventInit : EventInit { + USVString validationURL = ""; +}; + [Constructor(DOMString type, optional PaymentMethodChangeEventInit eventInitDict), SecureContext, Exposed=Window] interface PaymentMethodChangeEvent : PaymentRequestUpdateEvent { readonly attribute DOMString methodName; @@ -184,8 +197,8 @@ interface PaymentMethodChangeEvent : PaymentRequestUpdateEvent { }; dictionary PaymentMethodChangeEventInit : PaymentRequestUpdateEventInit { - required DOMString methodName; - object? methodDetails; + DOMString methodName = ""; + object? methodDetails = null; }; [Constructor(DOMString type, optional PaymentRequestUpdateEventInit eventInitDict), SecureContext, Exposed=Window] diff --git a/tests/wpt/web-platform-tests/interfaces/trusted-types.tentative.idl b/tests/wpt/web-platform-tests/interfaces/trusted-types.tentative.idl new file mode 100644 index 00000000000..a3a635b9927 --- /dev/null +++ b/tests/wpt/web-platform-tests/interfaces/trusted-types.tentative.idl @@ -0,0 +1,53 @@ +// https://github.com/wicg/trusted-types + +typedef (DOMString or TrustedHTML) HTMLString; +typedef (DOMString or TrustedScript) ScriptString; +typedef (DOMString or TrustedScriptURL) ScriptURLString; +typedef (USVString or TrustedURL) URLString; + +[Exposed=Window] +interface TrustedHTML { + stringifier; +}; + +[Exposed=Window] +interface TrustedScript { + stringifier; +}; + +[Exposed=Window] +interface TrustedScriptURL { + stringifier; +}; + +[Exposed=Window] +interface TrustedURL { + stringifier; +}; + +[Exposed=Window] +interface TrustedTypePolicyFactory { + TrustedTypePolicy createPolicy(DOMString policyName, TrustedTypePolicyOptions policyOptions); + // All the policy object names that have been created + sequence getPolicyNames(); +}; + +[Exposed=Window] +interface TrustedTypePolicy { + readonly attribute DOMString name; + TrustedHTML createHTML(DOMString input); + TrustedScript createScript(DOMString input); + TrustedScriptURL createScriptURL(DOMString input); + TrustedURL createURL(DOMString input); +}; + +dictionary TrustedTypePolicyOptions { + CreateHTMLCallback createHTML; + CreateScriptCallback createScript; + CreateURLCallback createScriptURL; + CreateURLCallback createURL; +}; + +callback CreateHTMLCallback = DOMString (DOMString input); +callback CreateScriptCallback = DOMString (DOMString input); +callback CreateURLCallback = USVString (DOMString input); diff --git a/tests/wpt/web-platform-tests/interfaces/wai-aria.idl b/tests/wpt/web-platform-tests/interfaces/wai-aria.idl new file mode 100644 index 00000000000..c6ea9591f8d --- /dev/null +++ b/tests/wpt/web-platform-tests/interfaces/wai-aria.idl @@ -0,0 +1,59 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content was automatically extracted by Reffy into reffy-reports +// (https://github.com/tidoust/reffy-reports) +// Source: Accessible Rich Internet Applications (WAI-ARIA) 1.2 (https://w3c.github.io/aria/) + +interface mixin AccessibilityRole { + attribute DOMString? role; +}; +Element includes AccessibilityRole; + +interface mixin AriaAttributes { + attribute DOMString? ariaActiveDescendant; + attribute DOMString? ariaAtomic; + attribute DOMString? ariaAutoComplete; + attribute DOMString? ariaBusy; + attribute DOMString? ariaChecked; + attribute DOMString? ariaColCount; + attribute DOMString? ariaColIndex; + attribute DOMString? ariaColSpan; + attribute DOMString? ariaControls; + attribute DOMString? ariaCurrent; + attribute DOMString? ariaDescribedBy; + attribute DOMString? ariaDetails; + attribute DOMString? ariaDisabled; + attribute DOMString? ariaErrorMessage; + attribute DOMString? ariaExpanded; + attribute DOMString? ariaFlowTo; + attribute DOMString? ariaHasPopup; + attribute DOMString? ariaHidden; + attribute DOMString? ariaInvalid; + attribute DOMString? ariaKeyShortcuts; + attribute DOMString? ariaLabel; + attribute DOMString? ariaLabelledBy; + attribute DOMString? ariaLevel; + attribute DOMString? ariaLive; + attribute DOMString? ariaModal; + attribute DOMString? ariaMultiLine; + attribute DOMString? ariaMultiSelectable; + attribute DOMString? ariaOrientation; + attribute DOMString? ariaOwns; + attribute DOMString? ariaPlaceholder; + attribute DOMString? ariaPosInSet; + attribute DOMString? ariaPressed; + attribute DOMString? ariaReadOnly; + attribute DOMString? ariaRelevant; + attribute DOMString? ariaRequired; + attribute DOMString? ariaRoleDescription; + attribute DOMString? ariaRowCount; + attribute DOMString? ariaRowIndex; + attribute DOMString? ariaRowSpan; + attribute DOMString? ariaSelected; + attribute DOMString? ariaSetSize; + attribute DOMString? ariaSort; + attribute DOMString? ariaValueMax; + attribute DOMString? ariaValueMin; + attribute DOMString? ariaValueNow; + attribute DOMString? ariaValueText; +}; +Element includes AriaAttributes; diff --git a/tests/wpt/web-platform-tests/interfaces/wasm-js-api.idl b/tests/wpt/web-platform-tests/interfaces/wasm-js-api.idl index 04c817dcb11..6de14fb8f08 100644 --- a/tests/wpt/web-platform-tests/interfaces/wasm-js-api.idl +++ b/tests/wpt/web-platform-tests/interfaces/wasm-js-api.idl @@ -41,9 +41,9 @@ dictionary ModuleImportDescriptor { [LegacyNamespace=WebAssembly, Constructor(BufferSource bytes), Exposed=(Window,Worker,Worklet)] interface Module { - static sequence exports(Module module); - static sequence imports(Module module); - static sequence customSections(Module module, USVString sectionName); + static sequence exports(Module moduleObject); + static sequence imports(Module moduleObject); + static sequence customSections(Module moduleObject, USVString sectionName); }; [LegacyNamespace=WebAssembly, Constructor(Module module, optional object importObject), Exposed=(Window,Worker,Worklet)] @@ -87,7 +87,7 @@ dictionary GlobalDescriptor { boolean mutable = false; }; -[LegacyNamespace=WebAssembly, Constructor(GlobalDescriptor descriptor, optional any value), Exposed=(Window,Worker,Worklet)] +[LegacyNamespace=WebAssembly, Constructor(GlobalDescriptor descriptor, optional any v), Exposed=(Window,Worker,Worklet)] interface Global { any valueOf(); attribute any value; diff --git a/tests/wpt/web-platform-tests/interfaces/webrtc-dscp.idl b/tests/wpt/web-platform-tests/interfaces/webrtc-dscp.idl new file mode 100644 index 00000000000..718447bbf4a --- /dev/null +++ b/tests/wpt/web-platform-tests/interfaces/webrtc-dscp.idl @@ -0,0 +1,8 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content was automatically extracted by Reffy into reffy-reports +// (https://github.com/tidoust/reffy-reports) +// Source: DSCP Control API (https://w3c.github.io/webrtc-dscp-exp/) + +partial dictionary RTCRtpEncodingParameters { + RTCPriorityType networkPriority; // Note: No default +}; diff --git a/tests/wpt/web-platform-tests/interfaces/webxr.idl b/tests/wpt/web-platform-tests/interfaces/webxr.idl index 00839eed1a2..ffa9ed4e91a 100644 --- a/tests/wpt/web-platform-tests/interfaces/webxr.idl +++ b/tests/wpt/web-platform-tests/interfaces/webxr.idl @@ -162,7 +162,7 @@ typedef (WebGLRenderingContext or dictionary XRWebGLLayerInit { boolean antialias = true; - boolean depth = false; + boolean depth = true; boolean stencil = false; boolean alpha = true; boolean multiview = false; diff --git a/tests/wpt/web-platform-tests/lint.whitelist b/tests/wpt/web-platform-tests/lint.whitelist index 5e4d06c4a6b..7d579b6b343 100644 --- a/tests/wpt/web-platform-tests/lint.whitelist +++ b/tests/wpt/web-platform-tests/lint.whitelist @@ -100,7 +100,7 @@ INDENT TABS: html/semantics/embedded-content/the-canvas-element/size.attributes. # Intentional use of print statements PRINT STATEMENT: dom/nodes/Document-createElement-namespace-tests/generate.py PRINT STATEMENT: encrypted-media/polyfill/make-polyfill-tests.py -PRINT STATEMENT: webdriver/tests/support/fixtures.py +PRINT STATEMENT: webdriver/tests/support/helpers.py # semi-legitimate use of console.* CONSOLE: console/* @@ -162,6 +162,7 @@ SET TIMEOUT: html/semantics/embedded-content/the-iframe-element/* SET TIMEOUT: html/semantics/embedded-content/the-img-element/* SET TIMEOUT: html/semantics/scripting-1/the-script-element/* SET TIMEOUT: html/webappapis/dynamic-markup-insertion/opening-the-input-stream/0* +SET TIMEOUT: html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/history-frame.html SET TIMEOUT: html/webappapis/dynamic-markup-insertion/opening-the-input-stream/tasks.window.js SET TIMEOUT: html/webappapis/scripting/event-loops/* SET TIMEOUT: html/webappapis/scripting/events/event-handler-processing-algorithm-error/* @@ -264,6 +265,9 @@ GENERATE_TESTS: dom/traversal/TreeWalker.html GENERATE_TESTS: domparsing/createContextualFragment.html GENERATE_TESTS: domxpath/001.html GENERATE_TESTS: domxpath/002.html +GENERATE_TESTS: mediacapture-image/MediaStreamTrack-applyConstraints-reject.html +GENERATE_TESTS: mediacapture-image/MediaStreamTrack-getConstraints-fast.html +GENERATE_TESTS: mediacapture-image/setOptions-reject.html GENERATE_TESTS: html/semantics/scripting-1/the-template-element/template-element/template-as-a-descendant.html GENERATE_TESTS: html/syntax/parsing/Document.getElementsByTagName-foreign-01.html GENERATE_TESTS: html/syntax/parsing/template/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-body-context.html diff --git a/tests/wpt/web-platform-tests/mediacapture-image/ImageCapture-MediaTrackSupportedConstraints.html b/tests/wpt/web-platform-tests/mediacapture-image/ImageCapture-MediaTrackSupportedConstraints.html new file mode 100644 index 00000000000..59a54f51d60 --- /dev/null +++ b/tests/wpt/web-platform-tests/mediacapture-image/ImageCapture-MediaTrackSupportedConstraints.html @@ -0,0 +1,26 @@ + + + + diff --git a/tests/wpt/web-platform-tests/mediacapture-image/ImageCapture-creation.https.html b/tests/wpt/web-platform-tests/mediacapture-image/ImageCapture-creation.https.html new file mode 100644 index 00000000000..9e8b5feeeb5 --- /dev/null +++ b/tests/wpt/web-platform-tests/mediacapture-image/ImageCapture-creation.https.html @@ -0,0 +1,76 @@ + + + + diff --git a/tests/wpt/web-platform-tests/mediacapture-image/ImageCapture-grabFrame.html b/tests/wpt/web-platform-tests/mediacapture-image/ImageCapture-grabFrame.html new file mode 100644 index 00000000000..bf5e9400a03 --- /dev/null +++ b/tests/wpt/web-platform-tests/mediacapture-image/ImageCapture-grabFrame.html @@ -0,0 +1,46 @@ + + + + + + + + diff --git a/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-applyConstraints-fast.html b/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-applyConstraints-fast.html new file mode 100644 index 00000000000..75ed17a9e33 --- /dev/null +++ b/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-applyConstraints-fast.html @@ -0,0 +1,85 @@ + + + + + + + diff --git a/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-applyConstraints-getSettings.html b/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-applyConstraints-getSettings.html new file mode 100644 index 00000000000..1a1b58e5415 --- /dev/null +++ b/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-applyConstraints-getSettings.html @@ -0,0 +1,94 @@ + + + + + + + + diff --git a/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-applyConstraints-reject.html b/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-applyConstraints-reject.html new file mode 100644 index 00000000000..8f08d250fd1 --- /dev/null +++ b/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-applyConstraints-reject.html @@ -0,0 +1,84 @@ + + + + + + + + diff --git a/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-applyConstraints.html b/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-applyConstraints.html new file mode 100644 index 00000000000..8dcff926173 --- /dev/null +++ b/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-applyConstraints.html @@ -0,0 +1,113 @@ + + + + + + + + diff --git a/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-getCapabilities-fast.html b/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-getCapabilities-fast.html new file mode 100644 index 00000000000..55272d14995 --- /dev/null +++ b/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-getCapabilities-fast.html @@ -0,0 +1,29 @@ + + + + + + + diff --git a/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-getCapabilities.html b/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-getCapabilities.html new file mode 100644 index 00000000000..eceaf5b1a86 --- /dev/null +++ b/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-getCapabilities.html @@ -0,0 +1,145 @@ + + + + + + + + diff --git a/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-getConstraints-fast.html b/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-getConstraints-fast.html new file mode 100644 index 00000000000..5a5ce5f2dad --- /dev/null +++ b/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-getConstraints-fast.html @@ -0,0 +1,75 @@ + + + + + + + diff --git a/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-getSettings-fast.html b/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-getSettings-fast.html new file mode 100644 index 00000000000..a4ecbe61181 --- /dev/null +++ b/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-getSettings-fast.html @@ -0,0 +1,29 @@ + + + + + + + diff --git a/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-getSettings.html b/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-getSettings.html new file mode 100644 index 00000000000..5e9256eeb74 --- /dev/null +++ b/tests/wpt/web-platform-tests/mediacapture-image/MediaStreamTrack-getSettings.html @@ -0,0 +1,68 @@ + + + + + + + + diff --git a/tests/wpt/web-platform-tests/mediacapture-image/detached-HTMLCanvasElement.html b/tests/wpt/web-platform-tests/mediacapture-image/detached-HTMLCanvasElement.html new file mode 100644 index 00000000000..e27950fc5ed --- /dev/null +++ b/tests/wpt/web-platform-tests/mediacapture-image/detached-HTMLCanvasElement.html @@ -0,0 +1,26 @@ + + + + + + diff --git a/tests/wpt/web-platform-tests/mediacapture-image/getPhotoCapabilities.html b/tests/wpt/web-platform-tests/mediacapture-image/getPhotoCapabilities.html new file mode 100644 index 00000000000..83329fcac4a --- /dev/null +++ b/tests/wpt/web-platform-tests/mediacapture-image/getPhotoCapabilities.html @@ -0,0 +1,45 @@ + + + + + + + + diff --git a/tests/wpt/web-platform-tests/mediacapture-image/getPhotoSettings.html b/tests/wpt/web-platform-tests/mediacapture-image/getPhotoSettings.html new file mode 100644 index 00000000000..6a6184f17cb --- /dev/null +++ b/tests/wpt/web-platform-tests/mediacapture-image/getPhotoSettings.html @@ -0,0 +1,30 @@ + + + + + + + + diff --git a/tests/wpt/web-platform-tests/mediacapture-image/resources/imagecapture-helpers.js b/tests/wpt/web-platform-tests/mediacapture-image/resources/imagecapture-helpers.js new file mode 100644 index 00000000000..6d5ffa1695d --- /dev/null +++ b/tests/wpt/web-platform-tests/mediacapture-image/resources/imagecapture-helpers.js @@ -0,0 +1,69 @@ +'use strict'; + +// These tests rely on the User Agent providing an implementation of +// platform image capture backends. +// +// In Chromium-based browsers this implementation is provided by a polyfill +// in order to reduce the amount of test-only code shipped to users. To enable +// these tests the browser must be run with these options: +// +// --enable-blink-features=MojoJS,MojoJSTest + +let loadChromiumResources = Promise.resolve().then(() => { + if (!MojoInterfaceInterceptor) { + // Do nothing on non-Chromium-based browsers or when the Mojo bindings are + // not present in the global namespace. + return; + } + + let chain = Promise.resolve(); + [ + '/resources/chromium/mojo_bindings.js', + '/resources/chromium/image_capture.mojom.js', + '/resources/chromium/mock-imagecapture.js', + ].forEach(path => { + // Use importScripts for workers. + if (typeof document === 'undefined') { + chain = chain.then(() => importScripts(path)); + return; + } + let script = document.createElement('script'); + script.src = path; + script.async = false; + chain = chain.then(() => new Promise(resolve => { + script.onload = () => resolve(); + })); + document.head.appendChild(script); + }); + + return chain; +}); + +async function initialize_image_capture_tests() { + if (typeof ImageCaptureTest === 'undefined') { + await loadChromiumResources; + } + assert_true(typeof ImageCaptureTest !== 'undefined'); + let imageCaptureTest = new ImageCaptureTest(); + await imageCaptureTest.initialize(); + return imageCaptureTest; +} + +function image_capture_test(func, name, properties) { + promise_test(async (t) => { + let imageCaptureTest = await initialize_image_capture_tests(); + try { + await func(t, imageCaptureTest); + } finally { + await imageCaptureTest.reset(); + }; + }, name, properties); +} + +function assert_point2d_array_approx_equals(actual, expected, epsilon) { + assert_equals(actual.length, expected.length, 'length'); + for (var i = 0; i < actual.length; ++i) { + assert_approx_equals(actual[i].x, expected[i].x, epsilon, 'x'); + assert_approx_equals(actual[i].y, expected[i].y, epsilon, 'y'); + } +} diff --git a/tests/wpt/web-platform-tests/mediacapture-image/setOptions-reject.html b/tests/wpt/web-platform-tests/mediacapture-image/setOptions-reject.html new file mode 100644 index 00000000000..4deee97d7bc --- /dev/null +++ b/tests/wpt/web-platform-tests/mediacapture-image/setOptions-reject.html @@ -0,0 +1,51 @@ + + + + + + + + diff --git a/tests/wpt/web-platform-tests/mediacapture-image/takePhoto-with-PhotoSettings.html b/tests/wpt/web-platform-tests/mediacapture-image/takePhoto-with-PhotoSettings.html new file mode 100644 index 00000000000..58708612456 --- /dev/null +++ b/tests/wpt/web-platform-tests/mediacapture-image/takePhoto-with-PhotoSettings.html @@ -0,0 +1,63 @@ + + + + + + + + diff --git a/tests/wpt/web-platform-tests/mediacapture-image/takePhoto.html b/tests/wpt/web-platform-tests/mediacapture-image/takePhoto.html new file mode 100644 index 00000000000..49926db1cde --- /dev/null +++ b/tests/wpt/web-platform-tests/mediacapture-image/takePhoto.html @@ -0,0 +1,29 @@ + + + + + + + + diff --git a/tests/wpt/web-platform-tests/mediacapture-streams/MediaStream-default-feature-policy.https.html b/tests/wpt/web-platform-tests/mediacapture-streams/MediaStream-default-feature-policy.https.html index f0f07da2122..0b45ac6f594 100644 --- a/tests/wpt/web-platform-tests/mediacapture-streams/MediaStream-default-feature-policy.https.html +++ b/tests/wpt/web-platform-tests/mediacapture-streams/MediaStream-default-feature-policy.https.html @@ -13,7 +13,7 @@ // mic/camera has been explicitly allowed by feature policy. function promise_factory(allowed_features) { return new Promise((resolve, reject) => { - navigator.getUserMedia({video: true, audio: true}, + navigator.getUserMedia({video: true, audio: true}).then( function(stream) { // If microphone is allowed, there should be at least one microphone // in the result. If camera is allowed, there should be at least one diff --git a/tests/wpt/web-platform-tests/network-error-logging/support/lock.py b/tests/wpt/web-platform-tests/network-error-logging/support/lock.py index 8c88250bde0..d87b3aef0fb 100644 --- a/tests/wpt/web-platform-tests/network-error-logging/support/lock.py +++ b/tests/wpt/web-platform-tests/network-error-logging/support/lock.py @@ -1,4 +1,14 @@ -_LOCK_KEY = "network-error-logging:lock" +# This file implements a shared lock that lets us ensure that the test cases in +# this directory run serially. Each test case obtains this lock as its first +# step, and releases it as its last. (The nel_test helper function in +# nel.sub.js automates this process.) Because the lock needs to be shared +# across all of the test cases, we use a hard-coded stash key. This hard-coded +# key is a random UUID, which should not conflict with any other auto-generated +# stash keys. + +import time + +_LOCK_KEY = "67966d2e-a847-41d8-b7c3-5f6aee3375ba" _TIMEOUT = 5 # seconds def wait_for_lock(request): diff --git a/tests/wpt/web-platform-tests/payment-request/META.yml b/tests/wpt/web-platform-tests/payment-request/META.yml index 74a165b1392..f8460d403ff 100644 --- a/tests/wpt/web-platform-tests/payment-request/META.yml +++ b/tests/wpt/web-platform-tests/payment-request/META.yml @@ -5,3 +5,4 @@ suggested_reviewers: - domenic - MSFTkihans - mnoorenberghe + - romandev diff --git a/tests/wpt/web-platform-tests/payment-request/MerchantValidationEvent/complete-method-manual.https.html b/tests/wpt/web-platform-tests/payment-request/MerchantValidationEvent/complete-method-manual.https.html new file mode 100644 index 00000000000..99a10e9dc79 --- /dev/null +++ b/tests/wpt/web-platform-tests/payment-request/MerchantValidationEvent/complete-method-manual.https.html @@ -0,0 +1,15 @@ + + + +Test for the MerchantValidationEvent's complete() method. + + + + diff --git a/tests/wpt/web-platform-tests/payment-request/MerchantValidationEvent/constructor.http.html b/tests/wpt/web-platform-tests/payment-request/MerchantValidationEvent/constructor.http.html new file mode 100644 index 00000000000..8368c79a3b1 --- /dev/null +++ b/tests/wpt/web-platform-tests/payment-request/MerchantValidationEvent/constructor.http.html @@ -0,0 +1,11 @@ + + +Test for MerchantValidationEvent Constructor (insecure) + + + + diff --git a/tests/wpt/web-platform-tests/payment-request/MerchantValidationEvent/constructor.https.html b/tests/wpt/web-platform-tests/payment-request/MerchantValidationEvent/constructor.https.html new file mode 100644 index 00000000000..952c0f734a3 --- /dev/null +++ b/tests/wpt/web-platform-tests/payment-request/MerchantValidationEvent/constructor.https.html @@ -0,0 +1,76 @@ + + + +Test for MerchantValidationEvent Constructor + + + + diff --git a/tests/wpt/web-platform-tests/payment-request/allowpaymentrequest/common.sub.js b/tests/wpt/web-platform-tests/payment-request/allowpaymentrequest/common.sub.js index 85a08461fcb..a94bac064c9 100644 --- a/tests/wpt/web-platform-tests/payment-request/allowpaymentrequest/common.sub.js +++ b/tests/wpt/web-platform-tests/payment-request/allowpaymentrequest/common.sub.js @@ -5,41 +5,57 @@ const tests = {}; -window.onmessage = (e) => { +window.onmessage = e => { const result = e.data; const tagName = result.urlQuery; const t = tests[tagName]; t.step(() => { if (expectSuccess[tagName]) { - assert_equals(result.message, 'Success'); + assert_equals(result.message, "Success"); + if (result.message === "Exception") { + const [, code, name, stack] = result.details; + assert_unreached(`Unexpected exception "${name}" (${code}) ${stack}`); + } } else { - assert_equals(result.message, 'Exception'); - assert_array_equals(result.details, [true /*ex instanceof DOMException*/, - DOMException.SECURITY_ERR /*ex.code*/, - 'SecurityError' /*ex.name*/]); + assert_equals(result.message, "Exception"); + const detailsArray = result.details.slice(0,3); + assert_array_equals(detailsArray, [ + true /*ex instanceof DOMException*/, + DOMException.SECURITY_ERR /*ex.code*/, + "SecurityError" /*ex.name*/, + ]); } t.done(); }); }; -['iframe', 'frame', 'object', 'embed'].forEach((tagName, i) => { - tests[tagName] = async_test((t) => { +["iframe", "frame", "object", "embed"].forEach((tagName, i) => { + tests[tagName] = async_test(t => { const elm = document.createElement(tagName); if (setAllowPaymentRequest) { - elm.setAttribute('allowpaymentrequest', ''); + elm.setAttribute("allowpaymentrequest", ""); } - const path = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - const url = (testCrossOrigin ? "https://{{domains[www1]}}:{{ports[https][0]}}" : "") + - path + "echo-PaymentRequest.html?" + tagName; - if (tagName === 'object') { + const path = location.pathname.substring( + 0, + location.pathname.lastIndexOf("/") + 1 + ); + const url = + (testCrossOrigin ? "https://{{domains[www1]}}:{{ports[https][0]}}" : "") + + path + + "echo-PaymentRequest.html?" + + tagName; + if (tagName === "object") { elm.data = url; } else { elm.src = url; } elm.onload = t.step_func(() => { - window[i].postMessage('What is the result of new PaymentRequest(...)?', '*'); + window[i].postMessage( + "What is the result of new PaymentRequest(...)?", + "*" + ); }); - elm.onerror = t.unreached_func('elm.onerror'); + elm.onerror = t.unreached_func("elm.onerror"); document.body.appendChild(elm); }, tagName); }); diff --git a/tests/wpt/web-platform-tests/payment-request/allowpaymentrequest/echo-PaymentRequest.html b/tests/wpt/web-platform-tests/payment-request/allowpaymentrequest/echo-PaymentRequest.html index f18b16ee31b..5211c7e5ce7 100644 --- a/tests/wpt/web-platform-tests/payment-request/allowpaymentrequest/echo-PaymentRequest.html +++ b/tests/wpt/web-platform-tests/payment-request/allowpaymentrequest/echo-PaymentRequest.html @@ -11,7 +11,9 @@ window.onmessage = (e) => { e.source.postMessage(result, '*'); } catch(ex) { result.message = 'Exception'; - result.details = [ex instanceof DOMException, ex.code, ex.name]; + const isDomException = ex instanceof DOMException; + const stack = "stack" in ex ? ex.stack : ""; + result.details = [ isDomException, ex.code, ex.name, stack ]; e.source.postMessage(result, '*'); } } else { diff --git a/tests/wpt/web-platform-tests/payment-request/idlharness.https.window.js b/tests/wpt/web-platform-tests/payment-request/idlharness.https.window.js index 9a068c6d27f..53ae47e8921 100644 --- a/tests/wpt/web-platform-tests/payment-request/idlharness.https.window.js +++ b/tests/wpt/web-platform-tests/payment-request/idlharness.https.window.js @@ -25,6 +25,7 @@ idl_test( PaymentRequest: ['paymentRequest'], PaymentMethodChangeEvent: ['new PaymentMethodChangeEvent("paymentmethodchange")'], PaymentRequestUpdateEvent: ['new PaymentRequestUpdateEvent("paymentrequestupdate")'], + MerchantValidationEvent: ['new MerchantValidationEvent("merchantvalidation")'], }); } ); diff --git a/tests/wpt/web-platform-tests/payment-request/onmerchantvalidation-attribute.https.html b/tests/wpt/web-platform-tests/payment-request/onmerchantvalidation-attribute.https.html new file mode 100644 index 00000000000..c0ed23167ed --- /dev/null +++ b/tests/wpt/web-platform-tests/payment-request/onmerchantvalidation-attribute.https.html @@ -0,0 +1,69 @@ + + +Test for PaymentRequest's onmerchantvalidation attribute + + + + diff --git a/tests/wpt/web-platform-tests/payment-request/payment-response/onpayerdetailchange-attribute.manual.https.html b/tests/wpt/web-platform-tests/payment-request/payment-response/onpayerdetailchange-attribute.manual.https.html index 9f92d284063..c8dd92636c6 100644 --- a/tests/wpt/web-platform-tests/payment-request/payment-response/onpayerdetailchange-attribute.manual.https.html +++ b/tests/wpt/web-platform-tests/payment-request/payment-response/onpayerdetailchange-attribute.manual.https.html @@ -13,7 +13,7 @@ function runTest(button, options, expected){ response.addEventListener("payerdetailchange", resolve); }); const error = button.previousElementSibling.textContent.trim(); - const retryPromise = response.retry({ error }); + await response.retry({ error }); const event = await eventPromise; assert_true(event instanceof PaymentRequestUpdateEvent); for(const [prop, value] of Object.entries(expected)){ diff --git a/tests/wpt/web-platform-tests/pointerevents/extension/pointerevent_pointerrawmove-manual.html b/tests/wpt/web-platform-tests/pointerevents/extension/pointerevent_pointerrawmove-manual.html new file mode 100644 index 00000000000..0c4ccf9ad48 --- /dev/null +++ b/tests/wpt/web-platform-tests/pointerevents/extension/pointerevent_pointerrawmove-manual.html @@ -0,0 +1,55 @@ + + + + pointerrawmove + + + + + + + + +

                  pointerrawmove

                  +

                  Test Description: This test checks if pointerrawmove is dispatched correctly.

                  +

                  Move your mouse within the black box.

                  +

                  Press left button down and then press middle button while holding down left button. Then release the buttons

                  +
                  + +
                  +
                  + + diff --git a/tests/wpt/web-platform-tests/preload/preload-strict-dynamic.html b/tests/wpt/web-platform-tests/preload/preload-strict-dynamic.html index 5e473a1c894..76395656f9b 100644 --- a/tests/wpt/web-platform-tests/preload/preload-strict-dynamic.html +++ b/tests/wpt/web-platform-tests/preload/preload-strict-dynamic.html @@ -22,7 +22,7 @@ } window.addEventListener("securitypolicyviolation", (e) => { counter++; - if (e.violatedDirective == "script-src" && e.blockedURI.includes("static-no-nonce")) { + if (e.violatedDirective == "script-src-elem" && e.blockedURI.includes("static-no-nonce")) { cspViolation = true; } }); diff --git a/tests/wpt/web-platform-tests/quirks/unitless-length/excluded-properties.html b/tests/wpt/web-platform-tests/quirks/unitless-length/excluded-properties-001.html similarity index 79% rename from tests/wpt/web-platform-tests/quirks/unitless-length/excluded-properties.html rename to tests/wpt/web-platform-tests/quirks/unitless-length/excluded-properties-001.html index a1de182770a..2e33cec0b33 100644 --- a/tests/wpt/web-platform-tests/quirks/unitless-length/excluded-properties.html +++ b/tests/wpt/web-platform-tests/quirks/unitless-length/excluded-properties-001.html @@ -14,7 +14,21 @@ 'use strict'; var properties = [ + 'background-position-x', + 'background-position-y', 'block-size', + 'border-bottom-left-radius', + 'border-bottom-right-radius', + 'border-top-left-radius', + 'border-top-right-radius', + 'column-gap', + 'column-rule-width', + 'column-width', + 'flex-basis', + 'grid-auto-columns', + 'grid-auto-rows', + 'grid-template-columns', + 'grid-template-rows', 'inline-size', 'margin-block-end', 'margin-block-start', @@ -23,10 +37,14 @@ var properties = [ 'min-block-size', 'min-inline-size', 'offset-distance', + 'outline-offset', + 'outline-width', 'padding-block-end', 'padding-block-start', 'padding-inline-end', 'padding-inline-start', + 'perspective', + 'row-gap', 'scroll-margin-block-end', 'scroll-margin-block-start', 'scroll-margin-bottom', diff --git a/tests/wpt/web-platform-tests/quirks/unitless-length/excluded-properties-002.html b/tests/wpt/web-platform-tests/quirks/unitless-length/excluded-properties-002.html new file mode 100644 index 00000000000..5f98bc283eb --- /dev/null +++ b/tests/wpt/web-platform-tests/quirks/unitless-length/excluded-properties-002.html @@ -0,0 +1,42 @@ + + + +Many properties do not support quirky-length + + + + + + + +
                  + + + diff --git a/tests/wpt/web-platform-tests/resources/chromium/generic_sensor_mocks.js b/tests/wpt/web-platform-tests/resources/chromium/generic_sensor_mocks.js index 24a469199ff..d9a23f44714 100644 --- a/tests/wpt/web-platform-tests/resources/chromium/generic_sensor_mocks.js +++ b/tests/wpt/web-platform-tests/resources/chromium/generic_sensor_mocks.js @@ -109,7 +109,7 @@ var GenericSensorTest = (() => { this.readingSizeInBytes_ = device.mojom.SensorInitParams.kReadBufferSizeForTests; this.sharedBufferSizeInBytes_ = this.readingSizeInBytes_ * - device.mojom.SensorType.LAST; + (device.mojom.SensorType.RELATIVE_ORIENTATION_QUATERNION + 1); let rv = Mojo.createSharedBuffer(this.sharedBufferSizeInBytes_); assert_equals(rv.result, Mojo.RESULT_OK, "Failed to create buffer"); this.sharedBufferHandle_ = rv.handle; @@ -130,8 +130,7 @@ var GenericSensorTest = (() => { } async getSensor(type) { - const offset = (device.mojom.SensorType.LAST - type) * - this.readingSizeInBytes_; + const offset = type * this.readingSizeInBytes_; const reportingMode = device.mojom.ReportingMode.ON_CHANGE; let sensorPtr = new device.mojom.SensorPtr(); diff --git a/tests/wpt/web-platform-tests/resources/chromium/image_capture-mojom.js.headers b/tests/wpt/web-platform-tests/resources/chromium/image_capture-mojom.js.headers new file mode 100644 index 00000000000..6c61a34a4ec --- /dev/null +++ b/tests/wpt/web-platform-tests/resources/chromium/image_capture-mojom.js.headers @@ -0,0 +1 @@ +Content-Type: text/javascript; charset=utf-8 \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/resources/chromium/image_capture.mojom.js b/tests/wpt/web-platform-tests/resources/chromium/image_capture.mojom.js new file mode 100644 index 00000000000..11123feb87d --- /dev/null +++ b/tests/wpt/web-platform-tests/resources/chromium/image_capture.mojom.js @@ -0,0 +1,1346 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +'use strict'; + +(function() { + var mojomId = 'media/capture/mojom/image_capture.mojom'; + if (mojo.internal.isMojomLoaded(mojomId)) { + console.warn('The following mojom is loaded multiple times: ' + mojomId); + return; + } + mojo.internal.markMojomLoaded(mojomId); + var bindings = mojo; + var associatedBindings = mojo; + var codec = mojo.internal; + var validator = mojo.internal; + + var exports = mojo.internal.exposeNamespace('media.mojom'); + + + var MeteringMode = {}; + MeteringMode.NONE = 0; + MeteringMode.MANUAL = MeteringMode.NONE + 1; + MeteringMode.SINGLE_SHOT = MeteringMode.MANUAL + 1; + MeteringMode.CONTINUOUS = MeteringMode.SINGLE_SHOT + 1; + + MeteringMode.isKnownEnumValue = function(value) { + switch (value) { + case 0: + case 1: + case 2: + case 3: + return true; + } + return false; + }; + + MeteringMode.validate = function(enumValue) { + var isExtensible = false; + if (isExtensible || this.isKnownEnumValue(enumValue)) + return validator.validationError.NONE; + + return validator.validationError.UNKNOWN_ENUM_VALUE; + }; + var RedEyeReduction = {}; + RedEyeReduction.NEVER = 0; + RedEyeReduction.ALWAYS = RedEyeReduction.NEVER + 1; + RedEyeReduction.CONTROLLABLE = RedEyeReduction.ALWAYS + 1; + + RedEyeReduction.isKnownEnumValue = function(value) { + switch (value) { + case 0: + case 1: + case 2: + return true; + } + return false; + }; + + RedEyeReduction.validate = function(enumValue) { + var isExtensible = false; + if (isExtensible || this.isKnownEnumValue(enumValue)) + return validator.validationError.NONE; + + return validator.validationError.UNKNOWN_ENUM_VALUE; + }; + var FillLightMode = {}; + FillLightMode.OFF = 0; + FillLightMode.AUTO = FillLightMode.OFF + 1; + FillLightMode.FLASH = FillLightMode.AUTO + 1; + + FillLightMode.isKnownEnumValue = function(value) { + switch (value) { + case 0: + case 1: + case 2: + return true; + } + return false; + }; + + FillLightMode.validate = function(enumValue) { + var isExtensible = false; + if (isExtensible || this.isKnownEnumValue(enumValue)) + return validator.validationError.NONE; + + return validator.validationError.UNKNOWN_ENUM_VALUE; + }; + + function Range(values) { + this.initDefaults_(); + this.initFields_(values); + } + + + Range.prototype.initDefaults_ = function() { + this.max = 0; + this.min = 0; + this.current = 0; + this.step = 0; + }; + Range.prototype.initFields_ = function(fields) { + for(var field in fields) { + if (this.hasOwnProperty(field)) + this[field] = fields[field]; + } + }; + + Range.validate = function(messageValidator, offset) { + var err; + err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); + if (err !== validator.validationError.NONE) + return err; + + var kVersionSizes = [ + {version: 0, numBytes: 40} + ]; + err = messageValidator.validateStructVersion(offset, kVersionSizes); + if (err !== validator.validationError.NONE) + return err; + + + + + + return validator.validationError.NONE; + }; + + Range.encodedSize = codec.kStructHeaderSize + 32; + + Range.decode = function(decoder) { + var packed; + var val = new Range(); + var numberOfBytes = decoder.readUint32(); + var version = decoder.readUint32(); + val.max = decoder.decodeStruct(codec.Double); + val.min = decoder.decodeStruct(codec.Double); + val.current = decoder.decodeStruct(codec.Double); + val.step = decoder.decodeStruct(codec.Double); + return val; + }; + + Range.encode = function(encoder, val) { + var packed; + encoder.writeUint32(Range.encodedSize); + encoder.writeUint32(0); + encoder.encodeStruct(codec.Double, val.max); + encoder.encodeStruct(codec.Double, val.min); + encoder.encodeStruct(codec.Double, val.current); + encoder.encodeStruct(codec.Double, val.step); + }; + function PhotoState(values) { + this.initDefaults_(); + this.initFields_(values); + } + + + PhotoState.prototype.initDefaults_ = function() { + this.supportedWhiteBalanceModes = null; + this.currentWhiteBalanceMode = 0; + this.currentExposureMode = 0; + this.supportedExposureModes = null; + this.supportedFocusModes = null; + this.currentFocusMode = 0; + this.supportsTorch = false; + this.torch = false; + this.pointsOfInterest = null; + this.exposureCompensation = null; + this.colorTemperature = null; + this.iso = null; + this.brightness = null; + this.contrast = null; + this.saturation = null; + this.sharpness = null; + this.focusDistance = null; + this.zoom = null; + this.redEyeReduction = 0; + this.height = null; + this.width = null; + this.fillLightMode = null; + }; + PhotoState.prototype.initFields_ = function(fields) { + for(var field in fields) { + if (this.hasOwnProperty(field)) + this[field] = fields[field]; + } + }; + + PhotoState.validate = function(messageValidator, offset) { + var err; + err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); + if (err !== validator.validationError.NONE) + return err; + + var kVersionSizes = [ + {version: 0, numBytes: 160} + ]; + err = messageValidator.validateStructVersion(offset, kVersionSizes); + if (err !== validator.validationError.NONE) + return err; + + + // validate PhotoState.supportedWhiteBalanceModes + err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 4, new codec.Enum(MeteringMode), false, [0], 0); + if (err !== validator.validationError.NONE) + return err; + + + // validate PhotoState.currentWhiteBalanceMode + err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 8, MeteringMode); + if (err !== validator.validationError.NONE) + return err; + + + // validate PhotoState.supportedExposureModes + err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 16, 4, new codec.Enum(MeteringMode), false, [0], 0); + if (err !== validator.validationError.NONE) + return err; + + + // validate PhotoState.currentExposureMode + err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 12, MeteringMode); + if (err !== validator.validationError.NONE) + return err; + + + // validate PhotoState.supportedFocusModes + err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 24, 4, new codec.Enum(MeteringMode), false, [0], 0); + if (err !== validator.validationError.NONE) + return err; + + + // validate PhotoState.currentFocusMode + err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 32, MeteringMode); + if (err !== validator.validationError.NONE) + return err; + + + // validate PhotoState.pointsOfInterest + err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 40, 8, new codec.PointerTo(Point2D), false, [0], 0); + if (err !== validator.validationError.NONE) + return err; + + + // validate PhotoState.exposureCompensation + err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 48, Range, false); + if (err !== validator.validationError.NONE) + return err; + + + // validate PhotoState.colorTemperature + err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 56, Range, false); + if (err !== validator.validationError.NONE) + return err; + + + // validate PhotoState.iso + err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 64, Range, false); + if (err !== validator.validationError.NONE) + return err; + + + // validate PhotoState.brightness + err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 72, Range, false); + if (err !== validator.validationError.NONE) + return err; + + + // validate PhotoState.contrast + err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 80, Range, false); + if (err !== validator.validationError.NONE) + return err; + + + // validate PhotoState.saturation + err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 88, Range, false); + if (err !== validator.validationError.NONE) + return err; + + + // validate PhotoState.sharpness + err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 96, Range, false); + if (err !== validator.validationError.NONE) + return err; + + + // validate PhotoState.focusDistance + err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 104, Range, false); + if (err !== validator.validationError.NONE) + return err; + + + // validate PhotoState.zoom + err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 112, Range, false); + if (err !== validator.validationError.NONE) + return err; + + + + + // validate PhotoState.redEyeReduction + err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 120, RedEyeReduction); + if (err !== validator.validationError.NONE) + return err; + + + // validate PhotoState.height + err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 128, Range, false); + if (err !== validator.validationError.NONE) + return err; + + + // validate PhotoState.width + err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 136, Range, false); + if (err !== validator.validationError.NONE) + return err; + + + // validate PhotoState.fillLightMode + err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 144, 4, new codec.Enum(FillLightMode), false, [0], 0); + if (err !== validator.validationError.NONE) + return err; + + return validator.validationError.NONE; + }; + + PhotoState.encodedSize = codec.kStructHeaderSize + 152; + + PhotoState.decode = function(decoder) { + var packed; + var val = new PhotoState(); + var numberOfBytes = decoder.readUint32(); + var version = decoder.readUint32(); + val.supportedWhiteBalanceModes = decoder.decodeArrayPointer(new codec.Enum(MeteringMode)); + val.currentWhiteBalanceMode = decoder.decodeStruct(codec.Int32); + val.currentExposureMode = decoder.decodeStruct(codec.Int32); + val.supportedExposureModes = decoder.decodeArrayPointer(new codec.Enum(MeteringMode)); + val.supportedFocusModes = decoder.decodeArrayPointer(new codec.Enum(MeteringMode)); + val.currentFocusMode = decoder.decodeStruct(codec.Int32); + packed = decoder.readUint8(); + val.supportsTorch = (packed >> 0) & 1 ? true : false; + val.torch = (packed >> 1) & 1 ? true : false; + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + val.pointsOfInterest = decoder.decodeArrayPointer(new codec.PointerTo(Point2D)); + val.exposureCompensation = decoder.decodeStructPointer(Range); + val.colorTemperature = decoder.decodeStructPointer(Range); + val.iso = decoder.decodeStructPointer(Range); + val.brightness = decoder.decodeStructPointer(Range); + val.contrast = decoder.decodeStructPointer(Range); + val.saturation = decoder.decodeStructPointer(Range); + val.sharpness = decoder.decodeStructPointer(Range); + val.focusDistance = decoder.decodeStructPointer(Range); + val.zoom = decoder.decodeStructPointer(Range); + val.redEyeReduction = decoder.decodeStruct(codec.Int32); + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + val.height = decoder.decodeStructPointer(Range); + val.width = decoder.decodeStructPointer(Range); + val.fillLightMode = decoder.decodeArrayPointer(new codec.Enum(FillLightMode)); + return val; + }; + + PhotoState.encode = function(encoder, val) { + var packed; + encoder.writeUint32(PhotoState.encodedSize); + encoder.writeUint32(0); + encoder.encodeArrayPointer(new codec.Enum(MeteringMode), val.supportedWhiteBalanceModes); + encoder.encodeStruct(codec.Int32, val.currentWhiteBalanceMode); + encoder.encodeStruct(codec.Int32, val.currentExposureMode); + encoder.encodeArrayPointer(new codec.Enum(MeteringMode), val.supportedExposureModes); + encoder.encodeArrayPointer(new codec.Enum(MeteringMode), val.supportedFocusModes); + encoder.encodeStruct(codec.Int32, val.currentFocusMode); + packed = 0; + packed |= (val.supportsTorch & 1) << 0 + packed |= (val.torch & 1) << 1 + encoder.writeUint8(packed); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + encoder.encodeArrayPointer(new codec.PointerTo(Point2D), val.pointsOfInterest); + encoder.encodeStructPointer(Range, val.exposureCompensation); + encoder.encodeStructPointer(Range, val.colorTemperature); + encoder.encodeStructPointer(Range, val.iso); + encoder.encodeStructPointer(Range, val.brightness); + encoder.encodeStructPointer(Range, val.contrast); + encoder.encodeStructPointer(Range, val.saturation); + encoder.encodeStructPointer(Range, val.sharpness); + encoder.encodeStructPointer(Range, val.focusDistance); + encoder.encodeStructPointer(Range, val.zoom); + encoder.encodeStruct(codec.Int32, val.redEyeReduction); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + encoder.encodeStructPointer(Range, val.height); + encoder.encodeStructPointer(Range, val.width); + encoder.encodeArrayPointer(new codec.Enum(FillLightMode), val.fillLightMode); + }; + function Point2D(values) { + this.initDefaults_(); + this.initFields_(values); + } + + + Point2D.prototype.initDefaults_ = function() { + this.x = 0; + this.y = 0; + }; + Point2D.prototype.initFields_ = function(fields) { + for(var field in fields) { + if (this.hasOwnProperty(field)) + this[field] = fields[field]; + } + }; + + Point2D.validate = function(messageValidator, offset) { + var err; + err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); + if (err !== validator.validationError.NONE) + return err; + + var kVersionSizes = [ + {version: 0, numBytes: 16} + ]; + err = messageValidator.validateStructVersion(offset, kVersionSizes); + if (err !== validator.validationError.NONE) + return err; + + + + return validator.validationError.NONE; + }; + + Point2D.encodedSize = codec.kStructHeaderSize + 8; + + Point2D.decode = function(decoder) { + var packed; + var val = new Point2D(); + var numberOfBytes = decoder.readUint32(); + var version = decoder.readUint32(); + val.x = decoder.decodeStruct(codec.Float); + val.y = decoder.decodeStruct(codec.Float); + return val; + }; + + Point2D.encode = function(encoder, val) { + var packed; + encoder.writeUint32(Point2D.encodedSize); + encoder.writeUint32(0); + encoder.encodeStruct(codec.Float, val.x); + encoder.encodeStruct(codec.Float, val.y); + }; + function PhotoSettings(values) { + this.initDefaults_(); + this.initFields_(values); + } + + + PhotoSettings.prototype.initDefaults_ = function() { + this.hasWhiteBalanceMode = false; + this.hasExposureMode = false; + this.hasFocusMode = false; + this.hasExposureCompensation = false; + this.hasColorTemperature = false; + this.hasIso = false; + this.hasBrightness = false; + this.hasContrast = false; + this.hasSaturation = false; + this.hasSharpness = false; + this.hasFocusDistance = false; + this.hasZoom = false; + this.hasTorch = false; + this.torch = false; + this.hasFillLightMode = false; + this.hasWidth = false; + this.hasHeight = false; + this.hasRedEyeReduction = false; + this.redEyeReduction = false; + this.whiteBalanceMode = 0; + this.exposureMode = 0; + this.focusMode = 0; + this.pointsOfInterest = null; + this.exposureCompensation = 0; + this.colorTemperature = 0; + this.iso = 0; + this.brightness = 0; + this.contrast = 0; + this.saturation = 0; + this.sharpness = 0; + this.focusDistance = 0; + this.zoom = 0; + this.fillLightMode = 0; + this.width = 0; + this.height = 0; + }; + PhotoSettings.prototype.initFields_ = function(fields) { + for(var field in fields) { + if (this.hasOwnProperty(field)) + this[field] = fields[field]; + } + }; + + PhotoSettings.validate = function(messageValidator, offset) { + var err; + err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); + if (err !== validator.validationError.NONE) + return err; + + var kVersionSizes = [ + {version: 0, numBytes: 128} + ]; + err = messageValidator.validateStructVersion(offset, kVersionSizes); + if (err !== validator.validationError.NONE) + return err; + + + + // validate PhotoSettings.whiteBalanceMode + err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 4, MeteringMode); + if (err !== validator.validationError.NONE) + return err; + + + + // validate PhotoSettings.exposureMode + err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 8, MeteringMode); + if (err !== validator.validationError.NONE) + return err; + + + + // validate PhotoSettings.focusMode + err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 12, MeteringMode); + if (err !== validator.validationError.NONE) + return err; + + + // validate PhotoSettings.pointsOfInterest + err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 16, 8, new codec.PointerTo(Point2D), false, [0], 0); + if (err !== validator.validationError.NONE) + return err; + + + + + + + + + + + + + + + + + + + + + + + + // validate PhotoSettings.fillLightMode + err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 96, FillLightMode); + if (err !== validator.validationError.NONE) + return err; + + + + + + + + return validator.validationError.NONE; + }; + + PhotoSettings.encodedSize = codec.kStructHeaderSize + 120; + + PhotoSettings.decode = function(decoder) { + var packed; + var val = new PhotoSettings(); + var numberOfBytes = decoder.readUint32(); + var version = decoder.readUint32(); + packed = decoder.readUint8(); + val.hasWhiteBalanceMode = (packed >> 0) & 1 ? true : false; + val.hasExposureMode = (packed >> 1) & 1 ? true : false; + val.hasFocusMode = (packed >> 2) & 1 ? true : false; + val.hasExposureCompensation = (packed >> 3) & 1 ? true : false; + val.hasColorTemperature = (packed >> 4) & 1 ? true : false; + val.hasIso = (packed >> 5) & 1 ? true : false; + val.hasBrightness = (packed >> 6) & 1 ? true : false; + val.hasContrast = (packed >> 7) & 1 ? true : false; + packed = decoder.readUint8(); + val.hasSaturation = (packed >> 0) & 1 ? true : false; + val.hasSharpness = (packed >> 1) & 1 ? true : false; + val.hasFocusDistance = (packed >> 2) & 1 ? true : false; + val.hasZoom = (packed >> 3) & 1 ? true : false; + val.hasTorch = (packed >> 4) & 1 ? true : false; + val.torch = (packed >> 5) & 1 ? true : false; + val.hasFillLightMode = (packed >> 6) & 1 ? true : false; + val.hasWidth = (packed >> 7) & 1 ? true : false; + packed = decoder.readUint8(); + val.hasHeight = (packed >> 0) & 1 ? true : false; + val.hasRedEyeReduction = (packed >> 1) & 1 ? true : false; + val.redEyeReduction = (packed >> 2) & 1 ? true : false; + decoder.skip(1); + val.whiteBalanceMode = decoder.decodeStruct(codec.Int32); + val.exposureMode = decoder.decodeStruct(codec.Int32); + val.focusMode = decoder.decodeStruct(codec.Int32); + val.pointsOfInterest = decoder.decodeArrayPointer(new codec.PointerTo(Point2D)); + val.exposureCompensation = decoder.decodeStruct(codec.Double); + val.colorTemperature = decoder.decodeStruct(codec.Double); + val.iso = decoder.decodeStruct(codec.Double); + val.brightness = decoder.decodeStruct(codec.Double); + val.contrast = decoder.decodeStruct(codec.Double); + val.saturation = decoder.decodeStruct(codec.Double); + val.sharpness = decoder.decodeStruct(codec.Double); + val.focusDistance = decoder.decodeStruct(codec.Double); + val.zoom = decoder.decodeStruct(codec.Double); + val.fillLightMode = decoder.decodeStruct(codec.Int32); + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + val.width = decoder.decodeStruct(codec.Double); + val.height = decoder.decodeStruct(codec.Double); + return val; + }; + + PhotoSettings.encode = function(encoder, val) { + var packed; + encoder.writeUint32(PhotoSettings.encodedSize); + encoder.writeUint32(0); + packed = 0; + packed |= (val.hasWhiteBalanceMode & 1) << 0 + packed |= (val.hasExposureMode & 1) << 1 + packed |= (val.hasFocusMode & 1) << 2 + packed |= (val.hasExposureCompensation & 1) << 3 + packed |= (val.hasColorTemperature & 1) << 4 + packed |= (val.hasIso & 1) << 5 + packed |= (val.hasBrightness & 1) << 6 + packed |= (val.hasContrast & 1) << 7 + encoder.writeUint8(packed); + packed = 0; + packed |= (val.hasSaturation & 1) << 0 + packed |= (val.hasSharpness & 1) << 1 + packed |= (val.hasFocusDistance & 1) << 2 + packed |= (val.hasZoom & 1) << 3 + packed |= (val.hasTorch & 1) << 4 + packed |= (val.torch & 1) << 5 + packed |= (val.hasFillLightMode & 1) << 6 + packed |= (val.hasWidth & 1) << 7 + encoder.writeUint8(packed); + packed = 0; + packed |= (val.hasHeight & 1) << 0 + packed |= (val.hasRedEyeReduction & 1) << 1 + packed |= (val.redEyeReduction & 1) << 2 + encoder.writeUint8(packed); + encoder.skip(1); + encoder.encodeStruct(codec.Int32, val.whiteBalanceMode); + encoder.encodeStruct(codec.Int32, val.exposureMode); + encoder.encodeStruct(codec.Int32, val.focusMode); + encoder.encodeArrayPointer(new codec.PointerTo(Point2D), val.pointsOfInterest); + encoder.encodeStruct(codec.Double, val.exposureCompensation); + encoder.encodeStruct(codec.Double, val.colorTemperature); + encoder.encodeStruct(codec.Double, val.iso); + encoder.encodeStruct(codec.Double, val.brightness); + encoder.encodeStruct(codec.Double, val.contrast); + encoder.encodeStruct(codec.Double, val.saturation); + encoder.encodeStruct(codec.Double, val.sharpness); + encoder.encodeStruct(codec.Double, val.focusDistance); + encoder.encodeStruct(codec.Double, val.zoom); + encoder.encodeStruct(codec.Int32, val.fillLightMode); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + encoder.encodeStruct(codec.Double, val.width); + encoder.encodeStruct(codec.Double, val.height); + }; + function Blob(values) { + this.initDefaults_(); + this.initFields_(values); + } + + + Blob.prototype.initDefaults_ = function() { + this.mimeType = null; + this.data = null; + }; + Blob.prototype.initFields_ = function(fields) { + for(var field in fields) { + if (this.hasOwnProperty(field)) + this[field] = fields[field]; + } + }; + + Blob.validate = function(messageValidator, offset) { + var err; + err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); + if (err !== validator.validationError.NONE) + return err; + + var kVersionSizes = [ + {version: 0, numBytes: 24} + ]; + err = messageValidator.validateStructVersion(offset, kVersionSizes); + if (err !== validator.validationError.NONE) + return err; + + + // validate Blob.mimeType + err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) + if (err !== validator.validationError.NONE) + return err; + + + // validate Blob.data + err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 1, codec.Uint8, false, [0], 0); + if (err !== validator.validationError.NONE) + return err; + + return validator.validationError.NONE; + }; + + Blob.encodedSize = codec.kStructHeaderSize + 16; + + Blob.decode = function(decoder) { + var packed; + var val = new Blob(); + var numberOfBytes = decoder.readUint32(); + var version = decoder.readUint32(); + val.mimeType = decoder.decodeStruct(codec.String); + val.data = decoder.decodeArrayPointer(codec.Uint8); + return val; + }; + + Blob.encode = function(encoder, val) { + var packed; + encoder.writeUint32(Blob.encodedSize); + encoder.writeUint32(0); + encoder.encodeStruct(codec.String, val.mimeType); + encoder.encodeArrayPointer(codec.Uint8, val.data); + }; + function ImageCapture_GetPhotoState_Params(values) { + this.initDefaults_(); + this.initFields_(values); + } + + + ImageCapture_GetPhotoState_Params.prototype.initDefaults_ = function() { + this.sourceId = null; + }; + ImageCapture_GetPhotoState_Params.prototype.initFields_ = function(fields) { + for(var field in fields) { + if (this.hasOwnProperty(field)) + this[field] = fields[field]; + } + }; + + ImageCapture_GetPhotoState_Params.validate = function(messageValidator, offset) { + var err; + err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); + if (err !== validator.validationError.NONE) + return err; + + var kVersionSizes = [ + {version: 0, numBytes: 16} + ]; + err = messageValidator.validateStructVersion(offset, kVersionSizes); + if (err !== validator.validationError.NONE) + return err; + + + // validate ImageCapture_GetPhotoState_Params.sourceId + err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) + if (err !== validator.validationError.NONE) + return err; + + return validator.validationError.NONE; + }; + + ImageCapture_GetPhotoState_Params.encodedSize = codec.kStructHeaderSize + 8; + + ImageCapture_GetPhotoState_Params.decode = function(decoder) { + var packed; + var val = new ImageCapture_GetPhotoState_Params(); + var numberOfBytes = decoder.readUint32(); + var version = decoder.readUint32(); + val.sourceId = decoder.decodeStruct(codec.String); + return val; + }; + + ImageCapture_GetPhotoState_Params.encode = function(encoder, val) { + var packed; + encoder.writeUint32(ImageCapture_GetPhotoState_Params.encodedSize); + encoder.writeUint32(0); + encoder.encodeStruct(codec.String, val.sourceId); + }; + function ImageCapture_GetPhotoState_ResponseParams(values) { + this.initDefaults_(); + this.initFields_(values); + } + + + ImageCapture_GetPhotoState_ResponseParams.prototype.initDefaults_ = function() { + this.state = null; + }; + ImageCapture_GetPhotoState_ResponseParams.prototype.initFields_ = function(fields) { + for(var field in fields) { + if (this.hasOwnProperty(field)) + this[field] = fields[field]; + } + }; + + ImageCapture_GetPhotoState_ResponseParams.validate = function(messageValidator, offset) { + var err; + err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); + if (err !== validator.validationError.NONE) + return err; + + var kVersionSizes = [ + {version: 0, numBytes: 16} + ]; + err = messageValidator.validateStructVersion(offset, kVersionSizes); + if (err !== validator.validationError.NONE) + return err; + + + // validate ImageCapture_GetPhotoState_ResponseParams.state + err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, PhotoState, false); + if (err !== validator.validationError.NONE) + return err; + + return validator.validationError.NONE; + }; + + ImageCapture_GetPhotoState_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; + + ImageCapture_GetPhotoState_ResponseParams.decode = function(decoder) { + var packed; + var val = new ImageCapture_GetPhotoState_ResponseParams(); + var numberOfBytes = decoder.readUint32(); + var version = decoder.readUint32(); + val.state = decoder.decodeStructPointer(PhotoState); + return val; + }; + + ImageCapture_GetPhotoState_ResponseParams.encode = function(encoder, val) { + var packed; + encoder.writeUint32(ImageCapture_GetPhotoState_ResponseParams.encodedSize); + encoder.writeUint32(0); + encoder.encodeStructPointer(PhotoState, val.state); + }; + function ImageCapture_SetOptions_Params(values) { + this.initDefaults_(); + this.initFields_(values); + } + + + ImageCapture_SetOptions_Params.prototype.initDefaults_ = function() { + this.sourceId = null; + this.settings = null; + }; + ImageCapture_SetOptions_Params.prototype.initFields_ = function(fields) { + for(var field in fields) { + if (this.hasOwnProperty(field)) + this[field] = fields[field]; + } + }; + + ImageCapture_SetOptions_Params.validate = function(messageValidator, offset) { + var err; + err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); + if (err !== validator.validationError.NONE) + return err; + + var kVersionSizes = [ + {version: 0, numBytes: 24} + ]; + err = messageValidator.validateStructVersion(offset, kVersionSizes); + if (err !== validator.validationError.NONE) + return err; + + + // validate ImageCapture_SetOptions_Params.sourceId + err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) + if (err !== validator.validationError.NONE) + return err; + + + // validate ImageCapture_SetOptions_Params.settings + err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 8, PhotoSettings, false); + if (err !== validator.validationError.NONE) + return err; + + return validator.validationError.NONE; + }; + + ImageCapture_SetOptions_Params.encodedSize = codec.kStructHeaderSize + 16; + + ImageCapture_SetOptions_Params.decode = function(decoder) { + var packed; + var val = new ImageCapture_SetOptions_Params(); + var numberOfBytes = decoder.readUint32(); + var version = decoder.readUint32(); + val.sourceId = decoder.decodeStruct(codec.String); + val.settings = decoder.decodeStructPointer(PhotoSettings); + return val; + }; + + ImageCapture_SetOptions_Params.encode = function(encoder, val) { + var packed; + encoder.writeUint32(ImageCapture_SetOptions_Params.encodedSize); + encoder.writeUint32(0); + encoder.encodeStruct(codec.String, val.sourceId); + encoder.encodeStructPointer(PhotoSettings, val.settings); + }; + function ImageCapture_SetOptions_ResponseParams(values) { + this.initDefaults_(); + this.initFields_(values); + } + + + ImageCapture_SetOptions_ResponseParams.prototype.initDefaults_ = function() { + this.success = false; + }; + ImageCapture_SetOptions_ResponseParams.prototype.initFields_ = function(fields) { + for(var field in fields) { + if (this.hasOwnProperty(field)) + this[field] = fields[field]; + } + }; + + ImageCapture_SetOptions_ResponseParams.validate = function(messageValidator, offset) { + var err; + err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); + if (err !== validator.validationError.NONE) + return err; + + var kVersionSizes = [ + {version: 0, numBytes: 16} + ]; + err = messageValidator.validateStructVersion(offset, kVersionSizes); + if (err !== validator.validationError.NONE) + return err; + + + return validator.validationError.NONE; + }; + + ImageCapture_SetOptions_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; + + ImageCapture_SetOptions_ResponseParams.decode = function(decoder) { + var packed; + var val = new ImageCapture_SetOptions_ResponseParams(); + var numberOfBytes = decoder.readUint32(); + var version = decoder.readUint32(); + packed = decoder.readUint8(); + val.success = (packed >> 0) & 1 ? true : false; + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + return val; + }; + + ImageCapture_SetOptions_ResponseParams.encode = function(encoder, val) { + var packed; + encoder.writeUint32(ImageCapture_SetOptions_ResponseParams.encodedSize); + encoder.writeUint32(0); + packed = 0; + packed |= (val.success & 1) << 0 + encoder.writeUint8(packed); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + }; + function ImageCapture_TakePhoto_Params(values) { + this.initDefaults_(); + this.initFields_(values); + } + + + ImageCapture_TakePhoto_Params.prototype.initDefaults_ = function() { + this.sourceId = null; + }; + ImageCapture_TakePhoto_Params.prototype.initFields_ = function(fields) { + for(var field in fields) { + if (this.hasOwnProperty(field)) + this[field] = fields[field]; + } + }; + + ImageCapture_TakePhoto_Params.validate = function(messageValidator, offset) { + var err; + err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); + if (err !== validator.validationError.NONE) + return err; + + var kVersionSizes = [ + {version: 0, numBytes: 16} + ]; + err = messageValidator.validateStructVersion(offset, kVersionSizes); + if (err !== validator.validationError.NONE) + return err; + + + // validate ImageCapture_TakePhoto_Params.sourceId + err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) + if (err !== validator.validationError.NONE) + return err; + + return validator.validationError.NONE; + }; + + ImageCapture_TakePhoto_Params.encodedSize = codec.kStructHeaderSize + 8; + + ImageCapture_TakePhoto_Params.decode = function(decoder) { + var packed; + var val = new ImageCapture_TakePhoto_Params(); + var numberOfBytes = decoder.readUint32(); + var version = decoder.readUint32(); + val.sourceId = decoder.decodeStruct(codec.String); + return val; + }; + + ImageCapture_TakePhoto_Params.encode = function(encoder, val) { + var packed; + encoder.writeUint32(ImageCapture_TakePhoto_Params.encodedSize); + encoder.writeUint32(0); + encoder.encodeStruct(codec.String, val.sourceId); + }; + function ImageCapture_TakePhoto_ResponseParams(values) { + this.initDefaults_(); + this.initFields_(values); + } + + + ImageCapture_TakePhoto_ResponseParams.prototype.initDefaults_ = function() { + this.blob = null; + }; + ImageCapture_TakePhoto_ResponseParams.prototype.initFields_ = function(fields) { + for(var field in fields) { + if (this.hasOwnProperty(field)) + this[field] = fields[field]; + } + }; + + ImageCapture_TakePhoto_ResponseParams.validate = function(messageValidator, offset) { + var err; + err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); + if (err !== validator.validationError.NONE) + return err; + + var kVersionSizes = [ + {version: 0, numBytes: 16} + ]; + err = messageValidator.validateStructVersion(offset, kVersionSizes); + if (err !== validator.validationError.NONE) + return err; + + + // validate ImageCapture_TakePhoto_ResponseParams.blob + err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, Blob, false); + if (err !== validator.validationError.NONE) + return err; + + return validator.validationError.NONE; + }; + + ImageCapture_TakePhoto_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; + + ImageCapture_TakePhoto_ResponseParams.decode = function(decoder) { + var packed; + var val = new ImageCapture_TakePhoto_ResponseParams(); + var numberOfBytes = decoder.readUint32(); + var version = decoder.readUint32(); + val.blob = decoder.decodeStructPointer(Blob); + return val; + }; + + ImageCapture_TakePhoto_ResponseParams.encode = function(encoder, val) { + var packed; + encoder.writeUint32(ImageCapture_TakePhoto_ResponseParams.encodedSize); + encoder.writeUint32(0); + encoder.encodeStructPointer(Blob, val.blob); + }; + var kImageCapture_GetPhotoState_Name = 0; + var kImageCapture_SetOptions_Name = 1; + var kImageCapture_TakePhoto_Name = 2; + + function ImageCapturePtr(handleOrPtrInfo) { + this.ptr = new bindings.InterfacePtrController(ImageCapture, + handleOrPtrInfo); + } + + function ImageCaptureAssociatedPtr(associatedInterfacePtrInfo) { + this.ptr = new associatedBindings.AssociatedInterfacePtrController( + ImageCapture, associatedInterfacePtrInfo); + } + + ImageCaptureAssociatedPtr.prototype = + Object.create(ImageCapturePtr.prototype); + ImageCaptureAssociatedPtr.prototype.constructor = + ImageCaptureAssociatedPtr; + + function ImageCaptureProxy(receiver) { + this.receiver_ = receiver; + } + ImageCapturePtr.prototype.getPhotoState = function() { + return ImageCaptureProxy.prototype.getPhotoState + .apply(this.ptr.getProxy(), arguments); + }; + + ImageCaptureProxy.prototype.getPhotoState = function(sourceId) { + var params_ = new ImageCapture_GetPhotoState_Params(); + params_.sourceId = sourceId; + return new Promise(function(resolve, reject) { + var builder = new codec.MessageV1Builder( + kImageCapture_GetPhotoState_Name, + codec.align(ImageCapture_GetPhotoState_Params.encodedSize), + codec.kMessageExpectsResponse, 0); + builder.encodeStruct(ImageCapture_GetPhotoState_Params, params_); + var message = builder.finish(); + this.receiver_.acceptAndExpectResponse(message).then(function(message) { + var reader = new codec.MessageReader(message); + var responseParams = + reader.decodeStruct(ImageCapture_GetPhotoState_ResponseParams); + resolve(responseParams); + }).catch(function(result) { + reject(Error("Connection error: " + result)); + }); + }.bind(this)); + }; + ImageCapturePtr.prototype.setOptions = function() { + return ImageCaptureProxy.prototype.setOptions + .apply(this.ptr.getProxy(), arguments); + }; + + ImageCaptureProxy.prototype.setOptions = function(sourceId, settings) { + var params_ = new ImageCapture_SetOptions_Params(); + params_.sourceId = sourceId; + params_.settings = settings; + return new Promise(function(resolve, reject) { + var builder = new codec.MessageV1Builder( + kImageCapture_SetOptions_Name, + codec.align(ImageCapture_SetOptions_Params.encodedSize), + codec.kMessageExpectsResponse, 0); + builder.encodeStruct(ImageCapture_SetOptions_Params, params_); + var message = builder.finish(); + this.receiver_.acceptAndExpectResponse(message).then(function(message) { + var reader = new codec.MessageReader(message); + var responseParams = + reader.decodeStruct(ImageCapture_SetOptions_ResponseParams); + resolve(responseParams); + }).catch(function(result) { + reject(Error("Connection error: " + result)); + }); + }.bind(this)); + }; + ImageCapturePtr.prototype.takePhoto = function() { + return ImageCaptureProxy.prototype.takePhoto + .apply(this.ptr.getProxy(), arguments); + }; + + ImageCaptureProxy.prototype.takePhoto = function(sourceId) { + var params_ = new ImageCapture_TakePhoto_Params(); + params_.sourceId = sourceId; + return new Promise(function(resolve, reject) { + var builder = new codec.MessageV1Builder( + kImageCapture_TakePhoto_Name, + codec.align(ImageCapture_TakePhoto_Params.encodedSize), + codec.kMessageExpectsResponse, 0); + builder.encodeStruct(ImageCapture_TakePhoto_Params, params_); + var message = builder.finish(); + this.receiver_.acceptAndExpectResponse(message).then(function(message) { + var reader = new codec.MessageReader(message); + var responseParams = + reader.decodeStruct(ImageCapture_TakePhoto_ResponseParams); + resolve(responseParams); + }).catch(function(result) { + reject(Error("Connection error: " + result)); + }); + }.bind(this)); + }; + + function ImageCaptureStub(delegate) { + this.delegate_ = delegate; + } + ImageCaptureStub.prototype.getPhotoState = function(sourceId) { + return this.delegate_ && this.delegate_.getPhotoState && this.delegate_.getPhotoState(sourceId); + } + ImageCaptureStub.prototype.setOptions = function(sourceId, settings) { + return this.delegate_ && this.delegate_.setOptions && this.delegate_.setOptions(sourceId, settings); + } + ImageCaptureStub.prototype.takePhoto = function(sourceId) { + return this.delegate_ && this.delegate_.takePhoto && this.delegate_.takePhoto(sourceId); + } + + ImageCaptureStub.prototype.accept = function(message) { + var reader = new codec.MessageReader(message); + switch (reader.messageName) { + default: + return false; + } + }; + + ImageCaptureStub.prototype.acceptWithResponder = + function(message, responder) { + var reader = new codec.MessageReader(message); + switch (reader.messageName) { + case kImageCapture_GetPhotoState_Name: + var params = reader.decodeStruct(ImageCapture_GetPhotoState_Params); + this.getPhotoState(params.sourceId).then(function(response) { + var responseParams = + new ImageCapture_GetPhotoState_ResponseParams(); + responseParams.state = response.state; + var builder = new codec.MessageV1Builder( + kImageCapture_GetPhotoState_Name, + codec.align(ImageCapture_GetPhotoState_ResponseParams.encodedSize), + codec.kMessageIsResponse, reader.requestID); + builder.encodeStruct(ImageCapture_GetPhotoState_ResponseParams, + responseParams); + var message = builder.finish(); + responder.accept(message); + }); + return true; + case kImageCapture_SetOptions_Name: + var params = reader.decodeStruct(ImageCapture_SetOptions_Params); + this.setOptions(params.sourceId, params.settings).then(function(response) { + var responseParams = + new ImageCapture_SetOptions_ResponseParams(); + responseParams.success = response.success; + var builder = new codec.MessageV1Builder( + kImageCapture_SetOptions_Name, + codec.align(ImageCapture_SetOptions_ResponseParams.encodedSize), + codec.kMessageIsResponse, reader.requestID); + builder.encodeStruct(ImageCapture_SetOptions_ResponseParams, + responseParams); + var message = builder.finish(); + responder.accept(message); + }); + return true; + case kImageCapture_TakePhoto_Name: + var params = reader.decodeStruct(ImageCapture_TakePhoto_Params); + this.takePhoto(params.sourceId).then(function(response) { + var responseParams = + new ImageCapture_TakePhoto_ResponseParams(); + responseParams.blob = response.blob; + var builder = new codec.MessageV1Builder( + kImageCapture_TakePhoto_Name, + codec.align(ImageCapture_TakePhoto_ResponseParams.encodedSize), + codec.kMessageIsResponse, reader.requestID); + builder.encodeStruct(ImageCapture_TakePhoto_ResponseParams, + responseParams); + var message = builder.finish(); + responder.accept(message); + }); + return true; + default: + return false; + } + }; + + function validateImageCaptureRequest(messageValidator) { + var message = messageValidator.message; + var paramsClass = null; + switch (message.getName()) { + case kImageCapture_GetPhotoState_Name: + if (message.expectsResponse()) + paramsClass = ImageCapture_GetPhotoState_Params; + break; + case kImageCapture_SetOptions_Name: + if (message.expectsResponse()) + paramsClass = ImageCapture_SetOptions_Params; + break; + case kImageCapture_TakePhoto_Name: + if (message.expectsResponse()) + paramsClass = ImageCapture_TakePhoto_Params; + break; + } + if (paramsClass === null) + return validator.validationError.NONE; + return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); + } + + function validateImageCaptureResponse(messageValidator) { + var message = messageValidator.message; + var paramsClass = null; + switch (message.getName()) { + case kImageCapture_GetPhotoState_Name: + if (message.isResponse()) + paramsClass = ImageCapture_GetPhotoState_ResponseParams; + break; + case kImageCapture_SetOptions_Name: + if (message.isResponse()) + paramsClass = ImageCapture_SetOptions_ResponseParams; + break; + case kImageCapture_TakePhoto_Name: + if (message.isResponse()) + paramsClass = ImageCapture_TakePhoto_ResponseParams; + break; + } + if (paramsClass === null) + return validator.validationError.NONE; + return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); + } + + var ImageCapture = { + name: 'media.mojom.ImageCapture', + kVersion: 0, + ptrClass: ImageCapturePtr, + proxyClass: ImageCaptureProxy, + stubClass: ImageCaptureStub, + validateRequest: validateImageCaptureRequest, + validateResponse: validateImageCaptureResponse, + }; + ImageCaptureStub.prototype.validator = validateImageCaptureRequest; + ImageCaptureProxy.prototype.validator = validateImageCaptureResponse; + exports.MeteringMode = MeteringMode; + exports.RedEyeReduction = RedEyeReduction; + exports.FillLightMode = FillLightMode; + exports.Range = Range; + exports.PhotoState = PhotoState; + exports.Point2D = Point2D; + exports.PhotoSettings = PhotoSettings; + exports.Blob = Blob; + exports.ImageCapture = ImageCapture; + exports.ImageCapturePtr = ImageCapturePtr; + exports.ImageCaptureAssociatedPtr = ImageCaptureAssociatedPtr; +})(); \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/resources/chromium/mock-imagecapture.js b/tests/wpt/web-platform-tests/resources/chromium/mock-imagecapture.js new file mode 100644 index 00000000000..878f59eb009 --- /dev/null +++ b/tests/wpt/web-platform-tests/resources/chromium/mock-imagecapture.js @@ -0,0 +1,236 @@ +"use strict"; + +var ImageCaptureTest = (() => { + // Class that mocks ImageCapture interface defined in + // https://cs.chromium.org/chromium/src/media/capture/mojom/image_capture.mojom + class MockImageCapture { + constructor() { + this.interceptor_ = new MojoInterfaceInterceptor( + media.mojom.ImageCapture.name); + this.interceptor_.oninterfacerequest = + e => this.bindingSet_.addBinding(this, e.handle); + this.interceptor_.start(); + + this.state_ = { + state: { + supportedWhiteBalanceModes: [ + media.mojom.MeteringMode.SINGLE_SHOT, + media.mojom.MeteringMode.CONTINUOUS + ], + currentWhiteBalanceMode: media.mojom.MeteringMode.CONTINUOUS, + supportedExposureModes: [ + media.mojom.MeteringMode.SINGLE_SHOT, + media.mojom.MeteringMode.CONTINUOUS + ], + currentExposureMode: media.mojom.MeteringMode.SINGLE_SHOT, + supportedFocusModes: [ + media.mojom.MeteringMode.MANUAL, + media.mojom.MeteringMode.SINGLE_SHOT + ], + currentFocusMode: media.mojom.MeteringMode.MANUAL, + pointsOfInterest: [{ + x: 0.4, + y: 0.6 + }], + + exposureCompensation: { + min: -200.0, + max: 200.0, + current: 33.0, + step: 33.0 + }, + colorTemperature: { + min: 2500.0, + max: 6500.0, + current: 6000.0, + step: 1000.0 + }, + iso: { + min: 100.0, + max: 12000.0, + current: 400.0, + step: 1.0 + }, + + brightness: { + min: 1.0, + max: 10.0, + current: 5.0, + step: 1.0 + }, + contrast: { + min: 2.0, + max: 9.0, + current: 5.0, + step: 1.0 + }, + saturation: { + min: 3.0, + max: 8.0, + current: 6.0, + step: 1.0 + }, + sharpness: { + min: 4.0, + max: 7.0, + current: 7.0, + step: 1.0 + }, + + focusDistance: { + min: 1.0, + max: 10.0, + current: 3.0, + step: 1.0 + }, + + zoom: { + min: 0.0, + max: 10.0, + current: 5.0, + step: 5.0 + }, + + supportsTorch: true, + torch: false, + + redEyeReduction: media.mojom.RedEyeReduction.CONTROLLABLE, + height: { + min: 240.0, + max: 2448.0, + current: 240.0, + step: 2.0 + }, + width: { + min: 320.0, + max: 3264.0, + current: 320.0, + step: 3.0 + }, + fillLightMode: [ + media.mojom.FillLightMode.AUTO, media.mojom.FillLightMode.FLASH + ], + } + }; + this.settings_ = null; + this.bindingSet_ = new mojo.BindingSet(media.mojom.ImageCapture); + } + + reset() { + this.bindingSet_.closeAllBindings(); + this.interceptor_.stop(); + } + + getPhotoState(source_id) { + return Promise.resolve(this.state_); + } + + setOptions(source_id, settings) { + this.settings_ = settings; + if (settings.hasIso) + this.state_.state.iso.current = settings.iso; + if (settings.hasHeight) + this.state_.state.height.current = settings.height; + if (settings.hasWidth) + this.state_.state.width.current = settings.width; + if (settings.hasZoom) + this.state_.state.zoom.current = settings.zoom; + if (settings.hasFocusMode) + this.state_.state.currentFocusMode = settings.focusMode; + if (settings.hasFocusDistance) + this.state_.state.focusDistance.current = settings.focusDistance; + + if (settings.pointsOfInterest.length > 0) { + this.state_.state.pointsOfInterest = + settings.pointsOfInterest; + } + + if (settings.hasExposureMode) + this.state_.state.currentExposureMode = settings.exposureMode; + + if (settings.hasExposureCompensation) { + this.state_.state.exposureCompensation.current = + settings.exposureCompensation; + } + if (settings.hasWhiteBalanceMode) { + this.state_.state.currentWhiteBalanceMode = + settings.whiteBalanceMode; + } + if (settings.hasFillLightMode) + this.state_.state.fillLightMode = [settings.fillLightMode]; + if (settings.hasRedEyeReduction) + this.state_.state.redEyeReduction = settings.redEyeReduction; + if (settings.hasColorTemperature) { + this.state_.state.colorTemperature.current = + settings.colorTemperature; + } + if (settings.hasBrightness) + this.state_.state.brightness.current = settings.brightness; + if (settings.hasContrast) + this.state_.state.contrast.current = settings.contrast; + if (settings.hasSaturation) + this.state_.state.saturation.current = settings.saturation; + if (settings.hasSharpness) + this.state_.state.sharpness.current = settings.sharpness; + + if (settings.hasTorch) + this.state_.state.torch = settings.torch; + + return Promise.resolve({ + success: true + }); + } + + takePhoto(source_id) { + return Promise.resolve({ + blob: { + mimeType: 'image/cat', + data: new Array(2) + } + }); + } + + state() { + return this.state_.state; + } + + options() { + return this.settings_; + } + } + + let testInternal = { + initialized: false, + mockImageCapture: null + } + + class ImageCaptureTestChromium { + + constructor() { + Object.freeze(this); // Make it immutable. + } + + initialize() { + if (testInternal.initialized) + throw new Error('Call reset() before initialize().'); + + testInternal.mockImageCapture = new MockImageCapture; + testInternal.initialized = true; + } + // Resets state of image capture mocks between test runs. + async reset() { + if (!testInternal.initialized) + throw new Error('Call initialize() before reset().'); + testInternal.mockImageCapture.reset(); + testInternal.mockImageCapture = null; + testInternal.initialized = false; + + await new Promise(resolve => setTimeout(resolve, 0)); + } + mockImageCapture() { + return testInternal.mockImageCapture; + } + } + + return ImageCaptureTestChromium; +})(); \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/resources/chromium/sensor.mojom.js b/tests/wpt/web-platform-tests/resources/chromium/sensor.mojom.js index daa99217335..ffbd25b57df 100644 --- a/tests/wpt/web-platform-tests/resources/chromium/sensor.mojom.js +++ b/tests/wpt/web-platform-tests/resources/chromium/sensor.mojom.js @@ -20,8 +20,7 @@ var SensorType = {}; - SensorType.FIRST = 1; - SensorType.AMBIENT_LIGHT = SensorType.FIRST; + SensorType.AMBIENT_LIGHT = 0; SensorType.PROXIMITY = SensorType.AMBIENT_LIGHT + 1; SensorType.ACCELEROMETER = SensorType.PROXIMITY + 1; SensorType.LINEAR_ACCELERATION = SensorType.ACCELEROMETER + 1; @@ -32,10 +31,10 @@ SensorType.ABSOLUTE_ORIENTATION_QUATERNION = SensorType.ABSOLUTE_ORIENTATION_EULER_ANGLES + 1; SensorType.RELATIVE_ORIENTATION_EULER_ANGLES = SensorType.ABSOLUTE_ORIENTATION_QUATERNION + 1; SensorType.RELATIVE_ORIENTATION_QUATERNION = SensorType.RELATIVE_ORIENTATION_EULER_ANGLES + 1; - SensorType.LAST = SensorType.RELATIVE_ORIENTATION_QUATERNION; SensorType.isKnownEnumValue = function(value) { switch (value) { + case 0: case 1: case 2: case 3: @@ -46,7 +45,6 @@ case 8: case 9: case 10: - case 11: return true; } return false; diff --git a/tests/wpt/web-platform-tests/resources/chromium/webusb-child-test.js b/tests/wpt/web-platform-tests/resources/chromium/webusb-child-test.js new file mode 100644 index 00000000000..add04fa5825 --- /dev/null +++ b/tests/wpt/web-platform-tests/resources/chromium/webusb-child-test.js @@ -0,0 +1,40 @@ +'use strict'; + +// This polyfill prepares a child context to be attached to a parent context. +// The parent must call navigator.usb.test.attachToContext() to attach to the +// child context. +(() => { + if (this.constructor.name === 'DedicatedWorkerGlobalScope' || + this !== window.top) { + + // Run Chromium specific set up code. + if (typeof MojoInterfaceInterceptor !== 'undefined') { + let messageChannel = new MessageChannel(); + messageChannel.port1.onmessage = async (messageEvent) => { + if (messageEvent.data.type === 'Attach') { + messageEvent.data.interfaces.forEach(interfaceName => { + let interfaceInterceptor = + new MojoInterfaceInterceptor(interfaceName); + interfaceInterceptor.oninterfacerequest = + e => messageChannel.port1.postMessage({ + type: interfaceName, + handle: e.handle + }, [e.handle]); + interfaceInterceptor.start(); + }); + + // Wait for a call to GetDevices() to ensure that the interface + // handles are forwarded to the parent context. + await navigator.usb.getDevices(); + messageChannel.port1.postMessage({ type: 'Complete' }); + } + }; + + let message = { type: 'ReadyForAttachment', port: messageChannel.port2 }; + if (typeof Window !== 'undefined') + parent.postMessage(message, '*', [messageChannel.port2]); + else + postMessage(message, [messageChannel.port2]); + } + } +})(); diff --git a/tests/wpt/web-platform-tests/resources/chromium/webusb-child-test.js.headers b/tests/wpt/web-platform-tests/resources/chromium/webusb-child-test.js.headers new file mode 100644 index 00000000000..6805c323df5 --- /dev/null +++ b/tests/wpt/web-platform-tests/resources/chromium/webusb-child-test.js.headers @@ -0,0 +1 @@ +Content-Type: text/javascript; charset=utf-8 diff --git a/tests/wpt/web-platform-tests/resources/chromium/webusb-test.js b/tests/wpt/web-platform-tests/resources/chromium/webusb-test.js index 9037a109c91..5f9262655f3 100644 --- a/tests/wpt/web-platform-tests/resources/chromium/webusb-test.js +++ b/tests/wpt/web-platform-tests/resources/chromium/webusb-test.js @@ -12,9 +12,23 @@ let internal = { webUsbService: null, webUsbServiceInterceptor: null, - webUsbServiceCrossFrameProxy: null, + + messagePort: null, }; +function getMessagePort(target) { + return new Promise(resolve => { + target.addEventListener('message', messageEvent => { + if (messageEvent.data.type === 'ReadyForAttachment') { + if (internal.messagePort === null) { + internal.messagePort = messageEvent.data.port; + } + resolve(); + } + }, {once: true}); + }); +} + // Converts an ECMAScript String object to an instance of // mojo_base.mojom.String16. function mojoString16ToString(string16) { @@ -421,25 +435,6 @@ class FakeUSBDevice { } } -// A helper for forwarding MojoHandle instances from one frame to another. -class CrossFrameHandleProxy { - constructor(callback) { - let {handle0, handle1} = Mojo.createMessagePipe(); - this.sender_ = handle0; - this.receiver_ = handle1; - this.receiver_.watch({readable: true}, () => { - let message = this.receiver_.readMessage(); - assert_equals(message.buffer.byteLength, 0); - assert_equals(message.handles.length, 1); - callback(message.handles[0]); - }); - } - - forwardHandle(handle) { - this.sender_.writeMessage(new ArrayBuffer, [handle]); - } -} - class USBTest { constructor() { this.onrequestdevice = undefined; @@ -449,14 +444,17 @@ class USBTest { if (internal.initialized) return; + // Be ready to handle 'ReadyForAttachment' message from child iframes. + if ('window' in self) { + getMessagePort(window); + } + internal.webUsbService = new FakeWebUsbService(); internal.webUsbServiceInterceptor = new MojoInterfaceInterceptor(blink.mojom.WebUsbService.name); internal.webUsbServiceInterceptor.oninterfacerequest = e => internal.webUsbService.addBinding(e.handle); internal.webUsbServiceInterceptor.start(); - internal.webUsbServiceCrossFrameProxy = new CrossFrameHandleProxy( - handle => internal.webUsbService.addBinding(handle)); // Wait for a call to GetDevices() to pass between the renderer and the // mock in order to establish that everything is set up. @@ -464,20 +462,32 @@ class USBTest { internal.initialized = true; } - async attachToWindow(otherWindow) { + // Returns a promise that is resolved when the implementation of |usb| in the + // global scope for |context| is controlled by the current context. + attachToContext(context) { if (!internal.initialized) - throw new Error('Call initialize() before attachToWindow().'); + throw new Error('Call initialize() before attachToContext()'); - otherWindow.webUsbServiceInterceptor = - new otherWindow.MojoInterfaceInterceptor( - blink.mojom.WebUsbService.name); - otherWindow.webUsbServiceInterceptor.oninterfacerequest = - e => internal.webUsbServiceCrossFrameProxy.forwardHandle(e.handle); - otherWindow.webUsbServiceInterceptor.start(); - - // Wait for a call to GetDevices() to pass between the renderer and the - // mock in order to establish that everything is set up. - await otherWindow.navigator.usb.getDevices(); + let target = context.constructor.name === 'Worker' ? context : window; + return getMessagePort(target).then(() => { + return new Promise(resolve => { + internal.messagePort.onmessage = channelEvent => { + switch (channelEvent.data.type) { + case blink.mojom.WebUsbService.name: + internal.webUsbService.addBinding(channelEvent.data.handle); + break; + case 'Complete': + resolve(); + break; + } + }; + internal.messagePort.postMessage({ + type: 'Attach' , + interfaces: [ + blink.mojom.WebUsbService.name, + ]}); + }); + }); } addFakeDevice(deviceInit) { @@ -501,6 +511,9 @@ class USBTest { // the fact that this polyfill can do this synchronously. return new Promise(resolve => { setTimeout(() => { + if (internal.messagePort !== null) + internal.messagePort.close(); + internal.messagePort = null; internal.webUsbService.removeAllDevices(); resolve(); }, 0); diff --git a/tests/wpt/web-platform-tests/resources/idlharness.js b/tests/wpt/web-platform-tests/resources/idlharness.js index 368c96d70cf..746f3e65503 100644 --- a/tests/wpt/web-platform-tests/resources/idlharness.js +++ b/tests/wpt/web-platform-tests/resources/idlharness.js @@ -826,7 +826,7 @@ IdlArray.prototype.test = function() this["includes"] = {}; // Assert B defined for A : B - for (var member of Object.values(this.members).filter(m => m.base)) { + for (const member of Object.values(this.members).filter(m => m.base)) { const lhs = member.name; const rhs = member.base; if (!(rhs in this.members)) throw new IdlHarnessError(`${lhs} inherits ${rhs}, but ${rhs} is undefined.`); @@ -2894,6 +2894,11 @@ IdlInterface.prototype.do_interface_attribute_asserts = function(obj, member, a_ // value 0." assert_equals(desc.get.length, 0, "getter length must be 0"); + // "Let name be the string "get " prepended to attribute’s identifier." + // "Perform ! SetFunctionName(F, name)." + assert_equals(desc.get.name, "get " + member.name, + "getter must have the name 'get " + member.name + "'"); + // TODO: Test calling setter on the interface prototype (should throw // TypeError in most cases). @@ -2934,6 +2939,11 @@ IdlInterface.prototype.do_interface_attribute_asserts = function(obj, member, a_ // "The value of the Function object’s “length” property is the Number // value 1." assert_equals(desc.set.length, 1, "setter length must be 1"); + + // "Let name be the string "set " prepended to id." + // "Perform ! SetFunctionName(F, name)." + assert_equals(desc.set.name, "set " + member.name, + "The attribute setter must have the name 'set " + member.name + "'"); } Promise.all(pendingPromises).then(a_test.done.bind(a_test)); diff --git a/tests/wpt/web-platform-tests/resources/test/tests/functional/promise.html b/tests/wpt/web-platform-tests/resources/test/tests/functional/promise.html index bdf6dc3ec2a..9db1dec0f9e 100644 --- a/tests/wpt/web-platform-tests/resources/test/tests/functional/promise.html +++ b/tests/wpt/web-platform-tests/resources/test/tests/functional/promise.html @@ -100,11 +100,15 @@ promise_test( function() { return true; }, - "promise_test with function that doesn't return a Promise"); + "promise_test with function that doesn't return a Promise (should FAIL)"); promise_test(function(){}, "promise_test with function that doesn't return anything"); +promise_test( + function() { return { then: 23 }; }, + "promise_test that returns a non-thenable (should FAIL)"); + promise_test( function() { return Promise.reject("Expected rejection"); @@ -170,15 +174,21 @@ promise_test( "properties": {} }, { - "status_string": "PASS", - "name": "promise_test with function that doesn't return a Promise", - "message": null, + "status_string": "FAIL", + "name": "promise_test with function that doesn't return a Promise (should FAIL)", + "message": "promise_test: test body must return a 'thenable' object (received an object with no `then` method)", "properties": {} }, { "status_string": "FAIL", "name": "promise_test with function that doesn't return anything", - "message": "assert_not_equals: got disallowed value undefined", + "message": "promise_test: test body must return a 'thenable' object (received undefined)", + "properties": {} + }, + { + "status_string": "FAIL", + "name": "promise_test that returns a non-thenable (should FAIL)", + "message": "promise_test: test body must return a 'thenable' object (received an object with no `then` method)", "properties": {} }, { diff --git a/tests/wpt/web-platform-tests/resources/testharness.js b/tests/wpt/web-platform-tests/resources/testharness.js index f0c24635017..85e211ff60a 100644 --- a/tests/wpt/web-platform-tests/resources/testharness.js +++ b/tests/wpt/web-platform-tests/resources/testharness.js @@ -576,7 +576,12 @@ policies and contribution forms [3]. var promise = test.step(func, test, test); test.step(function() { - assert_not_equals(promise, undefined); + assert(!!promise, "promise_test", null, + "test body must return a 'thenable' object (received ${value})", + {value:promise}); + assert(typeof promise.then === "function", "promise_test", null, + "test body must return a 'thenable' object (received an object with no `then` method)", + null); }); // Test authors may use the `step` method within a diff --git a/tests/wpt/web-platform-tests/screen-capture/getdisplaymedia.https.html b/tests/wpt/web-platform-tests/screen-capture/getdisplaymedia.https.html index 3a0444733b5..9b66419cb0a 100644 --- a/tests/wpt/web-platform-tests/screen-capture/getdisplaymedia.https.html +++ b/tests/wpt/web-platform-tests/screen-capture/getdisplaymedia.https.html @@ -74,4 +74,18 @@ promise_test(function() { }); }, 'getDisplayMedia() call with non-bool constraint'); +// Content shell picks a fake desktop device by default. +promise_test(function() { + assert_idl_attribute(navigator, 'getDisplayMedia'); + + return navigator.getDisplayMedia({video: true}).then(function(s) { + assert_equals(s.getVideoTracks().length, 1); + assert_equals(s.getAudioTracks().length, 0); + var settings = s.getVideoTracks()[0].getSettings(); + assert_equals(settings.displaySurface, "monitor"); + assert_equals(settings.logicalSurface, true); + assert_equals(settings.cursor, "never"); + }); +}, 'getDisplayMedia() with getSettings'); + diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-referrer-policy.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-referrer-policy.https.html index 9b67faccac8..73ae123ae4e 100644 --- a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-referrer-policy.https.html +++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-referrer-policy.https.html @@ -7,12 +7,19 @@ diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/redirected-response.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/redirected-response.https.html index f7370e023b1..05a94e2fd1d 100644 --- a/tests/wpt/web-platform-tests/service-workers/service-worker/redirected-response.https.html +++ b/tests/wpt/web-platform-tests/service-workers/service-worker/redirected-response.https.html @@ -49,12 +49,15 @@ function redirected_test(options) { }); } -function take_intercepted_urls() { - return new Promise((resolve) => { - let channel = new MessageChannel(); - channel.port1.onmessage = msg => { resolve(msg.data.urls); }; - worker.postMessage({port: channel.port2}, [channel.port2]); - }); +async function take_intercepted_urls() { + const message = new Promise((resolve) => { + let channel = new MessageChannel(); + channel.port1.onmessage = msg => { resolve(msg.data.requestInfos); }; + worker.postMessage({command: 'getRequestInfos', port: channel.port2}, + [channel.port2]); + }); + const request_infos = await message; + return request_infos.map(info => { return info.url; }); } function check_intercepted_urls(expected_urls) { diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-other-origin.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-other-origin.html index a9483c65345..0d2825f3109 100644 --- a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-other-origin.html +++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-other-origin.html @@ -33,12 +33,15 @@ function send_result(message_id, result) { host_info['HTTPS_ORIGIN']); } -function get_intercepted_urls(worker) { +function get_request_infos(worker) { return new Promise(function(resolve) { - var channel = new MessageChannel(); - channel.port1.onmessage = function(msg) { resolve(msg.data.urls); }; - worker.postMessage({port: channel.port2}, [channel.port2]); - }); + var channel = new MessageChannel(); + channel.port1.onmessage = (msg) => { + resolve(msg.data.requestInfos); + }; + worker.postMessage({command: 'getRequestInfos', port: channel.port2}, + [channel.port2]); + }); } window.addEventListener('message', on_message, false); @@ -48,14 +51,15 @@ function on_message(e) { console.error('invalid origin: ' + e.origin); return; } - if (e.data.message == 'wait_for_worker') { + const command = e.data.message.command; + if (command == 'wait_for_worker') { wait_for_worker_promise.then(function() { send_result(e.data.id, 'ok'); }); - } else if (e.data.message == 'get_intercepted_urls') { - get_intercepted_urls(worker) - .then(function(urls) { - send_result(e.data.id, urls); + } else if (command == 'get_request_infos') { + get_request_infos(worker) + .then(function(data) { + send_result(e.data.id, data); }); - } else if (e.data.message == 'unregister') { + } else if (command == 'unregister') { registration.unregister() .then(function() { send_result(e.data.id, 'ok'); diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/redirect-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/redirect-worker.js index 7e5ead19419..5258c5e7be4 100644 --- a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/redirect-worker.js +++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/redirect-worker.js @@ -5,20 +5,33 @@ var cacheName = 'urls-' + self.registration.scope; var waitUntilPromiseList = []; -self.addEventListener('message', function(event) { - var urls; - event.waitUntil(Promise.all(waitUntilPromiseList).then(function() { - waitUntilPromiseList = []; - return caches.open(cacheName); - }).then(function(cache) { - return cache.keys(); - }).then(function(requestList) { - urls = requestList.map(function(request) { return request.url; }); - return caches.delete(cacheName); - }).then(function() { - event.data.port.postMessage({urls: urls}); - })); - }); +async function getRequestInfos(event) { + // Wait for fetch events to finish. + await Promise.all(waitUntilPromiseList); + waitUntilPromiseList = []; + + // Generate the message. + const cache = await caches.open(cacheName); + const requestList = await cache.keys(); + const requestInfos = []; + for (let i = 0; i < requestList.length; i++) { + requestInfos[i] = { + url: requestList[i].url, + }; + } + await caches.delete(cacheName); + + event.data.port.postMessage({requestInfos}); +} + +self.addEventListener('message', async function(event) { + if (event.data.command == 'getRequestInfos') { + event.waitUntil(getRequestInfos(event)); + return; + } + + // TODO(falken): Add a getClientInfos command to test Clients API. +}); function get_query_params(url) { var search = (new URL(url)).search; diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/update-top-level-worker.py b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/update-top-level-worker.py deleted file mode 100644 index f77ef284ac0..00000000000 --- a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/update-top-level-worker.py +++ /dev/null @@ -1,18 +0,0 @@ -import time - -def main(request, response): - # no-cache itself to ensure the user agent finds a new version for each update. - headers = [('Cache-Control', 'no-cache, must-revalidate'), - ('Pragma', 'no-cache')] - content_type = 'application/javascript' - - headers.append(('Content-Type', content_type)) - - body = ''' -let promise = self.registration.update() -onmessage = (evt) => { - promise.then(r => { - evt.source.postMessage(self.registration === r ? 'PASS' : 'FAIL'); - }); -};''' - return headers, '/* %s %s */ %s' % (time.time(), time.clock(), body) diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/update-top-level.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/update-top-level.https.html deleted file mode 100644 index e382028b44a..00000000000 --- a/tests/wpt/web-platform-tests/service-workers/service-worker/update-top-level.https.html +++ /dev/null @@ -1,32 +0,0 @@ - -Service Worker: Registration update() - - - - diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/webvtt-cross-origin.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/webvtt-cross-origin.https.html index 637f494e4c1..9394ff75c4a 100644 --- a/tests/wpt/web-platform-tests/service-workers/service-worker/webvtt-cross-origin.https.html +++ b/tests/wpt/web-platform-tests/service-workers/service-worker/webvtt-cross-origin.https.html @@ -7,11 +7,14 @@ diff --git a/tests/wpt/web-platform-tests/shadow-dom/Extensions-to-Event-Interface.html b/tests/wpt/web-platform-tests/shadow-dom/Extensions-to-Event-Interface.html index 52cda0b6bb8..806d539cad4 100644 --- a/tests/wpt/web-platform-tests/shadow-dom/Extensions-to-Event-Interface.html +++ b/tests/wpt/web-platform-tests/shadow-dom/Extensions-to-Event-Interface.html @@ -54,7 +54,7 @@ function testComposedEvent(mode) { var expectedPath = ['A1a', 'A1-SR', 'A1', 'A-SR', 'A']; assert_array_equals(log.eventPath, expectedPath); - assert_array_equals(log.eventPath.length, log.pathAtTargets.length); + assert_equals(log.eventPath.length, log.pathAtTargets.length); assert_array_equals(log.pathAtTargets[0], expectedPath); assert_array_equals(log.pathAtTargets[1], expectedPath); assert_array_equals(log.pathAtTargets[2], mode == 'open' ? expectedPath : ['A1', 'A-SR', 'A'], @@ -82,7 +82,7 @@ function testNonComposedEvent(mode) { var expectedPath = ['A1a', 'A1-SR']; assert_array_equals(log.eventPath, expectedPath); - assert_array_equals(log.eventPath.length, log.pathAtTargets.length); + assert_equals(log.eventPath.length, log.pathAtTargets.length); assert_array_equals(log.pathAtTargets[0], expectedPath); assert_array_equals(log.pathAtTargets[1], expectedPath); }, 'The event must not propagate out of ' + mode + ' mode shadow boundaries when the composed flag is unset'); @@ -108,7 +108,7 @@ function testNonComposedEventWithRelatedTarget(mode) { var expectedPath = ['A1a', 'A1-SR']; assert_array_equals(log.eventPath, expectedPath); - assert_array_equals(log.eventPath.length, log.pathAtTargets.length); + assert_equals(log.eventPath.length, log.pathAtTargets.length); assert_array_equals(log.pathAtTargets[0], expectedPath); assert_array_equals(log.pathAtTargets[1], expectedPath); assert_array_equals(log.relatedTargets, ['A2-S', 'A2-S']); @@ -136,7 +136,7 @@ function testScopedEventWithUnscopedRelatedTargetThroughSlot(mode) { var expectedPath = ['B1a', 'B1c-S', 'B1-SR', 'B1', 'B-SR']; var pathExposedToB1a = ['B1a', 'B1', 'B-SR']; assert_array_equals(log.eventPath, expectedPath); - assert_array_equals(log.eventPath.length, log.pathAtTargets.length); + assert_equals(log.eventPath.length, log.pathAtTargets.length); assert_array_equals(log.pathAtTargets[0], mode == 'open' ? expectedPath : pathExposedToB1a); assert_array_equals(log.pathAtTargets[1], expectedPath); assert_array_equals(log.pathAtTargets[2], expectedPath); @@ -167,7 +167,7 @@ function testComposedEventWithRelatedTarget(mode) { var expectedPath = ['A1a', 'A1-SR', 'A1', 'A-SR']; var pathExposedToA1 = ['A1', 'A-SR']; assert_array_equals(log.eventPath, expectedPath); - assert_array_equals(log.eventPath.length, log.pathAtTargets.length); + assert_equals(log.eventPath.length, log.pathAtTargets.length); assert_array_equals(log.pathAtTargets[0], expectedPath); assert_array_equals(log.pathAtTargets[1], expectedPath); assert_array_equals(log.pathAtTargets[2], mode == 'open' ? expectedPath : pathExposedToA1); @@ -202,7 +202,7 @@ function testComposedEventThroughSlot(mode) { var pathExposedToA1 = [ 'B', 'A2-S', 'A-SR', 'A']; assert_array_equals(log.eventPath, expectedPath); - assert_array_equals(log.eventPath.length, log.pathAtTargets.length); + assert_equals(log.eventPath.length, log.pathAtTargets.length); assert_array_equals(log.pathAtTargets[0], mode == 'open' ? expectedPath : pathExposedToB1a); assert_array_equals(log.pathAtTargets[1], mode == 'open' ? expectedPath : pathExposedToB1cS); assert_array_equals(log.pathAtTargets[2], mode == 'open' ? expectedPath : pathExposedToB1cS); diff --git a/tests/wpt/web-platform-tests/shadow-dom/leaktests/get-elements.html b/tests/wpt/web-platform-tests/shadow-dom/leaktests/get-elements.html index 2ce916a650e..40fa9b69314 100644 --- a/tests/wpt/web-platform-tests/shadow-dom/leaktests/get-elements.html +++ b/tests/wpt/web-platform-tests/shadow-dom/leaktests/get-elements.html @@ -85,12 +85,12 @@ test(function() { assert_equals(doc.querySelectorAll('.bar').length, 1); assert_equals(doc.getElementsByClassName('bar')[0].getAttribute('label'), 'doc-div'); - assert_array_equals(hostOpen.querySelectorAll('.bar').length, 0); + assert_equals(hostOpen.querySelectorAll('.bar').length, 0); assert_equals(shadowOpen.querySelectorAll('.bar').length, 1); assert_equals(shadowOpen.querySelectorAll('.bar')[0].getAttribute('label'), 'shadow-open-div'); - assert_array_equals(hostClosed.querySelectorAll('.bar').length, 0); + assert_equals(hostClosed.querySelectorAll('.bar').length, 0); assert_equals(shadowClosed.querySelectorAll('.bar').length, 1); assert_equals(shadowClosed.querySelectorAll('.bar')[0].getAttribute('label'), 'shadow-closed-div'); @@ -106,11 +106,11 @@ test(function() { assert_equals(doc.querySelectorAll('[name=baz]').length, 1); - assert_array_equals(hostOpen.querySelectorAll('[name=baz]').length, 0); + assert_equals(hostOpen.querySelectorAll('[name=baz]').length, 0); assert_equals(shadowOpen.querySelectorAll('[name=baz]').length, 1); assert_equals(shadowOpen.querySelectorAll('[name=baz]')[0].getAttribute('label'), 'shadow-open-form'); - assert_array_equals(hostClosed.querySelectorAll('[name=baz]').length, 0); + assert_equals(hostClosed.querySelectorAll('[name=baz]').length, 0); assert_equals(shadowClosed.querySelectorAll('[name=baz]').length, 1); assert_equals(shadowClosed.querySelectorAll('[name=baz]')[0].getAttribute('label'), 'shadow-closed-form'); }, 'getElementsByName() should not leak nodes in shadow tree'); @@ -126,12 +126,12 @@ test(function() { assert_equals(doc.querySelectorAll('my-element').length, 1); assert_equals(doc.getElementsByTagName('my-element')[0].getAttribute('label'), 'doc-my-element'); - assert_array_equals(hostOpen.querySelectorAll('my-element').length, 0); + assert_equals(hostOpen.querySelectorAll('my-element').length, 0); // ShadowRoot isn't an Element, does not have getElementsByTagName(). assert_equals(shadowOpen.querySelectorAll('my-element').length, 1); assert_equals(shadowOpen.querySelectorAll('my-element')[0].getAttribute('label'), 'shadow-open-my-element'); - assert_array_equals(hostClosed.querySelectorAll('my-element').length, 0); + assert_equals(hostClosed.querySelectorAll('my-element').length, 0); assert_equals(shadowClosed.querySelectorAll('my-element').length, 1); assert_equals(shadowClosed.querySelectorAll('my-element')[0].getAttribute('label'), 'shadow-closed-my-element'); }, 'getElementsByTagName() should not leak nodes in shadow tree'); diff --git a/tests/wpt/web-platform-tests/storage/estimate-indexeddb-worker.https.html b/tests/wpt/web-platform-tests/storage/estimate-indexeddb-worker.https.html deleted file mode 100644 index 2366760bdbe..00000000000 --- a/tests/wpt/web-platform-tests/storage/estimate-indexeddb-worker.https.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - StorageManager: estimate() for indexeddb from worker - - - - - - - - - diff --git a/tests/wpt/web-platform-tests/storage/storage-estimate-indexeddb.js b/tests/wpt/web-platform-tests/storage/estimate-indexeddb.https.any.js similarity index 61% rename from tests/wpt/web-platform-tests/storage/storage-estimate-indexeddb.js rename to tests/wpt/web-platform-tests/storage/estimate-indexeddb.https.any.js index 5f7895350ef..3e34ad19bab 100644 --- a/tests/wpt/web-platform-tests/storage/storage-estimate-indexeddb.js +++ b/tests/wpt/web-platform-tests/storage/estimate-indexeddb.https.any.js @@ -1,15 +1,13 @@ -if (this.document === undefined) { - importScripts("/resources/testharness.js"); -} +// META: title=StorageManager: estimate() for indexeddb -test(function(t) { +test(t => { assert_true('estimate' in navigator.storage); assert_equals(typeof navigator.storage.estimate, 'function'); assert_true(navigator.storage.estimate() instanceof Promise); }, 'estimate() method exists and returns a Promise'); -promise_test(function(t) { - return navigator.storage.estimate().then(function(result) { +promise_test(t => { + return navigator.storage.estimate().then(result => { assert_true(typeof result === 'object'); assert_true('usage' in result); assert_equals(typeof result.usage, 'number'); @@ -18,20 +16,20 @@ promise_test(function(t) { }); }, 'estimate() resolves to dictionary with members'); -promise_test(function(t) { +promise_test(t => { const arraySize = 1e6; const objectStoreName = "storageManager"; const dbname = this.window ? window.location.pathname : - "estimate-worker.https.html"; + "estimate-worker.https.html"; let db; let usageBeforeCreate, usageAfterCreate, usageAfterPut; function deleteDB(name) { - return new Promise(function(resolve, reject) { + return new Promise((resolve, reject) => { let deleteRequest = indexedDB.deleteDatabase(name); - deleteRequest.onerror = function() { reject(deleteRequest.error); }; - deleteRequest.onsuccess = function() { resolve(); }; + deleteRequest.onerror = () => { reject(deleteRequest.error); }; + deleteRequest.onsuccess = () => { resolve(); }; }); } @@ -41,13 +39,13 @@ promise_test(function(t) { }) .then(estimate => { usageBeforeCreate = estimate.usage; - return new Promise(function(resolve, reject) { + return new Promise((resolve, reject) => { let openRequest = indexedDB.open(dbname); - openRequest.onerror = function() { reject(openRequest.error); }; - openRequest.onupgradeneeded = function(event) { + openRequest.onerror = () => { reject(openRequest.error); }; + openRequest.onupgradeneeded = event => { openRequest.result.createObjectStore(objectStoreName); }; - openRequest.onsuccess = function() { resolve(openRequest.result); }; + openRequest.onsuccess = () => { resolve(openRequest.result); }; }); }) .then(connection => { @@ -56,8 +54,9 @@ promise_test(function(t) { }) .then(estimate => { usageAfterCreate = estimate.usage; - assert_greater_than(usageAfterCreate, usageBeforeCreate, - 'estimated usage should increase after object store is created'); + assert_greater_than( + usageAfterCreate, usageBeforeCreate, + 'estimated usage should increase after object store is created'); let txn = db.transaction(objectStoreName, 'readwrite'); let buffer = new ArrayBuffer(arraySize); @@ -70,9 +69,9 @@ promise_test(function(t) { let testBlob = new Blob([buffer], {type: "binary/random"}); txn.objectStore(objectStoreName).add(testBlob, 1); - return new Promise(function(resolve, reject) { - txn.onabort = function() { reject(txn.error); }; - txn.oncomplete = function() { resolve(); }; + return new Promise((resolve, reject) => { + txn.onabort = () => { reject(txn.error); }; + txn.oncomplete = () => { resolve(); }; }); }) .then(() => { @@ -80,15 +79,14 @@ promise_test(function(t) { }) .then(estimate => { usageAfterPut = estimate.usage; - assert_greater_than(usageAfterPut, usageAfterCreate, - 'estimated usage should increase after large value is stored'); + assert_greater_than( + usageAfterPut, usageAfterCreate, + 'estimated usage should increase after large value is stored'); db.close(); - return deleteDB(dbname) + return deleteDB(dbname); }) .then(() => { t.done(); - }) + }); }, 'estimate() shows usage increase after large value is stored'); - -done(); diff --git a/tests/wpt/web-platform-tests/storage/estimate-indexeddb.https.html b/tests/wpt/web-platform-tests/storage/estimate-indexeddb.https.html deleted file mode 100644 index 3f5e1589d34..00000000000 --- a/tests/wpt/web-platform-tests/storage/estimate-indexeddb.https.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - StorageManager: estimate() for indexeddb - - - - - - - - - diff --git a/tests/wpt/web-platform-tests/storage/estimate-parallel.https.html b/tests/wpt/web-platform-tests/storage/estimate-parallel.https.any.js similarity index 59% rename from tests/wpt/web-platform-tests/storage/estimate-parallel.https.html rename to tests/wpt/web-platform-tests/storage/estimate-parallel.https.any.js index 571b08cd5e2..090f004b851 100644 --- a/tests/wpt/web-platform-tests/storage/estimate-parallel.https.html +++ b/tests/wpt/web-platform-tests/storage/estimate-parallel.https.any.js @@ -1,10 +1,5 @@ - - -StorageManager: multiple estimate() calls in parallel - - - - diff --git a/tests/wpt/web-platform-tests/storage/opaque-origin.https.html b/tests/wpt/web-platform-tests/storage/opaque-origin.https.window.js similarity index 91% rename from tests/wpt/web-platform-tests/storage/opaque-origin.https.html rename to tests/wpt/web-platform-tests/storage/opaque-origin.https.window.js index 563f2fea3c5..3e101dde675 100644 --- a/tests/wpt/web-platform-tests/storage/opaque-origin.https.html +++ b/tests/wpt/web-platform-tests/storage/opaque-origin.https.window.js @@ -1,9 +1,4 @@ - - -StorageManager API and opaque origins - - - diff --git a/tests/wpt/web-platform-tests/storage/permission-query.https.any.js b/tests/wpt/web-platform-tests/storage/permission-query.https.any.js new file mode 100644 index 00000000000..9984bdab793 --- /dev/null +++ b/tests/wpt/web-platform-tests/storage/permission-query.https.any.js @@ -0,0 +1,10 @@ +// META: title=The Permission API registration for "persistent-storage" + +promise_test(async t => { + const status = + await navigator.permissions.query({name: 'persistent-storage'}); + assert_equals(status.constructor, PermissionStatus, + 'query() result should resolve to a PermissionStatus'); + assert_true(['granted','denied', 'prompt'].includes(status.state), + 'state should be a PermissionState'); +}, 'The "persistent-storage" permission is recognized'); diff --git a/tests/wpt/web-platform-tests/storage/persisted-worker.https.html b/tests/wpt/web-platform-tests/storage/persisted-worker.https.html deleted file mode 100644 index 21f5c8bd92d..00000000000 --- a/tests/wpt/web-platform-tests/storage/persisted-worker.https.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - StorageManager: persisted() from worker - - - - - - - - - diff --git a/tests/wpt/web-platform-tests/storage/storage-persisted.js b/tests/wpt/web-platform-tests/storage/persisted.https.any.js similarity index 84% rename from tests/wpt/web-platform-tests/storage/storage-persisted.js rename to tests/wpt/web-platform-tests/storage/persisted.https.any.js index 5bc86fea951..57e15f0e811 100644 --- a/tests/wpt/web-platform-tests/storage/storage-persisted.js +++ b/tests/wpt/web-platform-tests/storage/persisted.https.any.js @@ -1,6 +1,4 @@ -if (this.document === undefined) { - importScripts("/resources/testharness.js"); -} +// META: title=StorageManager: persisted() test(function(t) { assert_true('persisted' in navigator.storage); @@ -14,5 +12,3 @@ promise_test(function(t) { assert_equals(result, false); }); }, 'persisted() returns a promise and resolves as boolean with false'); - -done(); diff --git a/tests/wpt/web-platform-tests/storage/persisted.https.html b/tests/wpt/web-platform-tests/storage/persisted.https.html deleted file mode 100644 index a5a91ff0b26..00000000000 --- a/tests/wpt/web-platform-tests/storage/persisted.https.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - StorageManager: persisted() - - - - - - - - - diff --git a/tests/wpt/web-platform-tests/storage/resources/storagemanager-persisted-worker.js b/tests/wpt/web-platform-tests/storage/resources/storagemanager-persisted-worker.js deleted file mode 100644 index 979c8be3cd3..00000000000 --- a/tests/wpt/web-platform-tests/storage/resources/storagemanager-persisted-worker.js +++ /dev/null @@ -1,13 +0,0 @@ -importScripts('/resources/testharness.js'); - -promise_test(function() { - var promise = navigator.storage.persisted(); - assert_true(promise instanceof Promise, - 'navigator.storage.persisted() returned a Promise.'); - return promise.then(function (result) { - assert_equals(typeof result, 'boolean', - result + ' should be a boolean'); - }); -}, 'navigator.storage.persisted returns a promise that resolves.'); - -done(); diff --git a/tests/wpt/web-platform-tests/storage/storagemanager-estimate.https.html b/tests/wpt/web-platform-tests/storage/storagemanager-estimate.https.any.js similarity index 88% rename from tests/wpt/web-platform-tests/storage/storagemanager-estimate.https.html rename to tests/wpt/web-platform-tests/storage/storagemanager-estimate.https.any.js index 08a699adfb0..d1d2e21924c 100644 --- a/tests/wpt/web-platform-tests/storage/storagemanager-estimate.https.html +++ b/tests/wpt/web-platform-tests/storage/storagemanager-estimate.https.any.js @@ -1,10 +1,4 @@ - - -StorageManager: estimate() - - - - diff --git a/tests/wpt/web-platform-tests/storage/storagemanager-persist-worker.https.html b/tests/wpt/web-platform-tests/storage/storagemanager-persist-worker.https.html deleted file mode 100644 index 9c89a2f6712..00000000000 --- a/tests/wpt/web-platform-tests/storage/storagemanager-persist-worker.https.html +++ /dev/null @@ -1,10 +0,0 @@ - - -StorageManager: persist() (worker) - - - - diff --git a/tests/wpt/web-platform-tests/storage/storagemanager-persist.https.html b/tests/wpt/web-platform-tests/storage/storagemanager-persist.https.window.js similarity index 56% rename from tests/wpt/web-platform-tests/storage/storagemanager-persist.https.html rename to tests/wpt/web-platform-tests/storage/storagemanager-persist.https.window.js index 61624fe272a..13e17a16e14 100644 --- a/tests/wpt/web-platform-tests/storage/storagemanager-persist.https.html +++ b/tests/wpt/web-platform-tests/storage/storagemanager-persist.https.window.js @@ -1,10 +1,4 @@ - - -StorageManager: persist() - - - - diff --git a/tests/wpt/web-platform-tests/storage/resources/storagemanager-persist-worker.js b/tests/wpt/web-platform-tests/storage/storagemanager-persist.https.worker.js similarity index 59% rename from tests/wpt/web-platform-tests/storage/resources/storagemanager-persist-worker.js rename to tests/wpt/web-platform-tests/storage/storagemanager-persist.https.worker.js index 1152e4ec734..fcf8175f706 100644 --- a/tests/wpt/web-platform-tests/storage/resources/storagemanager-persist-worker.js +++ b/tests/wpt/web-platform-tests/storage/storagemanager-persist.https.worker.js @@ -1,4 +1,5 @@ -importScripts('/resources/testharness.js'); +// META: title=StorageManager: persist() (worker) +importScripts("/resources/testharness.js"); test(function() { assert_false('persist' in navigator.storage); diff --git a/tests/wpt/web-platform-tests/storage/storagemanager-persisted-worker.https.html b/tests/wpt/web-platform-tests/storage/storagemanager-persisted-worker.https.html deleted file mode 100644 index 75004946164..00000000000 --- a/tests/wpt/web-platform-tests/storage/storagemanager-persisted-worker.https.html +++ /dev/null @@ -1,10 +0,0 @@ - - -StorageManager: persisted() (worker) - - - - diff --git a/tests/wpt/web-platform-tests/storage/storagemanager-persisted.https.html b/tests/wpt/web-platform-tests/storage/storagemanager-persisted.https.any.js similarity index 56% rename from tests/wpt/web-platform-tests/storage/storagemanager-persisted.https.html rename to tests/wpt/web-platform-tests/storage/storagemanager-persisted.https.any.js index 1d88c11bd8a..70999406690 100644 --- a/tests/wpt/web-platform-tests/storage/storagemanager-persisted.https.html +++ b/tests/wpt/web-platform-tests/storage/storagemanager-persisted.https.any.js @@ -1,10 +1,4 @@ - - -StorageManager: persist() - - - - diff --git a/tests/wpt/web-platform-tests/streams/readable-streams/patched-global.js b/tests/wpt/web-platform-tests/streams/readable-streams/patched-global.js index e8117c48048..c75b21e8c38 100644 --- a/tests/wpt/web-platform-tests/streams/readable-streams/patched-global.js +++ b/tests/wpt/web-platform-tests/streams/readable-streams/patched-global.js @@ -47,7 +47,6 @@ test(t => { const oldReadableStream = self.ReadableStream; - /* eslint-disable no-native-reassign */ self.ReadableStream = function() { throw new Error('ReadableStream called on global object'); }; @@ -60,8 +59,6 @@ test(t => { assert_true(isReadableStream(branch1), 'branch1 should be a ReadableStream'); assert_true(isReadableStream(branch2), 'branch2 should be a ReadableStream'); - - /* eslint-enable no-native-reassign */ }, 'ReadableStream tee() should not call the global ReadableStream'); done(); diff --git a/tests/wpt/web-platform-tests/streams/transform-streams/patched-global.js b/tests/wpt/web-platform-tests/streams/transform-streams/patched-global.js index d27b9cdd119..f5d32c08ea7 100644 --- a/tests/wpt/web-platform-tests/streams/transform-streams/patched-global.js +++ b/tests/wpt/web-platform-tests/streams/transform-streams/patched-global.js @@ -21,8 +21,6 @@ test(() => { }, 'TransformStream constructor should not call setters for highWaterMark or size'); test(t => { - /* eslint-disable no-native-reassign */ - const oldReadableStream = ReadableStream; const oldWritableStream = WritableStream; const getReader = ReadableStream.prototype.getReader; @@ -47,7 +45,6 @@ test(t => { 'getReader should work when called on ts.readable'); assert_not_equals(getWriter.call(ts.writable), undefined, 'getWriter should work when called on ts.writable'); - /* eslint-enable no-native-reassign */ }, 'TransformStream should use the original value of ReadableStream and WritableStream'); done(); diff --git a/tests/wpt/web-platform-tests/svg/path/property/d-interpolation-discrete.svg b/tests/wpt/web-platform-tests/svg/path/property/d-interpolation-discrete.svg index aa9087395fb..5b20a589bb5 100644 --- a/tests/wpt/web-platform-tests/svg/path/property/d-interpolation-discrete.svg +++ b/tests/wpt/web-platform-tests/svg/path/property/d-interpolation-discrete.svg @@ -17,27 +17,27 @@ // Distinct number of path segments test_no_interpolation({ property: 'd', - from: "path('M 0 0 H 1 H 2')", - to: "path('M 0 0 H 3')" + from: 'path("M 0 0 H 1 H 2")', + to: 'path("M 0 0 H 3")' }); test_no_interpolation({ property: 'd', - from: "path('M 1 2 L 3 4 Z')", + from: 'path("M 1 2 L 3 4 Z")', to: "none" }); // Distinct segment types test_no_interpolation({ property: 'd', - from: "path('M 10 0 H 11')", - to: "path('M 20 0 V 2')" + from: 'path("M 10 0 H 11")', + to: 'path("M 20 0 V 2")' }); test_no_interpolation({ property: 'd', - from: "path('M 1 2 L 4 6 Z')", - to: "path('M 1 2 H 4 V 6')" + from: 'path("M 1 2 L 4 6 Z")', + to: 'path("M 1 2 H 4 V 6")' }); ]]> diff --git a/tests/wpt/web-platform-tests/svg/path/property/d-interpolation-relative-absolute.svg b/tests/wpt/web-platform-tests/svg/path/property/d-interpolation-relative-absolute.svg index 65d2f3b2eb6..09d4c70712f 100644 --- a/tests/wpt/web-platform-tests/svg/path/property/d-interpolation-relative-absolute.svg +++ b/tests/wpt/web-platform-tests/svg/path/property/d-interpolation-relative-absolute.svg @@ -17,106 +17,106 @@ // Mix relative and non-relative test_interpolation({ property: 'd', - from: "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z')", - to: "path('M 0 0 L 100 100 m 0 100 l 100 0 z l 300 100 z')" + from: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z")', + to: 'path("M 0 0 L 100 100 m 0 100 l 100 0 z l 300 100 z")' }, [ - {at: -1, expect: "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 0 -100 Z')"}, - {at: 0, expect: "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z')"}, - {at: 0.125, expect: "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 225 125 Z')"}, - {at: 0.875, expect: "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 375 275 Z')"}, - {at: 1, expect: "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 400 300 Z')"}, - {at: 2, expect: "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 600 500 Z')"}, + {at: -1, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 0 -100 Z")'}, + {at: 0, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z")'}, + {at: 0.125, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 225 125 Z")'}, + {at: 0.875, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 375 275 Z")'}, + {at: 1, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 400 300 Z")'}, + {at: 2, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 600 500 Z")'}, ]); test_interpolation({ property: 'd', - from: "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z')", - to: "path('M 0 0 L 100 100 m 0 100 l 100 0 z l 100 -100 z')" + from: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z")', + to: 'path("M 0 0 L 100 100 m 0 100 l 100 0 z l 100 -100 z")' }, [ - {at: -1, expect: "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z')"}, - {at: 0, expect: "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z')"}, - {at: 0.125, expect: "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z')"}, - {at: 0.875, expect: "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z')"}, - {at: 1, expect: "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z')"}, - {at: 2, expect: "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z')"}, + {at: -1, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z")'}, + {at: 0, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z")'}, + {at: 0.125, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z")'}, + {at: 0.875, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z")'}, + {at: 1, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z")'}, + {at: 2, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z")'}, ]); test_interpolation({ property: 'd', - from: "path('m 10 20 l 40 50 z l 40 60 z m 60 70 l 90 60 z t 70 130')", - to: "path('M 210 220 L 170 190 Z L 90 120 Z M 110 130 L 200 230 Z T 220 220')" + from: 'path("m 10 20 l 40 50 z l 40 60 z m 60 70 l 90 60 z t 70 130")', + to: 'path("M 210 220 L 170 190 Z L 90 120 Z M 110 130 L 200 230 Z T 220 220")' }, [ - {at: -1, expect: "path('M -190 -180 L -70 -50 Z L 10 40 Z M 30 50 L 120 70 Z T 60 220')"}, - {at: 0, expect: "path('M 10 20 L 50 70 Z L 50 80 Z M 70 90 L 160 150 Z T 140 220')"}, - {at: 0.125, expect: "path('M 35 45 L 65 85 Z L 55 85 Z M 75 95 L 165 160 Z T 150 220')"}, - {at: 0.875, expect: "path('M 185 195 L 155 175 Z L 85 115 Z M 105 125 L 195 220 Z T 210 220')"}, - {at: 1, expect: "path('M 210 220 L 170 190 Z L 90 120 Z M 110 130 L 200 230 Z T 220 220')"}, - {at: 2, expect: "path('M 410 420 L 290 310 Z L 130 160 Z M 150 170 L 240 310 Z T 300 220')"} + {at: -1, expect: 'path("M -190 -180 L -70 -50 Z L 10 40 Z M 30 50 L 120 70 Z T 60 220")'}, + {at: 0, expect: 'path("M 10 20 L 50 70 Z L 50 80 Z M 70 90 L 160 150 Z T 140 220")'}, + {at: 0.125, expect: 'path("M 35 45 L 65 85 Z L 55 85 Z M 75 95 L 165 160 Z T 150 220")'}, + {at: 0.875, expect: 'path("M 185 195 L 155 175 Z L 85 115 Z M 105 125 L 195 220 Z T 210 220")'}, + {at: 1, expect: 'path("M 210 220 L 170 190 Z L 90 120 Z M 110 130 L 200 230 Z T 220 220")'}, + {at: 2, expect: 'path("M 410 420 L 290 310 Z L 130 160 Z M 150 170 L 240 310 Z T 300 220")'} ]); test_interpolation({ property: 'd', - from: "path('m 10 20 c 40 50 30 60 80 70 c 120 130 170 140 110 160')", - to: "path('M 130 100 C 130 150 120 160 210 170 C 290 300 340 310 320 330')" + from: 'path("m 10 20 c 40 50 30 60 80 70 c 120 130 170 140 110 160")', + to: 'path("M 130 100 C 130 150 120 160 210 170 C 290 300 340 310 320 330")' }, [ - {at: -1, expect: "path('M -110 -60 C -30 -10 -40 0 -30 10 C 130 140 180 150 80 170')"}, - {at: 0, expect: "path('M 10 20 C 50 70 40 80 90 90 C 210 220 260 230 200 250')"}, - {at: 0.125, expect: "path('M 25 30 C 60 80 50 90 105 100 C 220 230 270 240 215 260')"}, - {at: 0.875, expect: "path('M 115 90 C 120 140 110 150 195 160 C 280 290 330 300 305 320')"}, - {at: 1, expect: "path('M 130 100 C 130 150 120 160 210 170 C 290 300 340 310 320 330')"}, - {at: 2, expect: "path('M 250 180 C 210 230 200 240 330 250 C 370 380 420 390 440 410')"} + {at: -1, expect: 'path("M -110 -60 C -30 -10 -40 0 -30 10 C 130 140 180 150 80 170")'}, + {at: 0, expect: 'path("M 10 20 C 50 70 40 80 90 90 C 210 220 260 230 200 250")'}, + {at: 0.125, expect: 'path("M 25 30 C 60 80 50 90 105 100 C 220 230 270 240 215 260")'}, + {at: 0.875, expect: 'path("M 115 90 C 120 140 110 150 195 160 C 280 290 330 300 305 320")'}, + {at: 1, expect: 'path("M 130 100 C 130 150 120 160 210 170 C 290 300 340 310 320 330")'}, + {at: 2, expect: 'path("M 250 180 C 210 230 200 240 330 250 C 370 380 420 390 440 410")'} ]); test_interpolation({ property: 'd', - from: "path('m 10 20 q 30 60 40 50 q 110 80 90 80')", - to: "path('M 130 100 Q 120 160 130 150 Q 200 150 180 190')" + from: 'path("m 10 20 q 30 60 40 50 q 110 80 90 80")', + to: 'path("M 130 100 Q 120 160 130 150 Q 200 150 180 190")' }, [ - {at: -1, expect: "path('M -110 -60 Q -40 0 -30 -10 Q 120 150 100 110')"}, - {at: 0, expect: "path('M 10 20 Q 40 80 50 70 Q 160 150 140 150')"}, - {at: 0.125, expect: "path('M 25 30 Q 50 90 60 80 Q 165 150 145 155')"}, - {at: 0.875, expect: "path('M 115 90 Q 110 150 120 140 Q 195 150 175 185')"}, - {at: 1, expect: "path('M 130 100 Q 120 160 130 150 Q 200 150 180 190')"}, - {at: 2, expect: "path('M 250 180 Q 200 240 210 230 Q 240 150 220 230')"} + {at: -1, expect: 'path("M -110 -60 Q -40 0 -30 -10 Q 120 150 100 110")'}, + {at: 0, expect: 'path("M 10 20 Q 40 80 50 70 Q 160 150 140 150")'}, + {at: 0.125, expect: 'path("M 25 30 Q 50 90 60 80 Q 165 150 145 155")'}, + {at: 0.875, expect: 'path("M 115 90 Q 110 150 120 140 Q 195 150 175 185")'}, + {at: 1, expect: 'path("M 130 100 Q 120 160 130 150 Q 200 150 180 190")'}, + {at: 2, expect: 'path("M 250 180 Q 200 240 210 230 Q 240 150 220 230")'} ]); test_interpolation({ property: 'd', - from: "path('m 10 20 s 30 60 40 50 s 110 60 90 70')", - to: "path('M 130 140 S 120 160 130 150 S 200 170 140 180')" + from: 'path("m 10 20 s 30 60 40 50 s 110 60 90 70")', + to: 'path("M 130 140 S 120 160 130 150 S 200 170 140 180")' }, [ - {at: -1, expect: "path('M -110 -100 S -40 0 -30 -10 S 120 90 140 100')"}, - {at: 0, expect: "path('M 10 20 S 40 80 50 70 S 160 130 140 140')"}, - {at: 0.125, expect: "path('M 25 35 S 50 90 60 80 S 165 135 140 145')"}, - {at: 0.875, expect: "path('M 115 125 S 110 150 120 140 S 195 165 140 175')"}, - {at: 1, expect: "path('M 130 140 S 120 160 130 150 S 200 170 140 180')"}, - {at: 2, expect: "path('M 250 260 S 200 240 210 230 S 240 210 140 220')"} + {at: -1, expect: 'path("M -110 -100 S -40 0 -30 -10 S 120 90 140 100")'}, + {at: 0, expect: 'path("M 10 20 S 40 80 50 70 S 160 130 140 140")'}, + {at: 0.125, expect: 'path("M 25 35 S 50 90 60 80 S 165 135 140 145")'}, + {at: 0.875, expect: 'path("M 115 125 S 110 150 120 140 S 195 165 140 175")'}, + {at: 1, expect: 'path("M 130 140 S 120 160 130 150 S 200 170 140 180")'}, + {at: 2, expect: 'path("M 250 260 S 200 240 210 230 S 240 210 140 220")'} ]); test_interpolation({ property: 'd', - from: "path('m 10 20 h 30 v 60 h 10 v -10 l 110 60 Z')", - to: "path('M 130 140 H 120 V 160 H 130 V 150 L 200 170 Z')" + from: 'path("m 10 20 h 30 v 60 h 10 v -10 l 110 60 Z")', + to: 'path("M 130 140 H 120 V 160 H 130 V 150 L 200 170 Z")' }, [ - {at: -1, expect: "path('M -110 -100 H -40 V 0 H -30 V -10 L 120 90 Z')"}, - {at: 0, expect: "path('M 10 20 H 40 V 80 H 50 V 70 L 160 130 Z')"}, - {at: 0.125, expect: "path('M 25 35 H 50 V 90 H 60 V 80 L 165 135 Z')"}, - {at: 0.875, expect: "path('M 115 125 H 110 V 150 H 120 V 140 L 195 165 Z')"}, - {at: 1, expect: "path('M 130 140 H 120 V 160 H 130 V 150 L 200 170 Z')"}, - {at: 2, expect: "path('M 250 260 H 200 V 240 H 210 V 230 L 240 210 Z')"} + {at: -1, expect: 'path("M -110 -100 H -40 V 0 H -30 V -10 L 120 90 Z")'}, + {at: 0, expect: 'path("M 10 20 H 40 V 80 H 50 V 70 L 160 130 Z")'}, + {at: 0.125, expect: 'path("M 25 35 H 50 V 90 H 60 V 80 L 165 135 Z")'}, + {at: 0.875, expect: 'path("M 115 125 H 110 V 150 H 120 V 140 L 195 165 Z")'}, + {at: 1, expect: 'path("M 130 140 H 120 V 160 H 130 V 150 L 200 170 Z")'}, + {at: 2, expect: 'path("M 250 260 H 200 V 240 H 210 V 230 L 240 210 Z")'} ]); test_interpolation({ property: 'd', - from: "path('m 10 20 a 10 20 30 1 0 40 50 a 110 120 30 1 1 140 50')", - to: "path('M 18 12 A 50 100 70 0 1 90 110 A 150 160 70 0 1 70 80')" + from: 'path("m 10 20 a 10 20 30 1 0 40 50 a 110 120 30 1 1 140 50")', + to: 'path("M 18 12 A 50 100 70 0 1 90 110 A 150 160 70 0 1 70 80")' }, [ - {at: -1, expect: "path('M 2 28 A -30 -60 -10 1 0 10 30 A 70 80 -10 1 1 310 160')"}, - {at: 0, expect: "path('M 10 20 A 10 20 30 1 0 50 70 A 110 120 30 1 1 190 120')"}, - {at: 0.125, expect: "path('M 11 19 A 15 30 35 1 0 55 75 A 115 125 35 1 1 175 115')"}, - {at: 0.875, expect: "path('M 17 13 A 45 90 65 0 1 85 105 A 145 155 65 0 1 85 85')"}, - {at: 1, expect: "path('M 18 12 A 50 100 70 0 1 90 110 A 150 160 70 0 1 70 80')"}, - {at: 2, expect: "path('M 26 4 A 90 180 110 0 1 130 150 A 190 200 110 0 1 -50 40')"} + {at: -1, expect: 'path("M 2 28 A -30 -60 -10 1 0 10 30 A 70 80 -10 1 1 310 160")'}, + {at: 0, expect: 'path("M 10 20 A 10 20 30 1 0 50 70 A 110 120 30 1 1 190 120")'}, + {at: 0.125, expect: 'path("M 11 19 A 15 30 35 1 0 55 75 A 115 125 35 1 1 175 115")'}, + {at: 0.875, expect: 'path("M 17 13 A 45 90 65 0 1 85 105 A 145 155 65 0 1 85 85")'}, + {at: 1, expect: 'path("M 18 12 A 50 100 70 0 1 90 110 A 150 160 70 0 1 70 80")'}, + {at: 2, expect: 'path("M 26 4 A 90 180 110 0 1 130 150 A 190 200 110 0 1 -50 40")'} ]); ]]> diff --git a/tests/wpt/web-platform-tests/svg/path/property/d-interpolation-single.svg b/tests/wpt/web-platform-tests/svg/path/property/d-interpolation-single.svg index 25c523168a7..107b607beca 100644 --- a/tests/wpt/web-platform-tests/svg/path/property/d-interpolation-single.svg +++ b/tests/wpt/web-platform-tests/svg/path/property/d-interpolation-single.svg @@ -17,229 +17,229 @@ // Exercise each segment type test_interpolation({ property: 'd', - from: "path('M 20 70')", - to: "path('M 100 30')" + from: 'path("M 20 70")', + to: 'path("M 100 30")' }, [ - {at: -1, expect: "path('M -60 110')"}, - {at: 0, expect: "path('M 20 70')"}, - {at: 0.125, expect: "path('M 30 65')"}, - {at: 0.875, expect: "path('M 90 35')"}, - {at: 1, expect: "path('M 100 30')"}, - {at: 2, expect: "path('M 180 -10')"} + {at: -1, expect: 'path("M -60 110")'}, + {at: 0, expect: 'path("M 20 70")'}, + {at: 0.125, expect: 'path("M 30 65")'}, + {at: 0.875, expect: 'path("M 90 35")'}, + {at: 1, expect: 'path("M 100 30")'}, + {at: 2, expect: 'path("M 180 -10")'} ]); test_interpolation({ property: 'd', - from: "path('m 20 70')", - to: "path('m 100 30')" + from: 'path("m 20 70")', + to: 'path("m 100 30")' }, [ - {at: -1, expect: "path('M -60 110')"}, - {at: 0, expect: "path('M 20 70')"}, - {at: 0.125, expect: "path('M 30 65')"}, - {at: 0.875, expect: "path('M 90 35')"}, - {at: 1, expect: "path('M 100 30')"}, - {at: 2, expect: "path('M 180 -10')"} + {at: -1, expect: 'path("M -60 110")'}, + {at: 0, expect: 'path("M 20 70")'}, + {at: 0.125, expect: 'path("M 30 65")'}, + {at: 0.875, expect: 'path("M 90 35")'}, + {at: 1, expect: 'path("M 100 30")'}, + {at: 2, expect: 'path("M 180 -10")'} ]); test_interpolation({ property: 'd', - from: "path('m 100 200 L 120 270')", - to: "path('m 100 200 L 200 230')" + from: 'path("m 100 200 L 120 270")', + to: 'path("m 100 200 L 200 230")' }, [ - {at: -1, expect: "path('M 100 200 L 40 310')"}, - {at: 0, expect: "path('M 100 200 L 120 270')"}, - {at: 0.125, expect: "path('M 100 200 L 130 265')"}, - {at: 0.875, expect: "path('M 100 200 L 190 235')"}, - {at: 1, expect: "path('M 100 200 L 200 230')"}, - {at: 2, expect: "path('M 100 200 L 280 190')"} + {at: -1, expect: 'path("M 100 200 L 40 310")'}, + {at: 0, expect: 'path("M 100 200 L 120 270")'}, + {at: 0.125, expect: 'path("M 100 200 L 130 265")'}, + {at: 0.875, expect: 'path("M 100 200 L 190 235")'}, + {at: 1, expect: 'path("M 100 200 L 200 230")'}, + {at: 2, expect: 'path("M 100 200 L 280 190")'} ]); test_interpolation({ property: 'd', - from: "path('m 100 200 l 20 70')", - to: "path('m 100 200 l 100 30')" + from: 'path("m 100 200 l 20 70")', + to: 'path("m 100 200 l 100 30")' }, [ - {at: -1, expect: "path('M 100 200 L 40 310')"}, - {at: 0, expect: "path('M 100 200 L 120 270')"}, - {at: 0.125, expect: "path('M 100 200 L 130 265')"}, - {at: 0.875, expect: "path('M 100 200 L 190 235')"}, - {at: 1, expect: "path('M 100 200 L 200 230')"}, - {at: 2, expect: "path('M 100 200 L 280 190')"} + {at: -1, expect: 'path("M 100 200 L 40 310")'}, + {at: 0, expect: 'path("M 100 200 L 120 270")'}, + {at: 0.125, expect: 'path("M 100 200 L 130 265")'}, + {at: 0.875, expect: 'path("M 100 200 L 190 235")'}, + {at: 1, expect: 'path("M 100 200 L 200 230")'}, + {at: 2, expect: 'path("M 100 200 L 280 190")'} ]); test_interpolation({ property: 'd', - from: "path('M 20 10 C 32 42 52 62 120 2200')", - to: "path('M 20 10 C 40 50 60 70 200 3000')", + from: 'path("M 20 10 C 32 42 52 62 120 2200")', + to: 'path("M 20 10 C 40 50 60 70 200 3000")', }, [ - {at: -1, expect: "path('M 20 10 C 24 34 44 54 40 1400')"}, - {at: 0, expect: "path('M 20 10 C 32 42 52 62 120 2200')"}, - {at: 0.125, expect: "path('M 20 10 C 33 43 53 63 130 2300')"}, - {at: 0.875, expect: "path('M 20 10 C 39 49 59 69 190 2900')"}, - {at: 1, expect: "path('M 20 10 C 40 50 60 70 200 3000')"}, - {at: 2, expect: "path('M 20 10 C 48 58 68 78 280 3800')"} + {at: -1, expect: 'path("M 20 10 C 24 34 44 54 40 1400")'}, + {at: 0, expect: 'path("M 20 10 C 32 42 52 62 120 2200")'}, + {at: 0.125, expect: 'path("M 20 10 C 33 43 53 63 130 2300")'}, + {at: 0.875, expect: 'path("M 20 10 C 39 49 59 69 190 2900")'}, + {at: 1, expect: 'path("M 20 10 C 40 50 60 70 200 3000")'}, + {at: 2, expect: 'path("M 20 10 C 48 58 68 78 280 3800")'} ]); test_interpolation({ property: 'd', - from: "path('m 20 10 c 12 32 32 52 100 2190')", - to: "path('m 20 10 c 20 40 40 60 180 2990')" + from: 'path("m 20 10 c 12 32 32 52 100 2190")', + to: 'path("m 20 10 c 20 40 40 60 180 2990")' }, [ - {at: -1, expect: "path('M 20 10 C 24 34 44 54 40 1400')"}, - {at: 0, expect: "path('M 20 10 C 32 42 52 62 120 2200')"}, - {at: 0.125, expect: "path('M 20 10 C 33 43 53 63 130 2300')"}, - {at: 0.875, expect: "path('M 20 10 C 39 49 59 69 190 2900')"}, - {at: 1, expect: "path('M 20 10 C 40 50 60 70 200 3000')"}, - {at: 2, expect: "path('M 20 10 C 48 58 68 78 280 3800')"} + {at: -1, expect: 'path("M 20 10 C 24 34 44 54 40 1400")'}, + {at: 0, expect: 'path("M 20 10 C 32 42 52 62 120 2200")'}, + {at: 0.125, expect: 'path("M 20 10 C 33 43 53 63 130 2300")'}, + {at: 0.875, expect: 'path("M 20 10 C 39 49 59 69 190 2900")'}, + {at: 1, expect: 'path("M 20 10 C 40 50 60 70 200 3000")'}, + {at: 2, expect: 'path("M 20 10 C 48 58 68 78 280 3800")'} ]); test_interpolation({ property: 'd', - from: "path('M 20 10 Q 32 42 120 2200')", - to: "path('M 20 10 Q 40 50 200 3000')" + from: 'path("M 20 10 Q 32 42 120 2200")', + to: 'path("M 20 10 Q 40 50 200 3000")' }, [ - {at: -1, expect: "path('M 20 10 Q 24 34 40 1400')"}, - {at: 0, expect: "path('M 20 10 Q 32 42 120 2200')"}, - {at: 0.125, expect: "path('M 20 10 Q 33 43 130 2300')"}, - {at: 0.875, expect: "path('M 20 10 Q 39 49 190 2900')"}, - {at: 1, expect: "path('M 20 10 Q 40 50 200 3000')"}, - {at: 2, expect: "path('M 20 10 Q 48 58 280 3800')"} + {at: -1, expect: 'path("M 20 10 Q 24 34 40 1400")'}, + {at: 0, expect: 'path("M 20 10 Q 32 42 120 2200")'}, + {at: 0.125, expect: 'path("M 20 10 Q 33 43 130 2300")'}, + {at: 0.875, expect: 'path("M 20 10 Q 39 49 190 2900")'}, + {at: 1, expect: 'path("M 20 10 Q 40 50 200 3000")'}, + {at: 2, expect: 'path("M 20 10 Q 48 58 280 3800")'} ]); test_interpolation({ property: 'd', - from: "path('m 20 10 q 12 32 100 2190')", - to: "path('m 20 10 q 20 40 180 2990')" + from: 'path("m 20 10 q 12 32 100 2190")', + to: 'path("m 20 10 q 20 40 180 2990")' }, [ - {at: -1, expect: "path('M 20 10 Q 24 34 40 1400')"}, - {at: 0, expect: "path('M 20 10 Q 32 42 120 2200')"}, - {at: 0.125, expect: "path('M 20 10 Q 33 43 130 2300')"}, - {at: 0.875, expect: "path('M 20 10 Q 39 49 190 2900')"}, - {at: 1, expect: "path('M 20 10 Q 40 50 200 3000')"}, - {at: 2, expect: "path('M 20 10 Q 48 58 280 3800')"} + {at: -1, expect: 'path("M 20 10 Q 24 34 40 1400")'}, + {at: 0, expect: 'path("M 20 10 Q 32 42 120 2200")'}, + {at: 0.125, expect: 'path("M 20 10 Q 33 43 130 2300")'}, + {at: 0.875, expect: 'path("M 20 10 Q 39 49 190 2900")'}, + {at: 1, expect: 'path("M 20 10 Q 40 50 200 3000")'}, + {at: 2, expect: 'path("M 20 10 Q 48 58 280 3800")'} ]); test_interpolation({ property: 'd', - from: "path('M 100 400 A 10 20 30 1 0 140 450')", - to: "path('M 300 200 A 50 60 70 0 1 380 290')" + from: 'path("M 100 400 A 10 20 30 1 0 140 450")', + to: 'path("M 300 200 A 50 60 70 0 1 380 290")' }, [ - {at: -1, expect: "path('M -100 600 A -30 -20 -10 1 0 -100 610')"}, - {at: 0, expect: "path('M 100 400 A 10 20 30 1 0 140 450')"}, - {at: 0.125, expect: "path('M 125 375 A 15 25 35 1 0 170 430')"}, - {at: 0.875, expect: "path('M 275 225 A 45 55 65 0 1 350 310')"}, - {at: 1, expect: "path('M 300 200 A 50 60 70 0 1 380 290')"}, - {at: 2, expect: "path('M 500 0 A 90 100 110 0 1 620 130')"} + {at: -1, expect: 'path("M -100 600 A -30 -20 -10 1 0 -100 610")'}, + {at: 0, expect: 'path("M 100 400 A 10 20 30 1 0 140 450")'}, + {at: 0.125, expect: 'path("M 125 375 A 15 25 35 1 0 170 430")'}, + {at: 0.875, expect: 'path("M 275 225 A 45 55 65 0 1 350 310")'}, + {at: 1, expect: 'path("M 300 200 A 50 60 70 0 1 380 290")'}, + {at: 2, expect: 'path("M 500 0 A 90 100 110 0 1 620 130")'} ]); test_interpolation({ property: 'd', - from: "path('m 100 400 a 10 20 30 1 0 40 50')", - to: "path('m 300 200 a 50 60 70 0 1 80 90')" + from: 'path("m 100 400 a 10 20 30 1 0 40 50")', + to: 'path("m 300 200 a 50 60 70 0 1 80 90")' }, [ - {at: -1, expect: "path('M -100 600 A -30 -20 -10 1 0 -100 610')"}, - {at: 0, expect: "path('M 100 400 A 10 20 30 1 0 140 450')"}, - {at: 0.125, expect: "path('M 125 375 A 15 25 35 1 0 170 430')"}, - {at: 0.875, expect: "path('M 275 225 A 45 55 65 0 1 350 310')"}, - {at: 1, expect: "path('M 300 200 A 50 60 70 0 1 380 290')"}, - {at: 2, expect: "path('M 500 0 A 90 100 110 0 1 620 130')"} + {at: -1, expect: 'path("M -100 600 A -30 -20 -10 1 0 -100 610")'}, + {at: 0, expect: 'path("M 100 400 A 10 20 30 1 0 140 450")'}, + {at: 0.125, expect: 'path("M 125 375 A 15 25 35 1 0 170 430")'}, + {at: 0.875, expect: 'path("M 275 225 A 45 55 65 0 1 350 310")'}, + {at: 1, expect: 'path("M 300 200 A 50 60 70 0 1 380 290")'}, + {at: 2, expect: 'path("M 500 0 A 90 100 110 0 1 620 130")'} ]); test_interpolation({ property: 'd', - from: "path('M 50 60 H 70')", - to: "path('M 10 140 H 270')" + from: 'path("M 50 60 H 70")', + to: 'path("M 10 140 H 270")' }, [ - {at: -1, expect: "path('M 90 -20 H -130')"}, - {at: 0, expect: "path('M 50 60 H 70')"}, - {at: 0.125, expect: "path('M 45 70 H 95')"}, - {at: 0.875, expect: "path('M 15 130 H 245')"}, - {at: 1, expect: "path('M 10 140 H 270')"}, - {at: 2, expect: "path('M -30 220 H 470')"} + {at: -1, expect: 'path("M 90 -20 H -130")'}, + {at: 0, expect: 'path("M 50 60 H 70")'}, + {at: 0.125, expect: 'path("M 45 70 H 95")'}, + {at: 0.875, expect: 'path("M 15 130 H 245")'}, + {at: 1, expect: 'path("M 10 140 H 270")'}, + {at: 2, expect: 'path("M -30 220 H 470")'} ]); test_interpolation({ property: 'd', - from: "path('m 50 60 h 20')", - to: "path('m 10 140 h 260')" + from: 'path("m 50 60 h 20")', + to: 'path("m 10 140 h 260")' }, [ - {at: -1, expect: "path('M 90 -20 H -130')"}, - {at: 0, expect: "path('M 50 60 H 70')"}, - {at: 0.125, expect: "path('M 45 70 H 95')"}, - {at: 0.875, expect: "path('M 15 130 H 245')"}, - {at: 1, expect: "path('M 10 140 H 270')"}, - {at: 2, expect: "path('M -30 220 H 470')"} + {at: -1, expect: 'path("M 90 -20 H -130")'}, + {at: 0, expect: 'path("M 50 60 H 70")'}, + {at: 0.125, expect: 'path("M 45 70 H 95")'}, + {at: 0.875, expect: 'path("M 15 130 H 245")'}, + {at: 1, expect: 'path("M 10 140 H 270")'}, + {at: 2, expect: 'path("M -30 220 H 470")'} ]); test_interpolation({ property: 'd', - from: "path('M 50 60 V 70')", - to: "path('M 10 140 V 270')" + from: 'path("M 50 60 V 70")', + to: 'path("M 10 140 V 270")' }, [ - {at: -1, expect: "path('M 90 -20 V -130')"}, - {at: 0, expect: "path('M 50 60 V 70')"}, - {at: 0.125, expect: "path('M 45 70 V 95')"}, - {at: 0.875, expect: "path('M 15 130 V 245')"}, - {at: 1, expect: "path('M 10 140 V 270')"}, - {at: 2, expect: "path('M -30 220 V 470')"} + {at: -1, expect: 'path("M 90 -20 V -130")'}, + {at: 0, expect: 'path("M 50 60 V 70")'}, + {at: 0.125, expect: 'path("M 45 70 V 95")'}, + {at: 0.875, expect: 'path("M 15 130 V 245")'}, + {at: 1, expect: 'path("M 10 140 V 270")'}, + {at: 2, expect: 'path("M -30 220 V 470")'} ]); test_interpolation({ property: 'd', - from: "path('m 50 60 v 10')", - to: "path('m 10 140 v 130')" + from: 'path("m 50 60 v 10")', + to: 'path("m 10 140 v 130")' }, [ - {at: -1, expect: "path('M 90 -20 V -130')"}, - {at: 0, expect: "path('M 50 60 V 70')"}, - {at: 0.125, expect: "path('M 45 70 V 95')"}, - {at: 0.875, expect: "path('M 15 130 V 245')"}, - {at: 1, expect: "path('M 10 140 V 270')"}, - {at: 2, expect: "path('M -30 220 V 470')"} + {at: -1, expect: 'path("M 90 -20 V -130")'}, + {at: 0, expect: 'path("M 50 60 V 70")'}, + {at: 0.125, expect: 'path("M 45 70 V 95")'}, + {at: 0.875, expect: 'path("M 15 130 V 245")'}, + {at: 1, expect: 'path("M 10 140 V 270")'}, + {at: 2, expect: 'path("M -30 220 V 470")'} ]); test_interpolation({ property: 'd', - from: "path('M 12 34 S 45 67 89 123')", - to: "path('M 20 26 S 61 51 113 99')" + from: 'path("M 12 34 S 45 67 89 123")', + to: 'path("M 20 26 S 61 51 113 99")' }, [ - {at: -1, expect: "path('M 4 42 S 29 83 65 147')"}, - {at: 0, expect: "path('M 12 34 S 45 67 89 123')"}, - {at: 0.125, expect: "path('M 13 33 S 47 65 92 120')"}, - {at: 0.875, expect: "path('M 19 27 S 59 53 110 102')"}, - {at: 1, expect: "path('M 20 26 S 61 51 113 99')"}, - {at: 2, expect: "path('M 28 18 S 77 35 137 75')"}, + {at: -1, expect: 'path("M 4 42 S 29 83 65 147")'}, + {at: 0, expect: 'path("M 12 34 S 45 67 89 123")'}, + {at: 0.125, expect: 'path("M 13 33 S 47 65 92 120")'}, + {at: 0.875, expect: 'path("M 19 27 S 59 53 110 102")'}, + {at: 1, expect: 'path("M 20 26 S 61 51 113 99")'}, + {at: 2, expect: 'path("M 28 18 S 77 35 137 75")'}, ]); test_interpolation({ property: 'd', - from: "path('m 12 34 s 33 33 77 89')", - to: "path('m 20 26 s 41 25 93 73')" + from: 'path("m 12 34 s 33 33 77 89")', + to: 'path("m 20 26 s 41 25 93 73")' }, [ - {at: -1, expect: "path('M 4 42 S 29 83 65 147')"}, - {at: 0, expect: "path('M 12 34 S 45 67 89 123')"}, - {at: 0.125, expect: "path('M 13 33 S 47 65 92 120')"}, - {at: 0.875, expect: "path('M 19 27 S 59 53 110 102')"}, - {at: 1, expect: "path('M 20 26 S 61 51 113 99')"}, - {at: 2, expect: "path('M 28 18 S 77 35 137 75')"}, + {at: -1, expect: 'path("M 4 42 S 29 83 65 147")'}, + {at: 0, expect: 'path("M 12 34 S 45 67 89 123")'}, + {at: 0.125, expect: 'path("M 13 33 S 47 65 92 120")'}, + {at: 0.875, expect: 'path("M 19 27 S 59 53 110 102")'}, + {at: 1, expect: 'path("M 20 26 S 61 51 113 99")'}, + {at: 2, expect: 'path("M 28 18 S 77 35 137 75")'}, ]); test_interpolation({ property: 'd', - from: "path('M 12 34 T 45 67')", - to: "path('M 20 26 T 61 51')" + from: 'path("M 12 34 T 45 67")', + to: 'path("M 20 26 T 61 51")' }, [ - {at: -1, expect: "path('M 4 42 T 29 83')"}, - {at: 0, expect: "path('M 12 34 T 45 67')"}, - {at: 0.125, expect: "path('M 13 33 T 47 65')"}, - {at: 0.875, expect: "path('M 19 27 T 59 53')"}, - {at: 1, expect: "path('M 20 26 T 61 51')"}, - {at: 2, expect: "path('M 28 18 T 77 35')"}, + {at: -1, expect: 'path("M 4 42 T 29 83")'}, + {at: 0, expect: 'path("M 12 34 T 45 67")'}, + {at: 0.125, expect: 'path("M 13 33 T 47 65")'}, + {at: 0.875, expect: 'path("M 19 27 T 59 53")'}, + {at: 1, expect: 'path("M 20 26 T 61 51")'}, + {at: 2, expect: 'path("M 28 18 T 77 35")'}, ]); test_interpolation({ property: 'd', - from: "path('m 12 34 t 33 33')", - to: "path('m 20 26 t 41 25')" + from: 'path("m 12 34 t 33 33")', + to: 'path("m 20 26 t 41 25")' }, [ - {at: -1, expect: "path('M 4 42 T 29 83')"}, - {at: 0, expect: "path('M 12 34 T 45 67')"}, - {at: 0.125, expect: "path('M 13 33 T 47 65')"}, - {at: 0.875, expect: "path('M 19 27 T 59 53')"}, - {at: 1, expect: "path('M 20 26 T 61 51')"}, - {at: 2, expect: "path('M 28 18 T 77 35')"}, + {at: -1, expect: 'path("M 4 42 T 29 83")'}, + {at: 0, expect: 'path("M 12 34 T 45 67")'}, + {at: 0.125, expect: 'path("M 13 33 T 47 65")'}, + {at: 0.875, expect: 'path("M 19 27 T 59 53")'}, + {at: 1, expect: 'path("M 20 26 T 61 51")'}, + {at: 2, expect: 'path("M 28 18 T 77 35")'}, ]); ]]> diff --git a/tests/wpt/web-platform-tests/svg/path/property/getComputedStyle.svg b/tests/wpt/web-platform-tests/svg/path/property/getComputedStyle.svg index af30862781a..5830191931f 100644 --- a/tests/wpt/web-platform-tests/svg/path/property/getComputedStyle.svg +++ b/tests/wpt/web-platform-tests/svg/path/property/getComputedStyle.svg @@ -39,14 +39,14 @@ var p6 = document.getElementById('p6'); var p7 = document.getElementById('p7'); - assert_equals(getComputedStyle(g0).d, "none"); - assert_equals(getComputedStyle(p1).d, "none"); - assert_equals(getComputedStyle(p2).d, "path('M 10 2 H 20')"); - assert_equals(getComputedStyle(p3).d, "path('M 10 3 H 30')"); - assert_equals(getComputedStyle(p4).d, "path('M 10 4 H 40')"); - assert_equals(getComputedStyle(g5).d, "path('M 10 5 H 50')"); - assert_equals(getComputedStyle(p6).d, "path('M 10 5 H 50')"); - assert_equals(getComputedStyle(p7).d, "none"); + assert_equals(getComputedStyle(g0).d, 'none'); + assert_equals(getComputedStyle(p1).d, 'none'); + assert_equals(getComputedStyle(p2).d, 'path("M 10 2 H 20")'); + assert_equals(getComputedStyle(p3).d, 'path("M 10 3 H 30")'); + assert_equals(getComputedStyle(p4).d, 'path("M 10 4 H 40")'); + assert_equals(getComputedStyle(g5).d, 'path("M 10 5 H 50")'); + assert_equals(getComputedStyle(p6).d, 'path("M 10 5 H 50")'); + assert_equals(getComputedStyle(p7).d, 'none'); }); ]]> diff --git a/tests/wpt/web-platform-tests/tools/ci/check_stability.py b/tests/wpt/web-platform-tests/tools/ci/check_stability.py index 3235cee5ac6..2b32eb50c0f 100644 --- a/tests/wpt/web-platform-tests/tools/ci/check_stability.py +++ b/tests/wpt/web-platform-tests/tools/ci/check_stability.py @@ -20,7 +20,7 @@ from tools.wpt import markdown from tools import localpaths # noqa: F401 logger = None -run_step, write_inconsistent, write_results = None, None, None +run_step, write_inconsistent, write_slow_tests, write_results = None, None, None, None wptrunner = None def setup_logging(): @@ -35,9 +35,9 @@ def setup_logging(): def do_delayed_imports(): - global wptrunner, run_step, write_inconsistent, write_results + global wptrunner, run_step, write_inconsistent, write_slow_tests, write_results from wptrunner import wptrunner - from wptrunner.stability import run_step, write_inconsistent, write_results + from wptrunner.stability import run_step, write_inconsistent, write_slow_tests, write_results class TravisFold(object): @@ -266,8 +266,7 @@ def run(venv, wpt_args, **kwargs): do_delayed_imports() wpt_kwargs["prompt"] = False - wpt_kwargs["install_browser"] = True - wpt_kwargs["install"] = wpt_kwargs["product"].split(":")[0] == "firefox" + wpt_kwargs["install_browser"] = wpt_kwargs["product"].split(":")[0] == "firefox" wpt_kwargs["pause_after_test"] = False wpt_kwargs["verify_log_full"] = False @@ -283,12 +282,15 @@ def run(venv, wpt_args, **kwargs): logger.info("Starting tests") wpt_logger = wptrunner.logger - results, inconsistent, iterations = run_step(wpt_logger, wpt_kwargs["repeat"], True, {}, **wpt_kwargs) + results, inconsistent, slow, iterations = run_step(wpt_logger, wpt_kwargs["repeat"], True, {}, **wpt_kwargs) if results: if inconsistent: write_inconsistent(logger.error, inconsistent, iterations) retcode = 2 + elif slow: + write_slow_tests(logger.error, slow) + retcode = 2 else: logger.info("All results were stable\n") with TravisFold("full_results"): diff --git a/tests/wpt/web-platform-tests/tools/ci/ci_resources_unittest.sh b/tests/wpt/web-platform-tests/tools/ci/ci_resources_unittest.sh index 78868b93433..a13c60fbd8c 100755 --- a/tests/wpt/web-platform-tests/tools/ci/ci_resources_unittest.sh +++ b/tests/wpt/web-platform-tests/tools/ci/ci_resources_unittest.sh @@ -17,7 +17,7 @@ main() { export PATH=$HOME/firefox:$PATH cd $WPT_ROOT/resources/test - tox -- --binary=$HOME/browsers/firefox/firefox + tox -- --binary=$HOME/browsers/nightly/firefox/firefox } main diff --git a/tests/wpt/web-platform-tests/tools/ci/ci_taskcluster.sh b/tests/wpt/web-platform-tests/tools/ci/ci_taskcluster.sh index 118243881a9..901ae520c7f 100755 --- a/tests/wpt/web-platform-tests/tools/ci/ci_taskcluster.sh +++ b/tests/wpt/web-platform-tests/tools/ci/ci_taskcluster.sh @@ -1,10 +1,12 @@ #!/bin/bash +set -ex -./wpt manifest-download +# This is allowed to fail +./wpt manifest-download || echo if [ $1 == "firefox" ]; then - ./wpt run firefox --log-tbpl=../artifacts/log_tbpl.log --log-tbpl-level=info --log-wptreport=../artifacts/wpt_report.json --log-mach=- --this-chunk=$3 --total-chunks=$4 --test-type=$2 -y --install-browser --no-pause --no-restart-on-unexpected --reftest-internal --install-fonts --no-fail-on-unexpected + ./wpt run firefox --log-tbpl=../artifacts/log_tbpl.log --log-tbpl-level=info --log-wptreport=../artifacts/wpt_report.json --log-mach=- --this-chunk=$4 --total-chunks=$5 --test-type=$3 -y --install-browser --channel=$2 --no-pause --no-restart-on-unexpected --reftest-internal --install-fonts --no-fail-on-unexpected elif [ $1 == "chrome" ]; then - ./wpt run chrome --log-tbpl=../artifacts/log_tbpl.log --log-tbpl-level=info --log-wptreport=../artifacts/wpt_report.json --log-mach=- --this-chunk=$3 --total-chunks=$4 --test-type=$2 -y --no-pause --no-restart-on-unexpected --install-fonts --no-fail-on-unexpected + ./wpt run chrome --log-tbpl=../artifacts/log_tbpl.log --log-tbpl-level=info --log-wptreport=../artifacts/wpt_report.json --log-mach=- --channel=$2 --this-chunk=$4 --total-chunks=$5 --test-type=$3 -y --no-pause --no-restart-on-unexpected --install-fonts --no-fail-on-unexpected fi gzip ../artifacts/wpt_report.json diff --git a/tests/wpt/web-platform-tests/tools/ci/ci_wptrunner_infrastructure.sh b/tests/wpt/web-platform-tests/tools/ci/ci_wptrunner_infrastructure.sh index d6d6803974f..c32c9438703 100755 --- a/tests/wpt/web-platform-tests/tools/ci/ci_wptrunner_infrastructure.sh +++ b/tests/wpt/web-platform-tests/tools/ci/ci_wptrunner_infrastructure.sh @@ -18,14 +18,14 @@ test_infrastructure() { } main() { - PRODUCTS=( "firefox" "chrome" ) + PRODUCTS=( "firefox" "chrome" "chrome_webdriver" ) for PRODUCT in "${PRODUCTS[@]}"; do if [ "$PRODUCT" != "firefox" ]; then # Firefox is expected to work using pref settings for DNS # Don't adjust the hostnames in that case to ensure this keeps working hosts_fixup fi - if [ "$PRODUCT" == "chrome" ]; then + if [[ "$PRODUCT" == "chrome"* ]]; then install_chrome unstable test_infrastructure "--binary=$(which google-chrome-unstable)" else diff --git a/tests/wpt/web-platform-tests/tools/ci/commands.json b/tests/wpt/web-platform-tests/tools/ci/commands.json index 0f8f5823699..361c9e4f3de 100644 --- a/tests/wpt/web-platform-tests/tools/ci/commands.json +++ b/tests/wpt/web-platform-tests/tools/ci/commands.json @@ -1,7 +1,42 @@ { - "test-jobs": {"path": "jobs.py", "script": "run", "parser": "create_parser", "help": "List test jobs that should run for a set of commits", - "virtualenv": false}, - "check-stability": {"path": "check_stability.py", "script": "run", "parser": "get_parser", "parse_known": true, "help": "Check test stability", - "virtualenv": true, "install": ["requests"], "requirements": ["../wptrunner/requirements.txt"]}, - "make-hosts-file": {"path": "make_hosts_file.py", "script": "run", "parser": "create_parser", "help": "Output a hosts file to stdout", "virtualenv": false} + "test-jobs": { + "path": "jobs.py", + "script": "run", + "parser": "create_parser", + "help": "List test jobs that should run for a set of commits", + "virtualenv": false + }, + "check-stability": { + "path": "check_stability.py", + "script": "run", + "parser": "get_parser", + "parse_known": true, + "help": "Check test stability", + "virtualenv": true, + "install": [ + "requests" + ], + "requirements": [ + "../wptrunner/requirements.txt" + ] + }, + "make-hosts-file": { + "path": "make_hosts_file.py", + "script": "run", + "parser": "create_parser", + "help": "Output a hosts file to stdout", + "virtualenv": false + }, + "tc-download": { + "path": "tcdownload.py", + "script": "run", + "parser": "get_parser", + "parse_known": true, + "help": "Download logs from taskcluster", + "virtualenv": true, + "install": [ + "requests", + "pygithub" + ] + } } diff --git a/tests/wpt/web-platform-tests/tools/ci/tcdownload.py b/tests/wpt/web-platform-tests/tools/ci/tcdownload.py new file mode 100644 index 00000000000..8813dccc888 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/ci/tcdownload.py @@ -0,0 +1,95 @@ +import argparse +import os +import logging + +import requests + +import github + + +logging.basicConfig() +logger = logging.getLogger("tc-download") + + +def get_parser(): + parser = argparse.ArgumentParser() + parser.add_argument("--ref", action="store", default="master", + help="Branch (in the GitHub repository) or commit to fetch logs for") + parser.add_argument("--artifact-name", action="store", default="wpt_report.json.gz", + help="Log type to fetch") + parser.add_argument("--repo-name", action="store", default="web-platform-tests/wpt", + help="GitHub repo name in the format owner/repo. " + "This must be the repo from which the TaskCluster run was scheduled " + "(for PRs this is the repo into which the PR would merge)") + parser.add_argument("--token-file", action="store", + help="File containing GitHub token") + parser.add_argument("--out-dir", action="store", default=".", + help="Path to save the logfiles") + return parser + + +def get_json(url, key=None): + resp = requests.get(url) + resp.raise_for_status() + data = resp.json() + if key: + data = data[key] + return data + + +def get(url, dest, name): + resp = requests.get(url) + resp.raise_for_status() + path = os.path.join(dest, name) + with open(path, "w") as f: + f.write(resp.content) + return path + + +def run(*args, **kwargs): + if not os.path.exists(kwargs["out_dir"]): + os.mkdir(kwargs["out_dir"]) + + if kwargs["token_file"]: + with open(kwargs["token_file"]) as f: + gh = github.Github(f.read().strip()) + else: + gh = github.Github() + + repo = gh.get_repo(kwargs["repo_name"]) + commit = repo.get_commit(kwargs["ref"]) + statuses = commit.get_statuses() + taskgroups = set() + + for status in statuses: + if not status.context.startswith("Taskcluster "): + continue + if status.state == "pending": + continue + taskgroup_id = status.target_url.rsplit("/", 1)[1] + taskgroups.add(taskgroup_id) + + if not taskgroups: + logger.error("No complete TaskCluster runs found for ref %s" % kwargs["ref"]) + return + + for taskgroup in taskgroups: + taskgroup_url = "https://queue.taskcluster.net/v1/task-group/%s/list" + artifacts_list_url = "https://queue.taskcluster.net/v1/task/%s/artifacts" + tasks = get_json(taskgroup_url % taskgroup, "tasks") + for task in tasks: + task_id = task["status"]["taskId"] + url = artifacts_list_url % (task_id,) + for artifact in get_json(url, "artifacts"): + if artifact["name"].endswith(kwargs["artifact_name"]): + filename = "%s-%s-%s" % (task["task"]["metadata"]["name"], + task_id, + kwargs["artifact_name"]) + path = get("%s/%s" % (url, artifact["name"]), kwargs["out_dir"], filename) + logger.info(path) + + +def __main__(): + kwargs = get_parser().parse_args() + + run(None, vars(kwargs)) diff --git a/tests/wpt/web-platform-tests/tools/docker/start.sh b/tests/wpt/web-platform-tests/tools/docker/start.sh index 3325bb24f58..c2fd91d96d4 100755 --- a/tests/wpt/web-platform-tests/tools/docker/start.sh +++ b/tests/wpt/web-platform-tests/tools/docker/start.sh @@ -15,6 +15,7 @@ REMOTE=${1:-https://github.com/web-platform-tests/wpt} BRANCH=${2:-master} REV=${3:-FETCH_HEAD} BROWSER=${4:-all} +CHANNEL=${5:-nightly} cd ~ @@ -32,10 +33,22 @@ git checkout -b build ${REV} sudo sh -c './wpt make-hosts-file >> /etc/hosts' -if [[ $BROWSER == "chrome"* ]] || [[ "$BROWSER" == all ]] +if [[ $BROWSER == "chrome" ]] || [[ "$BROWSER" == all ]] then # Install Chrome dev - deb_archive=google-chrome-unstable_current_amd64.deb + if [[ "$CHANNEL" == "dev" ]] || [[ "$CHANNEL" == "nightly" ]] + then + deb_archive=google-chrome-unstable_current_amd64.deb + elif [[ "$CHANNEL" == "beta" ]] + then + deb_archive=google-chrome-beta_current_amd64.deb + elif [[ "$CHANNEL" == "stable" ]] + then + deb_archive=google-chrome-stable_current_amd64.deb + else + echo Unrecognized release channel: $CHANNEL >&2 + exit 1 + fi wget https://dl.google.com/linux/direct/$deb_archive sudo apt-get -qqy update && sudo gdebi -n $deb_archive diff --git a/tests/wpt/web-platform-tests/tools/lint/lint.py b/tests/wpt/web-platform-tests/tools/lint/lint.py index 3f43b373abe..cf668faea6f 100644 --- a/tests/wpt/web-platform-tests/tools/lint/lint.py +++ b/tests/wpt/web-platform-tests/tools/lint/lint.py @@ -216,7 +216,8 @@ def check_css_globally_unique(repo_root, paths): elif source_file.name_is_reference: ref_files[source_file.name].add(path) else: - test_files[source_file.name].add(path) + name = source_file.name.replace('-manual', '') + test_files[name].add(path) errors = [] diff --git a/tests/wpt/web-platform-tests/tools/manifest/item.py b/tests/wpt/web-platform-tests/tools/manifest/item.py index 61919fcc31e..ddf046a68fa 100644 --- a/tests/wpt/web-platform-tests/tools/manifest/item.py +++ b/tests/wpt/web-platform-tests/tools/manifest/item.py @@ -234,7 +234,7 @@ class Stub(URLManifestItem): item_type = "stub" -class WebdriverSpecTest(URLManifestItem): +class WebDriverSpecTest(URLManifestItem): item_type = "wdspec" def __init__(self, source_file, url, url_base="/", timeout=None, manifest=None): diff --git a/tests/wpt/web-platform-tests/tools/manifest/manifest.py b/tests/wpt/web-platform-tests/tools/manifest/manifest.py index 42a8e1ceb23..9b2f0a18a56 100644 --- a/tests/wpt/web-platform-tests/tools/manifest/manifest.py +++ b/tests/wpt/web-platform-tests/tools/manifest/manifest.py @@ -4,7 +4,7 @@ import os from collections import defaultdict from six import iteritems, itervalues, viewkeys, string_types -from .item import ManualTest, WebdriverSpecTest, Stub, RefTestNode, RefTest, TestharnessTest, SupportFile, ConformanceCheckerTest, VisualTest +from .item import ManualTest, WebDriverSpecTest, Stub, RefTestNode, RefTest, TestharnessTest, SupportFile, ConformanceCheckerTest, VisualTest from .log import get_logger from .utils import from_os_path, to_os_path @@ -193,7 +193,7 @@ class Manifest(object): "reftest_node": RefTestNode, "manual": ManualTest, "stub": Stub, - "wdspec": WebdriverSpecTest, + "wdspec": WebDriverSpecTest, "conformancechecker": ConformanceCheckerTest, "visual": VisualTest, "support": SupportFile} diff --git a/tests/wpt/web-platform-tests/tools/manifest/sourcefile.py b/tests/wpt/web-platform-tests/tools/manifest/sourcefile.py index 133f8b59828..9be0d8966ec 100644 --- a/tests/wpt/web-platform-tests/tools/manifest/sourcefile.py +++ b/tests/wpt/web-platform-tests/tools/manifest/sourcefile.py @@ -12,7 +12,7 @@ except ImportError: import html5lib from . import XMLParser -from .item import Stub, ManualTest, WebdriverSpecTest, RefTestNode, TestharnessTest, SupportFile, ConformanceCheckerTest, VisualTest +from .item import Stub, ManualTest, WebDriverSpecTest, RefTestNode, TestharnessTest, SupportFile, ConformanceCheckerTest, VisualTest from .utils import rel_path_to_url, ContextManagerBytesIO, cached_property wd_pattern = "*.py" @@ -645,7 +645,7 @@ class SourceFile(object): rv = TestharnessTest.item_type, tests elif self.name_is_webdriver: - rv = WebdriverSpecTest.item_type, [WebdriverSpecTest(self, self.url, + rv = WebDriverSpecTest.item_type, [WebDriverSpecTest(self, self.url, timeout=self.timeout)] elif self.content_is_css_manual and not self.name_is_reference: diff --git a/tests/wpt/web-platform-tests/tools/manifest/tests/test_manifest.py b/tests/wpt/web-platform-tests/tools/manifest/tests/test_manifest.py index 8bf7ef96c5f..f1241e04406 100644 --- a/tests/wpt/web-platform-tests/tools/manifest/tests/test_manifest.py +++ b/tests/wpt/web-platform-tests/tools/manifest/tests/test_manifest.py @@ -43,7 +43,7 @@ def rel_dir_file_path(draw): @hs.composite def sourcefile_strategy(draw): item_classes = [item.TestharnessTest, item.RefTest, item.RefTestNode, - item.ManualTest, item.Stub, item.WebdriverSpecTest, + item.ManualTest, item.Stub, item.WebDriverSpecTest, item.ConformanceCheckerTest, item.SupportFile] cls = draw(hs.sampled_from(item_classes)) diff --git a/tests/wpt/web-platform-tests/tools/serve/serve.py b/tests/wpt/web-platform-tests/tools/serve/serve.py index 97a5063c1b9..e66d38b3dae 100644 --- a/tests/wpt/web-platform-tests/tools/serve/serve.py +++ b/tests/wpt/web-platform-tests/tools/serve/serve.py @@ -100,9 +100,12 @@ class WrapperHandler(object): :param request: The Request being processed. """ path = self._get_path(filesystem_path(self.base_path, request, self.url_base), False) - with open(path, "rb") as f: - for key, value in read_script_metadata(f, js_meta_re): - yield key, value + try: + with open(path, "rb") as f: + for key, value in read_script_metadata(f, js_meta_re): + yield key, value + except IOError: + raise HTTPException(404) def _get_meta(self, request): """Get an iterator over strings to inject into the wrapper document @@ -378,15 +381,17 @@ def build_routes(aliases): class ServerProc(object): - def __init__(self): + def __init__(self, scheme=None): self.proc = None self.daemon = None self.stop = Event() + self.scheme = scheme def start(self, init_func, host, port, paths, routes, bind_address, config, **kwargs): self.proc = Process(target=self.create_daemon, args=(init_func, host, port, paths, routes, bind_address, config), + name='%s on port %s' % (self.scheme, port), kwargs=kwargs) self.proc.daemon = True self.proc.start() @@ -507,7 +512,7 @@ def start_servers(host, ports, paths, routes, bind_address, config, **kwargs): "ws":start_ws_server, "wss":start_wss_server}[scheme] - server_proc = ServerProc() + server_proc = ServerProc(scheme=scheme) server_proc.start(init_func, host, port, paths, routes, bind_address, config, **kwargs) servers[scheme].append((port, server_proc)) @@ -828,9 +833,16 @@ def run(**kwargs): servers = start(config, build_routes(config["aliases"]), **kwargs) try: - while any(item.is_alive() for item in iter_procs(servers)): + while all(item.is_alive() for item in iter_procs(servers)): for item in iter_procs(servers): item.join(1) + exited = [item for item in iter_procs(servers) if not item.is_alive()] + subject = "subprocess" if len(exited) == 1 else "subprocesses" + + logger.info("%s %s exited:" % (len(exited), subject)) + + for item in iter_procs(servers): + logger.info("Status of %s:\t%s" % (item.name, "running" if item.is_alive() else "not running")) except KeyboardInterrupt: logger.info("Shutting down") diff --git a/tests/wpt/web-platform-tests/tools/serve/test_functional.py b/tests/wpt/web-platform-tests/tools/serve/test_functional.py new file mode 100644 index 00000000000..87268ffc00d --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/serve/test_functional.py @@ -0,0 +1,77 @@ +try: + from importlib import reload +except ImportError: + pass +import json +import os +try: + import Queue as queue +except ImportError: + import queue +import tempfile +import threading + +import pytest + +from . import serve +from wptserve import logger + + +class ServerProcSpy(serve.ServerProc): + instances = None + + def start(self, *args, **kwargs): + result = super(ServerProcSpy, self).start(*args, **kwargs) + + if ServerProcSpy.instances is not None: + ServerProcSpy.instances.put(self) + + return result + +serve.ServerProc = ServerProcSpy + +@pytest.fixture() +def server_subprocesses(): + ServerProcSpy.instances = queue.Queue() + yield ServerProcSpy.instances + ServerProcSpy.instances = None + +@pytest.fixture() +def tempfile_name(): + name = tempfile.mkstemp()[1] + yield name + os.remove(name) + + +def test_subprocess_exit(server_subprocesses, tempfile_name): + timeout = 30 + + def target(): + # By default, the server initially creates a child process to validate + # local system configuration. That process is unrelated to the behavior + # under test, but at the time of this writing, the parent uses the same + # constructor that is also used to create the long-running processes + # which are relevant to this functionality. Disable the check so that + # the constructor is only used to create relevant processes. + with open(tempfile_name, 'w') as handle: + json.dump({"check_subdomains": False}, handle) + + # The `logger` module from the wptserver package uses a singleton + # pattern which resists testing. In order to avoid conflicting with + # other tests which rely on that module, pre-existing state is + # discarded through an explicit "reload" operation. + reload(logger) + + serve.run(config_path=tempfile_name) + + thread = threading.Thread(target=target) + + thread.start() + + server_subprocesses.get(True, timeout) + subprocess = server_subprocesses.get(True, timeout) + subprocess.kill() + + thread.join(timeout) + + assert not thread.is_alive() diff --git a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/error.py b/tests/wpt/web-platform-tests/tools/webdriver/webdriver/error.py index b2337ff3b38..23ffc40b31f 100644 --- a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/error.py +++ b/tests/wpt/web-platform-tests/tools/webdriver/webdriver/error.py @@ -6,8 +6,10 @@ class WebDriverException(Exception): http_status = None status_code = None - def __init__(self, message=None, stacktrace=None): + def __init__(self, http_status=None, status_code=None, message=None, stacktrace=None): super(WebDriverException, self) + self.http_status = http_status + self.status_code = status_code self.message = message self.stacktrace = stacktrace @@ -113,7 +115,7 @@ class NoSuchWindowException(WebDriverException): class ScriptTimeoutException(WebDriverException): - http_status = 408 + http_status = 500 status_code = "script timeout" @@ -128,7 +130,7 @@ class StaleElementReferenceException(WebDriverException): class TimeoutException(WebDriverException): - http_status = 408 + http_status = 500 status_code = "timeout" @@ -171,6 +173,8 @@ def from_response(response): """ if response.status == 200: raise UnknownErrorException( + response.status, + None, "Response is not an error:\n" "%s" % json.dumps(response.body)) @@ -178,6 +182,8 @@ def from_response(response): value = response.body["value"] else: raise UnknownErrorException( + response.status, + None, "Expected 'value' key in response body:\n" "%s" % json.dumps(response.body)) @@ -187,7 +193,7 @@ def from_response(response): stack = value["stacktrace"] or None cls = get(code) - return cls(message, stacktrace=stack) + return cls(response.status, code, message, stacktrace=stack) def get(error_code): diff --git a/tests/wpt/web-platform-tests/tools/wpt/browser.py b/tests/wpt/web-platform-tests/tools/wpt/browser.py index 9834e5d53f3..7b943c2e73c 100644 --- a/tests/wpt/web-platform-tests/tools/wpt/browser.py +++ b/tests/wpt/web-platform-tests/tools/wpt/browser.py @@ -26,12 +26,12 @@ class Browser(object): return NotImplemented @abstractmethod - def install_webdriver(self, dest=None): + def install_webdriver(self, dest=None, channel=None): """Install the WebDriver implementation for this browser.""" return NotImplemented @abstractmethod - def find_binary(self): + def find_binary(self, venv_path=None, channel=None): """Find the binary of the browser. If the WebDriver for the browser is able to find the binary itself, this @@ -84,9 +84,27 @@ class Firefox(Browser): return "%s%s" % (platform, bits) - def install(self, dest=None): + def install(self, dest=None, channel="nightly"): """Install Firefox.""" + branch = { + "nightly": "mozilla-central", + "beta": "mozilla-beta", + "stable": "mozilla-stable" + } + scraper = { + "nightly": "daily", + "beta": "release", + "stable": "release" + } + version = { + "stable": "latest", + "beta": "latest-beta", + "nightly": "latest" + } + if channel not in branch: + raise ValueError("Unrecognised release channel: %s" % channel) + from mozdownload import FactoryScraper import mozinstall @@ -103,9 +121,12 @@ class Firefox(Browser): # os.getcwd() doesn't include the venv path dest = os.path.join(os.getcwd(), "_venv") - dest = os.path.join(dest, "browsers") + dest = os.path.join(dest, "browsers", channel) - filename = FactoryScraper("daily", branch="mozilla-central", destination=dest).download() + filename = FactoryScraper(scraper[channel], + branch=branch[channel], + version=version[channel], + destination=dest).download() try: mozinstall.install(filename, dest) @@ -146,11 +167,14 @@ class Firefox(Browser): return binary - def find_binary(self, venv_path=None): + def find_binary(self, venv_path=None, channel=None): if venv_path is None: venv_path = os.path.join(os.getcwd(), "_venv") - binary = self.find_binary_path(os.path.join(venv_path, "browsers")) + path = os.path.join(venv_path, "browsers") + if channel is not None: + path = os.path.join(path, channel) + binary = self.find_binary_path(path) if not binary and uname[0] == "Darwin": macpaths = ["/Applications/FirefoxNightly.app/Contents/MacOS", @@ -190,6 +214,18 @@ class Firefox(Browser): if channel == "stable": repo = "https://hg.mozilla.org/releases/mozilla-release" tag = "FIREFOX_%s_RELEASE" % version.replace(".", "_") + elif channel == "beta": + repo = "https://hg.mozilla.org/releases/mozilla-beta" + major_version = version.split(".", 1)[0] + # For beta we have a different format for betas that are now in stable releases + # vs those that are not + tags = get("https://hg.mozilla.org/releases/mozilla-beta/json-tags").json()["tags"] + tags = {item["tag"] for item in tags} + end_tag = "FIREFOX_BETA_%s_END" % major_version + if end_tag in tags: + tag = end_tag + else: + tag = "tip" else: repo = "https://hg.mozilla.org/mozilla-central" if channel == "beta": @@ -202,8 +238,14 @@ class Firefox(Browser): return "%s/archive/%s.zip/testing/profiles/" % (repo, tag) - def install_prefs(self, binary, dest=None): - version, channel = self.get_version_and_channel(binary) + def install_prefs(self, binary, dest=None, channel=None): + version, channel_ = self.get_version_and_channel(binary) + if channel is not None and channel != channel_: + # Beta doesn't always seem to have the b in the version string, so allow the + # manually supplied value to override the one from the binary + logger.warning("Supplied channel doesn't match binary, using supplied channel") + elif channel is None: + channel = channel_ if dest is None: dest = os.pwd @@ -257,11 +299,18 @@ class Firefox(Browser): assert latest_release != 0 return "v%s.%s.%s" % tuple(str(item) for item in latest_release) - def install_webdriver(self, dest=None): + def install_webdriver(self, dest=None, channel=None): """Install latest Geckodriver.""" if dest is None: dest = os.getcwd() + if channel == "nightly": + path = self.install_geckodriver_nightly(dest) + if path is not None: + return path + else: + logger.warning("Nightly webdriver not found; falling back to release") + version = self._latest_geckodriver_version() format = "zip" if uname[0] == "Windows" else "tar.gz" logger.debug("Latest geckodriver release %s" % version) @@ -273,9 +322,39 @@ class Firefox(Browser): untar(get(url).raw, dest=dest) return find_executable(os.path.join(dest, "geckodriver")) - def version(self, binary=None): + def install_geckodriver_nightly(self, dest): + import tarfile + import mozdownload + logger.info("Attempting to install webdriver from nightly") + try: + s = mozdownload.DailyScraper(branch="mozilla-central", + extension="common.tests.tar.gz", + destination=dest) + package_path = s.download() + except mozdownload.errors.NotFoundError: + return + + try: + exe_suffix = ".exe" if uname[0] == "Windows" else "" + with tarfile.open(package_path, "r") as f: + try: + member = f.getmember("bin%sgeckodriver%s" % (os.path.sep, + exe_suffix)) + except KeyError: + return + # Remove bin/ from the path. + member.name = os.path.basename(member.name) + f.extractall(members=[member], path=dest) + path = os.path.join(dest, member.name) + logger.info("Extracted geckodriver to %s" % path) + finally: + os.unlink(package_path) + + return path + + def version(self, binary=None, channel=None): """Retrieve the release version of the installed browser.""" - binary = binary or self.find_binary() + binary = binary or self.find_binary(channel) version_string = call(binary, "--version").strip() m = re.match(r"Mozilla Firefox (.*)", version_string) if not m: @@ -289,16 +368,16 @@ class Fennec(Browser): product = "fennec" requirements = "requirements_firefox.txt" - def install(self, dest=None): + def install(self, dest=None, channel=None): raise NotImplementedError - def find_binary(self, venv_path=None): + def find_binary(self, venv_path=None, channel=None): raise NotImplementedError def find_webdriver(self): raise NotImplementedError - def install_webdriver(self, dest=None): + def install_webdriver(self, dest=None, channel=None): raise NotImplementedError def version(self, binary=None): @@ -324,7 +403,7 @@ class Chrome(Browser): logger.warn("Unable to find the browser binary.") return None - def install(self, dest=None): + def install(self, dest=None, channel=None): raise NotImplementedError def platform_string(self): @@ -346,13 +425,13 @@ class Chrome(Browser): return "%s%s" % (platform, bits) - def find_binary(self): + def find_binary(self, venv_path=None, channel=None): raise NotImplementedError def find_webdriver(self): return find_executable("chromedriver") - def install_webdriver(self, dest=None): + def install_webdriver(self, dest=None, channel=None): if dest is None: dest = os.pwd latest = get("http://chromedriver.storage.googleapis.com/LATEST_RELEASE").text.strip() @@ -391,22 +470,28 @@ class ChromeAndroid(Browser): product = "chrome_android" requirements = "requirements_chrome_android.txt" - def install(self, dest=None): + def install(self, dest=None, channel=None): raise NotImplementedError - def find_binary(self): + def find_binary(self, venv_path=None, channel=None): raise NotImplementedError def find_webdriver(self): return find_executable("chromedriver") - def install_webdriver(self, dest=None): + def install_webdriver(self, dest=None, channel=None): chrome = Chrome() - return chrome.install_webdriver(dest) + return chrome.install_webdriver(dest, channel) def version(self, binary): return None +class ChromeWebDriver(Chrome): + """Chrome-specific interface for chrome without using selenium. + + Includes webdriver installation. + """ + product = "chrome_webdriver" class Opera(Browser): """Opera-specific interface. @@ -425,7 +510,7 @@ class Opera(Browser): logger.warn("Unable to find the browser binary.") return None - def install(self, dest=None): + def install(self, dest=None, channel=None): raise NotImplementedError def platform_string(self): @@ -447,13 +532,13 @@ class Opera(Browser): return "%s%s" % (platform, bits) - def find_binary(self): + def find_binary(self, venv_path=None, channel=None): raise NotImplementedError def find_webdriver(self): return find_executable("operadriver") - def install_webdriver(self, dest=None): + def install_webdriver(self, dest=None, channel=None): if dest is None: dest = os.pwd latest = get("https://api.github.com/repos/operasoftware/operachromiumdriver/releases/latest").json()["tag_name"] @@ -487,38 +572,42 @@ class Edge(Browser): product = "edge" requirements = "requirements_edge.txt" - def install(self, dest=None): + def install(self, dest=None, channel=None): raise NotImplementedError - def find_binary(self): + def find_binary(self, venv_path=None, channel=None): raise NotImplementedError def find_webdriver(self): return find_executable("MicrosoftWebDriver") - def install_webdriver(self, dest=None): + def install_webdriver(self, dest=None, channel=None): raise NotImplementedError def version(self, binary): return None +class EdgeWebDriver(Edge): + product = "edge_webdriver" + + class InternetExplorer(Browser): """Internet Explorer-specific interface.""" product = "ie" requirements = "requirements_ie.txt" - def install(self, dest=None): + def install(self, dest=None, channel=None): raise NotImplementedError - def find_binary(self): + def find_binary(self, venv_path=None, channel=None): raise NotImplementedError def find_webdriver(self): return find_executable("IEDriverServer.exe") - def install_webdriver(self, dest=None): + def install_webdriver(self, dest=None, channel=None): raise NotImplementedError def version(self, binary): @@ -534,22 +623,26 @@ class Safari(Browser): product = "safari" requirements = "requirements_safari.txt" - def install(self, dest=None): + def install(self, dest=None, channel=None): raise NotImplementedError - def find_binary(self): + def find_binary(self, venv_path=None, channel=None): raise NotImplementedError def find_webdriver(self): return find_executable("safaridriver") - def install_webdriver(self): + def install_webdriver(self, dest=None, channel=None): raise NotImplementedError def version(self, binary): return None +class SafariWebDriver(Safari): + product = "safari_webdriver" + + class Servo(Browser): """Servo-specific interface.""" @@ -574,8 +667,10 @@ class Servo(Browser): return (platform, extension, decompress) - def install(self, dest=None): + def install(self, dest=None, channel="nightly"): """Install latest Browser Engine.""" + if channel != "nightly": + raise ValueError("Only nightly versions of Servo are available") if dest is None: dest = os.pwd @@ -588,13 +683,16 @@ class Servo(Browser): os.chmod(path, st.st_mode | stat.S_IEXEC) return path - def find_binary(self): - return find_executable("servo") + def find_binary(self, venv_path=None, channel=None): + path = find_executable("servo", os.path.join(venv_path, "servo")) + if path is None: + path = find_executable("servo") + return path def find_webdriver(self): return None - def install_webdriver(self, dest=None): + def install_webdriver(self, dest=None, channel=None): raise NotImplementedError def version(self, binary): @@ -609,16 +707,16 @@ class Sauce(Browser): product = "sauce" requirements = "requirements_sauce.txt" - def install(self, dest=None): + def install(self, dest=None, channel=None): raise NotImplementedError - def find_binary(self): + def find_binary(self, venev_path=None, channel=None): raise NotImplementedError def find_webdriver(self): raise NotImplementedError - def install_webdriver(self, dest=None): + def install_webdriver(self, dest=None, channel=None): raise NotImplementedError def version(self, binary): @@ -631,16 +729,16 @@ class WebKit(Browser): product = "webkit" requirements = "requirements_webkit.txt" - def install(self, dest=None): + def install(self, dest=None, channel=None): raise NotImplementedError - def find_binary(self, path=None): + def find_binary(self, venv_path=None, channel=None): return None def find_webdriver(self): return None - def install_webdriver(self): + def install_webdriver(self, dest=None, channel=None): raise NotImplementedError def version(self, binary): diff --git a/tests/wpt/web-platform-tests/tools/wpt/install.py b/tests/wpt/web-platform-tests/tools/wpt/install.py index d779651c990..62c833aa3f0 100644 --- a/tests/wpt/web-platform-tests/tools/wpt/install.py +++ b/tests/wpt/web-platform-tests/tools/wpt/install.py @@ -2,20 +2,62 @@ import argparse import browser import sys + +latest_channels = { + 'firefox': 'nightly', + 'chrome': 'dev', + 'servo': 'nightly' +} + +channel_by_name = { + 'stable': 'stable', + 'release': 'stable', + 'beta': 'beta', + 'nightly': latest_channels, + 'dev': latest_channels, + 'preview': latest_channels, + 'experimental': latest_channels, +} + + def get_parser(): - parser = argparse.ArgumentParser() - parser.add_argument('browser', choices=['firefox', 'chrome'], + parser = argparse.ArgumentParser(description="""Install a given browser or webdriver frontend. + + For convenience the release channel of the browser accepts various spellings, + but we actually support at most three variants; whatever the latest development + release is (e.g. Firefox nightly or Chrome dev), the latest beta release, and + the most recent stable release.""") + parser.add_argument('browser', choices=['firefox', 'chrome', 'servo'], help='name of web browser product') parser.add_argument('component', choices=['browser', 'webdriver'], help='name of component') + parser.add_argument('--channel', choices=channel_by_name.keys(), + default="nightly", help='Name of browser release channel. ' + '"stable" and "release" are synonyms for the latest browser stable release,' + '"nightly", "dev", "experimental", and "preview" are all synonyms for ' + 'the latest available development release. For WebDriver installs, ' + 'we attempt to select an appropriate, compatible, version for the ' + 'latest browser release on the selected channel.') parser.add_argument('-d', '--destination', help='filesystem directory to place the component') return parser +def get_channel(browser, channel): + channel = channel_by_name[channel] + if isinstance(channel, dict): + channel = channel[browser] + return channel + + def run(venv, **kwargs): browser = kwargs["browser"] destination = kwargs["destination"] + channel = get_channel(browser, kwargs["channel"]) + + if channel != kwargs["channel"]: + print "Interpreting channel '%s' as '%s'" % (kwargs["channel"], + channel) if destination is None: if venv: @@ -27,10 +69,10 @@ def run(venv, **kwargs): raise argparse.ArgumentError(None, "No --destination argument, and no default for the environment") - install(browser, kwargs["component"], destination) + install(browser, kwargs["component"], destination, channel) -def install(name, component, destination): +def install(name, component, destination, channel="nightly"): if component == 'webdriver': method = 'install_webdriver' else: @@ -38,4 +80,6 @@ def install(name, component, destination): subclass = getattr(browser, name.title()) sys.stdout.write('Now installing %s %s...\n' % (name, component)) - getattr(subclass(), method)(dest=destination) + path = getattr(subclass(), method)(dest=destination, channel=channel) + if path: + sys.stdout.write('Binary installed as %s\n' % (path,)) diff --git a/tests/wpt/web-platform-tests/tools/wpt/run.py b/tests/wpt/web-platform-tests/tools/wpt/run.py index 6b098b41f70..a1e5637bf1d 100644 --- a/tests/wpt/web-platform-tests/tools/wpt/run.py +++ b/tests/wpt/web-platform-tests/tools/wpt/run.py @@ -7,7 +7,7 @@ from distutils.spawn import find_executable wpt_root = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)) sys.path.insert(0, os.path.abspath(os.path.join(wpt_root, "tools"))) -from . import browser, utils, virtualenv +from . import browser, install, utils, virtualenv from ..serve import serve logger = None @@ -47,7 +47,15 @@ def create_parser(): parser.add_argument("--yes", "-y", dest="prompt", action="store_false", default=True, help="Don't prompt before installing components") parser.add_argument("--install-browser", action="store_true", - help="Install the latest development version of the browser") + help="Install the browser") + parser.add_argument("--channel", action="store", + choices=install.channel_by_name.keys(), + default=None, help='Name of browser release channel.' + '"stable" and "release" are synonyms for the latest browser stable release,' + '"nightly", "dev", "experimental", and "preview" are all synonyms for ' + 'the latest available development release. For WebDriver installs, ' + 'we attempt to select an appropriate, compatible, version for the ' + 'latest browser release on the selected channel.') parser._add_container_actions(wptcommandline.create_parser()) return parser @@ -105,7 +113,7 @@ def check_environ(product): missing_hosts = set(expected_hosts) if is_windows: - hosts_path = "C:\Windows\System32\drivers\etc\hosts" + hosts_path = "%s\System32\drivers\etc\hosts" % os.environ.get("SystemRoot", "C:\Windows") else: hosts_path = "/etc/hosts" @@ -120,7 +128,7 @@ def check_environ(product): if is_windows: message = """Missing hosts file configuration. Run -python wpt make-hosts-file | Out-File %SystemRoot%\System32\drivers\etc\hosts -Encoding ascii -Append +python wpt make-hosts-file | Out-File %s -Encoding ascii -Append in PowerShell with Administrator privileges.""" % hosts_path else: @@ -150,9 +158,9 @@ class BrowserSetup(object): elif resp == "n": return False - def install(self, venv): + def install(self, venv, channel=None): if self.prompt_install(self.name): - return self.browser.install(venv.path) + return self.browser.install(venv.path, channel) def install_requirements(self): self.venv.install_requirements(os.path.join(wpt_root, "tools", "wptrunner", self.browser.requirements)) @@ -167,7 +175,8 @@ class Firefox(BrowserSetup): def setup_kwargs(self, kwargs): if kwargs["binary"] is None: - binary = self.browser.find_binary(self.venv.path) + binary = self.browser.find_binary(self.venv.path, + kwargs["browser_channel"]) if binary is None: raise WptrunError("""Firefox binary not found on $PATH. @@ -205,7 +214,9 @@ Consider installing certutil via your OS package manager or directly.""") kwargs["test_types"].remove("wdspec") if kwargs["prefs_root"] is None: - prefs_root = self.browser.install_prefs(kwargs["binary"], self.venv.path) + prefs_root = self.browser.install_prefs(kwargs["binary"], + self.venv.path, + channel=kwargs["browser_channel"]) kwargs["prefs_root"] = prefs_root @@ -262,6 +273,10 @@ class ChromeAndroid(BrowserSetup): else: raise WptrunError("Unable to locate or install chromedriver binary") +class ChromeWebDriver(Chrome): + name = "chrome_webdriver" + browser_cls = browser.ChromeWebDriver + class Opera(BrowserSetup): name = "opera" @@ -290,7 +305,7 @@ class Edge(BrowserSetup): name = "edge" browser_cls = browser.Edge - def install(self, venv): + def install(self, venv, channel=None): raise NotImplementedError def setup_kwargs(self, kwargs): @@ -307,11 +322,16 @@ https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/ kwargs["webdriver_binary"] = webdriver_binary +class EdgeWebDriver(Edge): + name = "edge_webdriver" + browser_cls = browser.EdgeWebDriver + + class InternetExplorer(BrowserSetup): name = "ie" browser_cls = browser.InternetExplorer - def install(self, venv): + def install(self, venv, channel=None): raise NotImplementedError def setup_kwargs(self, kwargs): @@ -332,7 +352,7 @@ class Safari(BrowserSetup): name = "safari" browser_cls = browser.Safari - def install(self, venv): + def install(self, venv, channel=None): raise NotImplementedError def setup_kwargs(self, kwargs): @@ -345,11 +365,16 @@ class Safari(BrowserSetup): kwargs["webdriver_binary"] = webdriver_binary +class SafariWebDriver(Safari): + name = "safari_webdriver" + browser_cls = browser.SafariWebDriver + + class Sauce(BrowserSetup): name = "sauce" browser_cls = browser.Sauce - def install(self, venv): + def install(self, venv, channel=None): raise NotImplementedError def setup_kwargs(self, kwargs): @@ -362,13 +387,13 @@ class Servo(BrowserSetup): name = "servo" browser_cls = browser.Servo - def install(self, venv): + def install(self, venv, channel=None): if self.prompt_install(self.name): return self.browser.install(venv.path) def setup_kwargs(self, kwargs): if kwargs["binary"] is None: - binary = self.browser.find_binary() + binary = self.browser.find_binary(self.venv.path, None) if binary is None: raise WptrunError("Unable to find servo binary on the PATH") @@ -379,7 +404,7 @@ class WebKit(BrowserSetup): name = "webkit" browser_cls = browser.WebKit - def install(self, venv): + def install(self, venv, channel=None): raise NotImplementedError def setup_kwargs(self, kwargs): @@ -391,9 +416,12 @@ product_setup = { "firefox": Firefox, "chrome": Chrome, "chrome_android": ChromeAndroid, + "chrome_webdriver": ChromeWebDriver, "edge": Edge, + "edge_webdriver": EdgeWebDriver, "ie": InternetExplorer, "safari": Safari, + "safari_webdriver": SafariWebDriver, "servo": Servo, "sauce": Sauce, "opera": Opera, @@ -401,7 +429,7 @@ product_setup = { } -def setup_wptrunner(venv, prompt=True, install=False, **kwargs): +def setup_wptrunner(venv, prompt=True, install_browser=False, **kwargs): from wptrunner import wptrunner, wptcommandline global logger @@ -424,9 +452,20 @@ def setup_wptrunner(venv, prompt=True, install=False, **kwargs): setup_cls = product_setup[kwargs["product"]](venv, prompt, sub_product) setup_cls.install_requirements() - if install: + if install_browser and not kwargs["channel"]: + kwargs["channel"] = "nightly" + + if kwargs["channel"]: + channel = install.get_channel(kwargs["product"], kwargs["channel"]) + if channel != kwargs["channel"]: + logger.info("Interpreting channel '%s' as '%s'" % (kwargs["channel"], + channel)) + kwargs["browser_channel"] = channel + del kwargs["channel"] + + if install_browser: logger.info("Installing browser") - kwargs["binary"] = setup_cls.install(venv) + kwargs["binary"] = setup_cls.install(venv, channel=channel) setup_cls.setup(kwargs) @@ -447,7 +486,7 @@ def run(venv, **kwargs): kwargs = setup_wptrunner(venv, prompt=prompt, - install=install_browser, + install_browser=install_browser, **kwargs) rv = run_single(venv, **kwargs) > 0 diff --git a/tests/wpt/web-platform-tests/tools/wpt/tests/test_run.py b/tests/wpt/web-platform-tests/tools/wpt/tests/test_run.py new file mode 100644 index 00000000000..097131d7ba5 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wpt/tests/test_run.py @@ -0,0 +1,18 @@ +import mock + +import pytest + +from tools.wpt import run + + +@pytest.mark.parametrize("platform", ["Windows", "Linux", "Darwin"]) +def test_check_environ_fail(platform): + m_open = mock.mock_open(read_data=b"") + + with mock.patch.object(run, "open", m_open): + with mock.patch.object(run.platform, "uname", + return_value=(platform, "", "", "", "", "")): + with pytest.raises(run.WptrunError) as excinfo: + run.check_environ("foo") + + assert "wpt make-hosts-file" in excinfo.value.message diff --git a/tests/wpt/web-platform-tests/tools/wpt/tests/test_wpt.py b/tests/wpt/web-platform-tests/tools/wpt/tests/test_wpt.py index b39173e64f2..8f8e5186c7c 100644 --- a/tests/wpt/web-platform-tests/tools/wpt/tests/test_wpt.py +++ b/tests/wpt/web-platform-tests/tools/wpt/tests/test_wpt.py @@ -166,9 +166,9 @@ def test_run_firefox(manifest_dir): os.environ["MOZ_HEADLESS"] = "1" try: if sys.platform == "darwin": - fx_path = os.path.join(wpt.localpaths.repo_root, "_venv", "browsers", "Firefox Nightly.app") + fx_path = os.path.join(wpt.localpaths.repo_root, "_venv", "browsers", "nightly", "Firefox Nightly.app") else: - fx_path = os.path.join(wpt.localpaths.repo_root, "_venv", "browsers", "firefox") + fx_path = os.path.join(wpt.localpaths.repo_root, "_venv", "browsers", "nightly", "firefox") if os.path.exists(fx_path): shutil.rmtree(fx_path) with pytest.raises(SystemExit) as excinfo: @@ -294,15 +294,14 @@ def test_install_chromedriver(): @pytest.mark.xfail(sys.platform == "win32", reason="Tests currently don't work on Windows for path reasons") def test_install_firefox(): - if sys.platform == "darwin": - fx_path = os.path.join(wpt.localpaths.repo_root, "_venv", "browsers", "Firefox Nightly.app") + fx_path = os.path.join(wpt.localpaths.repo_root, "_venv", "browsers", "nightly", "Firefox Nightly.app") else: - fx_path = os.path.join(wpt.localpaths.repo_root, "_venv", "browsers", "firefox") + fx_path = os.path.join(wpt.localpaths.repo_root, "_venv", "browsers", "nightly", "firefox") if os.path.exists(fx_path): shutil.rmtree(fx_path) with pytest.raises(SystemExit) as excinfo: - wpt.main(argv=["install", "firefox", "browser"]) + wpt.main(argv=["install", "firefox", "browser", "--channel=nightly"]) assert excinfo.value.code == 0 assert os.path.exists(fx_path) shutil.rmtree(fx_path) diff --git a/tests/wpt/web-platform-tests/tools/wpt/tox.ini b/tests/wpt/web-platform-tests/tools/wpt/tox.ini index e486bb221d7..cd45a76e179 100644 --- a/tests/wpt/web-platform-tests/tools/wpt/tox.ini +++ b/tests/wpt/web-platform-tests/tools/wpt/tox.ini @@ -7,6 +7,7 @@ deps = pytest pytest-cov hypothesis + mock -r{toxinidir}/../wptrunner/requirements.txt -r{toxinidir}/../wptrunner/requirements_chrome.txt -r{toxinidir}/../wptrunner/requirements_firefox.txt diff --git a/tests/wpt/web-platform-tests/tools/wpt/wpt.py b/tests/wpt/web-platform-tests/tools/wpt/wpt.py index f4eecce22cf..55802461553 100644 --- a/tests/wpt/web-platform-tests/tools/wpt/wpt.py +++ b/tests/wpt/web-platform-tests/tools/wpt/wpt.py @@ -101,9 +101,6 @@ def main(prog=None, argv=None): main_args, command_args = parse_args(argv, commands) - if not(len(argv) and argv[0] in commands): - sys.exit(1) - command = main_args.command props = commands[command] venv = None diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/__init__.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/__init__.py index d8682e16a55..08949f79483 100644 --- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/__init__.py +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/__init__.py @@ -24,11 +24,14 @@ module global scope. product_list = ["chrome", "chrome_android", + "chrome_webdriver", "edge", + "edge_webdriver", "fennec", "firefox", "ie", "safari", + "safari_webdriver", "sauce", "servo", "servodriver", diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/base.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/base.py index dc03ef711b6..70324bec31f 100644 --- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/base.py +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/base.py @@ -2,12 +2,32 @@ import os import platform import socket from abc import ABCMeta, abstractmethod +from copy import deepcopy from ..wptcommandline import require_arg # noqa: F401 here = os.path.split(__file__)[0] +def inherit(super_module, child_globals, product_name): + super_wptrunner = super_module.__wptrunner__ + child_globals["__wptrunner__"] = child_wptrunner = deepcopy(super_wptrunner) + + child_wptrunner["product"] = product_name + + for k in ("check_args", "browser", "browser_kwargs", "executor_kwargs", + "env_extras", "env_options"): + attr = super_wptrunner[k] + child_globals[attr] = getattr(super_module, attr) + + for v in super_module.__wptrunner__["executor"].values(): + child_globals[v] = getattr(super_module, v) + + if "run_info_extras" in super_wptrunner: + attr = super_wptrunner["run_info_extras"] + child_globals[attr] = getattr(super_module, attr) + + def cmd_arg(name, value=None): prefix = "-" if platform.system() == "Windows" else "--" rv = prefix + name diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/chrome_webdriver.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/chrome_webdriver.py new file mode 100644 index 00000000000..a63460f4544 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/chrome_webdriver.py @@ -0,0 +1,50 @@ +from .base import inherit +from . import chrome + +from ..executors import executor_kwargs as base_executor_kwargs +from ..executors.executorwebdriver import (WebDriverTestharnessExecutor, # noqa: F401 + WebDriverRefTestExecutor) # noqa: F401 + + +inherit(chrome, globals(), "chrome_webdriver") + +# __wptrunner__ magically appears from inherit, F821 is undefined name +__wptrunner__["executor_kwargs"] = "executor_kwargs" # noqa: F821 +__wptrunner__["executor"]["testharness"] = "WebDriverTestharnessExecutor" # noqa: F821 +__wptrunner__["executor"]["reftest"] = "WebDriverRefTestExecutor" # noqa: F821 + + +def executor_kwargs(test_type, server_config, cache_manager, run_info_data, + **kwargs): + executor_kwargs = base_executor_kwargs(test_type, server_config, + cache_manager, run_info_data, + **kwargs) + executor_kwargs["close_after_done"] = True + + capabilities = { + "browserName": "chrome", + "platform": "ANY", + "version": "", + "goog:chromeOptions": { + "prefs": { + "profile": { + "default_content_setting_values": { + "popups": 1 + } + } + }, + "w3c": True + } + } + + for (kwarg, capability) in [("binary", "binary"), ("binary_args", "args")]: + if kwargs[kwarg] is not None: + capabilities["goog:chromeOptions"][capability] = kwargs[kwarg] + + if test_type == "testharness": + capabilities["goog:chromeOptions"]["useAutomationExtension"] = False + capabilities["goog:chromeOptions"]["excludeSwitches"] = ["enable-automation"] + + executor_kwargs["capabilities"] = capabilities + + return executor_kwargs diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/edge_webdriver.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/edge_webdriver.py new file mode 100644 index 00000000000..c2545de46f0 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/edge_webdriver.py @@ -0,0 +1,12 @@ +from .base import inherit +from . import edge + +from ..executors.executorwebdriver import (WebDriverTestharnessExecutor, # noqa: F401 + WebDriverRefTestExecutor) # noqa: F401 + + +inherit(edge, globals(), "edge_webdriver") + +# __wptrunner__ magically appears from inherit, F821 is undefined name +__wptrunner__["executor"]["testharness"] = "WebDriverTestharnessExecutor" # noqa: F821 +__wptrunner__["executor"]["reftest"] = "WebDriverRefTestExecutor" # noqa: F821 diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/safari_webdriver.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/safari_webdriver.py new file mode 100644 index 00000000000..12735c141b3 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/safari_webdriver.py @@ -0,0 +1,12 @@ +from .base import inherit +from . import safari + +from ..executors.executorwebdriver import (WebDriverTestharnessExecutor, # noqa: F401 + WebDriverRefTestExecutor) # noqa: F401 + + +inherit(safari, globals(), "safari_webdriver") + +# __wptrunner__ magically appears from inherit, F821 is undefined name +__wptrunner__["executor"]["testharness"] = "WebDriverTestharnessExecutor" # noqa: F821 +__wptrunner__["executor"]["reftest"] = "WebDriverRefTestExecutor" # noqa: F821 diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/sauce.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/sauce.py index 9aa484accd4..02cc322aa35 100644 --- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/sauce.py +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/sauce.py @@ -133,6 +133,7 @@ class SauceConnect(): self.sauce_key = kwargs["sauce_key"] self.sauce_tunnel_id = kwargs["sauce_tunnel_id"] self.sauce_connect_binary = kwargs.get("sauce_connect_binary") + self.sauce_init_timeout = kwargs.get("sauce_init_timeout") self.sc_process = None self.temp_dir = None self.env_config = None @@ -172,12 +173,9 @@ class SauceConnect(): ",".join(self.env_config.domains_set) ]) - # Timeout config vars - max_wait = 30 - tot_wait = 0 while not os.path.exists('./sauce_is_ready') and self.sc_process.poll() is None: - if tot_wait >= max_wait: + if tot_wait >= self.sauce_init_timeout: self.quit() raise SauceException("Sauce Connect Proxy was not ready after %d seconds" % tot_wait) diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executorselenium.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executorselenium.py index d9b67968ddf..0675461d5d8 100644 --- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executorselenium.py +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executorselenium.py @@ -95,14 +95,14 @@ class SeleniumTestharnessProtocolPart(TestharnessProtocolPart): def get_test_window(self, window_id, parent): test_window = None - if window_id: - try: - # Try this, it's in Level 1 but nothing supports it yet - win_s = self.webdriver.execute_script("return window['%s'];" % self.window_id) - win_obj = json.loads(win_s) - test_window = win_obj["window-fcc6-11e5-b4f8-330a88ab9d7f"] - except Exception: - pass + try: + # Try using the JSON serialization of the WindowProxy object, + # it's in Level 1 but nothing supports it yet + win_s = self.webdriver.execute_script("return window['%s'];" % window_id) + win_obj = json.loads(win_s) + test_window = win_obj["window-fcc6-11e5-b4f8-330a88ab9d7f"] + except Exception: + pass if test_window is None: after = self.webdriver.window_handles @@ -296,7 +296,7 @@ class SeleniumTestharnessExecutor(TestharnessExecutor): parent_window = protocol.testharness.close_old_windows() # Now start the test harness protocol.base.execute_script(self.script % format_map) - test_window = protocol.testharness.get_test_window(webdriver, parent_window) + test_window = protocol.testharness.get_test_window(self.window_id, parent_window) handler = CallbackHandler(self.logger, protocol, test_window) while True: diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executorwebdriver.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executorwebdriver.py new file mode 100644 index 00000000000..127c909e810 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executorwebdriver.py @@ -0,0 +1,373 @@ +import json +import os +import socket +import threading +import traceback +import urlparse +import uuid + +from .base import (CallbackHandler, + RefTestExecutor, + RefTestImplementation, + TestharnessExecutor, + extra_timeout, + strip_server) +from .protocol import (BaseProtocolPart, + TestharnessProtocolPart, + Protocol, + SelectorProtocolPart, + ClickProtocolPart, + SendKeysProtocolPart, + TestDriverProtocolPart) +from ..testrunner import Stop + +import webdriver as client + +here = os.path.join(os.path.split(__file__)[0]) + +class WebDriverBaseProtocolPart(BaseProtocolPart): + def setup(self): + self.webdriver = self.parent.webdriver + + def execute_script(self, script, async=False): + method = self.webdriver.execute_async_script if async else self.webdriver.execute_script + return method(script) + + def set_timeout(self, timeout): + try: + self.webdriver.timeouts.script = timeout + except client.WebDriverException: + # workaround https://bugs.chromium.org/p/chromedriver/issues/detail?id=2057 + body = {"type": "script", "ms": timeout * 1000} + self.webdriver.send_session_command("POST", "timeouts", body) + + @property + def current_window(self): + return self.webdriver.window_handle + + def set_window(self, handle): + self.webdriver.window_handle = handle + + def wait(self): + while True: + try: + self.webdriver.execute_async_script("") + except client.TimeoutException: + pass + except (socket.timeout, client.NoSuchWindowException, + client.UnknownErrorException, IOError): + break + except Exception as e: + self.logger.error(traceback.format_exc(e)) + break + + +class WebDriverTestharnessProtocolPart(TestharnessProtocolPart): + def setup(self): + self.webdriver = self.parent.webdriver + + def load_runner(self, url_protocol): + url = urlparse.urljoin(self.parent.executor.server_url(url_protocol), + "/testharness_runner.html") + self.logger.debug("Loading %s" % url) + + self.webdriver.url = url + self.webdriver.execute_script("document.title = '%s'" % + threading.current_thread().name.replace("'", '"')) + + def close_old_windows(self): + exclude = self.webdriver.window_handle + handles = [item for item in self.webdriver.handles if item != exclude] + for handle in handles: + try: + self.webdriver.window_handle = handle + self.webdriver.close() + except client.NoSuchWindowException: + pass + self.webdriver.window_handle = exclude + return exclude + + def get_test_window(self, window_id, parent): + test_window = None + try: + # Try using the JSON serialization of the WindowProxy object, + # it's in Level 1 but nothing supports it yet + win_s = self.webdriver.execute_script("return window['%s'];" % window_id) + win_obj = json.loads(win_s) + test_window = win_obj["window-fcc6-11e5-b4f8-330a88ab9d7f"] + except Exception: + pass + + if test_window is None: + after = self.webdriver.handles + if len(after) == 2: + test_window = next(iter(set(after) - set([parent]))) + elif after[0] == parent and len(after) > 2: + # Hope the first one here is the test window + test_window = after[1] + else: + raise Exception("unable to find test window") + + assert test_window != parent + return test_window + + +class WebDriverSelectorProtocolPart(SelectorProtocolPart): + def setup(self): + self.webdriver = self.parent.webdriver + + def elements_by_selector(self, selector): + return self.webdriver.find.css(selector) + + +class WebDriverClickProtocolPart(ClickProtocolPart): + def setup(self): + self.webdriver = self.parent.webdriver + + def element(self, element): + return element.click() + + +class WebDriverSendKeysProtocolPart(SendKeysProtocolPart): + def setup(self): + self.webdriver = self.parent.webdriver + + def send_keys(self, element, keys): + try: + return element.send_keys(keys) + except client.UnknownErrorException as e: + # workaround https://bugs.chromium.org/p/chromedriver/issues/detail?id=1999 + if (e.http_status != 500 or + e.status_code != "unknown error"): + raise + return element.send_element_command("POST", "value", {"value": list(keys)}) + + +class WebDriverTestDriverProtocolPart(TestDriverProtocolPart): + def setup(self): + self.webdriver = self.parent.webdriver + + def send_message(self, message_type, status, message=None): + obj = { + "type": "testdriver-%s" % str(message_type), + "status": str(status) + } + if message: + obj["message"] = str(message) + self.webdriver.execute_script("window.postMessage(%s, '*')" % json.dumps(obj)) + + +class WebDriverProtocol(Protocol): + implements = [WebDriverBaseProtocolPart, + WebDriverTestharnessProtocolPart, + WebDriverSelectorProtocolPart, + WebDriverClickProtocolPart, + WebDriverSendKeysProtocolPart, + WebDriverTestDriverProtocolPart] + + def __init__(self, executor, browser, capabilities, **kwargs): + super(WebDriverProtocol, self).__init__(executor, browser) + self.capabilities = capabilities + self.url = browser.webdriver_url + self.webdriver = None + + def connect(self): + """Connect to browser via WebDriver.""" + self.logger.debug("Connecting to WebDriver on URL: %s" % self.url) + + host, port = self.url.split(":")[1].strip("/"), self.url.split(':')[-1].strip("/") + + capabilities = {"alwaysMatch": self.capabilities} + self.webdriver = client.Session(host, port, capabilities=capabilities) + self.webdriver.start() + + + def after_conect(self): + pass + + def teardown(self): + self.logger.debug("Hanging up on WebDriver session") + try: + self.webdriver.quit() + except Exception: + pass + del self.webdriver + + def is_alive(self): + try: + # Get a simple property over the connection + self.webdriver.window_handle + except (socket.timeout, client.UnknownErrorException): + return False + return True + + def after_connect(self): + self.testharness.load_runner(self.executor.last_environment["protocol"]) + + +class WebDriverRun(object): + def __init__(self, func, protocol, url, timeout): + self.func = func + self.result = None + self.protocol = protocol + self.url = url + self.timeout = timeout + self.result_flag = threading.Event() + + def run(self): + timeout = self.timeout + + try: + self.protocol.base.set_timeout((timeout + extra_timeout)) + except client.UnknownErrorException: + self.logger.error("Lost WebDriver connection") + return Stop + + executor = threading.Thread(target=self._run) + executor.start() + + flag = self.result_flag.wait(timeout + 2 * extra_timeout) + if self.result is None: + assert not flag + self.result = False, ("EXTERNAL-TIMEOUT", None) + + return self.result + + def _run(self): + try: + self.result = True, self.func(self.protocol, self.url, self.timeout) + except client.TimeoutException: + self.result = False, ("EXTERNAL-TIMEOUT", None) + except (socket.timeout, client.UnknownErrorException): + self.result = False, ("CRASH", None) + except Exception as e: + if (isinstance(e, client.WebDriverException) and + e.http_status == 408 and + e.status_code == "asynchronous script timeout"): + # workaround for https://bugs.chromium.org/p/chromedriver/issues/detail?id=2001 + self.result = False, ("EXTERNAL-TIMEOUT", None) + else: + message = getattr(e, "message", "") + if message: + message += "\n" + message += traceback.format_exc(e) + self.result = False, ("ERROR", message) + finally: + self.result_flag.set() + + +class WebDriverTestharnessExecutor(TestharnessExecutor): + supports_testdriver = True + + def __init__(self, browser, server_config, timeout_multiplier=1, + close_after_done=True, capabilities=None, debug_info=None, + **kwargs): + """WebDriver-based executor for testharness.js tests""" + TestharnessExecutor.__init__(self, browser, server_config, + timeout_multiplier=timeout_multiplier, + debug_info=debug_info) + self.protocol = WebDriverProtocol(self, browser, capabilities) + with open(os.path.join(here, "testharness_webdriver.js")) as f: + self.script = f.read() + with open(os.path.join(here, "testharness_webdriver_resume.js")) as f: + self.script_resume = f.read() + self.close_after_done = close_after_done + self.window_id = str(uuid.uuid4()) + + def is_alive(self): + return self.protocol.is_alive() + + def on_environment_change(self, new_environment): + if new_environment["protocol"] != self.last_environment["protocol"]: + self.protocol.testharness.load_runner(new_environment["protocol"]) + + def do_test(self, test): + url = self.test_url(test) + + success, data = WebDriverRun(self.do_testharness, + self.protocol, + url, + test.timeout * self.timeout_multiplier).run() + + if success: + return self.convert_result(test, data) + + return (test.result_cls(*data), []) + + def do_testharness(self, protocol, url, timeout): + format_map = {"abs_url": url, + "url": strip_server(url), + "window_id": self.window_id, + "timeout_multiplier": self.timeout_multiplier, + "timeout": timeout * 1000} + + parent_window = protocol.testharness.close_old_windows() + # Now start the test harness + protocol.base.execute_script(self.script % format_map) + test_window = protocol.testharness.get_test_window(self.window_id, parent_window) + + handler = CallbackHandler(self.logger, protocol, test_window) + while True: + result = protocol.base.execute_script( + self.script_resume % format_map, async=True) + done, rv = handler(result) + if done: + break + return rv + + +class WebDriverRefTestExecutor(RefTestExecutor): + def __init__(self, browser, server_config, timeout_multiplier=1, + screenshot_cache=None, close_after_done=True, + debug_info=None, capabilities=None, **kwargs): + """WebDriver-based executor for reftests""" + RefTestExecutor.__init__(self, + browser, + server_config, + screenshot_cache=screenshot_cache, + timeout_multiplier=timeout_multiplier, + debug_info=debug_info) + self.protocol = WebDriverProtocol(self, browser, + capabilities=capabilities) + self.implementation = RefTestImplementation(self) + self.close_after_done = close_after_done + self.has_window = False + + with open(os.path.join(here, "reftest.js")) as f: + self.script = f.read() + with open(os.path.join(here, "reftest-wait_webdriver.js")) as f: + self.wait_script = f.read() + + def is_alive(self): + return self.protocol.is_alive() + + def do_test(self, test): + self.protocol.webdriver.window.size = (600, 600) + + result = self.implementation.run_test(test) + + return self.convert_result(test, result) + + def screenshot(self, test, viewport_size, dpi): + # https://github.com/w3c/wptrunner/issues/166 + assert viewport_size is None + assert dpi is None + + return WebDriverRun(self._screenshot, + self.protocol, + self.test_url(test), + test.timeout).run() + + def _screenshot(self, protocol, url, timeout): + webdriver = protocol.webdriver + webdriver.url = url + + webdriver.execute_async_script(self.wait_script) + + screenshot = webdriver.screenshot() + + # strip off the data:img/png, part of the url + if screenshot.startswith("data:image/png;base64,"): + screenshot = screenshot.split(",", 1)[1] + + return screenshot diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/stability.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/stability.py index 859f01444d3..e684bf68076 100644 --- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/stability.py +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/stability.py @@ -15,6 +15,11 @@ localpaths = imp.load_source("localpaths", os.path.abspath(os.path.join(here, os from wpt.markdown import markdown_adjust, table +# If a test takes more than (FLAKY_THRESHOLD*timeout) and does not consistently +# time out, it is considered slow (potentially flaky). +FLAKY_THRESHOLD = 0.8 + + class LogActionFilter(BaseHandler): """Handler that filters out messages not of a given set of actions. @@ -53,7 +58,8 @@ class LogHandler(reader.LogHandler): test = { "subtests": OrderedDict(), - "status": defaultdict(int) + "status": defaultdict(int), + "longest_duration": defaultdict(float), } self.results[test_name] = test return test @@ -73,6 +79,10 @@ class LogHandler(reader.LogHandler): return subtest + def test_start(self, data): + test = self.find_or_create_test(data) + test["start_time"] = data["time"] + def test_status(self, data): subtest = self.find_or_create_subtest(data) subtest["status"][data["status"]] += 1 @@ -82,6 +92,16 @@ class LogHandler(reader.LogHandler): def test_end(self, data): test = self.find_or_create_test(data) test["status"][data["status"]] += 1 + # Timestamps are in ms since epoch. + duration = data["time"] - test.pop("start_time") + test["longest_duration"][data["status"]] = max( + duration, test["longest_duration"][data["status"]]) + try: + # test_timeout is in seconds; convert it to ms. + test["timeout"] = data["extra"]["test_timeout"] * 1000 + except KeyError: + # If a test is skipped, it won't have extra info. + pass def is_inconsistent(results_dict, iterations): @@ -91,9 +111,31 @@ def is_inconsistent(results_dict, iterations): return len(results_dict) > 1 or sum(results_dict.values()) != iterations +def find_slow_status(test): + """Check if a single test almost times out. + + We are interested in tests that almost time out (i.e. likely to be flaky). + Therefore, timeout statuses are ignored, including (EXTERNAL-)TIMEOUT & + CRASH (tests that time out may be marked as CRASH if crashes are detected). + + Returns: + A result status produced by a run that almost times out; None, if no + runs almost time out. + """ + if "timeout" not in test: + return None + threshold = test["timeout"] * FLAKY_THRESHOLD + for status in ['PASS', 'FAIL', 'OK', 'ERROR']: + if (status in test["longest_duration"] and + test["longest_duration"][status] > threshold): + return status + return None + + def process_results(log, iterations): """Process test log and return overall results and list of inconsistent tests.""" inconsistent = [] + slow = [] handler = LogHandler() reader.handle_log(reader.read(log), handler) results = handler.results @@ -103,7 +145,17 @@ def process_results(log, iterations): for subtest_name, subtest in test["subtests"].iteritems(): if is_inconsistent(subtest["status"], iterations): inconsistent.append((test_name, subtest_name, subtest["status"], subtest["messages"])) - return results, inconsistent + + slow_status = find_slow_status(test) + if slow_status is not None: + slow.append(( + test_name, + slow_status, + test["longest_duration"][slow_status], + test["timeout"] + )) + + return results, inconsistent, slow def err_string(results_dict, iterations): @@ -133,6 +185,17 @@ def write_inconsistent(log, inconsistent, iterations): table(["Test", "Subtest", "Results", "Messages"], strings, log) +def write_slow_tests(log, slow): + log("## Slow tests ##\n") + strings = [( + "`%s`" % markdown_adjust(test), + "`%s`" % status, + "`%.0f`" % duration, + "`%.0f`" % timeout) + for test, status, duration, timeout in slow] + table(["Test", "Result", "Longest duration (ms)", "Timeout (ms)"], strings, log) + + def write_results(log, results, iterations, pr_number=None, use_details=False): log("## All results ##\n") if use_details: @@ -202,8 +265,8 @@ def run_step(logger, iterations, restart_after_iteration, kwargs_extras, **kwarg logger._state.suite_started = False log.seek(0) - results, inconsistent = process_results(log, iterations) - return results, inconsistent, iterations + results, inconsistent, slow = process_results(log, iterations) + return results, inconsistent, slow, iterations def get_steps(logger, repeat_loop, repeat_restart, kwargs_extras): @@ -242,7 +305,6 @@ def write_summary(logger, step_results, final_result): logger.info(':::') - def check_stability(logger, repeat_loop=10, repeat_restart=5, chaos_mode=True, max_time=None, output_results=True, **kwargs): kwargs_extras = [{}] @@ -264,7 +326,7 @@ def check_stability(logger, repeat_loop=10, repeat_restart=5, chaos_mode=True, m logger.info(':::') logger.info('::: Running test verification step "%s"...' % desc) logger.info(':::') - results, inconsistent, iterations = step_func(**kwargs) + results, inconsistent, slow, iterations = step_func(**kwargs) if output_results: write_results(logger.info, results, iterations) @@ -274,6 +336,12 @@ def check_stability(logger, repeat_loop=10, repeat_restart=5, chaos_mode=True, m write_summary(logger, step_results, "FAIL") return 1 + if slow: + step_results.append((desc, "FAIL")) + write_slow_tests(logger.info, slow) + write_summary(logger, step_results, "FAIL") + return 1 + step_results.append((desc, "PASS")) write_summary(logger, step_results, "PASS") diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testloader.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testloader.py index 018dc103983..2313a80c745 100644 --- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testloader.py +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testloader.py @@ -439,7 +439,10 @@ class ManifestLoader(object): if (not os.path.exists(manifest_path) or self.force_manifest_update): self.update_manifest(manifest_path, tests_path, url_base, download=self.manifest_download) - manifest_file = manifest.load(tests_path, manifest_path, types=self.types, meta_filters=self.meta_filters) + try: + manifest_file = manifest.load(tests_path, manifest_path, types=self.types, meta_filters=self.meta_filters) + except manifest.ManifestVersionMismatch: + manifest_file = manifest.Manifest(url_base) if manifest_file.url_base != url_base: self.logger.info("Updating url_base in manifest from %s to %s" % (manifest_file.url_base, url_base)) diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testrunner.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testrunner.py index 46d67e3c982..b4ce4381257 100644 --- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testrunner.py +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testrunner.py @@ -590,6 +590,8 @@ class TestRunnerManager(threading.Thread): test.min_assertion_count, test.max_assertion_count) + file_result.extra["test_timeout"] = test.timeout * self.executor_kwargs['timeout_multiplier'] + self.logger.test_end(test.id, status, message=file_result.message, diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/tests/base.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/tests/base.py index b5173f3b513..84dc4f2e7f8 100644 --- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/tests/base.py +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/tests/base.py @@ -17,7 +17,9 @@ if "CURRENT_TOX_ENV" in os.environ: current_tox_env_split = os.environ["CURRENT_TOX_ENV"].split("-") tox_env_extra_browsers = { - "chrome": {"chrome_android"}, + "chrome": {"chrome_android", "chrome_webdriver"}, + "edge": {"edge_webdriver"}, + "safari": {"safari_webdriver"}, "servo": {"servodriver"}, } diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/tests/test_stability.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/tests/test_stability.py index 72cff21016a..5a051b6c899 100644 --- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/tests/test_stability.py +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/tests/test_stability.py @@ -5,8 +5,29 @@ sys.path.insert(0, join(dirname(__file__), "..", "..")) from wptrunner import stability + def test_is_inconsistent(): assert stability.is_inconsistent({"PASS": 10}, 10) is False assert stability.is_inconsistent({"PASS": 9}, 10) is True assert stability.is_inconsistent({"PASS": 9, "FAIL": 1}, 10) is True assert stability.is_inconsistent({"PASS": 8, "FAIL": 1}, 10) is True + + +def test_find_slow_status(): + assert stability.find_slow_status({ + "longest_duration": {"TIMEOUT": 10}, + "timeout": 10}) is None + assert stability.find_slow_status({ + "longest_duration": {"CRASH": 10}, + "timeout": 10}) is None + assert stability.find_slow_status({ + "longest_duration": {"PASS": 1}, + "timeout": 10}) is None + assert stability.find_slow_status({ + "longest_duration": {"PASS": 81}, + "timeout": 100}) == "PASS" + assert stability.find_slow_status({ + "longest_duration": {"TIMEOUT": 10, "FAIL": 81}, + "timeout": 100}) == "FAIL" + assert stability.find_slow_status({ + "longest_duration": {"SKIP": 0}}) is None diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/tests/test_update.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/tests/test_update.py index 5c654c99a48..f8790815cf0 100644 --- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/tests/test_update.py +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/tests/test_update.py @@ -32,7 +32,7 @@ item_classes = {"testharness": manifest_item.TestharnessTest, "reftest_node": manifest_item.RefTestNode, "manual": manifest_item.ManualTest, "stub": manifest_item.Stub, - "wdspec": manifest_item.WebdriverSpecTest, + "wdspec": manifest_item.WebDriverSpecTest, "conformancechecker": manifest_item.ConformanceCheckerTest, "visual": manifest_item.VisualTest, "support": manifest_item.SupportFile} diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/update/update.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/update/update.py index 5685f840670..e5678be4f54 100644 --- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/update/update.py +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/update/update.py @@ -96,11 +96,38 @@ class UpdateMetadata(Step): runner.run() +class RemoveObsolete(Step): + """Remove metadata files that don't corespond to an existing test file""" + + def create(self, state): + if not state.kwargs["remove_obsolete"]: + return + + paths = state.kwargs["test_paths"] + state.tests_path = state.paths["/"]["tests_path"] + state.metadata_path = state.paths["/"]["metadata_path"] + + for url_paths in paths.itervalues(): + tests_path = url_paths["tests_path"] + metadata_path = url_paths["metadata_path"] + for dirpath, dirnames, filenames in os.walk(metadata_path): + for filename in filenames: + if filename == "__dir__.ini": + continue + if filename.endswith(".ini"): + full_path = os.path.join(dirpath, filename) + rel_path = os.path.relpath(full_path, metadata_path) + test_path = os.path.join(tests_path, rel_path[:-4]) + if not os.path.exists(test_path): + os.unlink(full_path) + + class UpdateRunner(StepRunner): """Runner for doing an overall update.""" steps = [LoadConfig, LoadTrees, SyncFromUpstream, + RemoveObsolete, UpdateMetadata] diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptcommandline.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptcommandline.py index 7e18a8b4379..0075ad90962 100644 --- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptcommandline.py +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptcommandline.py @@ -192,6 +192,12 @@ scheme host and port.""") help="Path to directory containing extra json files to add to run info") config_group.add_argument("--product", action="store", choices=product_choices, default=None, help="Browser against which to run tests") + config_group.add_argument("--browser-version", action="store", + default=None, help="Informative string detailing the browser " + "release version. This is included in the run_info data.") + config_group.add_argument("--browser-channel", action="store", + default=None, help="Informative string detailing the browser " + "release channel. This is included in the run_info data.") config_group.add_argument("--config", action="store", type=abs_path, dest="config", help="Path to config file") config_group.add_argument("--install-fonts", action="store_true", @@ -287,6 +293,11 @@ scheme host and port.""") sauce_group.add_argument("--sauce-connect-binary", dest="sauce_connect_binary", help="Path to Sauce Connect binary") + sauce_group.add_argument("--sauce-init-timeout", action="store", + type=int, default=30, + help="Number of seconds to wait for Sauce " + "Connect tunnel to be available before " + "aborting") webkit_group = parser.add_argument_group("WebKit-specific") webkit_group.add_argument("--webkit-port", dest="webkit_port", @@ -554,8 +565,14 @@ def create_parser_update(product_choices=None): parser.add_argument("--stability", nargs="?", action="store", const="unstable", default=None, help=("Reason for disabling tests. When updating test results, disable tests that have " "inconsistent results across many runs with the given reason.")) - parser.add_argument("--continue", action="store_true", help="Continue a previously started run of the update script") - parser.add_argument("--abort", action="store_true", help="Clear state from a previous incomplete run of the update script") + parser.add_argument("--no-remove-obsolete", action="store_false", dest="remove_obsolete", default=True, + help=("Don't remove metadata files that no longer correspond to a test file")) + parser.add_argument("--no-store-state", action="store_false", dest="store_state", + help="Store state so that steps can be resumed after failure") + parser.add_argument("--continue", action="store_true", + help="Continue a previously started run of the update script") + parser.add_argument("--abort", action="store_true", + help="Clear state from a previous incomplete run of the update script") parser.add_argument("--exclude", action="store", nargs="*", help="List of glob-style paths to exclude when syncing tests") parser.add_argument("--include", action="store", nargs="*", diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptrunner.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptrunner.py index 02420826d8a..a6a29724ad7 100644 --- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptrunner.py +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptrunner.py @@ -47,6 +47,7 @@ def get_loader(test_paths, product, debug=None, run_info_extras=None, **kwargs): run_info = wpttest.get_run_info(kwargs["run_info"], product, browser_version=kwargs.get("browser_version"), + browser_channel=kwargs.get("browser_channel"), debug=debug, extras=run_info_extras) diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wpttest.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wpttest.py index c29ba974a99..4086a89e4cf 100644 --- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wpttest.py +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wpttest.py @@ -67,7 +67,10 @@ def get_run_info(metadata_root, product, **kwargs): class RunInfo(dict): - def __init__(self, metadata_root, product, debug, browser_version=None, extras=None): + def __init__(self, metadata_root, product, debug, + browser_version=None, + browser_channel=None, + extras=None): import mozinfo self._update_mozinfo(metadata_root) self.update(mozinfo.info) @@ -89,6 +92,8 @@ class RunInfo(dict): self["debug"] = False if browser_version: self["browser_version"] = browser_version + if browser_channel: + self["browser_channel"] = browser_channel if extras is not None: self.update(extras) diff --git a/tests/wpt/web-platform-tests/trusted-types/DOMParser-parseFromString.tentative.html b/tests/wpt/web-platform-tests/trusted-types/DOMParser-parseFromString.tentative.html index 2fe9b31b787..2dfc37686bc 100644 --- a/tests/wpt/web-platform-tests/trusted-types/DOMParser-parseFromString.tentative.html +++ b/tests/wpt/web-platform-tests/trusted-types/DOMParser-parseFromString.tentative.html @@ -4,14 +4,12 @@ diff --git a/tests/wpt/web-platform-tests/trusted-types/Element-insertAdjacentHTML.tentative.html b/tests/wpt/web-platform-tests/trusted-types/Element-insertAdjacentHTML.tentative.html index 599ade44ec1..d5db7936b1f 100644 --- a/tests/wpt/web-platform-tests/trusted-types/Element-insertAdjacentHTML.tentative.html +++ b/tests/wpt/web-platform-tests/trusted-types/Element-insertAdjacentHTML.tentative.html @@ -7,32 +7,30 @@ diff --git a/tests/wpt/web-platform-tests/trusted-types/Element-outerHTML.tentative.html b/tests/wpt/web-platform-tests/trusted-types/Element-outerHTML.tentative.html index a0bb6c1a5e3..c8daddfe995 100644 --- a/tests/wpt/web-platform-tests/trusted-types/Element-outerHTML.tentative.html +++ b/tests/wpt/web-platform-tests/trusted-types/Element-outerHTML.tentative.html @@ -5,20 +5,18 @@
                  diff --git a/tests/wpt/web-platform-tests/trusted-types/Element-setAttribute.tentative.html b/tests/wpt/web-platform-tests/trusted-types/Element-setAttribute.tentative.html new file mode 100644 index 00000000000..a284b2f8355 --- /dev/null +++ b/tests/wpt/web-platform-tests/trusted-types/Element-setAttribute.tentative.html @@ -0,0 +1,67 @@ + + + + + + + + diff --git a/tests/wpt/web-platform-tests/trusted-types/HTMLElement-generic.tentative.html b/tests/wpt/web-platform-tests/trusted-types/HTMLElement-generic.tentative.html index cea32a5a2df..2d381045118 100644 --- a/tests/wpt/web-platform-tests/trusted-types/HTMLElement-generic.tentative.html +++ b/tests/wpt/web-platform-tests/trusted-types/HTMLElement-generic.tentative.html @@ -6,6 +6,7 @@ diff --git a/tests/wpt/web-platform-tests/trusted-types/Location-assign.tentative.html b/tests/wpt/web-platform-tests/trusted-types/Location-assign.tentative.html index 13cca567948..62f98e96d7f 100644 --- a/tests/wpt/web-platform-tests/trusted-types/Location-assign.tentative.html +++ b/tests/wpt/web-platform-tests/trusted-types/Location-assign.tentative.html @@ -4,12 +4,10 @@ diff --git a/tests/wpt/web-platform-tests/trusted-types/Location-href.tentative.html b/tests/wpt/web-platform-tests/trusted-types/Location-href.tentative.html index d759d28593e..bacadf6a91b 100644 --- a/tests/wpt/web-platform-tests/trusted-types/Location-href.tentative.html +++ b/tests/wpt/web-platform-tests/trusted-types/Location-href.tentative.html @@ -4,12 +4,10 @@ diff --git a/tests/wpt/web-platform-tests/trusted-types/Location-replace.tentative.html b/tests/wpt/web-platform-tests/trusted-types/Location-replace.tentative.html index 7d84905d198..4fb53d02609 100644 --- a/tests/wpt/web-platform-tests/trusted-types/Location-replace.tentative.html +++ b/tests/wpt/web-platform-tests/trusted-types/Location-replace.tentative.html @@ -4,12 +4,10 @@ diff --git a/tests/wpt/web-platform-tests/trusted-types/Range-createContextualFragment.tentative.html b/tests/wpt/web-platform-tests/trusted-types/Range-createContextualFragment.tentative.html index 3d45b33486d..3a880a53778 100644 --- a/tests/wpt/web-platform-tests/trusted-types/Range-createContextualFragment.tentative.html +++ b/tests/wpt/web-platform-tests/trusted-types/Range-createContextualFragment.tentative.html @@ -4,14 +4,12 @@ diff --git a/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy-createXYZTests.tentative.html b/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy-createXYZTests.tentative.html new file mode 100644 index 00000000000..b20fcf2436e --- /dev/null +++ b/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy-createXYZTests.tentative.html @@ -0,0 +1,294 @@ + + + + + + diff --git a/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy-cspTests-noNamesGiven.tentative.html b/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy-cspTests-noNamesGiven.tentative.html new file mode 100644 index 00000000000..49a9506b5a7 --- /dev/null +++ b/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy-cspTests-noNamesGiven.tentative.html @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy-cspTests.tentative.html b/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy-cspTests.tentative.html new file mode 100644 index 00000000000..9daf20ec186 --- /dev/null +++ b/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy-cspTests.tentative.html @@ -0,0 +1,24 @@ + + + + + + + diff --git a/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy-exposedTests.tentative.html b/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy-exposedTests.tentative.html new file mode 100644 index 00000000000..af6e04941c3 --- /dev/null +++ b/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy-exposedTests.tentative.html @@ -0,0 +1,24 @@ + + + + + + diff --git a/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy-nameTests.tentative.html b/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy-nameTests.tentative.html new file mode 100644 index 00000000000..6d43e0bafc6 --- /dev/null +++ b/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy-nameTests.tentative.html @@ -0,0 +1,28 @@ + + + + + + diff --git a/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy.tentative.html b/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy.tentative.html deleted file mode 100644 index 76e6d130b05..00000000000 --- a/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy.tentative.html +++ /dev/null @@ -1,299 +0,0 @@ - - - - - - diff --git a/tests/wpt/web-platform-tests/trusted-types/Window-trustedTypes.tentative.html b/tests/wpt/web-platform-tests/trusted-types/Window-TrustedTypes.tentative.html similarity index 77% rename from tests/wpt/web-platform-tests/trusted-types/Window-trustedTypes.tentative.html rename to tests/wpt/web-platform-tests/trusted-types/Window-TrustedTypes.tentative.html index ef4487749dd..8e20e492e6a 100644 --- a/tests/wpt/web-platform-tests/trusted-types/Window-trustedTypes.tentative.html +++ b/tests/wpt/web-platform-tests/trusted-types/Window-TrustedTypes.tentative.html @@ -5,7 +5,7 @@ diff --git a/tests/wpt/web-platform-tests/trusted-types/Window-open.tentative.html b/tests/wpt/web-platform-tests/trusted-types/Window-open.tentative.html index c005fbba143..172d566e57f 100644 --- a/tests/wpt/web-platform-tests/trusted-types/Window-open.tentative.html +++ b/tests/wpt/web-platform-tests/trusted-types/Window-open.tentative.html @@ -5,23 +5,21 @@ diff --git a/tests/wpt/web-platform-tests/trusted-types/block-string-assignment-to-DOMParser-parseFromString.tentative.html b/tests/wpt/web-platform-tests/trusted-types/block-string-assignment-to-DOMParser-parseFromString.tentative.html index cc575dc0085..366bdd2ab6d 100644 --- a/tests/wpt/web-platform-tests/trusted-types/block-string-assignment-to-DOMParser-parseFromString.tentative.html +++ b/tests/wpt/web-platform-tests/trusted-types/block-string-assignment-to-DOMParser-parseFromString.tentative.html @@ -3,18 +3,16 @@ - + - + - +
                  @@ -13,33 +13,31 @@ var container = document.querySelector('#container'); // Trusted HTML assignments do not throw. - async_test(t => { - createHTML_policy(window) - .then(t.step_func_done(p => { - let html = p.createHTML(INPUTS.HTML); + test(t => { + let p = createHTML_policy(window, 1); + let html = p.createHTML(INPUTS.HTML); - var d = document.createElement('div'); - container.appendChild(d); + var d = document.createElement('div'); + container.appendChild(d); - d.insertAdjacentHTML('beforebegin', html); - assert_equals(d.previousSibling.nodeType, Node.TEXT_NODE); - assert_equals(d.previousSibling.data, RESULTS.HTML); + d.insertAdjacentHTML('beforebegin', html); + assert_equals(d.previousSibling.nodeType, Node.TEXT_NODE); + assert_equals(d.previousSibling.data, RESULTS.HTML); - d.insertAdjacentHTML('afterbegin', html); - assert_equals(d.firstChild.nodeType, Node.TEXT_NODE); - assert_equals(d.firstChild.data, RESULTS.HTML); + d.insertAdjacentHTML('afterbegin', html); + assert_equals(d.firstChild.nodeType, Node.TEXT_NODE); + assert_equals(d.firstChild.data, RESULTS.HTML); - d.insertAdjacentHTML('beforeend', html); - assert_equals(d.lastChild.nodeType, Node.TEXT_NODE); - assert_equals(d.lastChild.data, RESULTS.HTML); + d.insertAdjacentHTML('beforeend', html); + assert_equals(d.lastChild.nodeType, Node.TEXT_NODE); + assert_equals(d.lastChild.data, RESULTS.HTML); - d.insertAdjacentHTML('afterend', html); - assert_equals(d.nextSibling.nodeType, Node.TEXT_NODE); - assert_equals(d.nextSibling.data, RESULTS.HTML); + d.insertAdjacentHTML('afterend', html); + assert_equals(d.nextSibling.nodeType, Node.TEXT_NODE); + assert_equals(d.nextSibling.data, RESULTS.HTML); - while (container.firstChild) - container.firstChild.remove(); - })); + while (container.firstChild) + container.firstChild.remove(); }, "insertAdjacentHTML with html assigned via policy (successful HTML transformation)."); // String assignments throw. diff --git a/tests/wpt/web-platform-tests/trusted-types/block-string-assignment-to-Element-outerHTML.tentative.html b/tests/wpt/web-platform-tests/trusted-types/block-string-assignment-to-Element-outerHTML.tentative.html index 47f1165b1a6..c9bde5eb6d5 100644 --- a/tests/wpt/web-platform-tests/trusted-types/block-string-assignment-to-Element-outerHTML.tentative.html +++ b/tests/wpt/web-platform-tests/trusted-types/block-string-assignment-to-Element-outerHTML.tentative.html @@ -5,7 +5,7 @@ - +
                  @@ -13,19 +13,17 @@ var container = document.querySelector('#container') // TrustedHTML assignments do not throw. - async_test(t => { - createHTML_policy(window) - .then(t.step_func_done(p => { - let html = p.createHTML(INPUTS.HTML); + test(t => { + let p = createHTML_policy(window, 1); + let html = p.createHTML(INPUTS.HTML); - var d = document.createElement('div'); - document.querySelector('#container').appendChild(d); - d.outerHTML = html; - assert_equals(container.innerText, RESULTS.HTML); + var d = document.createElement('div'); + document.querySelector('#container').appendChild(d); + d.outerHTML = html; + assert_equals(container.innerText, RESULTS.HTML); - while (container.firstChild) - container.firstChild.remove(); - })); + while (container.firstChild) + container.firstChild.remove(); }, "outerHTML with html assigned via policy (successful HTML transformation)."); // String assignments throw. diff --git a/tests/wpt/web-platform-tests/trusted-types/block-string-assignment-to-Element-setAttribute.tentative.html b/tests/wpt/web-platform-tests/trusted-types/block-string-assignment-to-Element-setAttribute.tentative.html new file mode 100644 index 00000000000..52e31708331 --- /dev/null +++ b/tests/wpt/web-platform-tests/trusted-types/block-string-assignment-to-Element-setAttribute.tentative.html @@ -0,0 +1,76 @@ + + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/trusted-types/block-string-assignment-to-HTMLElement-generic.tentative.html b/tests/wpt/web-platform-tests/trusted-types/block-string-assignment-to-HTMLElement-generic.tentative.html index eae52626190..f31fce629bc 100644 --- a/tests/wpt/web-platform-tests/trusted-types/block-string-assignment-to-HTMLElement-generic.tentative.html +++ b/tests/wpt/web-platform-tests/trusted-types/block-string-assignment-to-HTMLElement-generic.tentative.html @@ -5,10 +5,11 @@ - + - + - + - + - + - + diff --git a/tests/wpt/web-platform-tests/trusted-types/idlharness.window.js b/tests/wpt/web-platform-tests/trusted-types/idlharness.window.js new file mode 100644 index 00000000000..de13697764e --- /dev/null +++ b/tests/wpt/web-platform-tests/trusted-types/idlharness.window.js @@ -0,0 +1,18 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +idl_test( + ['trusted-types.tentative'], + ['dom', 'html'], + idl_array => { + idl_array.add_objects({ + TrustedTypePolicyFactory: ['window.TrustedTypes'], + TrustedTypePolicy: ['window.TrustedTypes.createPolicy("SomeName", { createHTML: s => s })'], + TrustedHTML: ['window.TrustedTypes.createPolicy("SomeName1", { createHTML: s => s }).createHTML("A string")'], + TrustedScript: ['window.TrustedTypes.createPolicy("SomeName2", { createScript: s => s }).createScript("A string")'], + TrustedScriptURL: ['window.TrustedTypes.createPolicy("SomeName3", { createScriptURL: s => s }).createScriptURL("A string")'], + TrustedURL: ['window.TrustedTypes.createPolicy("SomeName4", { createURL: s => s }).createURL("A string")'] + }); + }, + 'Trusted Types' +); diff --git a/tests/wpt/web-platform-tests/trusted-types/support/helper.sub.js b/tests/wpt/web-platform-tests/trusted-types/support/helper.sub.js index b5435917bec..1ad5b4ef0c6 100644 --- a/tests/wpt/web-platform-tests/trusted-types/support/helper.sub.js +++ b/tests/wpt/web-platform-tests/trusted-types/support/helper.sub.js @@ -31,52 +31,44 @@ function createURLJS(url) { .replace("an.url", "successfully.transformed"); } -function createHTML_policy(win) { - return win.trustedTypes.createPolicy('SomeName', { createHTML: createHTMLJS }); +function createHTML_policy(win, c) { + return win.TrustedTypes.createPolicy('SomeHTMLPolicyName' + c, { createHTML: createHTMLJS }); } -function createScript_policy(win) { - return win.trustedTypes.createPolicy('SomeName', { createScript: createScriptJS }); +function createScript_policy(win, c) { + return win.TrustedTypes.createPolicy('SomeScriptPolicyName' + c, { createScript: createScriptJS }); } -function createScriptURL_policy(win) { - return win.trustedTypes.createPolicy('SomeName', { createScriptURL: createScriptURLJS }); +function createScriptURL_policy(win, c) { + return win.TrustedTypes.createPolicy('SomeScriptURLPolicyName' + c, { createScriptURL: createScriptURLJS }); } -function createURL_policy(win) { - return win.trustedTypes.createPolicy('SomeName', { createURL: createURLJS }); +function createURL_policy(win, c) { + return win.TrustedTypes.createPolicy('SomeURLPolicyName' + c, { createURL: createURLJS }); } -function assert_element_accepts_trusted_html(win, t, tag, attribute, expected) { - createHTML_policy(win) - .then(t.step_func_done(p => { - let html = p.createHTML(INPUTS.HTML); - assert_element_accepts_trusted_type(tag, attribute, html, expected); - })); +function assert_element_accepts_trusted_html(win, c, t, tag, attribute, expected) { + let p = createHTML_policy(win, c); + let html = p.createHTML(INPUTS.HTML); + assert_element_accepts_trusted_type(tag, attribute, html, expected); } -function assert_element_accepts_trusted_script(win, t, tag, attribute, expected) { - createScript_policy(win) - .then(t.step_func_done(p => { - let script = p.createScript(INPUTS.SCRIPT); - assert_element_accepts_trusted_type(tag, attribute, script, expected); - })); +function assert_element_accepts_trusted_script(win, c, t, tag, attribute, expected) { + let p = createScript_policy(win, c); + let script = p.createScript(INPUTS.SCRIPT); + assert_element_accepts_trusted_type(tag, attribute, script, expected); } -function assert_element_accepts_trusted_script_url(win, t, tag, attribute, expected) { - createScriptURL_policy(win) - .then(t.step_func_done(p => { - let scripturl = p.createScriptURL(INPUTS.SCRIPTURL); - assert_element_accepts_trusted_type(tag, attribute, scripturl, expected); - })); +function assert_element_accepts_trusted_script_url(win, c, t, tag, attribute, expected) { + let p = createScriptURL_policy(win, c); + let scripturl = p.createScriptURL(INPUTS.SCRIPTURL); + assert_element_accepts_trusted_type(tag, attribute, scripturl, expected); } -function assert_element_accepts_trusted_url(win, t, tag, attribute, expected) { - createURL_policy(win) - .then(t.step_func_done(p => { - let url = p.createURL(INPUTS.URL); - assert_element_accepts_trusted_type(tag, attribute, url, expected); - })); +function assert_element_accepts_trusted_url(win, c, t, tag, attribute, expected) { + let p = createURL_policy(win, c); + let url = p.createURL(INPUTS.URL); + assert_element_accepts_trusted_type(tag, attribute, url, expected); } function assert_element_accepts_trusted_type(tag, attribute, value, expected) { @@ -91,3 +83,46 @@ function assert_throws_no_trusted_type(tag, attribute, value) { elem[attribute] = value; }); } + +function assert_element_accepts_trusted_html_explicit_set(win, c, t, tag, attribute, expected) { + let p = createHTML_policy(win, c); + let html = p.createHTML(INPUTS.HTML); + assert_element_accepts_trusted_type_explicit_set(tag, attribute, html, expected); +} + +function assert_element_accepts_trusted_script_explicit_set(win, c, t, tag, attribute, expected) { + let p = createScript_policy(win, c); + let script = p.createScript(INPUTS.SCRIPT); + assert_element_accepts_trusted_type_explicit_set(tag, attribute, script, expected); +} + +function assert_element_accepts_trusted_script_url_explicit_set(win, c, t, tag, attribute, expected) { + let p = createScriptURL_policy(win, c); + let scripturl = p.createScriptURL(INPUTS.SCRIPTURL); + assert_element_accepts_trusted_type_explicit_set(tag, attribute, scripturl, expected); +} + +function assert_element_accepts_trusted_url_explicit_set(win, c, t, tag, attribute, expected) { + let p = createURL_policy(win, c); + let url = p.createURL(INPUTS.URL); + assert_element_accepts_trusted_type_explicit_set(tag, attribute, url, expected); +} + +function assert_element_accepts_trusted_type_explicit_set(tag, attribute, value, expected) { + let elem = document.createElement(tag); + elem.setAttribute(attribute, value); + assert_equals(elem[attribute] + "", expected); +} + +function assert_throws_no_trusted_type_explicit_set(tag, attribute, value) { + let elem = document.createElement(tag); + assert_throws(new TypeError(), _ => { + elem.setAttribute(attribute, value); + }); +} + +function assert_element_accepts_non_trusted_type_explicit_set(tag, attribute, value, expected) { + let elem = document.createElement(tag); + elem.setAttribute(attribute, value); + assert_equals(elem[attribute] + "", expected); +} diff --git a/tests/wpt/web-platform-tests/wai-aria/idlharness.window.js b/tests/wpt/web-platform-tests/wai-aria/idlharness.window.js new file mode 100644 index 00000000000..590bf9e2e9f --- /dev/null +++ b/tests/wpt/web-platform-tests/wai-aria/idlharness.window.js @@ -0,0 +1,15 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +'use strict'; + +idl_test( + ['wai-aria'], + ['dom'], + idl_array => { + idl_array.add_objects({ + Element: ['element'], + }); + self.element = document.createElementNS(null, "test"); + } +); diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/assertions.js b/tests/wpt/web-platform-tests/wasm/jsapi/assertions.js index 151a406655c..bda3ae7bc3c 100644 --- a/tests/wpt/web-platform-tests/wasm/jsapi/assertions.js +++ b/tests/wpt/web-platform-tests/wasm/jsapi/assertions.js @@ -15,3 +15,59 @@ function assert_function_length(fn, length, description) { assert_true(propdesc.configurable, "configurable", `${description} length should be configurable`); assert_equals(propdesc.value, length, `${description} length should be ${length}`); } + +function assert_exported_function(fn, { name, length }, description) { + assert_equals(Object.getPrototypeOf(fn), Function.prototype, + `${description}: prototype`); + + assert_function_name(fn, name, description); + assert_function_length(fn, length, description); +} + +function assert_Instance(instance, expected_exports) { + assert_equals(Object.getPrototypeOf(instance), WebAssembly.Instance.prototype, + "prototype"); + assert_true(Object.isExtensible(instance), "extensible"); + + assert_equals(instance.exports, instance.exports, "exports should be idempotent"); + const exports = instance.exports; + + assert_equals(Object.getPrototypeOf(exports), null, "exports prototype"); + assert_false(Object.isExtensible(exports), "extensible exports"); + for (const [key, expected] of Object.entries(expected_exports)) { + const property = Object.getOwnPropertyDescriptor(exports, key); + assert_equals(typeof property, "object", `${key} should be present`); + assert_false(property.writable, `${key}: writable`); + assert_true(property.enumerable, `${key}: enumerable`); + assert_false(property.configurable, `${key}: configurable`); + const actual = property.value; + assert_true(Object.isExtensible(actual), `${key}: extensible`); + + switch (expected.kind) { + case "function": + assert_exported_function(actual, expected, `value of ${key}`); + break; + case "global": + assert_equals(Object.getPrototypeOf(actual), WebAssembly.Global.prototype, + `value of ${key}: prototype`); + assert_equals(actual.value, expected.value, `value of ${key}: value`); + assert_equals(actual.valueOf(), expected.value, `value of ${key}: valueOf()`); + break; + case "memory": + assert_equals(Object.getPrototypeOf(actual), WebAssembly.Memory.prototype, + `value of ${key}: prototype`); + assert_equals(Object.getPrototypeOf(actual.buffer), ArrayBuffer.prototype, + `value of ${key}: prototype of buffer`); + assert_equals(actual.buffer.byteLength, 0x10000 * expected.size, `value of ${key}: size of buffer`); + const array = new Uint8Array(actual.buffer); + assert_equals(array[0], 0, `value of ${key}: first element of buffer`); + assert_equals(array[array.byteLength - 1], 0, `value of ${key}: last element of buffer`); + break; + case "table": + assert_equals(Object.getPrototypeOf(actual), WebAssembly.Table.prototype, + `value of ${key}: prototype`); + assert_equals(actual.length, expected.length, `value of ${key}: length of table`); + break; + } + } +} diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/constructor/compile.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/constructor/compile.any.js new file mode 100644 index 00000000000..0139a18fda3 --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/jsapi/constructor/compile.any.js @@ -0,0 +1,77 @@ +// META: global=jsshell +// META: script=/wasm/jsapi/wasm-constants.js +// META: script=/wasm/jsapi/wasm-module-builder.js + +function assert_Module(module) { + assert_equals(Object.getPrototypeOf(module), WebAssembly.Module.prototype, + "Prototype"); + assert_true(Object.isExtensible(module), "Extensibility"); +} + +let emptyModuleBinary; +setup(() => { + emptyModuleBinary = new WasmModuleBuilder().toBuffer(); +}); + +promise_test(t => { + return promise_rejects(t, new TypeError(), WebAssembly.compile()); +}, "Missing argument"); + +promise_test(t => { + const invalidArguments = [ + undefined, + null, + true, + "", + Symbol(), + 1, + {}, + ArrayBuffer, + ArrayBuffer.prototype, + Array.from(emptyModuleBinary), + ]; + return Promise.all(invalidArguments.map(argument => { + return promise_rejects(t, new TypeError(), WebAssembly.compile(argument), + `compile(${format_value(argument)})`); + })); +}, "Invalid arguments"); + +promise_test(() => { + const fn = WebAssembly.compile; + const thisValues = [ + undefined, + null, + true, + "", + Symbol(), + 1, + {}, + WebAssembly, + ]; + return Promise.all(thisValues.map(thisValue => { + return fn.call(thisValue, emptyModuleBinary).then(assert_Module); + })); +}, "Branding"); + +test(() => { + const promise = WebAssembly.compile(emptyModuleBinary); + assert_equals(Object.getPrototypeOf(promise), Promise.prototype, "prototype"); + assert_true(Object.isExtensible(promise), "extensibility"); +}, "Promise type"); + +promise_test(t => { + const buffer = new Uint8Array(); + return promise_rejects(t, new WebAssembly.CompileError(), WebAssembly.compile(buffer)); +}, "Invalid code"); + +promise_test(() => { + return WebAssembly.compile(emptyModuleBinary).then(assert_Module); +}, "Result type"); + +promise_test(() => { + const buffer = new WasmModuleBuilder().toBuffer(); + assert_equals(buffer[0], 0); + const promise = WebAssembly.compile(buffer); + buffer[0] = 1; + return promise.then(assert_Module); +}, "Changing the buffer"); diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/constructor/instantiate.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/constructor/instantiate.any.js new file mode 100644 index 00000000000..e90f21e28eb --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/jsapi/constructor/instantiate.any.js @@ -0,0 +1,196 @@ +// META: global=jsshell +// META: script=/wasm/jsapi/wasm-constants.js +// META: script=/wasm/jsapi/wasm-module-builder.js +// META: script=/wasm/jsapi/assertions.js + +function assert_WebAssemblyInstantiatedSource(actual, expected_exports={}) { + assert_equals(Object.getPrototypeOf(actual), Object.prototype, + "Prototype"); + assert_true(Object.isExtensible(actual), "Extensibility"); + + const module = Object.getOwnPropertyDescriptor(actual, "module"); + assert_equals(typeof module, "object", "module: type of descriptor"); + assert_true(module.writable, "module: writable"); + assert_true(module.enumerable, "module: enumerable"); + assert_true(module.configurable, "module: configurable"); + assert_equals(Object.getPrototypeOf(module.value), WebAssembly.Module.prototype, + "module: prototype"); + + const instance = Object.getOwnPropertyDescriptor(actual, "instance"); + assert_equals(typeof instance, "object", "instance: type of descriptor"); + assert_true(instance.writable, "instance: writable"); + assert_true(instance.enumerable, "instance: enumerable"); + assert_true(instance.configurable, "instance: configurable"); + assert_Instance(instance.value, expected_exports); +} + +let emptyModuleBinary; +setup(() => { + emptyModuleBinary = new WasmModuleBuilder().toBuffer(); +}); + +promise_test(t => { + return promise_rejects(t, new TypeError(), WebAssembly.instantiate()); +}, "Missing arguments"); + +promise_test(() => { + const fn = WebAssembly.instantiate; + const thisValues = [ + undefined, + null, + true, + "", + Symbol(), + 1, + {}, + WebAssembly, + ]; + return Promise.all(thisValues.map(thisValue => { + return fn.call(thisValue, emptyModuleBinary).then(assert_WebAssemblyInstantiatedSource); + })); +}, "Branding"); + +promise_test(t => { + const invalidArguments = [ + undefined, + null, + true, + "", + Symbol(), + 1, + {}, + WebAssembly.Module, + WebAssembly.Module.prototype, + ArrayBuffer, + ArrayBuffer.prototype, + Array.from(emptyModuleBinary), + ]; + return Promise.all(invalidArguments.map(argument => { + return promise_rejects(t, new TypeError(), WebAssembly.instantiate(argument), + `instantiate(${format_value(argument)})`); + })); +}, "Invalid arguments"); + +test(() => { + const promise = WebAssembly.instantiate(emptyModuleBinary); + assert_equals(Object.getPrototypeOf(promise), Promise.prototype, "prototype"); + assert_true(Object.isExtensible(promise), "extensibility"); +}, "Promise type"); + +const createModule = () => { + const builder = new WasmModuleBuilder(); + + builder + .addFunction("fn", kSig_v_d) + .addBody([ + kExprEnd + ]) + .exportFunc(); + builder + .addFunction("fn2", kSig_v_v) + .addBody([ + kExprEnd + ]) + .exportFunc(); + + builder.setFunctionTableLength(1); + builder.addExportOfKind("table", kExternalTable, 0); + + builder.addGlobal(kWasmI32, true) + .exportAs("global") + .init = 7; + builder.addGlobal(kWasmF64, true) + .exportAs("global2") + .init = 1.2; + + builder.addMemory(4, 8, true); + + const buffer = builder.toBuffer(); + + const exports = { + "fn": { "kind": "function", "name": "0", "length": 1 }, + "fn2": { "kind": "function", "name": "1", "length": 0 }, + "table": { "kind": "table", "length": 1 }, + "global": { "kind": "global", "value": 7 }, + "global2": { "kind": "global", "value": 1.2 }, + "memory": { "kind": "memory", "size": 4 }, + }; + + return [buffer, exports]; +} + +promise_test(() => { + const [buffer, expected] = createModule(); + return WebAssembly.instantiate(buffer).then(result => assert_WebAssemblyInstantiatedSource(result, expected)); +}, "BufferSource argument"); + +promise_test(() => { + const [buffer, expected] = createModule(); + const module = new WebAssembly.Module(buffer); + return WebAssembly.instantiate(module).then(instance => assert_Instance(instance, expected)); +}, "Module argument"); + +const createModuleWithImports = () => { + const builder = new WasmModuleBuilder(); + + const index = builder.addImportedGlobal("module", "global", kWasmI32); + builder + .addFunction("fn", kSig_i_v) + .addBody([ + kExprGetGlobal, + index, + kExprReturn, + kExprEnd, + ]) + .exportFunc(); + + const buffer = builder.toBuffer(); + + const expected = { + "fn": { "kind": "function", "name": "0", "length": 0 }, + }; + + return [buffer, expected]; +}; + +promise_test(() => { + const [buffer, expected] = createModuleWithImports(); + + const value = 102; + return WebAssembly.instantiate(buffer, { + "module": { + "global": value, + }, + }).then(result => { + assert_WebAssemblyInstantiatedSource(result, expected) + assert_equals(result.instance.exports.fn(), value); + }); +}, "exports and imports: buffer argument"); + +promise_test(() => { + const [buffer, expected] = createModuleWithImports(); + const module = new WebAssembly.Module(buffer); + + const value = 102; + return WebAssembly.instantiate(module, { + "module": { + "global": value, + }, + }).then(instance => { + assert_Instance(instance, expected) + assert_equals(instance.exports.fn(), value); + }); +}, "exports and imports: Module argument"); + +promise_test(t => { + const buffer = new Uint8Array(); + return promise_rejects(t, new WebAssembly.CompileError(), WebAssembly.instantiate(buffer)); +}, "Invalid code"); + +promise_test(() => { + const buffer = new WasmModuleBuilder().toBuffer(); + assert_equals(buffer[0], 0); + const promise = WebAssembly.instantiate(buffer); + buffer[0] = 1; + return promise.then(assert_WebAssemblyInstantiatedSource); +}, "Changing the buffer"); diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/constructor/validate.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/constructor/validate.any.js new file mode 100644 index 00000000000..70bd9f7022a --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/jsapi/constructor/validate.any.js @@ -0,0 +1,96 @@ +// META: global=jsshell +// META: script=/wasm/jsapi/wasm-constants.js +// META: script=/wasm/jsapi/wasm-module-builder.js + +let emptyModuleBinary; +setup(() => { + emptyModuleBinary = new WasmModuleBuilder().toBuffer(); +}); + +test(() => { + assert_throws(new TypeError(), () => WebAssembly.validate()); +}, "Missing argument"); + +test(() => { + const invalidArguments = [ + undefined, + null, + true, + "", + Symbol(), + 1, + {}, + ArrayBuffer, + ArrayBuffer.prototype, + Array.from(emptyModuleBinary), + ]; + for (const argument of invalidArguments) { + assert_throws(new TypeError(), () => WebAssembly.validate(argument), + `validate(${format_value(argument)})`); + } +}, "Invalid arguments"); + +test(() => { + const fn = WebAssembly.validate; + const thisValues = [ + undefined, + null, + true, + "", + Symbol(), + 1, + {}, + WebAssembly, + ]; + for (const thisValue of thisValues) { + assert_true(fn.call(thisValue, emptyModuleBinary), `this=${format_value(thisValue)}`); + } +}, "Branding"); + +const modules = [ + // Incomplete header. + [[], false], + [[0x00], false], + [[0x00, 0x61], false], + [[0x00, 0x61, 0x73], false], + [[0x00, 0x61, 0x73, 0x6d], false], + [[0x00, 0x61, 0x73, 0x6d, 0x01], false], + [[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00], false], + [[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00], false], + + // Complete header. + [[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00], true], + + // Invalid version. + [[0x00, 0x61, 0x73, 0x6d, 0x00, 0x00, 0x00, 0x00], false], + [[0x00, 0x61, 0x73, 0x6d, 0x02, 0x00, 0x00, 0x00], false], + + // Nameless custom section. + [[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00], false], + + // Custom section with empty name. + [[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00], true], + + // Custom section with name "a". + [[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x61], true], +]; +const bufferTypes = [ + Uint8Array, + Int8Array, + Uint16Array, + Int16Array, + Uint32Array, + Int32Array, +]; +for (const [module, expected] of modules) { + const name = module.map(n => n.toString(16)).join(" "); + for (const bufferType of bufferTypes) { + if (module.length % bufferType.BYTES_PER_ELEMENT === 0) { + test(() => { + const bytes = new Uint8Array(module); + const moduleBuffer = new bufferType(bytes.buffer); + assert_equals(WebAssembly.validate(moduleBuffer), expected); + }, `Validating module [${name}] in ${bufferType.name}`); + } + } +} diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/global/constructor.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/global/constructor.any.js new file mode 100644 index 00000000000..7a45cc4191c --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/jsapi/global/constructor.any.js @@ -0,0 +1,121 @@ +// META: global=jsshell +// META: script=/wasm/jsapi/assertions.js + +function assert_Global(actual, expected) { + assert_equals(Object.getPrototypeOf(actual), WebAssembly.Global.prototype, + "prototype"); + assert_true(Object.isExtensible(actual), "extensible"); + + assert_equals(actual.value, expected, "value"); + assert_equals(actual.valueOf(), expected, "valueOf"); +} + +test(() => { + assert_function_name(WebAssembly.Global, "Global", "WebAssembly.Global"); +}, "name"); + +test(() => { + assert_function_length(WebAssembly.Global, 1, "WebAssembly.Global"); +}, "length"); + +test(() => { + assert_throws(new TypeError(), () => new WebAssembly.Global()); +}, "No arguments"); + +test(() => { + const argument = { "value": "i32" }; + assert_throws(new TypeError(), () => WebAssembly.Global(argument)); +}, "Calling"); + +test(() => { + const order = []; + + new WebAssembly.Global({ + get value() { + order.push("descriptor value"); + return { + toString() { + order.push("descriptor value toString"); + return "f64"; + }, + }; + }, + + get mutable() { + order.push("descriptor mutable"); + return false; + }, + }, { + valueOf() { + order.push("value valueOf()"); + } + }); + + assert_array_equals(order, [ + "descriptor mutable", + "descriptor value", + "descriptor value toString", + "value valueOf()", + ]); +}, "Order of evaluation"); + +test(() => { + const invalidArguments = [ + undefined, + null, + false, + true, + "", + "test", + Symbol(), + 1, + NaN, + {}, + ]; + for (const invalidArgument of invalidArguments) { + assert_throws(new TypeError(), + () => new WebAssembly.Global(invalidArgument), + `new Global(${format_value(invalidArgument)})`); + } +}, "Invalid descriptor argument"); + +test(() => { + const invalidTypes = ["i16", "i128", "f16", "f128", "u32", "u64", "i32\0"]; + for (const value of invalidTypes) { + const argument = { value }; + assert_throws(new TypeError(), () => new WebAssembly.Global(argument)); + } +}, "Invalid type argument"); + +test(() => { + const argument = { "value": "i64" }; + const global = new WebAssembly.Global(argument); + assert_throws(new TypeError(), () => global.value); + assert_throws(new TypeError(), () => global.valueOf()); +}, "i64 with default"); + +for (const type of ["i32", "f32", "f64"]) { + test(() => { + const argument = { "value": type }; + const global = new WebAssembly.Global(argument); + assert_Global(global, 0); + }, `Default value for type ${type}`); + + const valueArguments = [ + [undefined, 0], + [null, 0], + [true, 1], + [false, 0], + [2, 2], + ["3", 3], + [{ toString() { return "5" } }, 5, "object with toString"], + [{ valueOf() { return "8" } }, 8, "object with valueOf"], + ]; + for (const [value, expected, name = format_value(value)] of valueArguments) { + test(() => { + const argument = { "value": type }; + const global = new WebAssembly.Global(argument, value); + assert_Global(global, expected); + }, `Explicit value ${name} for type ${type}`); + } +} diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/global/toString.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/global/toString.any.js new file mode 100644 index 00000000000..ca025576c2b --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/jsapi/global/toString.any.js @@ -0,0 +1,7 @@ +// META: global=jsshell + +test(() => { + const argument = { "value": "i32" }; + const global = new WebAssembly.Global(argument); + assert_class_string(global, "WebAssembly.Global"); +}, "Object.prototype.toString on an Global"); diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/global/value-set.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/global/value-set.any.js new file mode 100644 index 00000000000..b4e6770f10e --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/jsapi/global/value-set.any.js @@ -0,0 +1,94 @@ +// META: global=jsshell + +test(() => { + const thisValues = [ + undefined, + null, + true, + "", + Symbol(), + 1, + {}, + WebAssembly.Global, + WebAssembly.Global.prototype, + ]; + + const desc = Object.getOwnPropertyDescriptor(WebAssembly.Global.prototype, "value"); + assert_equals(typeof desc, "object"); + + const getter = desc.get; + assert_equals(typeof getter, "function"); + + const setter = desc.set; + assert_equals(typeof setter, "function"); + + for (const thisValue of thisValues) { + assert_throws(new TypeError(), () => getter.call(thisValue), `getter with this=${format_value(thisValue)}`); + assert_throws(new TypeError(), () => setter.call(thisValue, 1), `setter with this=${format_value(thisValue)}`); + } +}, "Branding"); + +for (const type of ["i32", "f32", "f64"]) { + const immutableOptions = [ + [{}, "missing"], + [{ "mutable": undefined }, "undefined"], + [{ "mutable": null }, "null"], + [{ "mutable": false }, "false"], + [{ "mutable": "" }, "empty string"], + [{ "mutable": 0 }, "zero"], + ]; + for (const [opts, name] of immutableOptions) { + test(() => { + opts.value = type; + const global = new WebAssembly.Global(opts); + assert_equals(global.value, 0, "initial value"); + assert_equals(global.valueOf(), 0, "initial valueOf"); + + assert_throws(new TypeError(), () => global.value = 1); + + assert_equals(global.value, 0, "post-set value"); + assert_equals(global.valueOf(), 0, "post-set valueOf"); + }, `Immutable ${type} (${name})`); + } + + const mutableOptions = [ + [{ "mutable": true }, "true"], + [{ "mutable": 1 }, "one"], + [{ "mutable": "x" }, "string"], + [Object.create({ "mutable": true }), "true on prototype"], + ]; + for (const [opts, name] of mutableOptions) { + test(() => { + opts.value = type; + const global = new WebAssembly.Global(opts); + assert_equals(global.value, 0, "initial value"); + assert_equals(global.valueOf(), 0, "initial valueOf"); + + global.value = 1; + + assert_equals(global.value, 1, "post-set value"); + assert_equals(global.valueOf(), 1, "post-set valueOf"); + }, `Mutable ${type} (${name})`); + } +} + +test(() => { + const argument = { "value": "i64", "mutable": true }; + const global = new WebAssembly.Global(argument); + assert_throws(new TypeError(), () => global.value); + assert_throws(new TypeError(), () => global.value = 0); + assert_throws(new TypeError(), () => global.valueOf()); +}, "i64 with default"); + + +test(() => { + const argument = { "value": "i32", "mutable": true }; + const global = new WebAssembly.Global(argument); + const desc = Object.getOwnPropertyDescriptor(WebAssembly.Global.prototype, "value"); + assert_equals(typeof desc, "object"); + + const setter = desc.set; + assert_equals(typeof setter, "function"); + + assert_throws(new TypeError(), () => setter.call(global)); +}, "Calling setter without argument"); diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/global/valueOf.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/global/valueOf.any.js new file mode 100644 index 00000000000..176c5a78469 --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/jsapi/global/valueOf.any.js @@ -0,0 +1,22 @@ +// META: global=jsshell + +test(() => { + const argument = { "value": "i32" }; + const thisValues = [ + undefined, + null, + true, + "", + Symbol(), + 1, + {}, + WebAssembly.Global, + WebAssembly.Global.prototype, + ]; + + const fn = WebAssembly.Global.prototype.valueOf; + + for (const thisValue of thisValues) { + assert_throws(new TypeError(), () => fn.call(thisValue), `this=${format_value(thisValue)}`); + } +}, "Branding"); diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/instance/constructor.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/instance/constructor.any.js index 93a3ffda033..f9bd06ac8e9 100644 --- a/tests/wpt/web-platform-tests/wasm/jsapi/instance/constructor.any.js +++ b/tests/wpt/web-platform-tests/wasm/jsapi/instance/constructor.any.js @@ -3,61 +3,6 @@ // META: script=/wasm/jsapi/wasm-module-builder.js // META: script=/wasm/jsapi/assertions.js -function assert_exported_function(fn, { name, length }, description) { - assert_equals(Object.getPrototypeOf(fn), Function.prototype, - `${description}: prototype`); - - assert_function_name(fn, name, description); - assert_function_length(fn, length, description); -} - -function assert_Instance(instance, expected_exports) { - assert_equals(Object.getPrototypeOf(instance), WebAssembly.Instance.prototype, - "prototype"); - assert_true(Object.isExtensible(instance), "extensible"); - - assert_equals(instance.exports, instance.exports, "exports should be idempotent"); - const exports = instance.exports; - - assert_equals(Object.getPrototypeOf(exports), null, "exports prototype"); - assert_false(Object.isExtensible(exports), "extensible exports"); - for (const [key, expected] of Object.entries(expected_exports)) { - const property = Object.getOwnPropertyDescriptor(exports, key); - assert_equals(typeof property, "object", `${key} should be present`); - assert_false(property.writable, `${key}: writable`); - assert_true(property.enumerable, `${key}: enumerable`); - assert_false(property.configurable, `${key}: configurable`); - const actual = property.value; - - switch (expected.kind) { - case "function": - assert_exported_function(actual, expected, `value of ${key}`); - break; - case "global": - assert_equals(Object.getPrototypeOf(actual), WebAssembly.Global.prototype, - `value of ${key}: prototype`); - assert_equals(actual.value, expected.value, `value of ${key}: value`); - assert_equals(actual.valueOf(), expected.value, `value of ${key}: valueOf()`); - break; - case "memory": - assert_equals(Object.getPrototypeOf(actual), WebAssembly.Memory.prototype, - `value of ${key}: prototype`); - assert_equals(Object.getPrototypeOf(actual.buffer), ArrayBuffer.prototype, - `value of ${key}: prototype of buffer`); - assert_equals(actual.buffer.byteLength, 0x10000 * expected.size, `value of ${key}: size of buffer`); - const array = new Uint8Array(actual.buffer); - assert_equals(array[0], 0, `value of ${key}: first element of buffer`); - assert_equals(array[array.byteLength - 1], 0, `value of ${key}: last element of buffer`); - break; - case "table": - assert_equals(Object.getPrototypeOf(actual), WebAssembly.Table.prototype, - `value of ${key}: prototype`); - assert_equals(actual.length, expected.length, `value of ${key}: length of table`); - break; - } - } -} - let emptyModuleBinary; setup(() => { emptyModuleBinary = new WasmModuleBuilder().toBuffer(); @@ -75,6 +20,39 @@ test(() => { assert_throws(new TypeError(), () => new WebAssembly.Instance()); }, "No arguments"); +test(() => { + const invalidArguments = [ + undefined, + null, + true, + "", + Symbol(), + 1, + {}, + WebAssembly.Module, + WebAssembly.Module.prototype, + ]; + for (const argument of invalidArguments) { + assert_throws(new TypeError(), () => new WebAssembly.Instance(argument), + `new Instance(${format_value(argument)})`); + } +}, "Non-Module arguments"); + +test(() => { + const module = new WebAssembly.Module(emptyModuleBinary); + const invalidArguments = [ + null, + true, + "", + Symbol(), + 1, + ]; + for (const argument of invalidArguments) { + assert_throws(new TypeError(), () => new WebAssembly.Instance(module, argument), + `new Instance(module, ${format_value(argument)})`); + } +}, "Non-object imports"); + test(() => { const module = new WebAssembly.Module(emptyModuleBinary); assert_throws(new TypeError(), () => WebAssembly.Instance(module)); @@ -96,6 +74,8 @@ test(() => { test(() => { const builder = new WasmModuleBuilder(); builder.addImportedGlobal("module", "global1", kWasmI32); + builder.addImportedGlobal("module2", "global3", kWasmI32); + builder.addImportedMemory("module", "memory", 0, 128); builder.addImportedGlobal("module", "global2", kWasmI32); const buffer = builder.toBuffer(); const module = new WebAssembly.Module(buffer); @@ -112,6 +92,19 @@ test(() => { order.push("global2 getter"); return 0; }, + get memory() { + order.push("memory getter"); + return new WebAssembly.Memory({ "initial": 64, maximum: 128 }); + }, + } + }, + get module2() { + order.push("module2 getter"); + return { + get global3() { + order.push("global3 getter"); + return 0; + }, } }, }; @@ -119,6 +112,10 @@ test(() => { const expected = [ "module getter", "global1 getter", + "module2 getter", + "global3 getter", + "module getter", + "memory getter", "module getter", "global2 getter", ]; @@ -191,3 +188,34 @@ test(() => { }; assert_Instance(instance, expected); }, "exports"); + +test(() => { + const value = 102; + + const builder = new WasmModuleBuilder(); + + builder.addImportedGlobal("module", "global", kWasmI32); + builder + .addFunction("fn", kSig_i_v) + .addBody([ + kExprGetGlobal, + 0, + kExprReturn, + kExprEnd, + ]) + .exportFunc(); + + const buffer = builder.toBuffer(); + const module = new WebAssembly.Module(buffer); + const instance = new WebAssembly.Instance(module, { + "module": { + "global": value, + }, + }); + const expected = { + "fn": { "kind": "function", "name": "0", "length": 0 }, + }; + assert_Instance(instance, expected); + + assert_equals(instance.exports.fn(), value); +}, "exports and imports"); diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/instance/exports.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/instance/exports.any.js new file mode 100644 index 00000000000..31423918720 --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/jsapi/instance/exports.any.js @@ -0,0 +1,53 @@ +// META: global=jsshell +// META: script=/wasm/jsapi/wasm-constants.js +// META: script=/wasm/jsapi/wasm-module-builder.js + +let emptyModuleBinary; +setup(() => { + emptyModuleBinary = new WasmModuleBuilder().toBuffer(); +}); + +test(() => { + const thisValues = [ + undefined, + null, + true, + "", + Symbol(), + 1, + {}, + WebAssembly.Instance, + WebAssembly.Instance.prototype, + ]; + + const desc = Object.getOwnPropertyDescriptor(WebAssembly.Instance.prototype, "exports"); + assert_equals(typeof desc, "object"); + + const getter = desc.get; + assert_equals(typeof getter, "function"); + + assert_equals(typeof desc.set, "undefined"); + + for (const thisValue of thisValues) { + assert_throws(new TypeError(), () => getter.call(thisValue), `this=${format_value(thisValue)}`); + } +}, "Branding"); + +test(() => { + const module = new WebAssembly.Module(emptyModuleBinary); + const instance = new WebAssembly.Instance(module); + const exports = instance.exports; + instance.exports = {}; + assert_equals(instance.exports, exports, "Should not change the exports"); +}, "Setting (sloppy mode)"); + +test(() => { + const module = new WebAssembly.Module(emptyModuleBinary); + const instance = new WebAssembly.Instance(module); + const exports = instance.exports; + assert_throws(new TypeError(), () => { + "use strict"; + instance.exports = {}; + }); + assert_equals(instance.exports, exports, "Should not change the exports"); +}, "Setting (strict mode)"); diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/instance/toString.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/instance/toString.any.js new file mode 100644 index 00000000000..08dcb14a50d --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/jsapi/instance/toString.any.js @@ -0,0 +1,10 @@ +// META: global=jsshell +// META: script=/wasm/jsapi/wasm-constants.js +// META: script=/wasm/jsapi/wasm-module-builder.js + +test(() => { + const emptyModuleBinary = new WasmModuleBuilder().toBuffer(); + const module = new WebAssembly.Module(emptyModuleBinary); + const instance = new WebAssembly.Instance(module); + assert_class_string(instance, "WebAssembly.Instance"); +}, "Object.prototype.toString on an Instance"); diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/interface.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/interface.any.js index 64c1f60da1c..5d76ac56ec5 100644 --- a/tests/wpt/web-platform-tests/wasm/jsapi/interface.any.js +++ b/tests/wpt/web-platform-tests/wasm/jsapi/interface.any.js @@ -62,6 +62,10 @@ test(() => { assert_equals(propdesc.value, this.WebAssembly); }, "WebAssembly: property descriptor"); +test(() => { + assert_throws(new TypeError(), () => WebAssembly()); +}, "WebAssembly: calling"); + test(() => { assert_throws(new TypeError(), () => new WebAssembly()); }, "WebAssembly: constructing"); @@ -87,6 +91,15 @@ for (const name of interfaces) { assert_equals(propdesc.value, WebAssembly[name]); }, `WebAssembly.${name}: property descriptor`); + test(() => { + const interface_object = WebAssembly[name]; + const propdesc = Object.getOwnPropertyDescriptor(interface_object, "prototype"); + assert_equals(typeof propdesc, "object"); + assert_false(propdesc.writable, "writable"); + assert_false(propdesc.enumerable, "enumerable"); + assert_false(propdesc.configurable, "configurable"); + }, `WebAssembly.${name}: prototype`); + test(() => { const interface_object = WebAssembly[name]; const interface_prototype_object = interface_object.prototype; @@ -96,7 +109,7 @@ for (const name of interfaces) { assert_false(propdesc.enumerable, "enumerable"); assert_true(propdesc.configurable, "configurable"); assert_equals(propdesc.value, interface_object); - }, `WebAssembly.${name}: prototype`); + }, `WebAssembly.${name}: prototype.constructor`); } test_operations(WebAssembly, "WebAssembly", [ diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/memory/buffer.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/memory/buffer.any.js new file mode 100644 index 00000000000..b04460b6c5e --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/jsapi/memory/buffer.any.js @@ -0,0 +1,50 @@ +// META: global=jsshell + +test(() => { + const thisValues = [ + undefined, + null, + true, + "", + Symbol(), + 1, + {}, + WebAssembly.Memory, + WebAssembly.Memory.prototype, + ]; + + const desc = Object.getOwnPropertyDescriptor(WebAssembly.Memory.prototype, "buffer"); + assert_equals(typeof desc, "object"); + + const getter = desc.get; + assert_equals(typeof getter, "function"); + + assert_equals(typeof desc.set, "undefined"); + + for (const thisValue of thisValues) { + assert_throws(new TypeError(), () => getter.call(thisValue), `this=${format_value(thisValue)}`); + } +}, "Branding"); + +test(() => { + const argument = { "initial": 0 }; + const memory = new WebAssembly.Memory(argument); + const memory2 = new WebAssembly.Memory(argument); + const buffer = memory.buffer; + assert_not_equals(buffer, memory2.buffer, "Need two distinct buffers"); + memory.buffer = memory2.buffer; + assert_equals(memory.buffer, buffer, "Should not change the buffer"); +}, "Setting (sloppy mode)"); + +test(() => { + const argument = { "initial": 0 }; + const memory = new WebAssembly.Memory(argument); + const memory2 = new WebAssembly.Memory(argument); + const buffer = memory.buffer; + assert_not_equals(buffer, memory2.buffer, "Need two distinct buffers"); + assert_throws(new TypeError(), () => { + "use strict"; + memory.buffer = memory2.buffer; + }); + assert_equals(memory.buffer, buffer, "Should not change the buffer"); +}, "Setting (strict mode)"); diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/memory/constructor.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/memory/constructor.any.js index 33256f85e45..f9907ca6104 100644 --- a/tests/wpt/web-platform-tests/wasm/jsapi/memory/constructor.any.js +++ b/tests/wpt/web-platform-tests/wasm/jsapi/memory/constructor.any.js @@ -1,12 +1,23 @@ // META: global=jsshell -// META: script=/wasm/jsapi/wasm-constants.js -// META: script=/wasm/jsapi/wasm-module-builder.js // META: script=/wasm/jsapi/assertions.js -let emptyModuleBinary; -setup(() => { - emptyModuleBinary = new WasmModuleBuilder().toBuffer(); -}); +function assert_Memory(memory, expected) { + assert_equals(Object.getPrototypeOf(memory), WebAssembly.Memory.prototype, + "prototype"); + assert_true(Object.isExtensible(memory), "extensible"); + + // https://github.com/WebAssembly/spec/issues/840 + assert_equals(memory.buffer, memory.buffer, "buffer should be idempotent"); + assert_equals(Object.getPrototypeOf(memory.buffer), ArrayBuffer.prototype, + "prototype of buffer"); + assert_true(Object.isExtensible(memory.buffer), "buffer extensibility"); + assert_equals(memory.buffer.byteLength, 0x10000 * expected.size, "size of buffer"); + if (expected.size > 0) { + const array = new Uint8Array(memory.buffer); + assert_equals(array[0], 0, "first element of buffer"); + assert_equals(array[array.byteLength - 1], 0, "last element of buffer"); + } +} test(() => { assert_function_name(WebAssembly.Memory, "Memory", "WebAssembly.Memory"); @@ -26,8 +37,24 @@ test(() => { }, "Calling"); test(() => { - assert_throws(new TypeError(), () => new WebAssembly.Memory({})); -}, "Empty descriptor"); + const invalidArguments = [ + undefined, + null, + false, + true, + "", + "test", + Symbol(), + 1, + NaN, + {}, + ]; + for (const invalidArgument of invalidArguments) { + assert_throws(new TypeError(), + () => new WebAssembly.Memory(invalidArgument), + `new Memory(${format_value(invalidArgument)})`); + } +}, "Invalid descriptor argument"); test(() => { assert_throws(new TypeError(), () => new WebAssembly.Memory({ "initial": undefined })); @@ -64,8 +91,47 @@ test(() => { new WebAssembly.Memory(proxy); }, "Proxy descriptor"); +test(() => { + const order = []; + + new WebAssembly.Memory({ + get maximum() { + order.push("maximum"); + return { + valueOf() { + order.push("maximum valueOf"); + return 1; + }, + }; + }, + + get initial() { + order.push("initial"); + return { + valueOf() { + order.push("initial valueOf"); + return 1; + }, + }; + }, + }); + + assert_array_equals(order, [ + "initial", + "initial valueOf", + "maximum", + "maximum valueOf", + ]); +}, "Order of evaluation for descriptor"); + test(() => { const argument = { "initial": 0 }; const memory = new WebAssembly.Memory(argument); - assert_equals(Object.getPrototypeOf(memory), WebAssembly.Memory.prototype); -}, "Prototype"); + assert_Memory(memory, { "size": 0 }); +}, "Zero initial"); + +test(() => { + const argument = { "initial": 4 }; + const memory = new WebAssembly.Memory(argument); + assert_Memory(memory, { "size": 4 }); +}, "Non-zero initial"); diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/memory/grow.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/memory/grow.any.js new file mode 100644 index 00000000000..95300399f19 --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/jsapi/memory/grow.any.js @@ -0,0 +1,170 @@ +// META: global=jsshell + +function assert_ArrayBuffer(actual, expected, message) { + // https://github.com/WebAssembly/spec/issues/840 + assert_equals(Object.getPrototypeOf(actual), ArrayBuffer.prototype, + `${message}: prototype`); + if (expected.detached) { + // https://github.com/tc39/ecma262/issues/678 + let byteLength; + try { + byteLength = actual.byteLength; + } catch (e) { + byteLength = 0; + } + assert_equals(byteLength, 0, `${message}: detached size`); + } else { + assert_equals(actual.byteLength, 0x10000 * expected.size, `${message}: size`); + if (expected.size > 0) { + const array = new Uint8Array(actual); + assert_equals(array[0], 0, `${message}: first element`); + assert_equals(array[array.byteLength - 1], 0, `${message}: last element`); + } + } +} + +test(() => { + const argument = { "initial": 0 }; + const memory = new WebAssembly.Memory(argument); + assert_throws(new TypeError(), () => memory.grow()); +}, "Missing arguments"); + +test(t => { + const thisValues = [ + undefined, + null, + true, + "", + Symbol(), + 1, + {}, + WebAssembly.Memory, + WebAssembly.Memory.prototype, + ]; + + const argument = { + valueOf: t.unreached_func("Should not touch the argument (valueOf)"), + toString: t.unreached_func("Should not touch the argument (toString)"), + }; + + const fn = WebAssembly.Memory.prototype.grow; + + for (const thisValue of thisValues) { + assert_throws(new TypeError(), () => fn.call(thisValue, argument), `this=${format_value(thisValue)}`); + } +}, "Branding"); + +test(() => { + const argument = { "initial": 0 }; + const memory = new WebAssembly.Memory(argument); + const oldMemory = memory.buffer; + assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing"); + + const result = memory.grow(2); + assert_equals(result, 0); + + const newMemory = memory.buffer; + assert_not_equals(oldMemory, newMemory); + assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing"); + assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing"); +}, "Zero initial"); + +test(() => { + const argument = { "initial": { valueOf() { return 0 } } }; + const memory = new WebAssembly.Memory(argument); + const oldMemory = memory.buffer; + assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing"); + + const result = memory.grow({ valueOf() { return 2 } }); + assert_equals(result, 0); + + const newMemory = memory.buffer; + assert_not_equals(oldMemory, newMemory); + assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing"); + assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing"); +}, "Zero initial with valueOf"); + +test(() => { + const argument = { "initial": 3 }; + const memory = new WebAssembly.Memory(argument); + const oldMemory = memory.buffer; + assert_ArrayBuffer(oldMemory, { "size": 3 }, "Buffer before growing"); + + const result = memory.grow(2); + assert_equals(result, 3); + + const newMemory = memory.buffer; + assert_not_equals(oldMemory, newMemory); + assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing"); + assert_ArrayBuffer(newMemory, { "size": 5 }, "New buffer after growing"); +}, "Non-zero initial"); + +test(() => { + const argument = { "initial": 0, "maximum": 2 }; + const memory = new WebAssembly.Memory(argument); + const oldMemory = memory.buffer; + assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing"); + + const result = memory.grow(2); + assert_equals(result, 0); + + const newMemory = memory.buffer; + assert_not_equals(oldMemory, newMemory); + assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing"); + assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing"); +}, "Zero initial with respected maximum"); + +test(() => { + const argument = { "initial": 0, "maximum": 2 }; + const memory = new WebAssembly.Memory(argument); + const oldMemory = memory.buffer; + assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing"); + + const result = memory.grow(1); + assert_equals(result, 0); + + const newMemory = memory.buffer; + assert_not_equals(oldMemory, newMemory); + assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing once"); + assert_ArrayBuffer(newMemory, { "size": 1 }, "New buffer after growing once"); + + const result2 = memory.grow(1); + assert_equals(result2, 1); + + const newestMemory = memory.buffer; + assert_not_equals(newMemory, newestMemory); + assert_ArrayBuffer(oldMemory, { "detached": true }, "New buffer after growing twice"); + assert_ArrayBuffer(newMemory, { "detached": true }, "New buffer after growing twice"); + assert_ArrayBuffer(newestMemory, { "size": 2 }, "Newest buffer after growing twice"); +}, "Zero initial with respected maximum grown twice"); + +test(() => { + const argument = { "initial": 1, "maximum": 2 }; + const memory = new WebAssembly.Memory(argument); + const oldMemory = memory.buffer; + assert_ArrayBuffer(oldMemory, { "size": 1 }, "Buffer before growing"); + + assert_throws(new RangeError(), () => memory.grow(2)); + assert_equals(memory.buffer, oldMemory); + assert_ArrayBuffer(memory.buffer, { "size": 1 }, "Buffer before trying to grow"); +}, "Zero initial growing too much"); + +const outOfRangeValues = [ + undefined, + NaN, + Infinity, + -Infinity, + -1, + 0x100000000, + 0x1000000000, + "0x100000000", + { valueOf() { return 0x100000000; } }, +]; + +for (const value of outOfRangeValues) { + test(() => { + const argument = { "initial": 0 }; + const memory = new WebAssembly.Memory(argument); + assert_throws(new TypeError(), () => memory.grow(value)); + }, `Out-of-range argument: ${format_value(value)}`); +} diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/memory/toString.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/memory/toString.any.js new file mode 100644 index 00000000000..4e15d75ea20 --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/jsapi/memory/toString.any.js @@ -0,0 +1,7 @@ +// META: global=jsshell + +test(() => { + const argument = { "initial": 0 }; + const memory = new WebAssembly.Memory(argument); + assert_class_string(memory, "WebAssembly.Memory"); +}, "Object.prototype.toString on an Memory"); diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/module/constructor.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/module/constructor.any.js index 0f5eecf957e..32f183fac87 100644 --- a/tests/wpt/web-platform-tests/wasm/jsapi/module/constructor.any.js +++ b/tests/wpt/web-platform-tests/wasm/jsapi/module/constructor.any.js @@ -24,6 +24,26 @@ test(() => { assert_throws(new TypeError(), () => WebAssembly.Module(emptyModuleBinary)); }, "Calling"); +test(() => { + const invalidArguments = [ + undefined, + null, + true, + "test", + Symbol(), + 7, + NaN, + {}, + ArrayBuffer, + ArrayBuffer.prototype, + Array.from(emptyModuleBinary), + ]; + for (const argument of invalidArguments) { + assert_throws(new TypeError(), () => new WebAssembly.Module(argument), + `new Module(${format_value(argument)})`); + } +}, "Invalid arguments"); + test(() => { const buffer = new Uint8Array(); assert_throws(new WebAssembly.CompileError(), () => new WebAssembly.Module(buffer)); @@ -33,3 +53,8 @@ test(() => { const module = new WebAssembly.Module(emptyModuleBinary); assert_equals(Object.getPrototypeOf(module), WebAssembly.Module.prototype); }, "Prototype"); + +test(() => { + const module = new WebAssembly.Module(emptyModuleBinary); + assert_true(Object.isExtensible(module)); +}, "Extensibility"); diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/module/customSections.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/module/customSections.any.js index 146aa7fd332..58ac63b61c9 100644 --- a/tests/wpt/web-platform-tests/wasm/jsapi/module/customSections.any.js +++ b/tests/wpt/web-platform-tests/wasm/jsapi/module/customSections.any.js @@ -4,12 +4,14 @@ function assert_ArrayBuffer(buffer, expected) { assert_equals(Object.getPrototypeOf(buffer), ArrayBuffer.prototype, "Prototype"); + assert_true(Object.isExtensible(buffer), "isExtensible"); assert_array_equals(new Uint8Array(buffer), expected); } function assert_sections(sections, expected) { assert_true(Array.isArray(sections), "Should be array"); assert_equals(Object.getPrototypeOf(sections), Array.prototype, "Prototype"); + assert_true(Object.isExtensible(sections), "isExtensible"); assert_equals(sections.length, expected.length); for (let i = 0; i < expected.length; ++i) { @@ -29,10 +31,21 @@ test(() => { }, "Missing arguments"); test(() => { - assert_throws(new TypeError(), () => WebAssembly.Module.customSections({}, "")); - assert_throws(new TypeError(), () => WebAssembly.Module.customSections("", "")); - assert_throws(new TypeError(), () => WebAssembly.Module.customSections(undefined, "")); - assert_throws(new TypeError(), () => WebAssembly.Module.customSections(null, "")); + const invalidArguments = [ + undefined, + null, + true, + "", + Symbol(), + 1, + {}, + WebAssembly.Module, + WebAssembly.Module.prototype, + ]; + for (const argument of invalidArguments) { + assert_throws(new TypeError(), () => WebAssembly.Module.customSections(argument, ""), + `customSections(${format_value(argument)})`); + } }, "Non-Module arguments"); test(() => { @@ -102,3 +115,48 @@ test(() => { assert_sections(WebAssembly.Module.customSections(module, "name\0"), []) assert_sections(WebAssembly.Module.customSections(module, "foo\0"), []) }, "Custom sections"); + +test(() => { + const bytes = [87, 101, 98, 65, 115, 115, 101, 109, 98, 108, 121]; + const name = "yee\uD801\uDC37eey" + + const binary = new Binary; + binary.emit_section(kUnknownSectionCode, section => { + section.emit_string(name); + section.emit_bytes(bytes); + }); + + const builder = new WasmModuleBuilder(); + builder.addExplicitSection(binary); + const buffer = builder.toBuffer(); + const module = new WebAssembly.Module(buffer); + + assert_sections(WebAssembly.Module.customSections(module, name), [ + bytes, + ]); + assert_sections(WebAssembly.Module.customSections(module, "yee\uFFFDeey"), []); + assert_sections(WebAssembly.Module.customSections(module, "yee\uFFFD\uFFFDeey"), []); +}, "Custom sections with surrogate pairs"); + +test(() => { + const bytes = [87, 101, 98, 65, 115, 115, 101, 109, 98, 108, 121]; + + const binary = new Binary; + binary.emit_section(kUnknownSectionCode, section => { + section.emit_string("na\uFFFDme"); + section.emit_bytes(bytes); + }); + + const builder = new WasmModuleBuilder(); + builder.addExplicitSection(binary); + const buffer = builder.toBuffer(); + const module = new WebAssembly.Module(buffer); + + assert_sections(WebAssembly.Module.customSections(module, "name"), []); + assert_sections(WebAssembly.Module.customSections(module, "na\uFFFDme"), [ + bytes, + ]); + assert_sections(WebAssembly.Module.customSections(module, "na\uDC01me"), [ + bytes, + ]); +}, "Custom sections with U+FFFD"); diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/module/exports.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/module/exports.any.js index c7ecdcf6b61..e63a885a4c3 100644 --- a/tests/wpt/web-platform-tests/wasm/jsapi/module/exports.any.js +++ b/tests/wpt/web-platform-tests/wasm/jsapi/module/exports.any.js @@ -7,15 +7,54 @@ setup(() => { emptyModuleBinary = new WasmModuleBuilder().toBuffer(); }); +function assert_ModuleExportDescriptor(export_, expected) { + assert_equals(Object.getPrototypeOf(export_), Object.prototype, "Prototype"); + assert_true(Object.isExtensible(export_), "isExtensible"); + + const name = Object.getOwnPropertyDescriptor(export_, "name"); + assert_true(name.writable, "name: writable"); + assert_true(name.enumerable, "name: enumerable"); + assert_true(name.configurable, "name: configurable"); + assert_equals(name.value, expected.name); + + const kind = Object.getOwnPropertyDescriptor(export_, "kind"); + assert_true(kind.writable, "kind: writable"); + assert_true(kind.enumerable, "kind: enumerable"); + assert_true(kind.configurable, "kind: configurable"); + assert_equals(kind.value, expected.kind); +} + +function assert_exports(exports, expected) { + assert_true(Array.isArray(exports), "Should be array"); + assert_equals(Object.getPrototypeOf(exports), Array.prototype, "Prototype"); + assert_true(Object.isExtensible(exports), "isExtensible"); + + assert_equals(exports.length, expected.length); + for (let i = 0; i < expected.length; ++i) { + assert_ModuleExportDescriptor(exports[i], expected[i]); + } +} + test(() => { assert_throws(new TypeError(), () => WebAssembly.Module.exports()); }, "Missing arguments"); test(() => { - assert_throws(new TypeError(), () => WebAssembly.Module.exports({})); - assert_throws(new TypeError(), () => WebAssembly.Module.exports("")); - assert_throws(new TypeError(), () => WebAssembly.Module.exports(undefined)); - assert_throws(new TypeError(), () => WebAssembly.Module.exports(null)); + const invalidArguments = [ + undefined, + null, + true, + "", + Symbol(), + 1, + {}, + WebAssembly.Module, + WebAssembly.Module.prototype, + ]; + for (const argument of invalidArguments) { + assert_throws(new TypeError(), () => WebAssembly.Module.exports(argument), + `exports(${format_value(argument)})`); + } }, "Non-Module arguments"); test(() => { @@ -40,15 +79,7 @@ test(() => { test(() => { const module = new WebAssembly.Module(emptyModuleBinary); const exports = WebAssembly.Module.exports(module); - assert_true(Array.isArray(exports)); -}, "Return type"); - -test(() => { - const module = new WebAssembly.Module(emptyModuleBinary); - const exports = WebAssembly.Module.exports(module); - assert_true(Array.isArray(exports), "Should be array"); - assert_equals(Object.getPrototypeOf(exports), Array.prototype, "Prototype"); - assert_array_equals(exports, []); + assert_exports(exports, []); }, "Empty module"); test(() => { @@ -56,22 +87,6 @@ test(() => { assert_not_equals(WebAssembly.Module.exports(module), WebAssembly.Module.exports(module)); }, "Empty module: array caching"); -function assert_ModuleExportDescriptor(export_, expected) { - assert_equals(Object.getPrototypeOf(export_), Object.prototype, "Prototype"); - - const name = Object.getOwnPropertyDescriptor(export_, "name"); - assert_true(name.writable, "name: writable"); - assert_true(name.enumerable, "name: enumerable"); - assert_true(name.configurable, "name: configurable"); - assert_equals(name.value, expected.name); - - const kind = Object.getOwnPropertyDescriptor(export_, "kind"); - assert_true(kind.writable, "kind: writable"); - assert_true(kind.enumerable, "kind: enumerable"); - assert_true(kind.configurable, "kind: configurable"); - assert_equals(kind.value, expected.kind); -} - test(() => { const builder = new WasmModuleBuilder(); @@ -103,9 +118,6 @@ test(() => { const buffer = builder.toBuffer() const module = new WebAssembly.Module(buffer); const exports = WebAssembly.Module.exports(module); - assert_true(Array.isArray(exports), "Should be array"); - assert_equals(Object.getPrototypeOf(exports), Array.prototype, "Prototype"); - const expected = [ { "kind": "function", "name": "fn" }, { "kind": "function", "name": "fn2" }, @@ -114,8 +126,5 @@ test(() => { { "kind": "global", "name": "global2" }, { "kind": "memory", "name": "memory" }, ]; - assert_equals(exports.length, expected.length); - for (let i = 0; i < expected.length; ++i) { - assert_ModuleExportDescriptor(exports[i], expected[i]); - } + assert_exports(exports, expected); }, "exports"); diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/module/imports.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/module/imports.any.js index 522b262f549..640da591d21 100644 --- a/tests/wpt/web-platform-tests/wasm/jsapi/module/imports.any.js +++ b/tests/wpt/web-platform-tests/wasm/jsapi/module/imports.any.js @@ -2,6 +2,40 @@ // META: script=/wasm/jsapi/wasm-constants.js // META: script=/wasm/jsapi/wasm-module-builder.js +function assert_ModuleImportDescriptor(import_, expected) { + assert_equals(Object.getPrototypeOf(import_), Object.prototype, "Prototype"); + assert_true(Object.isExtensible(import_), "isExtensible"); + + const module = Object.getOwnPropertyDescriptor(import_, "module"); + assert_true(module.writable, "module: writable"); + assert_true(module.enumerable, "module: enumerable"); + assert_true(module.configurable, "module: configurable"); + assert_equals(module.value, expected.module); + + const name = Object.getOwnPropertyDescriptor(import_, "name"); + assert_true(name.writable, "name: writable"); + assert_true(name.enumerable, "name: enumerable"); + assert_true(name.configurable, "name: configurable"); + assert_equals(name.value, expected.name); + + const kind = Object.getOwnPropertyDescriptor(import_, "kind"); + assert_true(kind.writable, "kind: writable"); + assert_true(kind.enumerable, "kind: enumerable"); + assert_true(kind.configurable, "kind: configurable"); + assert_equals(kind.value, expected.kind); +} + +function assert_imports(imports, expected) { + assert_true(Array.isArray(imports), "Should be array"); + assert_equals(Object.getPrototypeOf(imports), Array.prototype, "Prototype"); + assert_true(Object.isExtensible(imports), "isExtensible"); + + assert_equals(imports.length, expected.length); + for (let i = 0; i < expected.length; ++i) { + assert_ModuleImportDescriptor(imports[i], expected[i]); + } +} + let emptyModuleBinary; setup(() => { emptyModuleBinary = new WasmModuleBuilder().toBuffer(); @@ -12,10 +46,21 @@ test(() => { }, "Missing arguments"); test(() => { - assert_throws(new TypeError(), () => WebAssembly.Module.imports({})); - assert_throws(new TypeError(), () => WebAssembly.Module.imports("")); - assert_throws(new TypeError(), () => WebAssembly.Module.imports(undefined)); - assert_throws(new TypeError(), () => WebAssembly.Module.imports(null)); + const invalidArguments = [ + undefined, + null, + true, + "", + Symbol(), + 1, + {}, + WebAssembly.Module, + WebAssembly.Module.prototype, + ]; + for (const argument of invalidArguments) { + assert_throws(new TypeError(), () => WebAssembly.Module.imports(argument), + `imports(${format_value(argument)})`); + } }, "Non-Module arguments"); test(() => { @@ -46,9 +91,7 @@ test(() => { test(() => { const module = new WebAssembly.Module(emptyModuleBinary); const imports = WebAssembly.Module.imports(module); - assert_true(Array.isArray(imports), "Should be array"); - assert_equals(Object.getPrototypeOf(imports), Array.prototype, "Prototype"); - assert_array_equals(imports, []); + assert_imports(imports, []); }, "Empty module"); test(() => { @@ -56,28 +99,6 @@ test(() => { assert_not_equals(WebAssembly.Module.imports(module), WebAssembly.Module.imports(module)); }, "Empty module: array caching"); -function assert_ModuleImportDescriptor(import_, expected) { - assert_equals(Object.getPrototypeOf(import_), Object.prototype, "Prototype"); - - const module = Object.getOwnPropertyDescriptor(import_, "module"); - assert_true(module.writable, "module: writable"); - assert_true(module.enumerable, "module: enumerable"); - assert_true(module.configurable, "module: configurable"); - assert_equals(module.value, expected.module); - - const name = Object.getOwnPropertyDescriptor(import_, "name"); - assert_true(name.writable, "name: writable"); - assert_true(name.enumerable, "name: enumerable"); - assert_true(name.configurable, "name: configurable"); - assert_equals(name.value, expected.name); - - const kind = Object.getOwnPropertyDescriptor(import_, "kind"); - assert_true(kind.writable, "kind: writable"); - assert_true(kind.enumerable, "kind: enumerable"); - assert_true(kind.configurable, "kind: configurable"); - assert_equals(kind.value, expected.kind); -} - test(() => { const builder = new WasmModuleBuilder(); @@ -89,17 +110,11 @@ test(() => { const buffer = builder.toBuffer() const module = new WebAssembly.Module(buffer); const imports = WebAssembly.Module.imports(module); - assert_true(Array.isArray(imports), "Should be array"); - assert_equals(Object.getPrototypeOf(imports), Array.prototype, "Prototype"); - const expected = [ { "module": "module", "kind": "function", "name": "fn" }, { "module": "module", "kind": "global", "name": "global" }, { "module": "module", "kind": "memory", "name": "memory" }, { "module": "module", "kind": "table", "name": "table" }, ]; - assert_equals(imports.length, expected.length); - for (let i = 0; i < expected.length; ++i) { - assert_ModuleImportDescriptor(imports[i], expected[i]); - } + assert_imports(imports, expected); }, "imports"); diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/module/toString.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/module/toString.any.js new file mode 100644 index 00000000000..d9231a132ca --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/jsapi/module/toString.any.js @@ -0,0 +1,9 @@ +// META: global=jsshell +// META: script=/wasm/jsapi/wasm-constants.js +// META: script=/wasm/jsapi/wasm-module-builder.js + +test(() => { + const emptyModuleBinary = new WasmModuleBuilder().toBuffer(); + const module = new WebAssembly.Module(emptyModuleBinary); + assert_class_string(module, "WebAssembly.Module"); +}, "Object.prototype.toString on an Module"); diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/table/assertions.js b/tests/wpt/web-platform-tests/wasm/jsapi/table/assertions.js new file mode 100644 index 00000000000..dde2fd77090 --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/jsapi/table/assertions.js @@ -0,0 +1,11 @@ +function assert_equal_to_array(table, expected, message) { + assert_equals(table.length, expected.length, `${message}: length`); + assert_throws(new RangeError(), () => table.get(-1), `${message}: table.get(-1)`); + for (let i = 0; i < expected.length; ++i) { + assert_equals(table.get(i), expected[i], `${message}: table.get(${i} of ${expected.length})`); + } + assert_throws(new RangeError(), () => table.get(expected.length), + `${message}: table.get(${expected.length} of ${expected.length})`); + assert_throws(new RangeError(), () => table.get(expected.length + 1), + `${message}: table.get(${expected.length + 1} of ${expected.length})`); +} diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/table/constructor.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/table/constructor.any.js index 4aeac10f7ad..e924bdb2ba4 100644 --- a/tests/wpt/web-platform-tests/wasm/jsapi/table/constructor.any.js +++ b/tests/wpt/web-platform-tests/wasm/jsapi/table/constructor.any.js @@ -1,12 +1,16 @@ // META: global=jsshell -// META: script=/wasm/jsapi/wasm-constants.js -// META: script=/wasm/jsapi/wasm-module-builder.js // META: script=/wasm/jsapi/assertions.js -let emptyModuleBinary; -setup(() => { - emptyModuleBinary = new WasmModuleBuilder().toBuffer(); -}); +function assert_Table(actual, expected) { + assert_equals(Object.getPrototypeOf(actual), WebAssembly.Table.prototype, + "prototype"); + assert_true(Object.isExtensible(actual), "extensible"); + + assert_equals(actual.length, expected.length, "length"); + for (let i = 0; i < expected.length; ++i) { + assert_equals(actual.get(i), null, `actual.get(${i})`); + } +} test(() => { assert_function_name(WebAssembly.Table, "Table", "WebAssembly.Table"); @@ -21,7 +25,7 @@ test(() => { }, "No arguments"); test(() => { - const argument = { "initial": 0 }; + const argument = { "element": "anyfunc", "initial": 0 }; assert_throws(new TypeError(), () => WebAssembly.Table(argument)); }, "Calling"); @@ -29,6 +33,26 @@ test(() => { assert_throws(new TypeError(), () => new WebAssembly.Table({})); }, "Empty descriptor"); +test(() => { + const invalidArguments = [ + undefined, + null, + false, + true, + "", + "test", + Symbol(), + 1, + NaN, + {}, + ]; + for (const invalidArgument of invalidArguments) { + assert_throws(new TypeError(), + () => new WebAssembly.Table(invalidArgument), + `new Table(${format_value(invalidArgument)})`); + } +}, "Invalid descriptor argument"); + test(() => { assert_throws(new TypeError(), () => new WebAssembly.Table({ "element": "anyfunc", "initial": undefined })); }, "Undefined initial value in descriptor"); @@ -56,6 +80,22 @@ for (const value of outOfRangeValues) { }, `Out-of-range maximum value in descriptor: ${format_value(value)}`); } +test(() => { + assert_throws(new RangeError(), () => new WebAssembly.Table({ "element": "anyfunc", "initial": 10, "maximum": 9 })); +}, "Initial value exceeds maximum"); + +test(() => { + const argument = { "element": "anyfunc", "initial": 0 }; + const table = new WebAssembly.Table(argument); + assert_Table(table, { "length": 0 }); +}, "Basic (zero)"); + +test(() => { + const argument = { "element": "anyfunc", "initial": 5 }; + const table = new WebAssembly.Table(argument); + assert_Table(table, { "length": 5 }); +}, "Basic (non-zero)"); + test(() => { const proxy = new Proxy({}, { has(o, x) { @@ -73,11 +113,61 @@ test(() => { } }, }); - new WebAssembly.Table(proxy); + const table = new WebAssembly.Table(proxy); + assert_Table(table, { "length": 0 }); }, "Proxy descriptor"); test(() => { - const argument = { "element": "anyfunc", "initial": 0 }; - const table = new WebAssembly.Table(argument); - assert_equals(Object.getPrototypeOf(table), WebAssembly.Table.prototype); -}, "Prototype"); + const table = new WebAssembly.Table({ + "element": { + toString() { return "anyfunc"; }, + }, + "initial": 1, + }); + assert_Table(table, { "length": 1 }); +}, "Type conversion for descriptor.element"); + +test(() => { + const order = []; + + new WebAssembly.Table({ + get maximum() { + order.push("maximum"); + return { + valueOf() { + order.push("maximum valueOf"); + return 1; + }, + }; + }, + + get initial() { + order.push("initial"); + return { + valueOf() { + order.push("initial valueOf"); + return 1; + }, + }; + }, + + get element() { + order.push("element"); + return { + toString() { + order.push("element toString"); + return "anyfunc"; + }, + }; + }, + }); + + assert_array_equals(order, [ + "element", + "element toString", + "initial", + "initial valueOf", + "maximum", + "maximum valueOf", + ]); +}, "Order of evaluation for descriptor"); diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/table/get-set.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/table/get-set.any.js new file mode 100644 index 00000000000..2bb43a9308d --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/jsapi/table/get-set.any.js @@ -0,0 +1,220 @@ +// META: global=jsshell +// META: script=/wasm/jsapi/wasm-constants.js +// META: script=/wasm/jsapi/wasm-module-builder.js +// META: script=assertions.js + +let functions; +setup(() => { + const builder = new WasmModuleBuilder(); + + builder + .addFunction("fn", kSig_v_d) + .addBody([ + kExprEnd + ]) + .exportFunc(); + builder + .addFunction("fn2", kSig_v_v) + .addBody([ + kExprEnd + ]) + .exportFunc(); + + const buffer = builder.toBuffer() + const module = new WebAssembly.Module(buffer); + const instance = new WebAssembly.Instance(module, {}); + functions = instance.exports; +}); + +test(() => { + const argument = { "element": "anyfunc", "initial": 5 }; + const table = new WebAssembly.Table(argument); + assert_throws(new TypeError(), () => table.get()); +}, "Missing arguments: get"); + +test(t => { + const thisValues = [ + undefined, + null, + true, + "", + Symbol(), + 1, + {}, + WebAssembly.Table, + WebAssembly.Table.prototype, + ]; + + const argument = { + valueOf: t.unreached_func("Should not touch the argument (valueOf)"), + toString: t.unreached_func("Should not touch the argument (toString)"), + }; + + const fn = WebAssembly.Table.prototype.get; + + for (const thisValue of thisValues) { + assert_throws(new TypeError(), () => fn.call(thisValue, argument), `this=${format_value(thisValue)}`); + } +}, "Branding: get"); + +test(() => { + const argument = { "element": "anyfunc", "initial": 5 }; + const table = new WebAssembly.Table(argument); + assert_throws(new TypeError(), () => table.set()); + assert_throws(new TypeError(), () => table.set(0)); +}, "Missing arguments: set"); + +test(t => { + const thisValues = [ + undefined, + null, + true, + "", + Symbol(), + 1, + {}, + WebAssembly.Table, + WebAssembly.Table.prototype, + ]; + + const argument = { + valueOf: t.unreached_func("Should not touch the argument (valueOf)"), + toString: t.unreached_func("Should not touch the argument (toString)"), + }; + + const fn = WebAssembly.Table.prototype.set; + + for (const thisValue of thisValues) { + assert_throws(new TypeError(), () => fn.call(thisValue, argument, null), `this=${format_value(thisValue)}`); + } +}, "Branding: set"); + +test(() => { + const argument = { "element": "anyfunc", "initial": 5 }; + const table = new WebAssembly.Table(argument); + assert_equal_to_array(table, [null, null, null, null, null]); + + const {fn, fn2} = functions; + + assert_equals(table.set(0, fn), undefined, "set() returns undefined."); + table.set(2, fn2); + table.set(4, fn); + + assert_equal_to_array(table, [fn, null, fn2, null, fn]); + + table.set(0, null); + assert_equal_to_array(table, [null, null, fn2, null, fn]); +}, "Basic"); + +test(() => { + const argument = { "element": "anyfunc", "initial": 5 }; + const table = new WebAssembly.Table(argument); + assert_equal_to_array(table, [null, null, null, null, null]); + + const {fn, fn2} = functions; + + table.set(0, fn); + table.set(2, fn2); + table.set(4, fn); + + assert_equal_to_array(table, [fn, null, fn2, null, fn]); + + table.grow(4); + + assert_equal_to_array(table, [fn, null, fn2, null, fn, null, null, null, null]); +}, "Growing"); + +test(() => { + const argument = { "element": "anyfunc", "initial": 5 }; + const table = new WebAssembly.Table(argument); + assert_equal_to_array(table, [null, null, null, null, null]); + + const {fn} = functions; + + assert_throws(new RangeError(), () => table.set(-1, fn)); + assert_throws(new RangeError(), () => table.set(5, fn)); + assert_equal_to_array(table, [null, null, null, null, null]); +}, "Setting out-of-bounds"); + +test(() => { + const argument = { "element": "anyfunc", "initial": 1 }; + const table = new WebAssembly.Table(argument); + assert_equal_to_array(table, [null]); + + const invalidArguments = [ + undefined, + true, + false, + "test", + Symbol(), + 7, + NaN, + {}, + ]; + for (const argument of invalidArguments) { + assert_throws(new TypeError(), () => table.set(0, argument), + `set(${format_value(argument)})`); + } + assert_equal_to_array(table, [null]); +}, "Setting non-function"); + +test(() => { + const argument = { "element": "anyfunc", "initial": 1 }; + const table = new WebAssembly.Table(argument); + assert_equal_to_array(table, [null]); + + const fn = function() {}; + assert_throws(new TypeError(), () => table.set(0, fn)); + assert_equal_to_array(table, [null]); +}, "Setting non-wasm function"); + +test(() => { + const argument = { "element": "anyfunc", "initial": 1 }; + const table = new WebAssembly.Table(argument); + assert_equal_to_array(table, [null]); + + const fn = () => {}; + assert_throws(new TypeError(), () => table.set(0, fn)); + assert_equal_to_array(table, [null]); +}, "Setting non-wasm arrow function"); + +const outOfRangeValues = [ + undefined, + NaN, + Infinity, + -Infinity, + -1, + 0x100000000, + 0x1000000000, + "0x100000000", + { valueOf() { return 0x100000000; } }, +]; + +for (const value of outOfRangeValues) { + test(() => { + const argument = { "element": "anyfunc", "initial": 1 }; + const table = new WebAssembly.Table(argument); + assert_throws(new TypeError(), () => table.get(value)); + }, `Getting out-of-range argument: ${format_value(value)}`); + + test(() => { + const argument = { "element": "anyfunc", "initial": 1 }; + const table = new WebAssembly.Table(argument); + assert_throws(new TypeError(), () => table.set(value, null)); + }, `Setting out-of-range argument: ${format_value(value)}`); +} + +test(() => { + const argument = { "element": "anyfunc", "initial": 1 }; + const table = new WebAssembly.Table(argument); + let called = 0; + const value = { + valueOf() { + called++; + return 0; + }, + }; + assert_throws(new TypeError(), () => table.set(value, {})); + assert_equals(called, 1); +}, "Order of argument conversion"); + diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/table/grow.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/table/grow.any.js new file mode 100644 index 00000000000..d3efb511e4b --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/jsapi/table/grow.any.js @@ -0,0 +1,86 @@ +// META: global=jsshell +// META: script=assertions.js + +function nulls(n) { + return Array(n).fill(null); +} + +test(() => { + const argument = { "element": "anyfunc", "initial": 5 }; + const table = new WebAssembly.Table(argument); + assert_throws(new TypeError(), () => table.grow()); +}, "Missing arguments"); + +test(t => { + const thisValues = [ + undefined, + null, + true, + "", + Symbol(), + 1, + {}, + WebAssembly.Table, + WebAssembly.Table.prototype, + ]; + + const argument = { + valueOf: t.unreached_func("Should not touch the argument (valueOf)"), + toString: t.unreached_func("Should not touch the argument (toString)"), + }; + + const fn = WebAssembly.Table.prototype.grow; + + for (const thisValue of thisValues) { + assert_throws(new TypeError(), () => fn.call(thisValue, argument), `this=${format_value(thisValue)}`); + } +}, "Branding"); + +test(() => { + const argument = { "element": "anyfunc", "initial": 5 }; + const table = new WebAssembly.Table(argument); + assert_equal_to_array(table, nulls(5), "before"); + + const result = table.grow(3); + assert_equals(result, 5); + assert_equal_to_array(table, nulls(8), "after"); +}, "Basic"); + +test(() => { + const argument = { "element": "anyfunc", "initial": 3, "maximum": 5 }; + const table = new WebAssembly.Table(argument); + assert_equal_to_array(table, nulls(3), "before"); + + const result = table.grow(2); + assert_equals(result, 3); + assert_equal_to_array(table, nulls(5), "after"); +}, "Reached maximum"); + +test(() => { + const argument = { "element": "anyfunc", "initial": 2, "maximum": 5 }; + const table = new WebAssembly.Table(argument); + assert_equal_to_array(table, nulls(2), "before"); + + assert_throws(new RangeError(), () => table.grow(4)); + assert_equal_to_array(table, nulls(2), "after"); +}, "Exceeded maximum"); + +const outOfRangeValues = [ + undefined, + NaN, + Infinity, + -Infinity, + -1, + 0x100000000, + 0x1000000000, + "0x100000000", + { valueOf() { return 0x100000000; } }, +]; + +for (const value of outOfRangeValues) { + test(() => { + const argument = { "element": "anyfunc", "initial": 1 }; + const table = new WebAssembly.Table(argument); + assert_throws(new TypeError(), () => table.grow(value)); + }, `Out-of-range argument: ${format_value(value)}`); +} diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/table/length.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/table/length.any.js new file mode 100644 index 00000000000..a6a9661dbad --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/jsapi/table/length.any.js @@ -0,0 +1,46 @@ +// META: global=jsshell + +test(() => { + const thisValues = [ + undefined, + null, + true, + "", + Symbol(), + 1, + {}, + WebAssembly.Table, + WebAssembly.Table.prototype, + ]; + + const desc = Object.getOwnPropertyDescriptor(WebAssembly.Table.prototype, "length"); + assert_equals(typeof desc, "object"); + + const getter = desc.get; + assert_equals(typeof getter, "function"); + + assert_equals(typeof desc.set, "undefined"); + + for (const thisValue of thisValues) { + assert_throws(new TypeError(), () => getter.call(thisValue), `this=${format_value(thisValue)}`); + } +}, "Branding"); + +test(() => { + const argument = { "element": "anyfunc", "initial": 2 }; + const table = new WebAssembly.Table(argument); + assert_equals(table.length, 2, "Initial length"); + table.length = 4; + assert_equals(table.length, 2, "Should not change the length"); +}, "Setting (sloppy mode)"); + +test(() => { + const argument = { "element": "anyfunc", "initial": 2 }; + const table = new WebAssembly.Table(argument); + assert_equals(table.length, 2, "Initial length"); + assert_throws(new TypeError(), () => { + "use strict"; + table.length = 4; + }); + assert_equals(table.length, 2, "Should not change the length"); +}, "Setting (strict mode)"); diff --git a/tests/wpt/web-platform-tests/wasm/jsapi/table/toString.any.js b/tests/wpt/web-platform-tests/wasm/jsapi/table/toString.any.js new file mode 100644 index 00000000000..e576477910a --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/jsapi/table/toString.any.js @@ -0,0 +1,7 @@ +// META: global=jsshell + +test(() => { + const argument = { "element": "anyfunc", "initial": 0 }; + const table = new WebAssembly.Table(argument); + assert_class_string(table, "WebAssembly.Table"); +}, "Object.prototype.toString on an Table"); diff --git a/tests/wpt/web-platform-tests/wasm/resources/frame.html b/tests/wpt/web-platform-tests/wasm/resources/frame.html deleted file mode 100644 index d1c83e114a0..00000000000 --- a/tests/wpt/web-platform-tests/wasm/resources/frame.html +++ /dev/null @@ -1,18 +0,0 @@ - diff --git a/tests/wpt/web-platform-tests/wasm/resources/service-worker.js b/tests/wpt/web-platform-tests/wasm/resources/service-worker.js deleted file mode 100644 index 684eaf64878..00000000000 --- a/tests/wpt/web-platform-tests/wasm/resources/service-worker.js +++ /dev/null @@ -1,30 +0,0 @@ -var port; - -importScripts('load_wasm.js'); - -self.onmessage = function(e) { - var message = e.data; - if ('port' in message) { - port = message.port; - } -}; - -// And an event listener: -self.addEventListener('message', function(e) { - var message = e.data; - if ("compile" in message) { - createWasmModule() - .then(m => { - try { - port.postMessage({type:"OK", module:m}); - } catch (e) { - port.postMessage({type:"SEND ERROR"}); - } - }) - .catch(e => port.postMessage({type:"OTHER ERROR"})); - } -}); - -self.addEventListener('messageerror', function(e) { - port.postMessage({type:"RECEIVE ERROR"}); -}); diff --git a/tests/wpt/web-platform-tests/wasm/serialization/broadcastchannel-success-and-failure.html b/tests/wpt/web-platform-tests/wasm/serialization/broadcastchannel-success-and-failure.html new file mode 100644 index 00000000000..0d11cc595be --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/broadcastchannel-success-and-failure.html @@ -0,0 +1,38 @@ + + +WebAssembly.Module cannot cross agent clusters, BroadcastChannel edition + + + + diff --git a/tests/wpt/web-platform-tests/wasm/serialization/broadcastchannel-success.html b/tests/wpt/web-platform-tests/wasm/serialization/broadcastchannel-success.html new file mode 100644 index 00000000000..cd5f8d0b56a --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/broadcastchannel-success.html @@ -0,0 +1,59 @@ + + + +Structured cloning of WebAssembly.Module: BroadcastChannel within the same agent cluster + + + + +
                  + + diff --git a/tests/wpt/web-platform-tests/wasm/serialization/identity-not-preserved.html b/tests/wpt/web-platform-tests/wasm/serialization/identity-not-preserved.html new file mode 100644 index 00000000000..24bb3b16d8c --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/identity-not-preserved.html @@ -0,0 +1,66 @@ + + + +WebAssembly.Modules, when cloned, do not give back the same object + + + + +
                  + + diff --git a/tests/wpt/web-platform-tests/wasm/resources/incrementer.wasm b/tests/wpt/web-platform-tests/wasm/serialization/incrementer.wasm similarity index 100% rename from tests/wpt/web-platform-tests/wasm/resources/incrementer.wasm rename to tests/wpt/web-platform-tests/wasm/serialization/incrementer.wasm diff --git a/tests/wpt/web-platform-tests/wasm/serialization/nested-worker-success.any.js b/tests/wpt/web-platform-tests/wasm/serialization/nested-worker-success.any.js new file mode 100644 index 00000000000..5388ebcc39b --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/nested-worker-success.any.js @@ -0,0 +1,9 @@ +// META: global=!default,dedicatedworker,sharedworker +// META: script=resources/test-incrementer.js +"use strict"; + +promise_test(t => { + const worker = new Worker("resources/incrementer-worker.js"); + + return testSharingViaIncrementerScript(t, worker, "parent worker", worker, "sub-worker"); +}, "postMessaging to a dedicated sub-worker allows them to see each others' modifications"); diff --git a/tests/wpt/web-platform-tests/wasm/serialization/no-transferring.html b/tests/wpt/web-platform-tests/wasm/serialization/no-transferring.html new file mode 100644 index 00000000000..a0bf11f01dd --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/no-transferring.html @@ -0,0 +1,31 @@ + + + +WebAssembly.Modules cannot be transferred + + + + + diff --git a/tests/wpt/web-platform-tests/wasm/resources/blank.html b/tests/wpt/web-platform-tests/wasm/serialization/resources/blank.html similarity index 100% rename from tests/wpt/web-platform-tests/wasm/resources/blank.html rename to tests/wpt/web-platform-tests/wasm/serialization/resources/blank.html diff --git a/tests/wpt/web-platform-tests/wasm/serialization/resources/broadcastchannel-iframe.html b/tests/wpt/web-platform-tests/wasm/serialization/resources/broadcastchannel-iframe.html new file mode 100644 index 00000000000..83e347b5cb3 --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/resources/broadcastchannel-iframe.html @@ -0,0 +1,20 @@ + + +A test page that uses a given WebAssembly.Module sent from a BroadcastChannel + + diff --git a/tests/wpt/web-platform-tests/wasm/serialization/resources/broadcastchannel-sharedworker.js b/tests/wpt/web-platform-tests/wasm/serialization/resources/broadcastchannel-sharedworker.js new file mode 100644 index 00000000000..310e0e93584 --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/resources/broadcastchannel-sharedworker.js @@ -0,0 +1,7 @@ +const channel = new BroadcastChannel("anne was here"); +channel.onmessageerror = ({ data }) => { + if(data === null) { + channel.postMessage("sw-success"); + } +} +channel.postMessage("hi"); diff --git a/tests/wpt/web-platform-tests/wasm/serialization/resources/broadcastchannel-worker.js b/tests/wpt/web-platform-tests/wasm/serialization/resources/broadcastchannel-worker.js new file mode 100644 index 00000000000..76a81770604 --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/resources/broadcastchannel-worker.js @@ -0,0 +1,9 @@ +const channel = new BroadcastChannel("anne was here"); +channel.onmessage = ({ data }) => { + if(data === "hi" || data === "sw-success") { + return; + } else if(data instanceof WebAssembly.Module) { + channel.postMessage("dw-success"); + } +} +channel.postMessage("hi"); diff --git a/tests/wpt/web-platform-tests/wasm/serialization/resources/create-empty-wasm-module.js b/tests/wpt/web-platform-tests/wasm/serialization/resources/create-empty-wasm-module.js new file mode 100644 index 00000000000..7326710c9e4 --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/resources/create-empty-wasm-module.js @@ -0,0 +1,4 @@ +function createEmptyWasmModule() { + return new WebAssembly.Module( + new Uint8Array([0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00])); +} diff --git a/tests/wpt/web-platform-tests/wasm/serialization/resources/echo-iframe.html b/tests/wpt/web-platform-tests/wasm/serialization/resources/echo-iframe.html new file mode 100644 index 00000000000..c4fd5824a1c --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/resources/echo-iframe.html @@ -0,0 +1,11 @@ + + +A test page that echos back anything postMessaged to it to its parent + + diff --git a/tests/wpt/web-platform-tests/wasm/serialization/resources/echo-worker.js b/tests/wpt/web-platform-tests/wasm/serialization/resources/echo-worker.js new file mode 100644 index 00000000000..cbbde8a73c8 --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/resources/echo-worker.js @@ -0,0 +1,5 @@ +"use strict"; + +self.onmessage = ({ data }) => { + self.postMessage(data); +}; diff --git a/tests/wpt/web-platform-tests/wasm/serialization/resources/incrementer-iframe-domain.sub.html b/tests/wpt/web-platform-tests/wasm/serialization/resources/incrementer-iframe-domain.sub.html new file mode 100644 index 00000000000..d2d18de4995 --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/resources/incrementer-iframe-domain.sub.html @@ -0,0 +1,12 @@ + + +A test page that is sent a WebAssembly Module + + + + diff --git a/tests/wpt/web-platform-tests/wasm/serialization/resources/incrementer-iframe.html b/tests/wpt/web-platform-tests/wasm/serialization/resources/incrementer-iframe.html new file mode 100644 index 00000000000..5c8bc0735e2 --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/resources/incrementer-iframe.html @@ -0,0 +1,11 @@ + + +A test page that is sent a WebAssembly Module + + + + diff --git a/tests/wpt/web-platform-tests/wasm/serialization/resources/incrementer-popup.html b/tests/wpt/web-platform-tests/wasm/serialization/resources/incrementer-popup.html new file mode 100644 index 00000000000..660e472b27c --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/resources/incrementer-popup.html @@ -0,0 +1,11 @@ + + +A test page that is sent a WebAssembly Module + + + + diff --git a/tests/wpt/web-platform-tests/wasm/serialization/resources/incrementer-worker-with-channel.js b/tests/wpt/web-platform-tests/wasm/serialization/resources/incrementer-worker-with-channel.js new file mode 100644 index 00000000000..0323b3e52e7 --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/resources/incrementer-worker-with-channel.js @@ -0,0 +1,8 @@ +"use strict"; +importScripts("/resources/testharness.js"); +importScripts("./test-incrementer.js"); + +self.onmessage = ({ data }) => { + // data will be a MessagePort + setupDestinationIncrementer(data, data); +}; diff --git a/tests/wpt/web-platform-tests/wasm/serialization/resources/incrementer-worker.js b/tests/wpt/web-platform-tests/wasm/serialization/resources/incrementer-worker.js new file mode 100644 index 00000000000..1779ceea520 --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/resources/incrementer-worker.js @@ -0,0 +1,5 @@ +"use strict"; +importScripts("/resources/testharness.js"); +importScripts("./test-incrementer.js"); + +setupDestinationIncrementer(self, self); diff --git a/tests/wpt/web-platform-tests/wasm/serialization/resources/incrementer.wasm b/tests/wpt/web-platform-tests/wasm/serialization/resources/incrementer.wasm new file mode 100644 index 00000000000..47afcdef2a2 Binary files /dev/null and b/tests/wpt/web-platform-tests/wasm/serialization/resources/incrementer.wasm differ diff --git a/tests/wpt/web-platform-tests/wasm/serialization/resources/nested-iframe-1.html b/tests/wpt/web-platform-tests/wasm/serialization/resources/nested-iframe-1.html new file mode 100644 index 00000000000..fe93cc0c4b0 --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/resources/nested-iframe-1.html @@ -0,0 +1,5 @@ + + +Nesting level 1 + + diff --git a/tests/wpt/web-platform-tests/wasm/serialization/resources/nested-iframe-2.html b/tests/wpt/web-platform-tests/wasm/serialization/resources/nested-iframe-2.html new file mode 100644 index 00000000000..fad52ce9de3 --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/resources/nested-iframe-2.html @@ -0,0 +1,5 @@ + + +Nesting level 2 + + diff --git a/tests/wpt/web-platform-tests/wasm/serialization/resources/nested-iframe-3.html b/tests/wpt/web-platform-tests/wasm/serialization/resources/nested-iframe-3.html new file mode 100644 index 00000000000..7971022b2cd --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/resources/nested-iframe-3.html @@ -0,0 +1,5 @@ + + +Nesting level 3 + + diff --git a/tests/wpt/web-platform-tests/wasm/serialization/resources/nested-iframe-4-incrementer.html b/tests/wpt/web-platform-tests/wasm/serialization/resources/nested-iframe-4-incrementer.html new file mode 100644 index 00000000000..f419f4bc36c --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/resources/nested-iframe-4-incrementer.html @@ -0,0 +1,11 @@ + + +A test page that is sent a WebAssembly Module, nested 4 levels deep in iframes + + + + diff --git a/tests/wpt/web-platform-tests/wasm/serialization/resources/serviceworker-failure.js b/tests/wpt/web-platform-tests/wasm/serialization/resources/serviceworker-failure.js new file mode 100644 index 00000000000..39796f9d94a --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/resources/serviceworker-failure.js @@ -0,0 +1,34 @@ +// Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/. +"use strict"; +self.importScripts("/resources/testharness.js"); +self.importScripts("./create-empty-wasm-module.js"); + +let state = "start in worker"; + +self.onmessage = e => { + if (e.data === "start in window") { + assert_equals(state, "start in worker"); + e.source.postMessage(state); + state = "we are expecting a messageerror due to the window sending us a WebAssembly.Module"; + } else if (e.data === "we are expecting a messageerror due to the worker sending us a WebAssembly.Module") { + assert_equals(state, "onmessageerror was received in worker"); + e.source.postMessage(createEmptyWasmModule()); + state = "done in worker"; + } else { + e.source.postMessage(`worker onmessage was reached when in state "${state}" and data ${e.data}`); + } +}; + +self.onmessageerror = e => { + if (state === "we are expecting a messageerror due to the window sending us a WebAssembly.Module") { + assert_equals(e.data, null, "data"); + assert_equals(e.origin, self.origin, "origin"); + assert_not_equals(e.source, null, "source"); + assert_equals(e.ports.length, 0, "ports length"); + + state = "onmessageerror was received in worker"; + e.source.postMessage(state); + } else { + e.source.postMessage(`worker onmessageerror was reached when in state "${state}" and data ${e.data}`); + } +}; diff --git a/tests/wpt/web-platform-tests/wasm/serialization/resources/sharedworker-failure.js b/tests/wpt/web-platform-tests/wasm/serialization/resources/sharedworker-failure.js new file mode 100644 index 00000000000..854c70b9e84 --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/resources/sharedworker-failure.js @@ -0,0 +1,21 @@ +importScripts("./test-incrementer.js"); +importScripts("./create-empty-wasm-module.js"); + +let state = "send-sw-failure" +onconnect = initialE => { + let port = initialE.source; + port.postMessage(state) + port.onmessage = e => { + if(state === "" && e.data === "send-window-failure") { + port.postMessage(createEmptyWasmModule()) + } else { + port.postMessage("failure") + } + } + port.onmessageerror = e => { + if(state === "send-sw-failure") { + port.postMessage("send-sw-failure-success") + state = "" + } + } +} diff --git a/tests/wpt/web-platform-tests/wasm/serialization/resources/test-incrementer.js b/tests/wpt/web-platform-tests/wasm/serialization/resources/test-incrementer.js new file mode 100644 index 00000000000..65cb33227a3 --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/resources/test-incrementer.js @@ -0,0 +1,57 @@ +// Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/. +// +// This file is simplified from the one there, because it only tests that the +// module can be passed and that functions can be run. The SharedArrayBuffer +// version also tests that the memory is shared between the agents. + +"use strict"; + +function createWasmModule() { + return fetch('incrementer.wasm') + .then(response => { + if (!response.ok) + throw new Error(response.statusText); + return response.arrayBuffer(); + }) + .then(WebAssembly.compile); +} + +function testModule(module) { + let instance = new WebAssembly.Instance(module); + let increment = instance.exports["increment"]; + assert_equals(typeof increment, "function", `The type of the increment export should be "function", got ${typeof increment}`); + let result = increment(42); + assert_equals(result, 43, `increment(42) should be 43, got ${result}`); +} + +self.testSharingViaIncrementerScript = (t, whereToListen, whereToListenLabel, whereToSend, whereToSendLabel, origin) => { + return createWasmModule().then(module => { + return new Promise(resolve => { + + whereToListen.onmessage = t.step_func(({ data }) => { + switch (data.message) { + case "module received": { + testModule(data.module); + resolve(); + break; + } + } + }); + + whereToSend.postMessage({ message: "send module", module }, origin); + }); + }); +}; + +self.setupDestinationIncrementer = (whereToListen, whereToSendBackTo, origin) => { + whereToListen.onmessage = ({ data }) => { + switch (data.message) { + case "send module": { + let module = data.module; + testModule(data.module); + whereToSendBackTo.postMessage({ message: "module received", module }, origin); + break; + } + } + }; +}; diff --git a/tests/wpt/web-platform-tests/wasm/serialization/serialization-via-history.html b/tests/wpt/web-platform-tests/wasm/serialization/serialization-via-history.html new file mode 100644 index 00000000000..35dc17b6701 --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/serialization-via-history.html @@ -0,0 +1,34 @@ + + + +WebAssembly.Module cloning via history's methods invoking StructuredSerializeForStorage + + + + + diff --git a/tests/wpt/web-platform-tests/wasm/serialization/serialization-via-idb.any.js b/tests/wpt/web-platform-tests/wasm/serialization/serialization-via-idb.any.js new file mode 100644 index 00000000000..1d861c3d3aa --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/serialization-via-idb.any.js @@ -0,0 +1,45 @@ +// META: script=/IndexedDB/support.js +"use strict"; + +function createEmptyWasmModule() { + return new WebAssembly.Module( + new Uint8Array([0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00])); +} + +async_test(t => { + const openReq = createdb(t); + + openReq.onupgradeneeded = e => { + const db = e.target.result; + const store = db.createObjectStore("store", { keyPath: "key" }); + + assert_throws("DataCloneError", () => { + store.put({ key: 1, property: createEmptyWasmModule() }); + }); + t.done(); + }; +}, "WebAssembly.Module cloning via IndexedDB: basic case"); + +async_test(t => { + const openReq = createdb(t); + + openReq.onupgradeneeded = e => { + const db = e.target.result; + const store = db.createObjectStore("store", { keyPath: "key" }); + + let getter1Called = false; + let getter2Called = false; + + assert_throws("DataCloneError", () => { + store.put({ key: 1, property: [ + { get x() { getter1Called = true; return 5; } }, + createEmptyWasmModule(), + { get x() { getter2Called = true; return 5; } } + ]}); + }); + + assert_true(getter1Called, "The getter before the WebAssembly.Module must have been called"); + assert_false(getter2Called, "The getter after the WebAssembly.Module must not have been called"); + t.done(); + }; +}, "WebAssembly.Module cloning via the IndexedDB: is interleaved correctly"); diff --git a/tests/wpt/web-platform-tests/wasm/serialization/serialization-via-notifications-api.any.js b/tests/wpt/web-platform-tests/wasm/serialization/serialization-via-notifications-api.any.js new file mode 100644 index 00000000000..84105651d3b --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/serialization-via-notifications-api.any.js @@ -0,0 +1,28 @@ +"use strict"; + +function createEmptyWasmModule() { + return new WebAssembly.Module( + new Uint8Array([0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00])); +} + +test(() => { + assert_throws("DataCloneError", () => { + new Notification("Bob: Hi", { data: createEmptyWasmModule() }); + }) +}, "WebAssembly.Module cloning via the Notifications API's data member: basic case"); + +test(() => { + let getter1Called = false; + let getter2Called = false; + + assert_throws("DataCloneError", () => { + new Notification("Bob: Hi", { data: [ + { get x() { getter1Called = true; return 5; } }, + createEmptyWasmModule(), + { get x() { getter2Called = true; return 5; } } + ]}); + }); + + assert_true(getter1Called, "The getter before the SAB must have been called"); + assert_false(getter2Called, "The getter after the SAB must not have been called"); +}, "WebAssembly.Module cloning via the Notifications API's data member: is interleaved correctly"); diff --git a/tests/wpt/web-platform-tests/wasm/serialization/window-domain-success.sub.html b/tests/wpt/web-platform-tests/wasm/serialization/window-domain-success.sub.html new file mode 100644 index 00000000000..51d4c5cb0ea --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/window-domain-success.sub.html @@ -0,0 +1,26 @@ + + + +Structured cloning of WebAssembly.Module into same-origin-domain windows + + + + +
                  + + diff --git a/tests/wpt/web-platform-tests/wasm/serialization/window-messagechannel-success.html b/tests/wpt/web-platform-tests/wasm/serialization/window-messagechannel-success.html new file mode 100644 index 00000000000..e686c811356 --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/window-messagechannel-success.html @@ -0,0 +1,21 @@ + + + +Structured cloning of WebAssembly.Module using MessageChannel + + + + +
                  + + diff --git a/tests/wpt/web-platform-tests/wasm/serialization/window-serviceworker-failure.https.html b/tests/wpt/web-platform-tests/wasm/serialization/window-serviceworker-failure.https.html new file mode 100644 index 00000000000..97c5a1decdb --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/window-serviceworker-failure.https.html @@ -0,0 +1,54 @@ + + + +WebAssembly.Module cannot cross agent clusters, service worker edition + + + + + + diff --git a/tests/wpt/web-platform-tests/wasm/serialization/window-sharedworker-failure.html b/tests/wpt/web-platform-tests/wasm/serialization/window-sharedworker-failure.html new file mode 100644 index 00000000000..667e985a30b --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/window-sharedworker-failure.html @@ -0,0 +1,33 @@ + + +WebAssembly.Modules cannot cross agent clusters, shared worker edition + + + + diff --git a/tests/wpt/web-platform-tests/wasm/serialization/window-similar-but-cross-origin-success.sub.html b/tests/wpt/web-platform-tests/wasm/serialization/window-similar-but-cross-origin-success.sub.html new file mode 100644 index 00000000000..070cf0a49a8 --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/window-similar-but-cross-origin-success.sub.html @@ -0,0 +1,25 @@ + + + +Structured cloning of WebAssembly.Module to similar-origin, but not same-origin, windows + + + + +
                  + + diff --git a/tests/wpt/web-platform-tests/wasm/serialization/window-simple-success.html b/tests/wpt/web-platform-tests/wasm/serialization/window-simple-success.html new file mode 100644 index 00000000000..6f2ccf465e9 --- /dev/null +++ b/tests/wpt/web-platform-tests/wasm/serialization/window-simple-success.html @@ -0,0 +1,57 @@ + + + +Structured cloning of WebAssembly.Module: simple success cases that don't need dedicated files + + + + +
                  + + diff --git a/tests/wpt/web-platform-tests/wasm/wasm_local_iframe_test.html b/tests/wpt/web-platform-tests/wasm/wasm_local_iframe_test.html deleted file mode 100644 index 0f4fbd0c719..00000000000 --- a/tests/wpt/web-platform-tests/wasm/wasm_local_iframe_test.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - diff --git a/tests/wpt/web-platform-tests/wasm/wasm_serialization_tests.html b/tests/wpt/web-platform-tests/wasm/wasm_serialization_tests.html deleted file mode 100644 index 49766c77052..00000000000 --- a/tests/wpt/web-platform-tests/wasm/wasm_serialization_tests.html +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/tests/wpt/web-platform-tests/wasm/wasm_serialization_tests.js b/tests/wpt/web-platform-tests/wasm/wasm_serialization_tests.js deleted file mode 100644 index 3cc4166168b..00000000000 --- a/tests/wpt/web-platform-tests/wasm/wasm_serialization_tests.js +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -function TestInstantiateInWorker() { - return createWasmModule() - .then((mod) => { - var worker = new Worker("wasm_serialization_worker.js"); - return new Promise((resolve, reject) => { - worker.postMessage(mod); - worker.onmessage = function(event) { - resolve(event.data); - } - }); - }) - .then(data => assert_equals(data, 43)) - .catch(error => assert_unreached(error)); -} diff --git a/tests/wpt/web-platform-tests/wasm/wasm_serialization_worker.js b/tests/wpt/web-platform-tests/wasm/wasm_serialization_worker.js deleted file mode 100644 index 3361ed73951..00000000000 --- a/tests/wpt/web-platform-tests/wasm/wasm_serialization_worker.js +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -onmessage = function(e) { - var compiled_module = e.data; - var instance = new WebAssembly.Instance(compiled_module); - if (instance === undefined) { - postMessage("error!"); - return; - } - var entrypoint = instance.exports["increment"]; - - if (typeof entrypoint !== "function") { - postMessage("error!"); - return; - } - - var ret = entrypoint(42); - postMessage(ret); -} diff --git a/tests/wpt/web-platform-tests/wasm/wasm_service_worker_test.https.html b/tests/wpt/web-platform-tests/wasm/wasm_service_worker_test.https.html deleted file mode 100644 index cced4b8f6ec..00000000000 --- a/tests/wpt/web-platform-tests/wasm/wasm_service_worker_test.https.html +++ /dev/null @@ -1,23 +0,0 @@ - -Service Worker: postMessage with wasm - - - - - diff --git a/tests/wpt/web-platform-tests/web-animations/animation-model/animation-types/property-list.js b/tests/wpt/web-platform-tests/web-animations/animation-model/animation-types/property-list.js index 8d027178351..e2f3adcd7af 100644 --- a/tests/wpt/web-platform-tests/web-animations/animation-model/animation-types/property-list.js +++ b/tests/wpt/web-platform-tests/web-animations/animation-model/animation-types/property-list.js @@ -361,13 +361,13 @@ const gCSSProperties = { 'color-interpolation': { // https://svgwg.org/svg2-draft/painting.html#ColorInterpolationProperty types: [ - { type: 'discrete', options: [ [ 'linearRGB', 'auto' ] ] } + { type: 'discrete', options: [ [ 'linearrgb', 'auto' ] ] } ] }, 'color-interpolation-filters': { // https://drafts.fxtf.org/filters-1/#propdef-color-interpolation-filters types: [ - { type: 'discrete', options: [ [ 'sRGB', 'linearRGB' ] ] } + { type: 'discrete', options: [ [ 'srgb', 'linearrgb' ] ] } ] }, 'column-count': { diff --git a/tests/wpt/web-platform-tests/web-animations/animation-model/animation-types/property-types.js b/tests/wpt/web-platform-tests/web-animations/animation-model/animation-types/property-types.js index 5bafb20dfcf..232a508e07c 100644 --- a/tests/wpt/web-platform-tests/web-animations/animation-model/animation-types/property-types.js +++ b/tests/wpt/web-platform-tests/web-animations/animation-model/animation-types/property-types.js @@ -1068,6 +1068,23 @@ const transformListType = { { time: 500, expected: [ 1, 1, 1, 1, 100, 100 ] }, { time: 1000, expected: [ 1, 1, 1, 1, 100, 100 ] }]); }, `${property}: non-invertible matrices in mismatched transform lists`); + + test(t => { + const idlName = propertyToIDL(property); + const target = createTestElement(t, setup); + const animation = target.animate( + { + [idlName]: ['perspective(0)', 'perspective(10px)'], + }, + 1000 + ); + testAnimationSampleMatrices(animation, idlName, + [{ time: 500, expected: [ 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, -0.05, + 0, 0, 0, 1 ] }]); + }, `${property}: perspective`); + }, testAddition: function(property, setup) { diff --git a/tests/wpt/web-platform-tests/webaudio/resources/audionodeoptions.js b/tests/wpt/web-platform-tests/webaudio/resources/audionodeoptions.js index 0d90a9c6300..df0090c6d60 100644 --- a/tests/wpt/web-platform-tests/webaudio/resources/audionodeoptions.js +++ b/tests/wpt/web-platform-tests/webaudio/resources/audionodeoptions.js @@ -40,19 +40,19 @@ function testAudioNodeOptions(should, context, nodeName, expectedNodeOptions) { {channelCount: testChannelCount})); }, 'new ' + nodeName + '(c, {channelCount: ' + testChannelCount + '}}') - .throw(expectedNodeOptions.channelCount.errorType || TypeError); + .throw(DOMException, + expectedNodeOptions.channelCount.exceptionType); } else { // The channel count is not fixed. Try to set the count to invalid // values and make sure an error is thrown. - let errorType = 'NotSupportedError'; - [0, 99].forEach(testValue => { should(() => { node = new window[nodeName]( context, Object.assign({}, expectedNodeOptions.additionalOptions, { channelCount: testValue })); - }, `new ${nodeName}(c, {channelCount: ${testValue}})`).throw(errorType); + }, `new ${nodeName}(c, {channelCount: ${testValue}})`) + .throw(DOMException, 'NotSupportedError'); }); } @@ -88,7 +88,8 @@ function testAudioNodeOptions(should, context, nodeName, expectedNodeOptions) { {channelCountMode: testValue})); }, `new ${nodeName}(c, {channelCountMode: "${testValue}"})`) - .throw(expectedNodeOptions.channelCountMode.errorType); + .throw(DOMException, + expectedNodeOptions.channelCountMode.exceptionType); } }); } else { @@ -140,7 +141,8 @@ function testAudioNodeOptions(should, context, nodeName, expectedNodeOptions) { {channelInterpretation: testValue})); }, `new ${nodeName}(c, {channelInterpretation: "${testValue}"})`) - .throw(expectedNodeOptions.channelInterpretation.errorType); + .throw(DOMException, + expectedNodeOptions.channelCountMode.exceptionType); } }); } else { diff --git a/tests/wpt/web-platform-tests/webaudio/resources/audit.js b/tests/wpt/web-platform-tests/webaudio/resources/audit.js index 7ffa4392b05..b7ca0201610 100644 --- a/tests/wpt/web-platform-tests/webaudio/resources/audit.js +++ b/tests/wpt/web-platform-tests/webaudio/resources/audit.js @@ -274,21 +274,25 @@ window.Audit = (function() { /** * Check if |actual| operation wrapped in a function throws an exception - * with a expected error type correctly. |expected| is optional. If it is a - * String, then it is considered to be the name of a DOMException. It can - * also be an instance of either an Error or a DOMException, to be more - * strict about the actual error type. + * with a expected error type correctly. |expected| is optional. If it is an + * instance of DOMException, then the description (second argument) can be + * provided to be more strict about the expected exception type. |expected| + * also can be other generic error types such as TypeError, RangeError or + * etc. * * @example * should(() => { let a = b; }, 'A bad code').throw(); - * should(() => { let c = d; }, 'Assigning d to c.') - * .throw('ReferenceError'); - * should(() => { let e = f; }, 'Assigning e to f.') - * .throw('ReferenceError', { omitErrorMessage: true }); + * should(() => { new SomeConstructor(); }, 'A bad construction') + * .throw(DOMException, 'NotSupportedError'); + * should(() => { let c = d; }, 'Assigning d to c') + * .throw(ReferenceError); + * should(() => { let e = f; }, 'Assigning e to f') + * .throw(ReferenceError, { omitErrorMessage: true }); * * @result * "PASS A bad code threw an exception of ReferenceError: b is not * defined." + * "PASS A bad construction threw DOMException:NotSupportedError." * "PASS Assigning d to c threw ReferenceError: d is not defined." * "PASS Assigning e to f threw ReferenceError: [error message * omitted]." @@ -313,17 +317,16 @@ window.Audit = (function() { // The expected error type was not given. didThrowCorrectly = true; passDetail = '${actual} threw ' + error.name + errorMessage + '.'; - } else if (typeof(this._expected) == "string" && - error instanceof DOMException && - error.name === this._expected) { - // A DOMException was thrown and expected, and the names match + } else if (this._expected === DOMException && + (this._expectedDescription === undefined || + this._expectedDescription === error.name)) { + // Handles DOMException with the associated name. didThrowCorrectly = true; passDetail = '${actual} threw ${expected}' + errorMessage + '.'; - } else if (this._expected == error.constructor && - this._expected.name == error.name) { - // The expected error type and names match the actual one. + } else if (this._expected == error.constructor) { + // Handler other error types. didThrowCorrectly = true; - passDetail = '${actual} threw ${expected}' + errorMessage + '.'; + passDetail = '${actual} threw ' + error.name + errorMessage + '.'; } else { didThrowCorrectly = false; failDetail = diff --git a/tests/wpt/web-platform-tests/webaudio/resources/start-stop-exceptions.js b/tests/wpt/web-platform-tests/webaudio/resources/start-stop-exceptions.js index 9a77e67ed86..0d2ea12f6db 100644 --- a/tests/wpt/web-platform-tests/webaudio/resources/start-stop-exceptions.js +++ b/tests/wpt/web-platform-tests/webaudio/resources/start-stop-exceptions.js @@ -13,7 +13,7 @@ function testStartStop(should, node, options) { should(() => { node.stop(); - }, 'Calling stop() before start()').throw('InvalidStateError'); + }, 'Calling stop() before start()').throw(DOMException, 'InvalidStateError'); should(() => { node.start(-1); @@ -29,7 +29,7 @@ function testStartStop(should, node, options) { node.start(); should(() => { node.start(); - }, 'Calling start() twice').throw('InvalidStateError'); + }, 'Calling start() twice').throw(DOMException, 'InvalidStateError'); should(() => { node.stop(-1); }, 'stop(-1)').throw(RangeError); diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/ctor-analyser.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/ctor-analyser.html index 2112edeeffc..4e27f842dde 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/ctor-analyser.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/ctor-analyser.html @@ -91,25 +91,25 @@ node = new AnalyserNode(context, {fftSize: 33}); }, 'node = new AnalyserNode(c, { fftSize: 33 })') - .throw('IndexSizeError'); + .throw(DOMException, 'IndexSizeError'); should( () => { node = new AnalyserNode(context, {maxDecibels: -500}); }, 'node = new AnalyserNode(c, { maxDecibels: -500 })') - .throw('IndexSizeError'); + .throw(DOMException, 'IndexSizeError'); should( () => { node = new AnalyserNode(context, {minDecibels: -10}); }, 'node = new AnalyserNode(c, { minDecibels: -10 })') - .throw('IndexSizeError'); + .throw(DOMException, 'IndexSizeError'); should( () => { node = new AnalyserNode(context, {smoothingTimeConstant: 2}); }, 'node = new AnalyserNode(c, { smoothingTimeConstant: 2 })') - .throw('IndexSizeError'); + .throw(DOMException, 'IndexSizeError'); should(function() { node = new AnalyserNode(context, {frequencyBinCount: 33}); }, 'node = new AnalyserNode(c, { frequencyBinCount: 33 })').notThrow(); @@ -164,7 +164,7 @@ node = new AnalyserNode(context, options); }, 'node = new AnalyserNode(c, ' + JSON.stringify(options) + ')') - .throw('IndexSizeError'); + .throw(DOMException, 'IndexSizeError'); options = {minDecibels: -10, maxDecibels: -150}; should( @@ -172,7 +172,7 @@ node = new AnalyserNode(context, options); }, 'node = new AnalyserNode(c, ' + JSON.stringify(options) + ')') - .throw('IndexSizeError'); + .throw(DOMException, 'IndexSizeError'); task.done(); }); diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-sizing.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-sizing.html index b3de37f119f..7ee6a2237ed 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-sizing.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-sizing.html @@ -22,7 +22,7 @@ }; if (illegal) { - should(tester, message).throw('IndexSizeError'); + should(tester, message).throw(DOMException, 'IndexSizeError'); } else { should(tester, message).notThrow(); } diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel.html index b71078d8f80..e0359953d2e 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel.html @@ -127,27 +127,27 @@ }, '2: buffer.copyFromChannel(context, 0)').throw(TypeError); should(() => { buffer.copyFromChannel(x, -1); - }, '3: buffer.copyFromChannel(x, -1)').throw('IndexSizeError'); + }, '3: buffer.copyFromChannel(x, -1)').throw(DOMException, 'IndexSizeError'); should( () => { buffer.copyFromChannel(x, numberOfChannels); }, '4: buffer.copyFromChannel(x, ' + numberOfChannels + ')') - .throw('IndexSizeError'); + .throw(DOMException, 'IndexSizeError'); ; should(() => { buffer.copyFromChannel(x, 0, -1); - }, '5: buffer.copyFromChannel(x, 0, -1)').throw('IndexSizeError'); + }, '5: buffer.copyFromChannel(x, 0, -1)').throw(DOMException, 'IndexSizeError'); should( () => { buffer.copyFromChannel(x, 0, bufferLength); }, '6: buffer.copyFromChannel(x, 0, ' + bufferLength + ')') - .throw('IndexSizeError'); + .throw(DOMException, 'IndexSizeError'); should(() => { buffer.copyFromChannel(x, 3); - }, '7: buffer.copyFromChannel(x, 3)').throw('IndexSizeError'); + }, '7: buffer.copyFromChannel(x, 3)').throw(DOMException, 'IndexSizeError'); if (window.SharedArrayBuffer) { let shared_buffer = new Float32Array(new SharedArrayBuffer(32)); @@ -183,26 +183,26 @@ }, '1: buffer.copyToChannel(context, 0)').throw(TypeError); should(() => { buffer.copyToChannel(x, -1); - }, '2: buffer.copyToChannel(x, -1)').throw('IndexSizeError'); + }, '2: buffer.copyToChannel(x, -1)').throw(DOMException, 'IndexSizeError'); should( () => { buffer.copyToChannel(x, numberOfChannels); }, '3: buffer.copyToChannel(x, ' + numberOfChannels + ')') - .throw('IndexSizeError'); + .throw(DOMException, 'IndexSizeError'); should(() => { buffer.copyToChannel(x, 0, -1); - }, '4: buffer.copyToChannel(x, 0, -1)').throw('IndexSizeError'); + }, '4: buffer.copyToChannel(x, 0, -1)').throw(DOMException, 'IndexSizeError'); should( () => { buffer.copyToChannel(x, 0, bufferLength); }, '5: buffer.copyToChannel(x, 0, ' + bufferLength + ')') - .throw('IndexSizeError'); + .throw(DOMException, 'IndexSizeError'); should(() => { buffer.copyToChannel(x, 3); - }, '6: buffer.copyToChannel(x, 3)').throw('IndexSizeError'); + }, '6: buffer.copyToChannel(x, 3)').throw(DOMException, 'IndexSizeError'); if (window.SharedArrayBuffer) { let shared_buffer = new Float32Array(new SharedArrayBuffer(32)); diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer.html index 07a34f07c18..a2c4581c4e8 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer.html @@ -53,7 +53,7 @@ buffer.getChannelData(buffer.numberOfChannels); }, 'buffer.getChannelData(' + buffer.numberOfChannels + ')') - .throw('IndexSizeError'); + .throw(DOMException, 'IndexSizeError'); let buffer2 = context.createBuffer(1, 1000, 24576); let expectedDuration = 1000 / 24576; diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/ctor-audiobuffer.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/ctor-audiobuffer.html index c5aae1ad532..9845d5eaba3 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/ctor-audiobuffer.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/ctor-audiobuffer.html @@ -96,7 +96,7 @@ let buffer = new AudioBuffer(options); }, 'new AudioBuffer(' + JSON.stringify(options) + ')') - .throw('NotSupportedError'); + .throw(DOMException, 'NotSupportedError'); options = {numberOfChannels: 99, length: 0, sampleRate: 16000}; should( @@ -104,7 +104,7 @@ let buffer = new AudioBuffer(options); }, 'new AudioBuffer(' + JSON.stringify(options) + ')') - .throw('NotSupportedError'); + .throw(DOMException, 'NotSupportedError'); options = {numberOfChannels: 1, length: 0, sampleRate: 16000}; should( @@ -112,7 +112,7 @@ let buffer = new AudioBuffer(options); }, 'new AudioBuffer(' + JSON.stringify(options) + ')') - .throw('NotSupportedError'); + .throw(DOMException, 'NotSupportedError'); options = {numberOfChannels: 1, length: 1, sampleRate: 100}; should( @@ -120,7 +120,7 @@ let buffer = new AudioBuffer(options); }, 'new AudioBuffer(' + JSON.stringify(options) + ')') - .throw('NotSupportedError'); + .throw(DOMException, 'NotSupportedError'); task.done(); }); @@ -178,7 +178,7 @@ buffer.getChannelData(options.numberOfChannels); }, 'buffer.getChannelData(' + options.numberOfChannels + ')') - .throw('IndexSizeError'); + .throw(DOMException, 'IndexSizeError'); task.done(); }); diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiobuffersource-channels.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiobuffersource-channels.html index 5527f44cc9c..f3f16c4c648 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiobuffersource-channels.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiobuffersource-channels.html @@ -47,7 +47,7 @@ should(function() { source.buffer = new AudioBuffer({length: 128, sampleRate: context.sampleRate}) - }, 'source.buffer = new buffer').throw('InvalidStateError'); + }, 'source.buffer = new buffer').throw(DOMException, 'InvalidStateError'); // The buffer has been set; it's ok to set it to null. should(function() { @@ -58,7 +58,7 @@ // again. should(function() { source.buffer = buffer; - }, 'source.buffer = buffer again').throw('InvalidStateError'); + }, 'source.buffer = buffer again').throw(DOMException, 'InvalidStateError'); // But setting to null is ok. should(function() { diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/buffer-resampling.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/buffer-resampling.html new file mode 100644 index 00000000000..c181ceb8e0f --- /dev/null +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/buffer-resampling.html @@ -0,0 +1,101 @@ + + + + Test Extrapolation at end of AudibBuffer in an AudioBufferSourceNode + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-connect-method-chaining.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-connect-method-chaining.html index 0a8c73160e5..4163a8439cd 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-connect-method-chaining.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-connect-method-chaining.html @@ -114,7 +114,7 @@ // does not have the second output, so it should throw. should(function() { gain1.connect(gain2, 1).connect(contextA.destination); - }, 'Connecting with an invalid output').throw('IndexSizeError'); + }, 'Connecting with an invalid output').throw(DOMException, 'IndexSizeError'); // Test if the second connection throws correctly. The contextB's // destination is not compatible with the nodes from contextA, thus the @@ -124,7 +124,7 @@ gain1.connect(gain2).connect(contextB.destination); }, 'Connecting to a node from the different context') - .throw('InvalidAccessError'); + .throw(DOMException, 'InvalidAccessError'); task.done(); }); diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam.html index c3d3fae2155..386614ff2e2 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam.html @@ -193,17 +193,17 @@ // gain1 is not connected to gain3.gain. Exception should be thrown. should(function() { gain1.disconnect(gain3.gain); - }, 'gain1.disconnect(gain3.gain)').throw('InvalidAccessError'); + }, 'gain1.disconnect(gain3.gain)').throw(DOMException, 'InvalidAccessError'); // When the output index is good but the destination is invalid. should(function() { splitter.disconnect(gain1.gain, 1); - }, 'splitter.disconnect(gain1.gain, 1)').throw('InvalidAccessError'); + }, 'splitter.disconnect(gain1.gain, 1)').throw(DOMException, 'InvalidAccessError'); // When both arguments are wrong, throw IndexSizeError first. should(function() { splitter.disconnect(gain1.gain, 2); - }, 'splitter.disconnect(gain1.gain, 2)').throw('IndexSizeError'); + }, 'splitter.disconnect(gain1.gain, 2)').throw(DOMException, 'IndexSizeError'); task.done(); }); diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect.html index b29c09d395f..65b93222d10 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect.html @@ -230,7 +230,7 @@ // There is no output #2. An exception should be thrown. should(function() { splitter.disconnect(2); - }, 'splitter.disconnect(2)').throw('IndexSizeError'); + }, 'splitter.disconnect(2)').throw(DOMException, 'IndexSizeError'); // Disconnecting the output already disconnected should not throw. should(function() { @@ -241,34 +241,34 @@ // gain1 is not connected gain2. An exception should be thrown. should(function() { gain1.disconnect(gain2); - }, 'gain1.disconnect(gain2)').throw('InvalidAccessError'); + }, 'gain1.disconnect(gain2)').throw(DOMException, 'InvalidAccessError'); // gain1 and gain3 are not connected. An exception should be thrown. should(function() { gain1.disconnect(gain3); - }, 'gain1.disconnect(gain3)').throw('InvalidAccessError'); + }, 'gain1.disconnect(gain3)').throw(DOMException, 'InvalidAccessError'); // There is no output #2 in the splitter. An exception should be thrown. should(function() { splitter.disconnect(gain2, 2); - }, 'splitter.disconnect(gain2, 2)').throw('IndexSizeError'); + }, 'splitter.disconnect(gain2, 2)').throw(DOMException, 'IndexSizeError'); // The splitter and gain1 are not connected. An exception should be // thrown. should(function() { splitter.disconnect(gain1, 0); - }, 'splitter.disconnect(gain1, 0)').throw('InvalidAccessError'); + }, 'splitter.disconnect(gain1, 0)').throw(DOMException, 'InvalidAccessError'); // The splitter output #0 and the gain3 output #0 are not connected. An // exception should be thrown. should(function() { splitter.disconnect(gain3, 0, 0); - }, 'splitter.disconnect(gain3, 0, 0)').throw('InvalidAccessError'); + }, 'splitter.disconnect(gain3, 0, 0)').throw(DOMException, 'InvalidAccessError'); // The output index is out of bound. An exception should be thrown. should(function() { splitter.disconnect(merger, 3, 0); - }, 'splitter.disconnect(merger, 3, 0)').throw('IndexSizeError'); + }, 'splitter.disconnect(merger, 3, 0)').throw(DOMException, 'IndexSizeError'); task.done(); }); diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode.html index 14cfbff7e27..0b57d27e8e1 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audionode-interface/audionode.html @@ -54,11 +54,11 @@ should( () => audioNode.connect(context.destination, 5, 0), 'audioNode.connect(context.destination, 5, 0)') - .throw('IndexSizeError'); + .throw(DOMException, 'IndexSizeError'); should( () => audioNode.connect(context.destination, 0, 5), 'audioNode.connect(context.destination, 0, 5)') - .throw('IndexSizeError'); + .throw(DOMException, 'IndexSizeError'); should( () => audioNode.connect(context.destination, 0, 0), @@ -71,7 +71,7 @@ should( () => window.audioNode.connect(context2.destination), 'Connecting a node to a different context') - .throw('InvalidAccessError'); + .throw(DOMException, 'InvalidAccessError'); // 3-arg AudioContext doesn't create an offline context anymore. should( diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-exceptional-values.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-exceptional-values.html index c928b3dc165..982731d3384 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-exceptional-values.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-exceptional-values.html @@ -174,11 +174,16 @@ }, ]); - // One final test for setValueCurve: duration can't be 0. + // Two final tests for setValueCurve: duration must be strictly + // positive. should( () => gain.gain.setValueCurveAtTime(curve, 1, 0), 'gain.gain.setValueCurveAtTime(curve, 1, 0)') .throw(RangeError); + should( + () => gain.gain.setValueCurveAtTime(curve, 1, -1), + 'gain.gain.setValueCurveAtTime(curve, 1, -1)') + .throw(RangeError); task.done(); }); diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions.html index 31405ebfcd2..37062993f9d 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions.html @@ -30,7 +30,7 @@ let curveStartTime = 0.1 * testDurationSec; let duration = 0.1 * testDurationSec; - // Some time that is known to during the setValueCurveTime interval. + // Some time that is known to be during the setValueCurveTime interval. let automationTime = curveStartTime + duration / 2; should( @@ -46,28 +46,28 @@ g.gain.setValueAtTime(1, automationTime); }, 'setValueAtTime(1, ' + automationTime + ')') - .throw('NotSupportedError'); + .throw(DOMException, 'NotSupportedError'); should( function() { g.gain.linearRampToValueAtTime(1, automationTime); }, 'linearRampToValueAtTime(1, ' + automationTime + ')') - .throw('NotSupportedError'); + .throw(DOMException, 'NotSupportedError'); should( function() { g.gain.exponentialRampToValueAtTime(1, automationTime); }, 'exponentialRampToValueAtTime(1, ' + automationTime + ')') - .throw('NotSupportedError'); + .throw(DOMException, 'NotSupportedError'); should( function() { g.gain.setTargetAtTime(1, automationTime, 1); }, 'setTargetAtTime(1, ' + automationTime + ', 1)') - .throw('NotSupportedError'); + .throw(DOMException, 'NotSupportedError'); should( function() { @@ -120,7 +120,7 @@ g.gain.setValueCurveAtTime(curve, time, 0.01); }, 'setValueCurveAtTime(curve, ' + time + ', 0.01)') - .throw('NotSupportedError'); + .throw(DOMException, 'NotSupportedError'); } // Elements of setValueCurve should be finite. @@ -167,7 +167,7 @@ g.gain.setValueCurveAtTime(curve, time, 0.01); }, 'setValueCurveAtTime(curve, ' + time + ', 0.01)') - .throw('NotSupportedError'); + .throw(DOMException, 'NotSupportedError'); task.done(); }); @@ -286,6 +286,83 @@ task.done(); }); + audit.define('curve overlap', (task, should) => { + let context = + new OfflineAudioContext(1, testDurationFrames, sampleRate); + let g = context.createGain(); + let startTime = 5; + let startTimeLater = 10; + let startTimeEarlier = 2.5; + let curveDuration = 10; + let curveDurationShorter = 5; + let curve = [1, 2, 3]; + + // An initial curve event + should( + () => { + g.gain.setValueCurveAtTime(curve, startTime, curveDuration); + }, + `g.gain.setValueCurveAtTime([${curve}], ${startTime}, ${curveDuration})`) + .notThrow(); + + // Check that an exception is thrown when trying to overlap two curves, + // in various ways + + // Same start time and end time (curve exactly overlapping) + should( + () => { + g.gain.setValueCurveAtTime(curve, startTime, curveDuration); + }, + `second g.gain.setValueCurveAtTime([${curve}], ${startTime}, ${curveDuration})`) + .throw(DOMException, 'NotSupportedError'); + // Same start time, shorter end time + should( + () => { + g.gain.setValueCurveAtTime(curve, startTime, curveDurationShorter); + }, + `g.gain.setValueCurveAtTime([${curve}], ${startTime}, ${curveDurationShorter})`) + .throw(DOMException, 'NotSupportedError'); + // Earlier start time, end time after the start time an another curve + should( + () => { + g.gain.setValueCurveAtTime(curve, startTimeEarlier, curveDuration); + }, + `g.gain.setValueCurveAtTime([${curve}], ${startTimeEarlier}, ${curveDuration})`) + .throw(DOMException, 'NotSupportedError'); + // Start time after the start time of the other curve, but earlier than + // its end. + should( + () => { + g.gain.setValueCurveAtTime(curve, startTimeLater, curveDuration); + }, + `g.gain.setValueCurveAtTime([${curve}], ${startTimeLater}, ${curveDuration})`) + .throw(DOMException, 'NotSupportedError'); + + // New event wholly contained inside existing event + should( + () => { + g.gain.setValueCurveAtTime(curve, startTime + 1, curveDuration - 1); + }, + `g.gain.setValueCurveAtTime([${curve}], ${startTime+1}, ${curveDuration-1})`) + .throw(DOMException, 'NotSupportedError'); + // Old event completely contained inside new event + should( + () => { + g.gain.setValueCurveAtTime(curve, startTime - 1, curveDuration + 1); + }, + `g.gain.setValueCurveAtTime([${curve}], ${startTime-1}, ${curveDuration+1})`) + .throw(DOMException, 'NotSupportedError'); + // Setting an event exactly at the end of the curve should work. + should( + () => { + g.gain.setValueAtTime(1.0, startTime + curveDuration); + }, + `g.gain.setValueAtTime(1.0, ${startTime + curveDuration})`) + .notThrow(); + + task.done(); + }); + audit.define('curve lengths', (task, should) => { let context = new OfflineAudioContext(1, testDurationFrames, sampleRate); @@ -298,14 +375,14 @@ g.gain.setValueCurveAtTime(Float32Array.from([]), time, 0.01); }, 'setValueCurveAtTime([], ' + time + ', 0.01)') - .throw('InvalidStateError'); + .throw(DOMException, 'InvalidStateError'); should( () => { g.gain.setValueCurveAtTime(Float32Array.from([1]), time, 0.01); }, 'setValueCurveAtTime([1], ' + time + ', 0.01)') - .throw('InvalidStateError'); + .throw(DOMException, 'InvalidStateError'); should(() => { g.gain.setValueCurveAtTime(Float32Array.from([1, 2]), time, 0.01); diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate.html index a3c789e2f2c..a3c11994bbe 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate.html @@ -151,7 +151,7 @@ if (param.isFixed) { should(() => audioParam.automationRate = newRate, setMessage) - .throw('InvalidStateError'); + .throw(DOMException, 'InvalidStateError'); } else { should(() => audioParam.automationRate = newRate, setMessage) diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion.html index eab77c494d1..688d0478235 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion.html @@ -30,8 +30,8 @@ // An array of tests to be done. Each entry specifies the event // type and the event time. The events are inserted in the order - // given (in |values|), and the second event should replace the - // first, as required by the spec. + // given (in |values|), and the second event should be inserted + // after the first one, as required by the spec. let testCases = [ { event: 'setValueAtTime', @@ -57,7 +57,7 @@ { event: 'setValueCurveAtTime', frame: 3 * RENDER_QUANTUM_FRAMES, - values: [[98, 99], [3, 4]], + values: [[3, 4]], extraArgs: RENDER_QUANTUM_FRAMES / context.sampleRate, outputTestFrame: 4 * RENDER_QUANTUM_FRAMES, expectedOutputValue: 4 diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-construction.https.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-construction.https.html index 7cfd423c071..8b7704a781b 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-construction.https.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-construction.https.html @@ -23,7 +23,7 @@ (task, should) => { should(() => new AudioWorkletNode(realtimeContext, 'dummy'), 'Creating a node before loading a module should throw.') - .throw('InvalidStateError'); + .throw(DOMException, 'InvalidStateError'); task.done(); }); diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-constructor-options.https.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-constructor-options.https.html index 31e204cdc8d..cee9ec82c20 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-constructor-options.https.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-constructor-options.https.html @@ -90,13 +90,13 @@ should( () => new AudioWorkletNode(context, 'dummy', options2), 'Creating AudioWorkletNode with channelCount 0') - .throw('NotSupportedError'); + .throw(DOMException, 'NotSupportedError'); const options3 = {channelCount: 33}; should( () => new AudioWorkletNode(context, 'dummy', options3), 'Creating AudioWorkletNode with channelCount 33') - .throw('NotSupportedError'); + .throw(DOMException, 'NotSupportedError'); task.done(); }); diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-basic.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-basic.html index 83f53aafb19..441e98a2511 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-basic.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-basic.html @@ -110,7 +110,7 @@ 'new Float32Array(10), ' + 'new Float32Array(1), ' + 'new Float32Array(20))') - .throw('InvalidAccessError'); + .throw(DOMException, 'InvalidAccessError'); should( function() { @@ -123,7 +123,7 @@ 'new Float32Array(10), ' + 'new Float32Array(20), ' + 'new Float32Array(1))') - .throw('InvalidAccessError'); + .throw(DOMException, 'InvalidAccessError'); task.done(); }); diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/audiochannelmerger-basic.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/audiochannelmerger-basic.html index f967f0699a3..71a62f176f8 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/audiochannelmerger-basic.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/audiochannelmerger-basic.html @@ -24,7 +24,7 @@ should(function() { merger = context.createChannelMerger(0); - }, 'context.createChannelMerger(0)').throw('IndexSizeError'); + }, 'context.createChannelMerger(0)').throw(DOMException, 'IndexSizeError'); should(function() { merger = context.createChannelMerger(32); @@ -34,7 +34,7 @@ // context has a 32-channel-limit in Chrome. should(function() { merger = context.createChannelMerger(33); - }, 'context.createChannelMerger(33)').throw('IndexSizeError'); + }, 'context.createChannelMerger(33)').throw(DOMException, 'IndexSizeError'); task.done(); }); @@ -49,14 +49,14 @@ should(function() { merger.channelCount = 3; - }, 'merger.channelCount = 3').throw('InvalidStateError'); + }, 'merger.channelCount = 3').throw(DOMException, 'InvalidStateError'); should(merger.channelCountMode, 'merger.channelCountMode') .beEqualTo('explicit'); should(function() { merger.channelCountMode = 'max'; - }, 'merger.channelCountMode = "max"').throw('InvalidStateError'); + }, 'merger.channelCountMode = "max"').throw(DOMException, 'InvalidStateError'); task.done(); }); diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/ctor-channelmerger.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/ctor-channelmerger.html index 115bd994349..0d6b45c56df 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/ctor-channelmerger.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-channelmergernode-interface/ctor-channelmerger.html @@ -43,12 +43,15 @@ audit.define('test AudioNodeOptions', (task, should) => { testAudioNodeOptions(should, context, 'ChannelMergerNode', { - channelCount: - {value: 1, isFixed: true, errorType: 'InvalidStateError'}, + channelCount: { + value: 1, + isFixed: true, + exceptionType: 'InvalidStateError' + }, channelCountMode: { value: 'explicit', isFixed: true, - errorType: 'InvalidStateError' + exceptionType: 'InvalidStateError' } }); task.done(); @@ -82,7 +85,7 @@ node = new ChannelMergerNode(context, options); }, 'new ChannelMergerNode(c, ' + JSON.stringify(options) + ')') - .throw('IndexSizeError'); + .throw(DOMException, 'IndexSizeError'); options = {channelCount: 3}; should( @@ -90,7 +93,7 @@ node = new ChannelMergerNode(context, options); }, 'new ChannelMergerNode(c, ' + JSON.stringify(options) + ')') - .throw('InvalidStateError'); + .throw(DOMException, 'InvalidStateError'); options = {channelCountMode: 'max'}; should( @@ -98,7 +101,7 @@ node = new ChannelMergerNode(context, options); }, 'new ChannelMergerNode(c, ' + JSON.stringify(options) + ')') - .throw('InvalidStateError'); + .throw(DOMException, 'InvalidStateError'); task.done(); }); diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-channelsplitternode-interface/audiochannelsplitter.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-channelsplitternode-interface/audiochannelsplitter.html index e0449919ad5..954c71a96b2 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-channelsplitternode-interface/audiochannelsplitter.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-channelsplitternode-interface/audiochannelsplitter.html @@ -75,11 +75,11 @@ Tests that AudioChannelSplitter works correctly. let splitternode; should(() => { let splitternode = context.createChannelSplitter(0); - }, 'createChannelSplitter(0)').throw('IndexSizeError'); + }, 'createChannelSplitter(0)').throw(DOMException, 'IndexSizeError'); should(() => { splitternode = context.createChannelSplitter(33); - }, 'createChannelSplitter(33)').throw('IndexSizeError'); + }, 'createChannelSplitter(33)').throw(DOMException, 'IndexSizeError'); should(() => { splitternode = context.createChannelSplitter(32); diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-channelsplitternode-interface/ctor-channelsplitter.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-channelsplitternode-interface/ctor-channelsplitter.html index 7fa9d6fa546..9cbb46b6d96 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-channelsplitternode-interface/ctor-channelsplitter.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-channelsplitternode-interface/ctor-channelsplitter.html @@ -41,8 +41,11 @@ audit.define('test AudioNodeOptions', (task, should) => { testAudioNodeOptions(should, context, 'ChannelSplitterNode', { - channelCount: - {value: 6, isFixed: true, errorType: 'InvalidStateError'}, + channelCount: { + value: 6, + isFixed: true, + exceptionType: 'InvalidStateError' + }, channelCountMode: { value: 'explicit', isFixed: true, @@ -50,7 +53,7 @@ channelInterpretation: { value: 'discrete', isFixed: true, - errorType: 'InvalidStateError' + exceptionType: 'InvalidStateError' }, }); task.done(); @@ -84,7 +87,7 @@ node = new ChannelSplitterNode(context, options); }, 'new ChannelSplitterNode(c, ' + JSON.stringify(options) + ')') - .throw('IndexSizeError'); + .throw(DOMException, 'IndexSizeError'); options = {channelCount: 3}; should( @@ -92,7 +95,7 @@ node = new ChannelSplitterNode(context, options); }, 'new ChannelSplitterNode(c, ' + JSON.stringify(options) + ')') - .throw('InvalidStateError'); + .throw(DOMException, 'InvalidStateError'); options = {channelCountMode: 'max'}; should( @@ -100,7 +103,7 @@ node = new ChannelSplitterNode(context, options); }, 'new ChannelSplitterNode(c, ' + JSON.stringify(options) + ')') - .throw('InvalidStateError'); + .throw(DOMException, 'InvalidStateError'); task.done(); }); diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/convolver-channels.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/convolver-channels.html index 11d6f332a1b..ac4f198d7c1 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/convolver-channels.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/convolver-channels.html @@ -30,7 +30,7 @@ should(() => convolver.buffer = buffer, message).notThrow(); } else { should(() => convolver.buffer = buffer, message) - .throw('NotSupportedError'); + .throw(DOMException, 'NotSupportedError'); } } diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/convolver-setBuffer-already-has-value.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/convolver-setBuffer-already-has-value.html index 31f115da532..c8dbeb941bc 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/convolver-setBuffer-already-has-value.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/convolver-setBuffer-already-has-value.html @@ -27,7 +27,7 @@ should(() => { convolver.buffer = audioBuffer; - }, 'Set buffer a second time').throw('InvalidStateError'); + }, 'Set buffer a second time').throw(DOMException, 'InvalidStateError'); should(() => { convolver.buffer = null; @@ -40,7 +40,7 @@ should(() => { convolver.buffer = audioBuffer; }, 'Set buffer to non-null to verify to throw an error') - .throw('InvalidStateError'); + .throw(DOMException, 'InvalidStateError'); task.done(); }); diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/ctor-convolver.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/ctor-convolver.html index cf818330060..935ceeb715e 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/ctor-convolver.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/ctor-convolver.html @@ -46,12 +46,15 @@ audit.define('test AudioNodeOptions', (task, should) => { testAudioNodeOptions(should, context, 'ConvolverNode', { - channelCount: - {value: 2, isFixed: true, errorType: 'NotSupportedError'}, + channelCount: { + value: 2, + isFixed: true, + exceptionType: 'NotSupportedError' + }, channelCountMode: { value: 'clamped-max', isFixed: true, - errorType: 'NotSupportedError' + exceptionType: 'NotSupportedError' }, }); task.done(); diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/delaynode-maxdelaylimit.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/delaynode-maxdelaylimit.html index 7bbff410650..caf2f85dfd4 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/delaynode-maxdelaylimit.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-delaynode-interface/delaynode-maxdelaylimit.html @@ -32,14 +32,18 @@ bufferSource.buffer = toneBuffer; window.context = context; - should(() => context.createDelay(180)).throw("NotSupportedError", - "Delay length cannot be 180 seconds or more"); - should(() => context.createDelay(0)).throw("NotSupportedError", - "Delay length cannot be 0"); - should(() => context.createDelay(-1)).throw("NotSupportedError", - "Delay length cannot be negative"); - should(() => context.createDelay(NaN)).throw(TypeError, - "Delay length cannot be a NaN"); + should(() => context.createDelay(180), + 'Setting Delay length to 180 seconds or more') + .throw(DOMException, 'NotSupportedError'); + should(() => context.createDelay(0), + 'Setting Delay length to 0 seconds') + .throw(DOMException, 'NotSupportedError'); + should(() => context.createDelay(-1), + 'Setting Delay length to negative') + .throw(DOMException, 'NotSupportedError'); + should(() => context.createDelay(NaN), + 'Setting Delay length to NaN') + .throw(TypeError); let delay = context.createDelay(179); delay.delayTime.value = delayTimeSeconds; diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-dynamicscompressornode-interface/ctor-dynamicscompressor.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-dynamicscompressornode-interface/ctor-dynamicscompressor.html index 98d5dbfded1..c2460dfa1dd 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-dynamicscompressornode-interface/ctor-dynamicscompressor.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-dynamicscompressornode-interface/ctor-dynamicscompressor.html @@ -182,9 +182,12 @@ let message = 'new DynamicsCompressorNode(c, ' + JSON.stringify(options.nodeOptions) + ')'; - if (options.expectedErrorType) { + if (options.expectedErrorType === TypeError) { should(createNodeFunction(), message) .throw(options.expectedErrorType); + } else if (options.expectedErrorType === 'NotSupportedError') { + should(createNodeFunction(), message) + .throw(DOMException, 'NotSupportedError'); } else { should(createNodeFunction(), message).notThrow(); should(node[options.testAttribute], 'node.' + options.testAttribute) diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-iirfilternode-interface/iirfilter-basic.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-iirfilternode-interface/iirfilter-basic.html index 79c40dc0847..7828f052261 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-iirfilternode-interface/iirfilter-basic.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-iirfilternode-interface/iirfilter-basic.html @@ -66,17 +66,17 @@ should(function() { // There has to be at least one coefficient. context.createIIRFilter([], []); - }, 'createIIRFilter([], [])').throw('NotSupportedError'); + }, 'createIIRFilter([], [])').throw(DOMException, 'NotSupportedError'); should(function() { // There has to be at least one coefficient. context.createIIRFilter([1], []); - }, 'createIIRFilter([1], [])').throw('NotSupportedError'); + }, 'createIIRFilter([1], [])').throw(DOMException, 'NotSupportedError'); should(function() { // There has to be at least one coefficient. context.createIIRFilter([], [1]); - }, 'createIIRFilter([], [1])').throw('NotSupportedError'); + }, 'createIIRFilter([], [1])').throw(DOMException, 'NotSupportedError'); should( function() { @@ -96,7 +96,7 @@ context.createIIRFilter(coef, [1]); }, 'createIIRFilter(new Float32Array(21), [1])') - .throw('NotSupportedError'); + .throw(DOMException, 'NotSupportedError'); should( function() { @@ -106,7 +106,7 @@ context.createIIRFilter([1], coef); }, 'createIIRFilter([1], new Float32Array(21))') - .throw('NotSupportedError'); + .throw(DOMException, 'NotSupportedError'); should( function() { @@ -114,7 +114,7 @@ context.createIIRFilter([1], new Float32Array(2)); }, 'createIIRFilter([1], new Float32Array(2))') - .throw('InvalidStateError'); + .throw(DOMException, 'InvalidStateError'); should( function() { @@ -122,7 +122,7 @@ context.createIIRFilter(new Float32Array(10), [1]); }, 'createIIRFilter(new Float32Array(10), [1])') - .throw('InvalidStateError'); + .throw(DOMException, 'InvalidStateError'); should(function() { // Feedback coefficients must be finite. @@ -183,7 +183,7 @@ new Float32Array(20)); }, 'getFrequencyResponse(new Float32Array(10), new Float32Array(1), new Float32Array(20))') - .throw('InvalidAccessError'); + .throw(DOMException, 'InvalidAccessError'); should( function() { @@ -193,7 +193,7 @@ new Float32Array(1)); }, 'getFrequencyResponse(new Float32Array(10), new Float32Array(20), new Float32Array(1))') - .throw('InvalidAccessError'); + .throw(DOMException, 'InvalidAccessError'); task.done(); }); diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-offlineaudiocontext-interface/ctor-offlineaudiocontext.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-offlineaudiocontext-interface/ctor-offlineaudiocontext.html index f480ec8ce51..4b686310362 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-offlineaudiocontext-interface/ctor-offlineaudiocontext.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-offlineaudiocontext-interface/ctor-offlineaudiocontext.html @@ -129,7 +129,7 @@ new OfflineAudioContext(options); }, 'new OfflineAudioContext(' + JSON.stringify(options) + ')') - .throw('NotSupportedError'); + .throw(DOMException, 'NotSupportedError'); // length cannot be 0 options = {length: 0, sampleRate: 8000}; @@ -138,7 +138,7 @@ new OfflineAudioContext(options); }, 'new OfflineAudioContext(' + JSON.stringify(options) + ')') - .throw('NotSupportedError'); + .throw(DOMException, 'NotSupportedError'); // sampleRate outside valid range options = {length: 1, sampleRate: 1}; @@ -147,7 +147,7 @@ new OfflineAudioContext(options); }, 'new OfflineAudioContext(' + JSON.stringify(options) + ')') - .throw('NotSupportedError'); + .throw(DOMException, 'NotSupportedError'); task.done(); }); diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-oscillatornode-interface/ctor-oscillator.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-oscillatornode-interface/ctor-oscillator.html index aaf77aec555..36bf604b296 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-oscillatornode-interface/ctor-oscillator.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-oscillatornode-interface/ctor-oscillator.html @@ -87,7 +87,7 @@ node = new OscillatorNode(context, options); }, 'new OscillatorNode(c, ' + JSON.stringify(options) + ')') - .throw('InvalidStateError'); + .throw(DOMException, 'InvalidStateError'); options = { type: 'custom', diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-oscillatornode-interface/detune-limiting.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-oscillatornode-interface/detune-limiting.html new file mode 100644 index 00000000000..81a1293d035 --- /dev/null +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-oscillatornode-interface/detune-limiting.html @@ -0,0 +1,154 @@ + + + + + Oscillator Detune Limits + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html index 5475a6210b7..d330c9c3de4 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html @@ -107,7 +107,7 @@ node = new PannerNode(context, options); }, 'new PannerNode(c, ' + JSON.stringify(options) + ')') - .throw('NotSupportedError'); + .throw(DOMException, 'NotSupportedError'); options = {channelCount: 3}; should( @@ -115,7 +115,7 @@ node = new PannerNode(context, options); }, 'new PannerNode(c, ' + JSON.stringify(options) + ')') - .throw('NotSupportedError'); + .throw(DOMException, 'NotSupportedError'); options = {channelCount: 99}; should( @@ -123,7 +123,7 @@ node = new PannerNode(context, options); }, 'new PannerNode(c, ' + JSON.stringify(options) + ')') - .throw('NotSupportedError'); + .throw(DOMException, 'NotSupportedError'); // Test channelCountMode. A mode of "max" is illegal, but others are // ok. @@ -153,7 +153,7 @@ node = new PannerNode(context, options); }, 'new PannerNode(c, ' + JSON.stringify(options) + ')') - .throw('NotSupportedError'); + .throw(DOMException, 'NotSupportedError'); options = {channelCountMode: 'foobar'}; should( @@ -192,6 +192,106 @@ 'new PannerNode(c, ' + JSON.stringify(options) + ')') .throw(TypeError); + // Test maxDistance + options = {maxDistance: -1}; + should( + () => { + node = new PannerNode(context, options); + }, + 'new PannerNode(c, ' + JSON.stringify(options) + ')') + .throw(RangeError); + options = {maxDistance: 100}; + should( + () => { + node = new PannerNode(context, options); + }, + 'node7 = new PannerNode(c, ' + JSON.stringify(options) + ')') + .notThrow(); + should(node.maxDistance, 'node7.maxDistance') + .beEqualTo(options.maxDistance); + + // Test rolloffFactor + options = {rolloffFactor: -1}; + should( + () => { + node = new PannerNode(context, options); + }, + 'new PannerNode(c, ' + JSON.stringify(options) + ')') + .throw(RangeError); + options = {rolloffFactor: 0}; + should( + () => { + node = new PannerNode(context, options); + }, + 'node8 = new PannerNode(c, ' + JSON.stringify(options) + ')') + .notThrow(); + should(node.rolloffFactor, 'node8.rolloffFactor') + .beEqualTo(options.rolloffFactor); + + options = {rolloffFactor: 0.5}; + should( + () => { + node = new PannerNode(context, options); + }, + 'node8 = new PannerNode(c, ' + JSON.stringify(options) + ')') + .notThrow(); + should(node.rolloffFactor, 'node8.rolloffFactor') + .beEqualTo(options.rolloffFactor); + + options = {rolloffFactor: 100}; + should( + () => { + node = new PannerNode(context, options); + }, + 'node8 = new PannerNode(c, ' + JSON.stringify(options) + ')') + .notThrow(); + should(node.rolloffFactor, 'node8.rolloffFactor') + .beEqualTo(options.rolloffFactor); + + // Test coneOuterGain + options = {coneOuterGain: -1}; + should( + () => { + node = new PannerNode(context, options); + }, + 'new PannerNode(c, ' + JSON.stringify(options) + ')') + .throw(DOMException, 'InvalidStateError'); + options = {coneOuterGain: 1.1}; + should( + () => { + node = new PannerNode(context, options); + }, + 'new PannerNode(c, ' + JSON.stringify(options) + ')') + .throw(DOMException, 'InvalidStateError'); + options = {coneOuterGain: 0.0}; + should( + () => { + node = new PannerNode(context, options); + }, + 'node9 = new PannerNode(c, ' + JSON.stringify(options) + ')') + .notThrow(); + should(node.coneOuterGain, 'node9.coneOuterGain') + .beEqualTo(options.coneOuterGain); + options = {coneOuterGain: 0.5}; + should( + () => { + node = new PannerNode(context, options); + }, + 'node9 = new PannerNode(c, ' + JSON.stringify(options) + ')') + .notThrow(); + should(node.coneOuterGain, 'node9.coneOuterGain') + .beEqualTo(options.coneOuterGain); + + options = {coneOuterGain: 1.0}; + should( + () => { + node = new PannerNode(context, options); + }, + 'node9 = new PannerNode(c, ' + JSON.stringify(options) + ')') + .notThrow(); + should(node.coneOuterGain, 'node9.coneOuterGain') + .beEqualTo(options.coneOuterGain); + task.done(); }); @@ -218,7 +318,7 @@ rolloffFactor: 3 * Math.PI, coneInnerAngle: 4 * Math.PI, coneOuterAngle: 5 * Math.PI, - coneOuterGain: 6 * Math.PI + coneOuterGain: 0.1 * Math.PI }; should( diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/panner-rolloff-clamping.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/panner-rolloff-clamping.html index e1519f8c302..387f8730109 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/panner-rolloff-clamping.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/panner-rolloff-clamping.html @@ -17,41 +17,19 @@ let audit = Audit.createTaskRunner(); - audit.define('linear-clamp-low', (task, should) => { - runTest(should, { - distanceModel: 'linear', - // Fairly arbitrary value outside the nominal range - rolloffFactor: -1, - clampedRolloff: 0 - }).then(() => task.done()); - }); - - audit.define('linear-clamp-high', (task, should) => { - runTest(should, { - distanceModel: 'linear', - // Fairly arbitrary value outside the nominal range - rolloffFactor: 2, - clampedRolloff: 1 - }).then(() => task.done()); - }); - - audit.define('inverse-clamp', (task, should) => { - runTest(should, { - distanceModel: 'inverse', - // Fairly arbitrary value outside the nominal range - rolloffFactor: -1, - clampedRolloff: 0 - }).then(() => task.done()); - }); - - audit.define('exponential-clamp', (task, should) => { - runTest(should, { - distanceModel: 'exponential', - // Fairly arbitrary value outside the nominal range - rolloffFactor: -2, - clampedRolloff: 0 - }).then(() => task.done()); - }); + audit.define( + { + label: 'linear-clamp-high', + description: 'rolloffFactor clamping for linear distance model' + }, + (task, should) => { + runTest(should, { + distanceModel: 'linear', + // Fairly arbitrary value outside the nominal range + rolloffFactor: 2, + clampedRolloff: 1 + }).then(() => task.done()); + }); // Test clamping of the rolloffFactor. The test is done by comparing the // output of a panner with the rolloffFactor set outside the nominal range diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-stereopanner-interface/ctor-stereopanner.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-stereopanner-interface/ctor-stereopanner.html index caa99aa4031..9409f1ffce2 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-stereopanner-interface/ctor-stereopanner.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-stereopanner-interface/ctor-stereopanner.html @@ -80,17 +80,23 @@ entry.tests.forEach(testItem => { let options = {}; options[entry.attribute] = testItem.value; - let method = testItem.error ? 'throw' : 'notThrow'; - should( - () => { - node = new StereoPannerNode(context, options); - }, - `new StereoPannerNode(c, ${JSON.stringify(options)})`)[method]( - testItem.error); - if (!testItem.error) + const testFunction = () => { + node = new StereoPannerNode(context, options); + }; + const testDescription = + `new StereoPannerNode(c, ${JSON.stringify(options)})`; + + if (testItem.error) { + testItem.error === TypeError + ? should(testFunction, testDescription).throw(TypeError) + : should(testFunction, testDescription) + .throw(DOMException, 'NotSupportedError'); + } else { + should(testFunction, testDescription).notThrow(); should(node[entry.attribute], `node.${entry.attribute}`) .beEqualTo(options[entry.attribute]); + } }); }); diff --git a/tests/wpt/web-platform-tests/webdriver/tests/actions/sequence.py b/tests/wpt/web-platform-tests/webdriver/tests/actions/sequence.py index 426dbe82f48..b62d00c3e9b 100644 --- a/tests/wpt/web-platform-tests/webdriver/tests/actions/sequence.py +++ b/tests/wpt/web-platform-tests/webdriver/tests/actions/sequence.py @@ -1,15 +1,20 @@ # META: timeout=long from tests.actions.support.refine import get_keys, filter_dict, get_events -from tests.actions.support.keys import Keys -def test_no_actions_send_no_events(session, key_reporter, key_chain): +def test_perform_no_actions_send_no_events(session, key_reporter, key_chain): key_chain.perform() assert len(get_keys(key_reporter)) == 0 assert len(get_events(session)) == 0 +def test_release_no_actions_sends_no_events(session, key_reporter): + session.actions.release() + assert len(get_keys(key_reporter)) == 0 + assert len(get_events(session)) == 0 + + def test_release_char_sequence_sends_keyup_events_in_reverse(session, key_reporter, key_chain): @@ -26,14 +31,58 @@ def test_release_char_sequence_sends_keyup_events_in_reverse(session, ] all_events = get_events(session) events = [filter_dict(e, expected[0]) for e in all_events] - if len(events) > 0 and events[0]["code"] == None: + if len(events) > 0 and events[0]["code"] is None: # Remove 'code' entry if browser doesn't support it expected = [filter_dict(e, {"key": "", "type": ""}) for e in expected] events = [filter_dict(e, expected[0]) for e in events] assert events == expected -def test_release_no_actions_sends_no_events(session, key_reporter): +def test_release_mouse_sequence_resets_dblclick_state(session, + test_actions_page, + mouse_chain): + reporter = session.find.css("#outer", all=False) + + mouse_chain \ + .click(element=reporter) \ + .perform() session.actions.release() - assert len(get_keys(key_reporter)) == 0 - assert len(get_events(session)) == 0 + mouse_chain \ + .perform() + events = get_events(session) + + expected = [ + {"type": "mousedown", "button": 0}, + {"type": "mouseup", "button": 0}, + {"type": "click", "button": 0}, + {"type": "mousedown", "button": 0}, + {"type": "mouseup", "button": 0}, + {"type": "click", "button": 0}, + ] + filtered_events = [filter_dict(e, expected[0]) for e in events] + assert expected == filtered_events[1:] + + +def test_no_release_mouse_sequence_keeps_dblclick_state(session, + test_actions_page, + mouse_chain): + reporter = session.find.css("#outer", all=False) + + mouse_chain \ + .click(element=reporter) \ + .perform() + mouse_chain \ + .perform() + events = get_events(session) + + expected = [ + {"type": "mousedown", "button": 0}, + {"type": "mouseup", "button": 0}, + {"type": "click", "button": 0}, + {"type": "mousedown", "button": 0}, + {"type": "mouseup", "button": 0}, + {"type": "click", "button": 0}, + {"type": "dblclick", "button": 0}, + ] + filtered_events = [filter_dict(e, expected[0]) for e in events] + assert expected == filtered_events[1:] diff --git a/tests/wpt/web-platform-tests/webdriver/tests/actions/special_keys.py b/tests/wpt/web-platform-tests/webdriver/tests/actions/special_keys.py index d2a44229ce0..416cbdcf20f 100644 --- a/tests/wpt/web-platform-tests/webdriver/tests/actions/special_keys.py +++ b/tests/wpt/web-platform-tests/webdriver/tests/actions/special_keys.py @@ -2,7 +2,6 @@ import pytest import time -from tests.support.fixtures import configuration from tests.actions.support.keys import ALL_EVENTS, Keys from tests.actions.support.refine import filter_dict, get_keys, get_events from webdriver import error diff --git a/tests/wpt/web-platform-tests/webdriver/tests/add_cookie/add.py b/tests/wpt/web-platform-tests/webdriver/tests/add_cookie/add.py index 48fdf64f2f9..24ac645029e 100644 --- a/tests/wpt/web-platform-tests/webdriver/tests/add_cookie/add.py +++ b/tests/wpt/web-platform-tests/webdriver/tests/add_cookie/add.py @@ -3,8 +3,7 @@ from datetime import datetime, timedelta from webdriver.transport import Response from tests.support.asserts import assert_error, assert_success -from tests.support.fixtures import clear_all_cookies - +from tests.support.helpers import clear_all_cookies def add_cookie(session, cookie): return session.transport.send( diff --git a/tests/wpt/web-platform-tests/webdriver/tests/conftest.py b/tests/wpt/web-platform-tests/webdriver/tests/conftest.py index c39671797f6..7e72eb9ca58 100644 --- a/tests/wpt/web-platform-tests/webdriver/tests/conftest.py +++ b/tests/wpt/web-platform-tests/webdriver/tests/conftest.py @@ -1,18 +1,20 @@ -import pytest +import copy +import json +import os +import urlparse + +import pytest +import webdriver + +from tests.support import defaults +from tests.support.helpers import cleanup_session +from tests.support.http_request import HTTPRequest +from tests.support.wait import wait + + +_current_session = None +_custom_session = False -from tests.support.fixtures import ( - add_event_listeners, - configuration, - closed_window, - create_cookie, - create_dialog, - create_frame, - create_window, - current_session, - http, - server_config, - session, - url) def pytest_configure(config): # register the capabilities marker @@ -33,17 +35,199 @@ def pytest_generate_tests(metafunc): metafunc.parametrize("capabilities", marker.args, ids=None) -pytest.fixture()(add_event_listeners) -pytest.fixture(scope="session")(configuration) -pytest.fixture()(create_cookie) -pytest.fixture()(create_dialog) -pytest.fixture()(create_frame) -pytest.fixture()(create_window) -pytest.fixture(scope="function")(current_session) -pytest.fixture()(http) -pytest.fixture()(server_config) -pytest.fixture(scope="function")(session) -pytest.fixture()(url) +@pytest.fixture +def add_event_listeners(session): + """Register listeners for tracked events on element.""" + def add_event_listeners(element, tracked_events): + element.session.execute_script(""" + let element = arguments[0]; + let trackedEvents = arguments[1]; + + if (!("events" in window)) { + window.events = []; + } + + for (var i = 0; i < trackedEvents.length; i++) { + element.addEventListener(trackedEvents[i], function (event) { + window.events.push(event.type); + }); + } + """, args=(element, tracked_events)) + return add_event_listeners + + +@pytest.fixture +def create_cookie(session, url): + """Create a cookie""" + def create_cookie(name, value, **kwargs): + if kwargs.get("path", None) is not None: + session.url = url(kwargs["path"]) + + session.set_cookie(name, value, **kwargs) + return session.cookies(name) + + return create_cookie + + +@pytest.fixture +def create_frame(session): + """Create an `iframe` element in the current browsing context and insert it + into the document. Return a reference to the newly-created element.""" + def create_frame(): + append = """ + var frame = document.createElement('iframe'); + document.body.appendChild(frame); + return frame; + """ + return session.execute_script(append) + + return create_frame + + +@pytest.fixture +def create_window(session): + """Open new window and return the window handle.""" + def create_window(): + windows_before = session.handles + name = session.execute_script("window.open()") + assert len(session.handles) == len(windows_before) + 1 + new_windows = list(set(session.handles) - set(windows_before)) + return new_windows.pop() + return create_window + + +@pytest.fixture +def http(configuration): + return HTTPRequest(configuration["host"], configuration["port"]) + + +@pytest.fixture +def server_config(): + return json.loads(os.environ.get("WD_SERVER_CONFIG")) + + +@pytest.fixture(scope="session") +def configuration(): + host = os.environ.get("WD_HOST", defaults.DRIVER_HOST) + port = int(os.environ.get("WD_PORT", str(defaults.DRIVER_PORT))) + capabilities = json.loads(os.environ.get("WD_CAPABILITIES", "{}")) + + return { + "host": host, + "port": port, + "capabilities": capabilities + } + + +@pytest.fixture(scope="function") +def session(capabilities, configuration, request): + """Create and start a session for a test that does not itself test session creation. + + By default the session will stay open after each test, but we always try to start a + new one and assume that if that fails there is already a valid session. This makes it + possible to recover from some errors that might leave the session in a bad state, but + does not demand that we start a new session per test.""" + global _current_session + + # Update configuration capabilities with custom ones from the + # capabilities fixture, which can be set by tests + caps = copy.deepcopy(configuration["capabilities"]) + caps.update(capabilities) + caps = {"alwaysMatch": caps} + + # If there is a session with different capabilities active, end it now + if _current_session is not None and ( + caps != _current_session.requested_capabilities): + _current_session.end() + _current_session = None + + if _current_session is None: + _current_session = webdriver.Session( + configuration["host"], + configuration["port"], + capabilities=caps) + try: + _current_session.start() + except webdriver.error.SessionNotCreatedException: + if not _current_session.session_id: + raise + + # Enforce a fixed default window size + _current_session.window.size = defaults.WINDOW_SIZE + + yield _current_session + + cleanup_session(_current_session) + + +@pytest.fixture(scope="function") +def current_session(): + return _current_session + + +@pytest.fixture +def url(server_config): + def inner(path, protocol="http", query="", fragment=""): + port = server_config["ports"][protocol][0] + host = "%s:%s" % (server_config["browser_host"], port) + return urlparse.urlunsplit((protocol, host, path, query, fragment)) + + inner.__name__ = "url" + return inner + + +@pytest.fixture +def create_dialog(session): + """Create a dialog (one of "alert", "prompt", or "confirm") and provide a + function to validate that the dialog has been "handled" (either accepted or + dismissed) by returning some value.""" + + def create_dialog(dialog_type, text=None): + assert dialog_type in ("alert", "confirm", "prompt"), ( + "Invalid dialog type: '%s'" % dialog_type) + + if text is None: + text = "" + + assert isinstance(text, basestring), "`text` parameter must be a string" + + # Script completes itself when the user prompt has been opened. + # For prompt() dialogs, add a value for the 'default' argument, + # as some user agents (IE, for example) do not produce consistent + # values for the default. + session.execute_async_script(""" + let dialog_type = arguments[0]; + let text = arguments[1]; + + setTimeout(function() { + if (dialog_type == 'prompt') { + window.dialog_return_value = window[dialog_type](text, ''); + } else { + window.dialog_return_value = window[dialog_type](text); + } + }, 0); + """, args=(dialog_type, text)) + + wait(session, + lambda s: s.alert.text == text, + "No user prompt with text '{}' detected".format(text), + timeout=15, + ignored_exceptions=webdriver.NoSuchAlertException) + + return create_dialog + + +@pytest.fixture +def closed_window(session, create_window): + original_handle = session.window_handle + + new_handle = create_window() + session.window_handle = new_handle + + session.close() + assert new_handle not in session.handles, "Unable to close window {}".format(new_handle) + + yield new_handle + + session.window_handle = original_handle -# Fixtures for specific tests -pytest.fixture()(closed_window) diff --git a/tests/wpt/web-platform-tests/webdriver/tests/element_send_keys/scroll_into_view.py b/tests/wpt/web-platform-tests/webdriver/tests/element_send_keys/scroll_into_view.py index 9ff0a9e2578..18f87ffaaec 100644 --- a/tests/wpt/web-platform-tests/webdriver/tests/element_send_keys/scroll_into_view.py +++ b/tests/wpt/web-platform-tests/webdriver/tests/element_send_keys/scroll_into_view.py @@ -1,8 +1,7 @@ from tests.support.asserts import assert_success -from tests.support.fixtures import is_element_in_viewport +from tests.support.helpers import is_element_in_viewport from tests.support.inline import inline - def element_send_keys(session, element, text): return session.transport.send( "POST", "/session/{session_id}/element/{element_id}/value".format( diff --git a/tests/wpt/web-platform-tests/webdriver/tests/execute_script/execute.py b/tests/wpt/web-platform-tests/webdriver/tests/execute_script/execute.py index 9e220d02687..2af16c1e5e8 100644 --- a/tests/wpt/web-platform-tests/webdriver/tests/execute_script/execute.py +++ b/tests/wpt/web-platform-tests/webdriver/tests/execute_script/execute.py @@ -27,6 +27,11 @@ def test_no_browsing_context(session, closed_window): assert_error(response, "no such window") +def test_ending_comment(session): + response = execute_script(session, "return 1; // foo") + assert_success(response, 1) + + @pytest.mark.parametrize("dialog_type", ["alert", "confirm", "prompt"]) def test_abort_by_user_prompt(session, dialog_type): response = execute_script( diff --git a/tests/wpt/web-platform-tests/webdriver/tests/get_element_attribute/__init__.py b/tests/wpt/web-platform-tests/webdriver/tests/get_element_attribute/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/wpt/web-platform-tests/webdriver/tests/get_element_css_value/__init__.py b/tests/wpt/web-platform-tests/webdriver/tests/get_element_css_value/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/wpt/web-platform-tests/webdriver/tests/get_element_css_value/get.py b/tests/wpt/web-platform-tests/webdriver/tests/get_element_css_value/get.py new file mode 100644 index 00000000000..88a56e1ad45 --- /dev/null +++ b/tests/wpt/web-platform-tests/webdriver/tests/get_element_css_value/get.py @@ -0,0 +1,48 @@ +from tests.support.asserts import assert_error, assert_success +from tests.support.inline import inline + + +def get_element_css_value(session, element_id, prop): + return session.transport.send( + "GET", + "session/{session_id}/element/{element_id}/css/{prop}".format( + session_id=session.session_id, + element_id=element_id, + prop=prop + ) + ) + + +def test_no_browsing_context(session, closed_window): + response = get_element_css_value(session, "foo", "bar") + assert_error(response, "no such window") + + +def test_element_not_found(session): + result = get_element_css_value(session, "foo", "display") + assert_error(result, "no such element") + + +def test_element_stale(session): + session.url = inline("") + element = session.find.css("input", all=False) + session.refresh() + + result = get_element_css_value(session, element.id, "display") + assert_error(result, "stale element reference") + + +def test_property_name_value(session): + session.url = inline("""""") + element = session.find.css("input", all=False) + + result = get_element_css_value(session, element.id, "display") + assert_success(result, "block") + + +def test_property_name_not_existent(session): + session.url = inline("") + element = session.find.css("input", all=False) + + result = get_element_css_value(session, element.id, "foo") + assert_success(result, "") diff --git a/tests/wpt/web-platform-tests/webdriver/tests/get_element_css_value/user_prompts.py b/tests/wpt/web-platform-tests/webdriver/tests/get_element_css_value/user_prompts.py new file mode 100644 index 00000000000..529b6ae9183 --- /dev/null +++ b/tests/wpt/web-platform-tests/webdriver/tests/get_element_css_value/user_prompts.py @@ -0,0 +1,121 @@ +# META: timeout=long + +import pytest + +from tests.support.asserts import assert_error, assert_success, assert_dialog_handled +from tests.support.inline import inline + + +def get_element_css_value(session, element_id, prop): + return session.transport.send( + "GET", + "session/{session_id}/element/{element_id}/css/{prop}".format( + session_id=session.session_id, + element_id=element_id, + prop=prop + ) + ) + + +@pytest.fixture +def check_user_prompt_closed_without_exception(session, create_dialog): + def check_user_prompt_closed_without_exception(dialog_type, retval): + session.url = inline("""""") + element = session.find.css("input", all=False) + + create_dialog(dialog_type, text=dialog_type) + + response = get_element_css_value(session, element.id, "display") + assert_success(response, "block") + + assert_dialog_handled(session, expected_text=dialog_type, expected_retval=retval) + + return check_user_prompt_closed_without_exception + + +@pytest.fixture +def check_user_prompt_closed_with_exception(session, create_dialog): + def check_user_prompt_closed_with_exception(dialog_type, retval): + session.url = inline("""""") + element = session.find.css("input", all=False) + + create_dialog(dialog_type, text=dialog_type) + + response = get_element_css_value(session, element.id, "display") + assert_error(response, "unexpected alert open") + + assert_dialog_handled(session, expected_text=dialog_type, expected_retval=retval) + + return check_user_prompt_closed_with_exception + + +@pytest.fixture +def check_user_prompt_not_closed_but_exception(session, create_dialog): + def check_user_prompt_not_closed_but_exception(dialog_type): + session.url = inline("""""") + element = session.find.css("input", all=False) + + create_dialog(dialog_type, text=dialog_type) + + response = get_element_css_value(session, element.id, "display") + assert_error(response, "unexpected alert open") + + assert session.alert.text == dialog_type + session.alert.dismiss() + + return check_user_prompt_not_closed_but_exception + + +@pytest.mark.capabilities({"unhandledPromptBehavior": "accept"}) +@pytest.mark.parametrize("dialog_type, retval", [ + ("alert", None), + ("confirm", True), + ("prompt", ""), +]) +def test_accept(check_user_prompt_closed_without_exception, dialog_type, retval): + check_user_prompt_closed_without_exception(dialog_type, retval) + + +@pytest.mark.capabilities({"unhandledPromptBehavior": "accept and notify"}) +@pytest.mark.parametrize("dialog_type, retval", [ + ("alert", None), + ("confirm", True), + ("prompt", ""), +]) +def test_accept_and_notify(check_user_prompt_closed_with_exception, dialog_type, retval): + check_user_prompt_closed_with_exception(dialog_type, retval) + + +@pytest.mark.capabilities({"unhandledPromptBehavior": "dismiss"}) +@pytest.mark.parametrize("dialog_type, retval", [ + ("alert", None), + ("confirm", False), + ("prompt", None), +]) +def test_dismiss(check_user_prompt_closed_without_exception, dialog_type, retval): + check_user_prompt_closed_without_exception(dialog_type, retval) + + +@pytest.mark.capabilities({"unhandledPromptBehavior": "dismiss and notify"}) +@pytest.mark.parametrize("dialog_type, retval", [ + ("alert", None), + ("confirm", False), + ("prompt", None), +]) +def test_dismiss_and_notify(check_user_prompt_closed_with_exception, dialog_type, retval): + check_user_prompt_closed_with_exception(dialog_type, retval) + + +@pytest.mark.capabilities({"unhandledPromptBehavior": "ignore"}) +@pytest.mark.parametrize("dialog_type", ["alert", "confirm", "prompt"]) +def test_ignore(check_user_prompt_not_closed_but_exception, dialog_type): + check_user_prompt_not_closed_but_exception(dialog_type) + + +@pytest.mark.parametrize("dialog_type, retval", [ + ("alert", None), + ("confirm", False), + ("prompt", None), +]) +def test_default(check_user_prompt_closed_with_exception, dialog_type, retval): + check_user_prompt_closed_with_exception(dialog_type, retval) diff --git a/tests/wpt/web-platform-tests/webdriver/tests/get_element_rect/__init__.py b/tests/wpt/web-platform-tests/webdriver/tests/get_element_rect/__init__.py new file mode 100644 index 00000000000..abf1a913675 --- /dev/null +++ b/tests/wpt/web-platform-tests/webdriver/tests/get_element_rect/__init__.py @@ -0,0 +1,10 @@ +def retrieve_element_rect(session, element): + return session.execute_script(""" + let rect = arguments[0].getBoundingClientRect(); + return { + x: rect.left + window.pageXOffset, + y: rect.top + window.pageYOffset, + width: rect.width, + height: rect.height, + }; + """, args=(element,)) diff --git a/tests/wpt/web-platform-tests/webdriver/tests/get_element_rect/get.py b/tests/wpt/web-platform-tests/webdriver/tests/get_element_rect/get.py new file mode 100644 index 00000000000..433e2f6bf8b --- /dev/null +++ b/tests/wpt/web-platform-tests/webdriver/tests/get_element_rect/get.py @@ -0,0 +1,41 @@ +from tests.support.asserts import assert_error, assert_success +from tests.support.inline import inline + +from . import retrieve_element_rect + + +def get_element_rect(session, element_id): + return session.transport.send( + "GET", + "session/{session_id}/element/{element_id}/rect".format( + session_id=session.session_id, + element_id=element_id, + ) + ) + + +def test_no_browsing_context(session, closed_window): + response = get_element_rect(session, "foo") + assert_error(response, "no such window") + + +def test_element_not_found(session): + result = get_element_rect(session, "foo") + assert_error(result, "no such element") + + +def test_element_stale(session): + session.url = inline("") + element = session.find.css("input", all=False) + session.refresh() + + result = get_element_rect(session, element.id) + assert_error(result, "stale element reference") + + +def test_basic(session): + session.url = inline("") + element = session.find.css("input", all=False) + + result = get_element_rect(session, element.id) + assert_success(result, retrieve_element_rect(session, element)) diff --git a/tests/wpt/web-platform-tests/webdriver/tests/get_element_rect/user_prompts.py b/tests/wpt/web-platform-tests/webdriver/tests/get_element_rect/user_prompts.py new file mode 100644 index 00000000000..ec1047bd389 --- /dev/null +++ b/tests/wpt/web-platform-tests/webdriver/tests/get_element_rect/user_prompts.py @@ -0,0 +1,122 @@ +# META: timeout=long + +import pytest + +from tests.support.asserts import assert_error, assert_success, assert_dialog_handled +from tests.support.inline import inline + +from . import retrieve_element_rect + + +def get_element_rect(session, element_id): + return session.transport.send( + "GET", + "session/{session_id}/element/{element_id}/rect".format( + session_id=session.session_id, + element_id=element_id, + ) + ) + + +@pytest.fixture +def check_user_prompt_closed_without_exception(session, create_dialog): + def check_user_prompt_closed_without_exception(dialog_type, retval): + session.url = inline("") + element = session.find.css("input", all=False) + + create_dialog(dialog_type, text=dialog_type) + + response = get_element_rect(session, element.id) + assert_success(response, retrieve_element_rect(session, element)) + + assert_dialog_handled(session, expected_text=dialog_type, expected_retval=retval) + + return check_user_prompt_closed_without_exception + + +@pytest.fixture +def check_user_prompt_closed_with_exception(session, create_dialog): + def check_user_prompt_closed_with_exception(dialog_type, retval): + session.url = inline("") + element = session.find.css("input", all=False) + + create_dialog(dialog_type, text=dialog_type) + + response = get_element_rect(session, element.id) + assert_error(response, "unexpected alert open") + + assert_dialog_handled(session, expected_text=dialog_type, expected_retval=retval) + + return check_user_prompt_closed_with_exception + + +@pytest.fixture +def check_user_prompt_not_closed_but_exception(session, create_dialog): + def check_user_prompt_not_closed_but_exception(dialog_type): + session.url = inline("") + element = session.find.css("input", all=False) + + create_dialog(dialog_type, text=dialog_type) + + response = get_element_rect(session, element.id) + assert_error(response, "unexpected alert open") + + assert session.alert.text == dialog_type + session.alert.dismiss() + + return check_user_prompt_not_closed_but_exception + + +@pytest.mark.capabilities({"unhandledPromptBehavior": "accept"}) +@pytest.mark.parametrize("dialog_type, retval", [ + ("alert", None), + ("confirm", True), + ("prompt", ""), +]) +def test_accept(check_user_prompt_closed_without_exception, dialog_type, retval): + check_user_prompt_closed_without_exception(dialog_type, retval) + + +@pytest.mark.capabilities({"unhandledPromptBehavior": "accept and notify"}) +@pytest.mark.parametrize("dialog_type, retval", [ + ("alert", None), + ("confirm", True), + ("prompt", ""), +]) +def test_accept_and_notify(check_user_prompt_closed_with_exception, dialog_type, retval): + check_user_prompt_closed_with_exception(dialog_type, retval) + + +@pytest.mark.capabilities({"unhandledPromptBehavior": "dismiss"}) +@pytest.mark.parametrize("dialog_type, retval", [ + ("alert", None), + ("confirm", False), + ("prompt", None), +]) +def test_dismiss(check_user_prompt_closed_without_exception, dialog_type, retval): + check_user_prompt_closed_without_exception(dialog_type, retval) + + +@pytest.mark.capabilities({"unhandledPromptBehavior": "dismiss and notify"}) +@pytest.mark.parametrize("dialog_type, retval", [ + ("alert", None), + ("confirm", False), + ("prompt", None), +]) +def test_dismiss_and_notify(check_user_prompt_closed_with_exception, dialog_type, retval): + check_user_prompt_closed_with_exception(dialog_type, retval) + + +@pytest.mark.capabilities({"unhandledPromptBehavior": "ignore"}) +@pytest.mark.parametrize("dialog_type", ["alert", "confirm", "prompt"]) +def test_ignore(check_user_prompt_not_closed_but_exception, dialog_type): + check_user_prompt_not_closed_but_exception(dialog_type) + + +@pytest.mark.parametrize("dialog_type, retval", [ + ("alert", None), + ("confirm", False), + ("prompt", None), +]) +def test_default(check_user_prompt_closed_with_exception, dialog_type, retval): + check_user_prompt_closed_with_exception(dialog_type, retval) diff --git a/tests/wpt/web-platform-tests/webdriver/tests/get_named_cookie/get.py b/tests/wpt/web-platform-tests/webdriver/tests/get_named_cookie/get.py index 915f26c801b..50a46519168 100644 --- a/tests/wpt/web-platform-tests/webdriver/tests/get_named_cookie/get.py +++ b/tests/wpt/web-platform-tests/webdriver/tests/get_named_cookie/get.py @@ -1,10 +1,9 @@ from datetime import datetime, timedelta from tests.support.asserts import assert_error, assert_success -from tests.support.fixtures import clear_all_cookies +from tests.support.helpers import clear_all_cookies from tests.support.inline import inline - def get_named_cookie(session, name): return session.transport.send( "GET", "session/{session_id}/cookie/{name}".format( diff --git a/tests/wpt/web-platform-tests/webdriver/tests/is_element_enabled/__init__.py b/tests/wpt/web-platform-tests/webdriver/tests/is_element_enabled/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/wpt/web-platform-tests/webdriver/tests/is_element_enabled/enabled.py b/tests/wpt/web-platform-tests/webdriver/tests/is_element_enabled/enabled.py new file mode 100644 index 00000000000..dd56084d8d0 --- /dev/null +++ b/tests/wpt/web-platform-tests/webdriver/tests/is_element_enabled/enabled.py @@ -0,0 +1,109 @@ +import pytest + +from tests.support.asserts import assert_error, assert_success +from tests.support.inline import inline + + +def is_element_enabled(session, element_id): + return session.transport.send( + "GET", + "session/{session_id}/element/{element_id}/enabled".format( + session_id=session.session_id, + element_id=element_id + ) + ) + + +def test_no_browsing_context(session, closed_window): + response = is_element_enabled(session, "foo") + assert_error(response, "no such window") + + +def test_element_stale(session): + session.url = inline("") + element = session.find.css("input", all=False) + session.refresh() + + result = is_element_enabled(session, element.id) + assert_error(result, "stale element reference") + + +@pytest.mark.parametrize("element", ["button", "input", "select", "textarea"]) +def test_form_control_disabled(session, element): + session.url = inline("<{} disabled/>".format(element)) + element = session.find.css(element, all=False) + + result = is_element_enabled(session, element.id) + assert_success(result, False) + + +@pytest.mark.parametrize("element", ["button", "input", "select", "textarea"]) +def test_form_control_enabled(session, element): + session.url = inline("<{}/>".format(element)) + element = session.find.css(element, all=False) + + result = is_element_enabled(session, element.id) + assert_success(result, True) + + +@pytest.mark.parametrize("element", ["button", "input", "select", "textarea"]) +def test_fieldset_disabled_descendant(session, element): + session.url = inline("
                  <{}/>
                  ".format(element)) + element = session.find.css(element, all=False) + + result = is_element_enabled(session, element.id) + assert_success(result, False) + + +@pytest.mark.parametrize("element", ["button", "input", "select", "textarea"]) +def test_fieldset_enabled_descendant(session, element): + session.url = inline("
                  <{}/>
                  ".format(element)) + element = session.find.css(element, all=False) + + result = is_element_enabled(session, element.id) + assert_success(result, True) + + +@pytest.mark.parametrize("element", ["button", "input", "select", "textarea"]) +def test_fieldset_disabled_descendant_legend(session, element): + session.url = inline("
                  <{}/>
                  ".format(element)) + element = session.find.css(element, all=False) + + result = is_element_enabled(session, element.id) + assert_success(result, True) + + +@pytest.mark.parametrize("element", ["button", "input", "select", "textarea"]) +def test_fieldset_enabled_descendant_legend(session, element): + session.url = inline("
                  <{}/>
                  ".format(element)) + element = session.find.css(element, all=False) + + result = is_element_enabled(session, element.id) + assert_success(result, True) + + +@pytest.mark.parametrize("element", ["button", "input", "select", "textarea"]) +def test_xhtml_form_control_disabled(session, element): + session.url = inline("""<{} disabled="disabled"/>""".format(element), + doctype="xhtml") + element = session.find.css(element, all=False) + + result = is_element_enabled(session, element.id) + assert_success(result, False) + + +@pytest.mark.parametrize("element", ["button", "input", "select", "textarea"]) +def test_xhtml_form_control_enabled(session, element): + session.url = inline("""<{}/>""".format(element), doctype="xhtml") + element = session.find.css(element, all=False) + + result = is_element_enabled(session, element.id) + assert_success(result, True) + + +def test_xml_always_not_enabled(session): + session.url = inline("""""", doctype="xml") + element = session.find.css("note", all=False) + + result = is_element_enabled(session, element.id) + assert_success(result, False) diff --git a/tests/wpt/web-platform-tests/webdriver/tests/is_element_enabled/user_prompts.py b/tests/wpt/web-platform-tests/webdriver/tests/is_element_enabled/user_prompts.py new file mode 100644 index 00000000000..bd8bc81bdfc --- /dev/null +++ b/tests/wpt/web-platform-tests/webdriver/tests/is_element_enabled/user_prompts.py @@ -0,0 +1,120 @@ +# META: timeout=long + +import pytest + +from tests.support.asserts import assert_error, assert_dialog_handled, assert_success +from tests.support.inline import inline + + +def is_element_enabled(session, element_id): + return session.transport.send( + "GET", + "session/{session_id}/element/{element_id}/enabled".format( + session_id=session.session_id, + element_id=element_id + ) + ) + + +@pytest.fixture +def check_user_prompt_closed_without_exception(session, create_dialog): + def check_user_prompt_closed_without_exception(dialog_type, retval): + session.url = inline("") + element = session.find.css("#foo", all=False) + + create_dialog(dialog_type, text=dialog_type) + + response = is_element_enabled(session, element.id) + assert_success(response, False) + + assert_dialog_handled(session, expected_text=dialog_type, expected_retval=retval) + + return check_user_prompt_closed_without_exception + + +@pytest.fixture +def check_user_prompt_closed_with_exception(session, create_dialog): + def check_user_prompt_closed_with_exception(dialog_type, retval): + session.url = inline("") + element = session.find.css("#foo", all=False) + + create_dialog(dialog_type, text=dialog_type) + + response = is_element_enabled(session, element.id) + assert_error(response, "unexpected alert open") + + assert_dialog_handled(session, expected_text=dialog_type, expected_retval=retval) + + return check_user_prompt_closed_with_exception + + +@pytest.fixture +def check_user_prompt_not_closed_but_exception(session, create_dialog): + def check_user_prompt_not_closed_but_exception(dialog_type): + session.url = inline("") + element = session.find.css("#foo", all=False) + + create_dialog(dialog_type, text=dialog_type) + + response = is_element_enabled(session, element.id) + assert_error(response, "unexpected alert open") + + assert session.alert.text == dialog_type + session.alert.dismiss() + + return check_user_prompt_not_closed_but_exception + + +@pytest.mark.capabilities({"unhandledPromptBehavior": "accept"}) +@pytest.mark.parametrize("dialog_type, retval", [ + ("alert", None), + ("confirm", True), + ("prompt", ""), +]) +def test_accept(check_user_prompt_closed_without_exception, dialog_type, retval): + check_user_prompt_closed_without_exception(dialog_type, retval) + + +@pytest.mark.capabilities({"unhandledPromptBehavior": "accept and notify"}) +@pytest.mark.parametrize("dialog_type, retval", [ + ("alert", None), + ("confirm", True), + ("prompt", ""), +]) +def test_accept_and_notify(check_user_prompt_closed_with_exception, dialog_type, retval): + check_user_prompt_closed_with_exception(dialog_type, retval) + + +@pytest.mark.capabilities({"unhandledPromptBehavior": "dismiss"}) +@pytest.mark.parametrize("dialog_type, retval", [ + ("alert", None), + ("confirm", False), + ("prompt", None), +]) +def test_dismiss(check_user_prompt_closed_without_exception, dialog_type, retval): + check_user_prompt_closed_without_exception(dialog_type, retval) + + +@pytest.mark.capabilities({"unhandledPromptBehavior": "dismiss and notify"}) +@pytest.mark.parametrize("dialog_type, retval", [ + ("alert", None), + ("confirm", False), + ("prompt", None), +]) +def test_dismiss_and_notify(check_user_prompt_closed_with_exception, dialog_type, retval): + check_user_prompt_closed_with_exception(dialog_type, retval) + + +@pytest.mark.capabilities({"unhandledPromptBehavior": "ignore"}) +@pytest.mark.parametrize("dialog_type", ["alert", "confirm", "prompt"]) +def test_ignore(check_user_prompt_not_closed_but_exception, dialog_type): + check_user_prompt_not_closed_but_exception(dialog_type) + + +@pytest.mark.parametrize("dialog_type, retval", [ + ("alert", None), + ("confirm", False), + ("prompt", None), +]) +def test_default(check_user_prompt_closed_with_exception, dialog_type, retval): + check_user_prompt_closed_with_exception(dialog_type, retval) diff --git a/tests/wpt/web-platform-tests/webdriver/tests/new_session/invalid_capabilities.py b/tests/wpt/web-platform-tests/webdriver/tests/new_session/invalid_capabilities.py index 83f93ea22f7..f31ce3b8b6f 100644 --- a/tests/wpt/web-platform-tests/webdriver/tests/new_session/invalid_capabilities.py +++ b/tests/wpt/web-platform-tests/webdriver/tests/new_session/invalid_capabilities.py @@ -1,8 +1,10 @@ import pytest -from tests.support.asserts import assert_error from conftest import product, flatten +from tests.new_session.support.create import invalid_data, invalid_extensions +from tests.support.asserts import assert_error + @pytest.mark.parametrize("value", [None, 1, "{}", []]) def test_invalid_capabilites(new_session, value): @@ -26,29 +28,6 @@ def test_invalid_first_match(new_session, add_browser_capabilities, value): assert_error(response, "invalid argument") -invalid_data = [ - ("acceptInsecureCerts", [1, [], {}, "false"]), - ("browserName", [1, [], {}, False]), - ("browserVersion", [1, [], {}, False]), - ("platformName", [1, [], {}, False]), - ("pageLoadStrategy", [1, [], {}, False, "invalid", "NONE", "Eager", "eagerblah", "interactive", - " eager", "eager "]), - ("proxy", [1, [], "{}", {"proxyType": "SYSTEM"}, {"proxyType": "systemSomething"}, - {"proxy type": "pac"}, {"proxy-Type": "system"}, {"proxy_type": "system"}, - {"proxytype": "system"}, {"PROXYTYPE": "system"}, {"proxyType": None}, - {"proxyType": 1}, {"proxyType": []}, {"proxyType": {"value": "system"}}, - {" proxyType": "system"}, {"proxyType ": "system"}, {"proxyType ": " system"}, - {"proxyType": "system "}]), - ("timeouts", [1, [], "{}", False, {"pageLOAD": 10}, {"page load": 10}, - {"page load": 10}, {"pageLoad": "10"}, {"pageLoad": {"value": 10}}, - {"invalid": 10}, {"pageLoad": -1}, {"pageLoad": 2**64}, - {"pageLoad": None}, {"pageLoad": 1.1}, {"pageLoad": 10, "invalid": 10}, - {" pageLoad": 10}, {"pageLoad ": 10}]), - ("unhandledPromptBehavior", [1, [], {}, False, "DISMISS", "dismissABC", "Accept", - " dismiss", "dismiss "]) -] - - @pytest.mark.parametrize("body", [lambda key, value: {"alwaysMatch": {key: value}}, lambda key, value: {"firstMatch": [{key: value}]}]) @pytest.mark.parametrize("key,value", flatten(product(*item) for item in invalid_data)) @@ -63,31 +42,6 @@ def test_invalid_values(new_session, add_browser_capabilities, body, key, value) assert_error(response, "invalid argument") -invalid_extensions = [ - "firefox", - "firefox_binary", - "firefoxOptions", - "chromeOptions", - "automaticInspection", - "automaticProfiling", - "platform", - "version", - "browser", - "platformVersion", - "javascriptEnabled", - "nativeEvents", - "seleniumProtocol", - "profile", - "trustAllSSLCertificates", - "initialBrowserUrl", - "requireWindowFocus", - "logFile", - "logLevel", - "safari.options", - "ensureCleanSession", -] - - @pytest.mark.parametrize("body", [lambda key, value: {"alwaysMatch": {key: value}}, lambda key, value: {"firstMatch": [{key: value}]}]) @pytest.mark.parametrize("key", invalid_extensions) diff --git a/tests/wpt/web-platform-tests/webdriver/tests/new_session/support/create.py b/tests/wpt/web-platform-tests/webdriver/tests/new_session/support/create.py index 85ae1cd4ea8..475fe5a424f 100644 --- a/tests/wpt/web-platform-tests/webdriver/tests/new_session/support/create.py +++ b/tests/wpt/web-platform-tests/webdriver/tests/new_session/support/create.py @@ -1,15 +1,130 @@ # Note that we can only test things here all implementations must support valid_data = [ - ("acceptInsecureCerts", [False, None]), - ("browserName", [None]), - ("browserVersion", [None]), - ("platformName", [None]), - ("pageLoadStrategy", ["none", "eager", "normal", None]), - ("proxy", [None]), - ("timeouts", [{"script": 0, "pageLoad": 2.0, "implicit": 2**53 - 1}, - {"script": 50, "pageLoad": 25}, - {"script": 500}, - {}]), - ("unhandledPromptBehavior", ["dismiss", "accept", None]), - ("test:extension", [True, "abc", 123, [], {"key": "value"}, None]), + ("acceptInsecureCerts", [ + False, None, + ]), + ("browserName", [ + None, + ]), + ("browserVersion", [ + None, + ]), + ("platformName", [ + None, + ]), + ("pageLoadStrategy", [ + None, + "none", + "eager", + "normal", + ]), + ("proxy", [ + None, + ]), + ("timeouts", [ + None, {}, + {"script": 0, "pageLoad": 2.0, "implicit": 2**53 - 1}, + {"script": 50, "pageLoad": 25}, + {"script": 500}, + ]), + ("unhandledPromptBehavior", [ + "dismiss", + "accept", + None, + ]), + ("test:extension", [ + None, False, "abc", 123, [], + {"key": "value"}, + ]), +] + +invalid_data = [ + ("acceptInsecureCerts", [ + 1, [], {}, "false", + ]), + ("browserName", [ + 1, [], {}, False, + ]), + ("browserVersion", [ + 1, [], {}, False, + ]), + ("platformName", [ + 1, [], {}, False, + ]), + ("pageLoadStrategy", [ + 1, [], {}, False, + "invalid", + "NONE", + "Eager", + "eagerblah", + "interactive", + " eager", + "eager "]), + ("proxy", [ + 1, [], "{}", + {"proxyType": "SYSTEM"}, + {"proxyType": "systemSomething"}, + {"proxy type": "pac"}, + {"proxy-Type": "system"}, + {"proxy_type": "system"}, + {"proxytype": "system"}, + {"PROXYTYPE": "system"}, + {"proxyType": None}, + {"proxyType": 1}, + {"proxyType": []}, + {"proxyType": {"value": "system"}}, + {" proxyType": "system"}, + {"proxyType ": "system"}, + {"proxyType ": " system"}, + {"proxyType": "system "}, + ]), + ("timeouts", [ + 1, [], "{}", False, + {"invalid": 10}, + {"PAGELOAD": 10}, + {"page load": 10}, + {" pageLoad": 10}, + {"pageLoad ": 10}, + {"pageLoad": None}, + {"pageLoad": False}, + {"pageLoad": []}, + {"pageLoad": "10"}, + {"pageLoad": 2.5}, + {"pageLoad": -1}, + {"pageLoad": 2**53}, + {"pageLoad": {"value": 10}}, + {"pageLoad": 10, "invalid": 10}, + ]), + ("unhandledPromptBehavior", [ + 1, [], {}, False, + "DISMISS", + "dismissABC", + "Accept", + " dismiss", + "dismiss ", + ]) +] + +invalid_extensions = [ + "firefox", + "firefox_binary", + "firefoxOptions", + "chromeOptions", + "automaticInspection", + "automaticProfiling", + "platform", + "version", + "browser", + "platformVersion", + "javascriptEnabled", + "nativeEvents", + "seleniumProtocol", + "profile", + "trustAllSSLCertificates", + "initialBrowserUrl", + "requireWindowFocus", + "logFile", + "logLevel", + "safari.options", + "ensureCleanSession", ] diff --git a/tests/wpt/web-platform-tests/webdriver/tests/send_alert_text/send.py b/tests/wpt/web-platform-tests/webdriver/tests/send_alert_text/send.py index edc37d6edb4..6dbc03f9401 100644 --- a/tests/wpt/web-platform-tests/webdriver/tests/send_alert_text/send.py +++ b/tests/wpt/web-platform-tests/webdriver/tests/send_alert_text/send.py @@ -6,6 +6,13 @@ from tests.support.asserts import assert_error, assert_success from tests.support.inline import inline +@pytest.fixture +def page(session): + session.url = inline(""" + + """) + + def send_alert_text(session, text=None): return session.transport.send( "POST", "session/{session_id}/alert/text".format(**vars(session)), @@ -18,64 +25,41 @@ def test_null_parameter_value(session, http): assert_error(Response.from_http(response), "invalid argument") -def test_null_response_value(session, url): - session.url = inline("") - +def test_null_response_value(session, page): response = send_alert_text(session, "Federer") value = assert_success(response) assert value is None -def test_no_browsing_context(session, closed_window): - response = send_alert_text(session, "foo") - assert_error(response, "no such window") - - @pytest.mark.parametrize("text", [None, {}, [], 42, True]) -def test_invalid_input(session, text): - session.url = inline("") +def test_invalid_input(session, page, text): response = send_alert_text(session, text) assert_error(response, "invalid argument") +def test_no_browsing_context(session, closed_window): + response = send_alert_text(session, "Federer") + assert_error(response, "no such window") + + def test_no_user_prompt(session): response = send_alert_text(session, "Federer") assert_error(response, "no such alert") -def test_alert_element_not_interactable(session): - session.url = inline("") +@pytest.mark.parametrize("dialog_type", ["alert", "confirm"]) +def test_alert_element_not_interactable(session, dialog_type): + session.url = inline("".format(dialog_type)) response = send_alert_text(session, "Federer") assert_error(response, "element not interactable") -def test_confirm_element_not_interactable(session): - session.url = inline("") - - response = send_alert_text(session, "Federer") - assert_error(response, "element not interactable") - - -def test_send_alert_text(session): - session.url = inline("") - - send_response = send_alert_text(session, "Federer") +@pytest.mark.parametrize("text", ["", "Federer", " Fed erer "]) +def test_send_alert_text(session, page, text): + send_response = send_alert_text(session, text) assert_success(send_response) - accept_response = session.transport.send("POST", "session/{session_id}/alert/accept" - .format(session_id=session.session_id)) - assert_success(accept_response) - assert session.execute_script("return window.result") == "Federer" + session.alert.accept() - -def test_send_alert_text_with_whitespace(session): - session.url = inline("") - - send_response = send_alert_text(session, " Fed erer ") - assert_success(send_response) - - accept_response = session.transport.send("POST", "session/{session_id}/alert/accept" - .format(session_id=session.session_id)) - assert_success(accept_response) - assert session.execute_script("return window.result") == " Fed erer " + assert session.execute_script("return window.result") == text diff --git a/tests/wpt/web-platform-tests/webdriver/tests/set_timeouts/set.py b/tests/wpt/web-platform-tests/webdriver/tests/set_timeouts/set.py index e603e217ec7..a78ab2e68e8 100644 --- a/tests/wpt/web-platform-tests/webdriver/tests/set_timeouts/set.py +++ b/tests/wpt/web-platform-tests/webdriver/tests/set_timeouts/set.py @@ -1,3 +1,5 @@ +import pytest + from webdriver.transport import Response from tests.support.asserts import assert_error, assert_success @@ -16,14 +18,60 @@ def test_null_parameter_value(session, http): def test_null_response_value(session): - response = set_timeouts(session, {"implicit": 1000}) + timeouts = {"implicit": 10, "pageLoad": 10, "script": 10} + response = set_timeouts(session, timeouts) value = assert_success(response) assert value is None - response = set_timeouts(session, {"pageLoad": 1000}) - value = assert_success(response) - assert value is None - response = set_timeouts(session, {"script": 1000}) - value = assert_success(response) - assert value is None +@pytest.mark.parametrize("value", [1, "{}", False, []]) +def test_parameters_invalid(session, value): + response = set_timeouts(session, value) + assert_error(response, "invalid argument") + + +def test_parameters_empty_no_change(session): + original = session.timeouts._get() + + response = set_timeouts(session, {}) + assert_success(response) + + assert session.timeouts._get() == original + + +def test_key_invalid(session): + response = set_timeouts(session, {"foo": 1000}) + assert_error(response, "invalid argument") + + +@pytest.mark.parametrize("typ", ["implicit", "pageLoad", "script"]) +@pytest.mark.parametrize("value", [0, 2.0, 2**53 - 1]) +def test_positive_integer(session, typ, value): + response = set_timeouts(session, {typ: value}) + assert_success(response) + + assert session.timeouts._get(typ) == value + + +@pytest.mark.parametrize("typ", ["implicit", "pageLoad", "script"]) +@pytest.mark.parametrize("value", [None, [], {}, False, "10"]) +def test_value_invalid_types(session, typ, value): + response = set_timeouts(session, {typ: value}) + assert_error(response, "invalid argument") + + +@pytest.mark.parametrize("typ", ["implicit", "pageLoad", "script"]) +@pytest.mark.parametrize("value", [-1, 2.5, 2**53]) +def test_value_positive_integer(session, typ, value): + response = set_timeouts(session, {typ: value}) + assert_error(response, "invalid argument") + + +def test_set_all_fields(session): + timeouts = {"implicit": 10, "pageLoad": 20, "script": 30} + response = set_timeouts(session, timeouts) + assert_success(response) + + assert session.timeouts.implicit == 10 + assert session.timeouts.page_load == 20 + assert session.timeouts.script == 30 diff --git a/tests/wpt/web-platform-tests/webdriver/tests/set_timeouts/user_prompts.py b/tests/wpt/web-platform-tests/webdriver/tests/set_timeouts/user_prompts.py new file mode 100644 index 00000000000..a98d87e9b2e --- /dev/null +++ b/tests/wpt/web-platform-tests/webdriver/tests/set_timeouts/user_prompts.py @@ -0,0 +1,62 @@ +# META: timeout=long + +import pytest + +from tests.support.asserts import assert_success + + +def set_timeouts(session, timeouts): + return session.transport.send( + "POST", "session/{session_id}/timeouts".format(**vars(session)), + timeouts) + + +@pytest.fixture +def check_user_prompt_not_closed(session, create_dialog): + def check_user_prompt_not_closed(dialog_type): + create_dialog(dialog_type, text=dialog_type) + + response = set_timeouts(session, {"script": 100}) + assert_success(response) + + assert session.alert.text == dialog_type + session.alert.dismiss() + + assert session.timeouts.script == 100 + + return check_user_prompt_not_closed + + +@pytest.mark.capabilities({"unhandledPromptBehavior": "accept"}) +@pytest.mark.parametrize("dialog_type", ["alert", "confirm", "prompt"]) +def test_accept(check_user_prompt_not_closed, dialog_type): + check_user_prompt_not_closed(dialog_type) + + +@pytest.mark.capabilities({"unhandledPromptBehavior": "accept and notify"}) +@pytest.mark.parametrize("dialog_type", ["alert", "confirm", "prompt"]) +def test_accept_and_notify(check_user_prompt_not_closed, dialog_type): + check_user_prompt_not_closed(dialog_type) + + +@pytest.mark.capabilities({"unhandledPromptBehavior": "dismiss"}) +@pytest.mark.parametrize("dialog_type", ["alert", "confirm", "prompt"]) +def test_dismiss(check_user_prompt_not_closed, dialog_type): + check_user_prompt_not_closed(dialog_type) + + +@pytest.mark.capabilities({"unhandledPromptBehavior": "dismiss and notify"}) +@pytest.mark.parametrize("dialog_type", ["alert", "confirm", "prompt"]) +def test_dismiss_and_notify(check_user_prompt_not_closed, dialog_type): + check_user_prompt_not_closed(dialog_type) + + +@pytest.mark.capabilities({"unhandledPromptBehavior": "ignore"}) +@pytest.mark.parametrize("dialog_type", ["alert", "confirm", "prompt"]) +def test_ignore(check_user_prompt_not_closed, dialog_type): + check_user_prompt_not_closed(dialog_type) + + +@pytest.mark.parametrize("dialog_type", ["alert", "confirm", "prompt"]) +def test_default(check_user_prompt_not_closed, dialog_type): + check_user_prompt_not_closed(dialog_type) diff --git a/tests/wpt/web-platform-tests/webdriver/tests/support/asserts.py b/tests/wpt/web-platform-tests/webdriver/tests/support/asserts.py index 44c76a96b09..2d305a0f3be 100644 --- a/tests/wpt/web-platform-tests/webdriver/tests/support/asserts.py +++ b/tests/wpt/web-platform-tests/webdriver/tests/support/asserts.py @@ -20,10 +20,10 @@ errors = { "no such element": 404, "no such frame": 404, "no such window": 404, - "script timeout": 408, + "script timeout": 500, "session not created": 500, "stale element reference": 404, - "timeout": 408, + "timeout": 500, "unable to set cookie": 500, "unable to capture screen": 500, "unexpected alert open": 500, diff --git a/tests/wpt/web-platform-tests/webdriver/tests/support/defaults.py b/tests/wpt/web-platform-tests/webdriver/tests/support/defaults.py new file mode 100644 index 00000000000..c2020527a6f --- /dev/null +++ b/tests/wpt/web-platform-tests/webdriver/tests/support/defaults.py @@ -0,0 +1,8 @@ +SCRIPT_TIMEOUT = 30 +PAGE_LOAD_TIMEOUT = 300 +IMPLICIT_WAIT_TIMEOUT = 0 + +WINDOW_SIZE = (800, 600) + +DRIVER_HOST = '127.0.0.1' +DRIVER_PORT = 4444 diff --git a/tests/wpt/web-platform-tests/webdriver/tests/support/fixtures.py b/tests/wpt/web-platform-tests/webdriver/tests/support/fixtures.py deleted file mode 100644 index 64427b4670f..00000000000 --- a/tests/wpt/web-platform-tests/webdriver/tests/support/fixtures.py +++ /dev/null @@ -1,323 +0,0 @@ -from __future__ import print_function - -import copy -import json -import os -import urlparse -import re -import sys - -import webdriver - -from tests.support.http_request import HTTPRequest -from tests.support.wait import wait - -default_host = "http://127.0.0.1" -default_port = "4444" - -default_script_timeout = 30 -default_page_load_timeout = 300 -default_implicit_wait_timeout = 0 - -default_window_size = (800, 600) - -_current_session = None -_custom_session = False - - -def ignore_exceptions(f): - def inner(*args, **kwargs): - try: - return f(*args, **kwargs) - except webdriver.error.WebDriverException as e: - print("Ignored exception %s" % e, file=sys.stderr) - inner.__name__ = f.__name__ - return inner - - -def cleanup_session(session): - """Clean-up the current session for a clean state.""" - @ignore_exceptions - def _dismiss_user_prompts(session): - """Dismiss any open user prompts in windows.""" - current_window = session.window_handle - - for window in _windows(session): - session.window_handle = window - try: - session.alert.dismiss() - except webdriver.NoSuchAlertException: - pass - - session.window_handle = current_window - - @ignore_exceptions - def _ensure_valid_window(session): - """If current window was closed, ensure to have a valid one selected.""" - try: - session.window_handle - except webdriver.NoSuchWindowException: - session.window_handle = session.handles[0] - - @ignore_exceptions - def _restore_timeouts(session): - """Restore modified timeouts to their default values.""" - session.timeouts.implicit = default_implicit_wait_timeout - session.timeouts.page_load = default_page_load_timeout - session.timeouts.script = default_script_timeout - - @ignore_exceptions - def _restore_window_state(session): - """Reset window to an acceptable size. - - This also includes bringing it out of maximized, minimized, - or fullscreened state. - """ - session.window.size = default_window_size - - @ignore_exceptions - def _restore_windows(session): - """Close superfluous windows opened by the test. - - It will not end the session implicitly by closing the last window. - """ - current_window = session.window_handle - - for window in _windows(session, exclude=[current_window]): - session.window_handle = window - if len(session.handles) > 1: - session.close() - - session.window_handle = current_window - - _restore_timeouts(session) - _ensure_valid_window(session) - _dismiss_user_prompts(session) - _restore_windows(session) - _restore_window_state(session) - _switch_to_top_level_browsing_context(session) - - -@ignore_exceptions -def _switch_to_top_level_browsing_context(session): - """If the current browsing context selected by WebDriver is a - `` or an `