diff options
717 files changed, 14613 insertions, 9640 deletions
diff --git a/.github/workflows/pull-request-wpt-export.yml b/.github/workflows/pull-request-wpt-export.yml index aaab9d47907..2ac564dc12f 100644 --- a/.github/workflows/pull-request-wpt-export.yml +++ b/.github/workflows/pull-request-wpt-export.yml @@ -4,6 +4,10 @@ on: types: ['opened', 'synchronize', 'reopened', 'edited', 'closed'] branches: ['main'] +concurrency: + group: ${{ github.head_ref }} + cancel-in-progress: false + jobs: upstream: # Run job only on servo/servo diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 93e1710e464..37a6218347e 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -167,10 +167,6 @@ jobs: run: | .\mach build --use-crown --locked --${{ inputs.profile }} ${{ inputs.build-args }} cp C:\a\servo\servo\target\cargo-timings C:\a\servo\servo\target\cargo-timings-windows -Recurse - - name: Copy resources - if: ${{ runner.environment != 'self-hosted' }} - # GitHub-hosted runners check out the repo on D: drive. - run: cp D:\a\servo\servo\resources C:\a\servo\servo -Recurse - name: Smoketest run: .\mach smoketest --${{ inputs.profile }} - name: Unit tests diff --git a/Cargo.lock b/Cargo.lock index c9520177f77..5a297337f6d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -199,9 +199,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.18" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" dependencies = [ "anstyle", "anstyle-parse", @@ -214,33 +214,33 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" [[package]] name = "anstyle-parse" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" dependencies = [ "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.8" +version = "3.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6680de5231bd6ee4c6191b8a1325daa282b415391ec9d3a37bd34f2060dc73fa" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" dependencies = [ "anstyle", "once_cell_polyfill", @@ -701,9 +701,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.17.0" +version = "3.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee" [[package]] name = "byte-slice-cast" @@ -849,9 +849,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.24" +version = "1.2.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16595d3be041c03b09d08d0858631facccee9221e579704070e6e9e4915d3bc7" +checksum = "956a5e21988b87f372569b66183b78babf23ebc2e744b733e4350a752c4dafac" dependencies = [ "jobserver", "libc", @@ -1059,9 +1059,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "colorchoice" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "colored" @@ -1070,7 +1070,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" dependencies = [ "lazy_static", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1109,6 +1109,7 @@ dependencies = [ "servo_geometry", "stylo_traits", "surfman", + "timers", "tracing", "webrender", "webrender_api", @@ -1227,7 +1228,7 @@ dependencies = [ [[package]] name = "content-security-policy" version = "0.5.4" -source = "git+https://github.com/servo/rust-content-security-policy/?branch=servo-csp#58a09ee320fd6fbb828748ae04255e4c8d3f9c9e" +source = "git+https://github.com/servo/rust-content-security-policy/?branch=servo-csp#dc1fd32b2b32b704a43f4ae170bb2cbb80a7cf59" dependencies = [ "base64 0.22.1", "bitflags 2.9.1", @@ -1594,7 +1595,7 @@ dependencies = [ "crossbeam-channel", "devtools_traits", "embedder_traits", - "headers 0.4.0", + "headers 0.4.1", "http 1.3.1", "ipc-channel", "log", @@ -3157,11 +3158,11 @@ dependencies = [ [[package]] name = "headers" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322106e6bd0cba2d5ead589ddb8150a13d7c4217cf80d7c4f682ca994ccc6aa9" +checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "bytes", "headers-core 0.3.0", "http 1.3.1", @@ -3196,12 +3197,6 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hermit-abi" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" @@ -3247,9 +3242,9 @@ dependencies = [ [[package]] name = "hitrace" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92c0ae6f30b32eaeb811143fba3b56864f477b2e69458b13779a07b3aaf2f6e" +checksum = "4e3037245d690359ac992d8e3bb96e15ace6ad0a00305b680f4b1fd4ede684d9" dependencies = [ "hitrace-sys", ] @@ -3415,9 +3410,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c293b6b3d21eca78250dc7dbebd6b9210ec5530e038cbfe0661b5c47ab06e8" +checksum = "dc2fdfdbff08affe55bb779f33b053aa1fe5dd5b54c257343c17edfa55711bdb" dependencies = [ "bytes", "futures-channel", @@ -3439,7 +3434,7 @@ name = "hyper_serde" version = "0.13.2" dependencies = [ "cookie 0.18.1", - "headers 0.4.0", + "headers 0.4.1", "http 1.3.1", "hyper 1.6.0", "mime", @@ -4439,9 +4434,9 @@ checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" dependencies = [ "autocfg", "scopeguard", @@ -4864,7 +4859,7 @@ dependencies = [ "futures-core", "futures-util", "generic-array", - "headers 0.4.0", + "headers 0.4.1", "http 1.3.1", "http-body-util", "hyper 1.6.0", @@ -4917,7 +4912,7 @@ dependencies = [ "crossbeam-channel", "data-url", "embedder_traits", - "headers 0.4.0", + "headers 0.4.1", "http 1.3.1", "hyper-util", "hyper_serde", @@ -5053,11 +5048,11 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" dependencies = [ - "hermit-abi 0.3.9", + "hermit-abi 0.5.0", "libc", ] @@ -5395,9 +5390,9 @@ dependencies = [ [[package]] name = "ohos-ime" -version = "0.2.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48107e68ed8451c17c2ff95938e1ba86003fb290a04f7a0213ce2d16ce4b3ee6" +checksum = "c28c803dbc0fa52e888c62c0a3573ea7559e5283ac10d1d3a75f064dba032575" dependencies = [ "log", "ohos-ime-sys", @@ -5405,15 +5400,15 @@ dependencies = [ [[package]] name = "ohos-ime-sys" -version = "0.1.4" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f68e03eb5b698781a69dc4918a17fe040a30be87de7014c12e4a2a3cb8a00f" +checksum = "89d326ae2b2e71f95ca756b7d418c0adcb0018889e73f7eabed59671cb179608" [[package]] name = "ohos-sys-opaque-types" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e59a875cf4950c9d16fda34b7e619e559b5e7db2642ef5bafac5e7cd98539940" +checksum = "463c7a72b9abdef3e78d580284cccbef4b1a4a46588d64f02f68d04030a304b9" [[package]] name = "ohos-vsync" @@ -5531,9 +5526,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" dependencies = [ "lock_api", "parking_lot_core", @@ -5541,9 +5536,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ "cfg-if", "libc", @@ -5805,9 +5800,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" [[package]] name = "portable-atomic-util" @@ -5847,9 +5842,9 @@ checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" [[package]] name = "prettyplease" -version = "0.2.32" +version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "664ec5419c51e34154eec046ebcba56312d5a2fc3b09a06da188e1ad21afadf6" +checksum = "9dee91521343f4c5c6a63edd65e54f31f5c92fe8978c40a4282f8372194c6a7d" dependencies = [ "proc-macro2", "syn", @@ -6409,7 +6404,7 @@ dependencies = [ "fonts_traits", "fxhash", "glow", - "headers 0.4.0", + "headers 0.4.1", "html5ever", "http 1.3.1", "hyper_serde", @@ -6612,7 +6607,7 @@ dependencies = [ [[package]] name = "selectors" version = "0.28.0" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#610fcfb48987d75b7d1d53887882fcdb244d74ee" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#945b70e9a1984cd44ee56b7a674c302b19a4f620" dependencies = [ "bitflags 2.9.1", "cssparser", @@ -6678,9 +6673,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" dependencies = [ "serde", ] @@ -6907,7 +6902,7 @@ dependencies = [ [[package]] name = "servo_arc" version = "0.4.1" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#610fcfb48987d75b7d1d53887882fcdb244d74ee" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#945b70e9a1984cd44ee56b7a674c302b19a4f620" dependencies = [ "serde", "stable_deref_trait", @@ -7026,7 +7021,7 @@ dependencies = [ "getopts", "gilrs", "glow", - "headers 0.4.0", + "headers 0.4.1", "hilog", "hitrace", "image", @@ -7368,7 +7363,7 @@ dependencies = [ [[package]] name = "stylo" version = "0.3.0" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#610fcfb48987d75b7d1d53887882fcdb244d74ee" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#945b70e9a1984cd44ee56b7a674c302b19a4f620" dependencies = [ "app_units", "arrayvec", @@ -7426,7 +7421,7 @@ dependencies = [ [[package]] name = "stylo_atoms" version = "0.3.0" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#610fcfb48987d75b7d1d53887882fcdb244d74ee" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#945b70e9a1984cd44ee56b7a674c302b19a4f620" dependencies = [ "string_cache", "string_cache_codegen", @@ -7435,12 +7430,12 @@ dependencies = [ [[package]] name = "stylo_config" version = "0.3.0" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#610fcfb48987d75b7d1d53887882fcdb244d74ee" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#945b70e9a1984cd44ee56b7a674c302b19a4f620" [[package]] name = "stylo_derive" version = "0.3.0" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#610fcfb48987d75b7d1d53887882fcdb244d74ee" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#945b70e9a1984cd44ee56b7a674c302b19a4f620" dependencies = [ "darling", "proc-macro2", @@ -7452,7 +7447,7 @@ dependencies = [ [[package]] name = "stylo_dom" version = "0.3.0" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#610fcfb48987d75b7d1d53887882fcdb244d74ee" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#945b70e9a1984cd44ee56b7a674c302b19a4f620" dependencies = [ "bitflags 2.9.1", "stylo_malloc_size_of", @@ -7461,7 +7456,7 @@ dependencies = [ [[package]] name = "stylo_malloc_size_of" version = "0.3.0" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#610fcfb48987d75b7d1d53887882fcdb244d74ee" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#945b70e9a1984cd44ee56b7a674c302b19a4f620" dependencies = [ "app_units", "cssparser", @@ -7478,12 +7473,12 @@ dependencies = [ [[package]] name = "stylo_static_prefs" version = "0.3.0" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#610fcfb48987d75b7d1d53887882fcdb244d74ee" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#945b70e9a1984cd44ee56b7a674c302b19a4f620" [[package]] name = "stylo_traits" version = "0.3.0" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#610fcfb48987d75b7d1d53887882fcdb244d74ee" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#945b70e9a1984cd44ee56b7a674c302b19a4f620" dependencies = [ "app_units", "bitflags 2.9.1", @@ -7892,7 +7887,7 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "to_shmem" version = "0.2.0" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#610fcfb48987d75b7d1d53887882fcdb244d74ee" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#945b70e9a1984cd44ee56b7a674c302b19a4f620" dependencies = [ "cssparser", "servo_arc", @@ -7905,7 +7900,7 @@ dependencies = [ [[package]] name = "to_shmem_derive" version = "0.1.0" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#610fcfb48987d75b7d1d53887882fcdb244d74ee" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#945b70e9a1984cd44ee56b7a674c302b19a4f620" dependencies = [ "darling", "proc-macro2", @@ -7998,9 +7993,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" dependencies = [ "serde", ] @@ -8044,9 +8039,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +checksum = "1b1ffbcf9c6f6b99d386e7444eb608ba646ae452a36b39737deb9663b610f662" dependencies = [ "proc-macro2", "quote", @@ -8055,9 +8050,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ "once_cell", "valuable", @@ -9074,7 +9069,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -9799,9 +9794,9 @@ dependencies = [ [[package]] name = "zune-jpeg" -version = "0.4.14" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99a5bab8d7dedf81405c4bb1f2b83ea057643d9cb28778cea9eecddeedd2e028" +checksum = "3e4a518c0ea2576f4da876349d7f67a7be489297cd77c2cf9e04c2e05fcd3974" dependencies = [ "zune-core", ] diff --git a/Cargo.toml b/Cargo.toml index b24a468abd0..0fc9d90bf14 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,7 +70,7 @@ gstreamer-sys = "0.23" gstreamer-video = "0.23" harfbuzz-sys = "0.6.1" headers = "0.4" -hitrace = "0.1.4" +hitrace = "0.1.5" html5ever = "0.31" http = "1.3" http-body-util = "0.1" @@ -100,7 +100,7 @@ mozangle = "0.5.3" net_traits = { path = "components/shared/net" } nix = "0.29" num-traits = "0.2" -num_cpus = "1.1.0" +num_cpus = "1.17.0" openxr = "0.19" parking_lot = "0.12" percent-encoding = "2.3" diff --git a/components/canvas/backend.rs b/components/canvas/backend.rs index 7e348fbc9b9..b7296b81ba3 100644 --- a/components/canvas/backend.rs +++ b/components/canvas/backend.rs @@ -2,6 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use std::borrow::Cow; + use canvas_traits::canvas::{ CompositionOrBlending, FillOrStrokeStyle, LineCapStyle, LineJoinStyle, }; @@ -21,7 +23,6 @@ pub(crate) trait Backend: Clone + Sized { type DrawTarget: GenericDrawTarget<Self>; type PathBuilder: GenericPathBuilder<Self>; type SourceSurface; - type Bytes<'a>: AsRef<[u8]>; type Path: PathHelpers<Self> + Clone; type GradientStop; type GradientStops; @@ -122,7 +123,7 @@ pub(crate) trait GenericDrawTarget<B: Backend> { draw_options: &B::DrawOptions, ); fn surface(&self) -> B::SourceSurface; - fn bytes(&'_ self) -> B::Bytes<'_>; + fn bytes(&self) -> Cow<[u8]>; } /// A generic PathBuilder that abstracts the interface for azure's and raqote's PathBuilder. diff --git a/components/canvas/canvas_data.rs b/components/canvas/canvas_data.rs index ea30589d0af..90b26df1cda 100644 --- a/components/canvas/canvas_data.rs +++ b/components/canvas/canvas_data.rs @@ -154,7 +154,18 @@ struct PathBuilderRef<'a, B: Backend> { } impl<B: Backend> PathBuilderRef<'_, B> { + /// <https://html.spec.whatwg.org/multipage#ensure-there-is-a-subpath> + fn ensure_there_is_a_subpath(&mut self, point: &Point2D<f32>) { + if self.builder.get_current_point().is_none() { + self.builder.move_to(*point); + } + } + + /// <https://html.spec.whatwg.org/multipage#dom-context-2d-lineto> fn line_to(&mut self, pt: &Point2D<f32>) { + // 2. If the object's path has no subpaths, then ensure there is a subpath for (x, y). + self.ensure_there_is_a_subpath(pt); + let pt = self.transform.transform_point(*pt); self.builder.line_to(pt); } @@ -182,14 +193,22 @@ impl<B: Backend> PathBuilderRef<'_, B> { self.move_to(&first); } + /// <https://html.spec.whatwg.org/multipage#dom-context-2d-quadraticcurveto> fn quadratic_curve_to(&mut self, cp: &Point2D<f32>, endpoint: &Point2D<f32>) { + // 2. Ensure there is a subpath for (cpx, cpy). + self.ensure_there_is_a_subpath(cp); + self.builder.quadratic_curve_to( &self.transform.transform_point(*cp), &self.transform.transform_point(*endpoint), ) } + /// <https://html.spec.whatwg.org/multipage#dom-context-2d-beziercurveto> fn bezier_curve_to(&mut self, cp1: &Point2D<f32>, cp2: &Point2D<f32>, endpoint: &Point2D<f32>) { + // 2. Ensure there is a subpath for (cp1x, cp1y). + self.ensure_there_is_a_subpath(cp1); + self.builder.bezier_curve_to( &self.transform.transform_point(*cp1), &self.transform.transform_point(*cp2), @@ -210,6 +229,7 @@ impl<B: Backend> PathBuilderRef<'_, B> { .arc(center, radius, start_angle, end_angle, ccw); } + /// <https://html.spec.whatwg.org/multipage#dom-context-2d-arcto> fn arc_to(&mut self, cp1: &Point2D<f32>, cp2: &Point2D<f32>, radius: f32) { let cp0 = if let (Some(inverse), Some(point)) = (self.transform.inverse(), self.builder.get_current_point()) @@ -218,6 +238,9 @@ impl<B: Backend> PathBuilderRef<'_, B> { } else { *cp1 }; + + // 2. Ensure there is a subpath for (x1, y1) is done by one of self.line_to calls + if (cp0.x == cp1.x && cp0.y == cp1.y) || cp1 == cp2 || radius == 0.0 { self.line_to(cp1); return; @@ -447,7 +470,7 @@ impl<'a, B: Backend> CanvasData<'a, B> { pub(crate) fn draw_image( &mut self, image_data: &[u8], - image_size: Size2D<u64>, + image_size: Size2D<u32>, dest_rect: Rect<f64>, source_rect: Rect<f64>, smoothing_enabled: bool, @@ -457,7 +480,7 @@ impl<'a, B: Backend> CanvasData<'a, B> { let source_rect = source_rect.ceil(); // It discards the extra pixels (if any) that won't be painted let image_data = if Rect::from_size(image_size.to_f64()).contains_rect(&source_rect) { - pixels::rgba8_get_rect(image_data, image_size, source_rect.to_u64()).into() + pixels::rgba8_get_rect(image_data, image_size, source_rect.to_u32()).into() } else { image_data.into() }; @@ -1221,7 +1244,7 @@ impl<'a, B: Backend> CanvasData<'a, B> { } // https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata - pub(crate) fn put_image_data(&mut self, mut imagedata: Vec<u8>, rect: Rect<u64>) { + pub(crate) fn put_image_data(&mut self, mut imagedata: Vec<u8>, rect: Rect<u32>) { assert_eq!(imagedata.len() % 4, 0); assert_eq!(rect.size.area() as usize, imagedata.len() / 4); pixels::rgba8_byte_swap_and_premultiply_inplace(&mut imagedata); @@ -1310,8 +1333,8 @@ impl<'a, B: Backend> CanvasData<'a, B> { #[allow(unsafe_code)] pub(crate) fn read_pixels( &self, - read_rect: Option<Rect<u64>>, - canvas_size: Option<Size2D<u64>>, + read_rect: Option<Rect<u32>>, + canvas_size: Option<Size2D<u32>>, ) -> Snapshot { let canvas_size = canvas_size.unwrap_or(self.drawtarget.get_size().cast()); @@ -1327,7 +1350,7 @@ impl<'a, B: Backend> CanvasData<'a, B> { .to_vec() } } else { - self.drawtarget.bytes().as_ref().to_vec() + self.drawtarget.bytes().into_owned() }; Snapshot::from_vec( diff --git a/components/canvas/canvas_paint_thread.rs b/components/canvas/canvas_paint_thread.rs index 82a221d560d..93aff081c35 100644 --- a/components/canvas/canvas_paint_thread.rs +++ b/components/canvas/canvas_paint_thread.rs @@ -97,7 +97,10 @@ impl<'a> CanvasPaintThread<'a> { let canvas_data = canvas_paint_thread.create_canvas(size); creator.send(canvas_data).unwrap(); }, - Ok(ConstellationCanvasMsg::Exit) => break, + Ok(ConstellationCanvasMsg::Exit(exit_sender)) => { + let _ = exit_sender.send(()); + break; + }, Err(e) => { warn!("Error on CanvasPaintThread receive ({})", e); break; @@ -184,7 +187,7 @@ impl<'a> CanvasPaintThread<'a> { Canvas2dMsg::DrawEmptyImage(image_size, dest_rect, source_rect) => { self.canvas(canvas_id).draw_image( &vec![0; image_size.area() as usize * 4], - image_size.to_u64(), + image_size, dest_rect, source_rect, false, @@ -200,10 +203,10 @@ impl<'a> CanvasPaintThread<'a> { ) => { let image_data = self .canvas(canvas_id) - .read_pixels(Some(source_rect.to_u64()), Some(image_size.to_u64())); + .read_pixels(Some(source_rect.to_u32()), Some(image_size)); self.canvas(other_canvas_id).draw_image( image_data.data(), - source_rect.size.to_u64(), + source_rect.size.to_u32(), dest_rect, source_rect, smoothing, @@ -395,7 +398,7 @@ impl Canvas<'_> { fn draw_image( &mut self, data: &[u8], - size: Size2D<u64>, + size: Size2D<u32>, dest_rect: Rect<f64>, source_rect: Rect<f64>, smoothing_enabled: bool, @@ -415,8 +418,8 @@ impl Canvas<'_> { fn read_pixels( &mut self, - read_rect: Option<Rect<u64>>, - canvas_size: Option<Size2D<u64>>, + read_rect: Option<Rect<u32>>, + canvas_size: Option<Size2D<u32>>, ) -> snapshot::Snapshot { match self { Canvas::Raqote(canvas_data) => canvas_data.read_pixels(read_rect, canvas_size), @@ -609,7 +612,7 @@ impl Canvas<'_> { } } - fn put_image_data(&mut self, unwrap: Vec<u8>, rect: Rect<u64>) { + fn put_image_data(&mut self, unwrap: Vec<u8>, rect: Rect<u32>) { match self { Canvas::Raqote(canvas_data) => canvas_data.put_image_data(unwrap, rect), } diff --git a/components/canvas/raqote_backend.rs b/components/canvas/raqote_backend.rs index ecf780c36d5..02d87dfcd54 100644 --- a/components/canvas/raqote_backend.rs +++ b/components/canvas/raqote_backend.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use std::borrow::Cow; use std::cell::RefCell; use std::collections::HashMap; @@ -41,7 +42,6 @@ impl Backend for RaqoteBackend { type DrawTarget = raqote::DrawTarget; type PathBuilder = PathBuilder; type SourceSurface = Vec<u8>; // TODO: See if we can avoid the alloc (probably?) - type Bytes<'a> = &'a [u8]; type Path = raqote::Path; type GradientStop = raqote::GradientStop; type GradientStops = Vec<raqote::GradientStop>; @@ -656,9 +656,11 @@ impl GenericDrawTarget<RaqoteBackend> for raqote::DrawTarget { ); } #[allow(unsafe_code)] - fn bytes(&self) -> &[u8] { + fn bytes(&self) -> Cow<[u8]> { let v = self.get_data(); - unsafe { std::slice::from_raw_parts(v.as_ptr() as *const u8, std::mem::size_of_val(v)) } + Cow::Borrowed(unsafe { + std::slice::from_raw_parts(v.as_ptr() as *const u8, std::mem::size_of_val(v)) + }) } } @@ -708,7 +710,7 @@ impl GenericPathBuilder<RaqoteBackend> for PathBuilder { PathOp::MoveTo(point) | PathOp::LineTo(point) => Some(Point2D::new(point.x, point.y)), PathOp::CubicTo(_, _, point) => Some(Point2D::new(point.x, point.y)), PathOp::QuadTo(_, point) => Some(Point2D::new(point.x, point.y)), - PathOp::Close => None, + PathOp::Close => path.ops.first().and_then(get_first_point), }) } @@ -731,6 +733,15 @@ impl GenericPathBuilder<RaqoteBackend> for PathBuilder { } } +fn get_first_point(op: &PathOp) -> Option<euclid::Point2D<f32, euclid::UnknownUnit>> { + match op { + PathOp::MoveTo(point) | PathOp::LineTo(point) => Some(Point2D::new(point.x, point.y)), + PathOp::CubicTo(point, _, _) => Some(Point2D::new(point.x, point.y)), + PathOp::QuadTo(point, _) => Some(Point2D::new(point.x, point.y)), + PathOp::Close => None, + } +} + pub trait ToRaqoteStyle { type Target; diff --git a/components/compositing/Cargo.toml b/components/compositing/Cargo.toml index 9b4ff54d29e..084bb54a5fc 100644 --- a/components/compositing/Cargo.toml +++ b/components/compositing/Cargo.toml @@ -38,6 +38,7 @@ servo_allocator = { path = "../allocator" } servo_config = { path = "../config" } servo_geometry = { path = "../geometry" } stylo_traits = { workspace = true } +timers = { path = "../timers" } tracing = { workspace = true, optional = true } webrender = { workspace = true } webrender_api = { workspace = true } diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index 27d1e8f93e1..a4afeb01b3c 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -9,7 +9,7 @@ use std::fs::create_dir_all; use std::iter::once; use std::rc::Rc; use std::sync::Arc; -use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; +use std::time::{SystemTime, UNIX_EPOCH}; use base::cross_process_instant::CrossProcessInstant; use base::id::{PipelineId, WebViewId}; @@ -53,6 +53,7 @@ use webrender_api::{ }; use crate::InitialCompositorState; +use crate::refresh_driver::RefreshDriver; use crate::webview_manager::WebViewManager; use crate::webview_renderer::{PinchZoomResult, UnknownWebView, WebViewRenderer}; @@ -86,6 +87,9 @@ pub enum WebRenderDebugOption { } /// Data that is shared by all WebView renderers. pub struct ServoRenderer { + /// The [`RefreshDriver`] which manages the rythym of painting. + refresh_driver: RefreshDriver, + /// This is a temporary map between [`PipelineId`]s and their associated [`WebViewId`]. Once /// all renderer operations become per-`WebView` this map can be removed, but we still sometimes /// need to work backwards to figure out what `WebView` is associated with a `Pipeline`. @@ -151,18 +155,14 @@ pub struct IOCompositor { /// The number of frames pending to receive from WebRender. pending_frames: usize, - /// The [`Instant`] of the last animation tick, used to avoid flooding the Constellation and - /// ScriptThread with a deluge of animation ticks. - last_animation_tick: Instant, - /// A handle to the memory profiler which will automatically unregister /// when it's dropped. _mem_profiler_registration: ProfilerRegistration, } /// Why we need to be repainted. This is used for debugging. -#[derive(Clone, Copy, Default)] -struct RepaintReason(u8); +#[derive(Clone, Copy, Default, PartialEq)] +pub(crate) struct RepaintReason(u8); bitflags! { impl RepaintReason: u8 { @@ -281,6 +281,11 @@ impl PipelineDetails { } } +pub enum HitTestError { + EpochMismatch, + Others, +} + impl ServoRenderer { pub fn shutdown_state(&self) -> ShutdownState { self.shutdown_state.get() @@ -290,15 +295,19 @@ impl ServoRenderer { &self, point: DevicePoint, details_for_pipeline: impl Fn(PipelineId) -> Option<&'a PipelineDetails>, - ) -> Option<CompositorHitTestResult> { - self.hit_test_at_point_with_flags_and_pipeline( + ) -> Result<CompositorHitTestResult, HitTestError> { + match self.hit_test_at_point_with_flags_and_pipeline( point, HitTestFlags::empty(), None, details_for_pipeline, - ) - .first() - .cloned() + ) { + Ok(hit_test_results) => hit_test_results + .first() + .cloned() + .ok_or(HitTestError::Others), + Err(error) => Err(error), + } } // TODO: split this into first half (global) and second half (one for whole compositor, one for webview) @@ -308,14 +317,15 @@ impl ServoRenderer { flags: HitTestFlags, pipeline_id: Option<WebRenderPipelineId>, details_for_pipeline: impl Fn(PipelineId) -> Option<&'a PipelineDetails>, - ) -> Vec<CompositorHitTestResult> { + ) -> Result<Vec<CompositorHitTestResult>, HitTestError> { // DevicePoint and WorldPoint are the same for us. let world_point = WorldPoint::from_untyped(point.to_untyped()); let results = self.webrender_api .hit_test(self.webrender_document, pipeline_id, world_point, flags); - results + let mut epoch_mismatch = false; + let results = results .items .iter() .filter_map(|item| { @@ -323,10 +333,16 @@ impl ServoRenderer { let details = details_for_pipeline(pipeline_id)?; // If the epoch in the tag does not match the current epoch of the pipeline, - // then the hit test is against an old version of the display list and we - // should ignore this hit test for now. + // then the hit test is against an old version of the display list. match details.most_recent_display_list_epoch { - Some(epoch) if epoch.as_u16() == item.tag.1 => {}, + Some(epoch) => { + if epoch.as_u16() != item.tag.1 { + // It's too early to hit test for now. + // New scene building is in progress. + epoch_mismatch = true; + return None; + } + }, _ => return None, } @@ -340,7 +356,13 @@ impl ServoRenderer { scroll_tree_node: info.scroll_tree_node, }) }) - .collect() + .collect(); + + if epoch_mismatch { + return Err(HitTestError::EpochMismatch); + } + + Ok(results) } pub(crate) fn send_transaction(&mut self, transaction: Transaction) { @@ -386,6 +408,10 @@ impl IOCompositor { ); let compositor = IOCompositor { global: Rc::new(RefCell::new(ServoRenderer { + refresh_driver: RefreshDriver::new( + state.constellation_chan.clone(), + state.event_loop_waker, + ), shutdown_state: state.shutdown_state, pipeline_to_webview_map: Default::default(), compositor_receiver: state.receiver, @@ -406,7 +432,6 @@ impl IOCompositor { webrender: Some(state.webrender), rendering_context: state.rendering_context, pending_frames: 0, - last_animation_tick: Instant::now(), _mem_profiler_registration: registration, }; @@ -450,7 +475,16 @@ impl IOCompositor { } pub fn needs_repaint(&self) -> bool { - !self.needs_repaint.get().is_empty() + let repaint_reason = self.needs_repaint.get(); + if repaint_reason.is_empty() { + return false; + } + + !self + .global + .borrow() + .refresh_driver + .wait_to_paint(repaint_reason) } pub fn finish_shutting_down(&mut self) { @@ -519,15 +553,17 @@ impl IOCompositor { pipeline_id, animation_state, ) => { - if let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) { - if webview_renderer - .change_pipeline_running_animations_state(pipeline_id, animation_state) && - webview_renderer.animating() - { - // These operations should eventually happen per-WebView, but they are - // global now as rendering is still global to all WebViews. - self.process_animations(true); - } + let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) else { + return; + }; + + if webview_renderer + .change_pipeline_running_animations_state(pipeline_id, animation_state) + { + self.global + .borrow() + .refresh_driver + .notify_animation_state_changed(webview_renderer); } }, @@ -572,14 +608,15 @@ impl IOCompositor { }, CompositorMsg::SetThrottled(webview_id, pipeline_id, throttled) => { - if let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) { - if webview_renderer.set_throttled(pipeline_id, throttled) && - webview_renderer.animating() - { - // These operations should eventually happen per-WebView, but they are - // global now as rendering is still global to all WebViews. - self.process_animations(true); - } + let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) else { + return; + }; + + if webview_renderer.set_throttled(pipeline_id, throttled) { + self.global + .borrow() + .refresh_driver + .notify_animation_state_changed(webview_renderer); } }, @@ -604,7 +641,7 @@ impl IOCompositor { .global .borrow() .hit_test_at_point(point, details_for_pipeline); - if let Some(result) = result { + if let Ok(result) = result { self.global.borrow_mut().update_cursor(point, &result); } } @@ -634,7 +671,7 @@ impl IOCompositor { }; let dppx = webview_renderer.device_pixels_per_page_pixel(); let point = dppx.transform_point(Point2D::new(x, y)); - webview_renderer.dispatch_input_event( + webview_renderer.dispatch_point_input_event( InputEvent::MouseButton(MouseButtonEvent::new(action, button, point)) .with_webdriver_message_id(Some(message_id)), ); @@ -647,7 +684,7 @@ impl IOCompositor { }; let dppx = webview_renderer.device_pixels_per_page_pixel(); let point = dppx.transform_point(Point2D::new(x, y)); - webview_renderer.dispatch_input_event( + webview_renderer.dispatch_point_input_event( InputEvent::MouseMove(MouseMoveEvent::new(point)) .with_webdriver_message_id(Some(message_id)), ); @@ -669,7 +706,7 @@ impl IOCompositor { let scroll_delta = dppx.transform_vector(Vector2D::new(delta_x as f32, delta_y as f32)); webview_renderer - .dispatch_input_event(InputEvent::Wheel(WheelEvent { delta, point })); + .dispatch_point_input_event(InputEvent::Wheel(WheelEvent { delta, point })); webview_renderer.on_webdriver_wheel_action(scroll_delta, point); }, @@ -777,6 +814,8 @@ impl IOCompositor { let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) else { return warn!("Could not find WebView for incoming display list"); }; + // WebRender is not ready until we receive "NewWebRenderFrameReady" + webview_renderer.webrender_frame_ready.set(false); let pipeline_id = display_list_info.pipeline_id; let details = webview_renderer.ensure_pipeline_details(pipeline_id.into()); @@ -826,7 +865,8 @@ impl IOCompositor { flags, pipeline, details_for_pipeline, - ); + ) + .unwrap_or_default(); let _ = sender.send(result); }, @@ -933,6 +973,11 @@ impl IOCompositor { warn!("Sending response to get screen size failed ({error:?})."); } }, + CompositorMsg::Viewport(webview_id, viewport_description) => { + if let Some(webview) = self.webview_renderers.get_mut(webview_id) { + webview.set_viewport_description(viewport_description); + } + }, } } @@ -1271,39 +1316,6 @@ impl IOCompositor { self.set_needs_repaint(RepaintReason::Resize); } - /// If there are any animations running, dispatches appropriate messages to the constellation. - fn process_animations(&mut self, force: bool) { - // When running animations in order to dump a screenshot (not after a full composite), don't send - // animation ticks faster than about 60Hz. - // - // TODO: This should be based on the refresh rate of the screen and also apply to all - // animation ticks, not just ones sent while waiting to dump screenshots. This requires - // something like a refresh driver concept though. - if !force && (Instant::now() - self.last_animation_tick) < Duration::from_millis(16) { - return; - } - self.last_animation_tick = Instant::now(); - - let animating_webviews: Vec<_> = self - .webview_renderers - .iter() - .filter_map(|webview_renderer| { - if webview_renderer.animating() { - Some(webview_renderer.id) - } else { - None - } - }) - .collect(); - if !animating_webviews.is_empty() { - if let Err(error) = self.global.borrow().constellation_sender.send( - EmbedderToConstellationMessage::TickAnimation(animating_webviews), - ) { - warn!("Sending tick to constellation failed ({error:?})."); - } - } - } - pub fn on_zoom_reset_window_event(&mut self, webview_id: WebViewId) { if self.global.borrow().shutdown_state() != ShutdownState::NotShuttingDown { return; @@ -1410,6 +1422,11 @@ impl IOCompositor { /// Render the WebRender scene to the active `RenderingContext`. If successful, trigger /// the next round of animations. pub fn render(&mut self) -> bool { + self.global + .borrow() + .refresh_driver + .notify_will_paint(self.webview_renderers.iter()); + if let Err(error) = self.render_inner() { warn!("Unable to render: {error:?}"); return false; @@ -1419,9 +1436,6 @@ impl IOCompositor { // the scene no longer needs to be repainted. self.needs_repaint.set(RepaintReason::empty()); - // Queue up any subsequent paints for animations. - self.process_animations(true); - true } @@ -1492,10 +1506,8 @@ impl IOCompositor { if opts::get().wait_for_stable_image { // The current image may be ready to output. However, if there are animations active, - // tick those instead and continue waiting for the image output to be stable AND - // all active animations to complete. + // continue waiting for the image output to be stable AND all active animations to complete. if self.animations_or_animation_callbacks_running() { - self.process_animations(false); return Err(UnableToComposite::NotReadyToPaintImage( NotReadyToPaint::AnimationsActive, )); @@ -1647,11 +1659,20 @@ impl IOCompositor { }, CompositorMsg::NewWebRenderFrameReady(..) => { found_recomposite_msg = true; - compositor_messages.push(msg) + compositor_messages.push(msg); }, _ => compositor_messages.push(msg), } } + + if found_recomposite_msg { + // Process all pending events + self.webview_renderers.iter().for_each(|webview| { + webview.dispatch_pending_point_input_events(); + webview.webrender_frame_ready.set(true); + }); + } + for msg in compositor_messages { self.handle_browser_message(msg); diff --git a/components/compositing/lib.rs b/components/compositing/lib.rs index a66c61499e5..4faeadf5ba6 100644 --- a/components/compositing/lib.rs +++ b/components/compositing/lib.rs @@ -11,7 +11,7 @@ use compositing_traits::rendering_context::RenderingContext; use compositing_traits::{CompositorMsg, CompositorProxy}; use constellation_traits::EmbedderToConstellationMessage; use crossbeam_channel::{Receiver, Sender}; -use embedder_traits::ShutdownState; +use embedder_traits::{EventLoopWaker, ShutdownState}; use profile_traits::{mem, time}; use webrender::RenderApi; use webrender_api::DocumentId; @@ -22,9 +22,10 @@ pub use crate::compositor::{IOCompositor, WebRenderDebugOption}; mod tracing; mod compositor; +mod refresh_driver; mod touch; -pub mod webview_manager; -pub mod webview_renderer; +mod webview_manager; +mod webview_renderer; /// Data used to construct a compositor. pub struct InitialCompositorState { @@ -49,4 +50,7 @@ pub struct InitialCompositorState { pub webrender_gl: Rc<dyn gleam::gl::Gl>, #[cfg(feature = "webxr")] pub webxr_main_thread: webxr::MainThreadRegistry, + /// An [`EventLoopWaker`] used in order to wake up the embedder when it is + /// time to paint. + pub event_loop_waker: Box<dyn EventLoopWaker>, } diff --git a/components/compositing/refresh_driver.rs b/components/compositing/refresh_driver.rs new file mode 100644 index 00000000000..5531a7257c8 --- /dev/null +++ b/components/compositing/refresh_driver.rs @@ -0,0 +1,234 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +use std::cell::Cell; +use std::collections::hash_map::Values; +use std::sync::Arc; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::thread::{self, JoinHandle}; +use std::time::Duration; + +use base::id::WebViewId; +use constellation_traits::EmbedderToConstellationMessage; +use crossbeam_channel::{Sender, select}; +use embedder_traits::EventLoopWaker; +use log::warn; +use timers::{BoxedTimerCallback, TimerEventId, TimerEventRequest, TimerScheduler, TimerSource}; + +use crate::compositor::RepaintReason; +use crate::webview_renderer::WebViewRenderer; + +const FRAME_DURATION: Duration = Duration::from_millis(1000 / 120); + +/// The [`RefreshDriver`] is responsible for controlling updates to aall `WebView`s +/// onscreen presentation. Currently, it only manages controlling animation update +/// requests. +/// +/// The implementation is very basic at the moment, only requesting new animation +/// frames at a constant time after a repaint. +pub(crate) struct RefreshDriver { + /// The channel on which messages can be sent to the Constellation. + pub(crate) constellation_sender: Sender<EmbedderToConstellationMessage>, + + /// Whether or not we are currently animating via a timer. + pub(crate) animating: Cell<bool>, + + /// Whether or not we are waiting for our frame timeout to trigger + pub(crate) waiting_for_frame_timeout: Arc<AtomicBool>, + + /// A [`TimerThread`] which is used to schedule frame timeouts in the future. + timer_thread: TimerThread, + + /// An [`EventLoopWaker`] to be used to wake up the embedder when it is + /// time to paint a frame. + event_loop_waker: Box<dyn EventLoopWaker>, +} + +impl RefreshDriver { + pub(crate) fn new( + constellation_sender: Sender<EmbedderToConstellationMessage>, + event_loop_waker: Box<dyn EventLoopWaker>, + ) -> Self { + Self { + constellation_sender, + animating: Default::default(), + waiting_for_frame_timeout: Default::default(), + timer_thread: Default::default(), + event_loop_waker, + } + } + + fn timer_callback(&self) -> BoxedTimerCallback { + let waiting_for_frame_timeout = self.waiting_for_frame_timeout.clone(); + let event_loop_waker = self.event_loop_waker.clone_box(); + Box::new(move |_| { + waiting_for_frame_timeout.store(false, Ordering::Relaxed); + event_loop_waker.wake(); + }) + } + + /// Notify the [`RefreshDriver`] that a paint is about to happen. This will trigger + /// new animation frames for all active `WebView`s and schedule a new frame deadline. + pub(crate) fn notify_will_paint( + &self, + webview_renderers: Values<'_, WebViewId, WebViewRenderer>, + ) { + // If we are still waiting for the frame to timeout this paint was caused for some + // non-animation related reason and we should wait until the frame timeout to trigger + // the next one. + if self.waiting_for_frame_timeout.load(Ordering::Relaxed) { + return; + } + + // If any WebViews are animating ask them to paint again for another animation tick. + let animating_webviews: Vec<_> = webview_renderers + .filter_map(|webview_renderer| { + if webview_renderer.animating() { + Some(webview_renderer.id) + } else { + None + } + }) + .collect(); + + // If nothing is animating any longer, update our state and exit early without requesting + // any noew frames nor triggering a new animation deadline. + if animating_webviews.is_empty() { + self.animating.set(false); + return; + } + + if let Err(error) = + self.constellation_sender + .send(EmbedderToConstellationMessage::TickAnimation( + animating_webviews, + )) + { + warn!("Sending tick to constellation failed ({error:?})."); + } + + // Queue the next frame deadline. + self.animating.set(true); + self.waiting_for_frame_timeout + .store(true, Ordering::Relaxed); + self.timer_thread + .queue_timer(FRAME_DURATION, self.timer_callback()); + } + + /// Notify the [`RefreshDriver`] that the animation state of a particular `WebView` + /// via its associated [`WebViewRenderer`] has changed. In the case that a `WebView` + /// has started animating, the [`RefreshDriver`] will request a new frame from it + /// immediately, but only render that frame at the next frame deadline. + pub(crate) fn notify_animation_state_changed(&self, webview_renderer: &WebViewRenderer) { + if !webview_renderer.animating() { + // If no other WebView is animating we will officially stop animated once the + // next frame has been painted. + return; + } + + if let Err(error) = + self.constellation_sender + .send(EmbedderToConstellationMessage::TickAnimation(vec![ + webview_renderer.id, + ])) + { + warn!("Sending tick to constellation failed ({error:?})."); + } + + if self.animating.get() { + return; + } + + self.animating.set(true); + self.waiting_for_frame_timeout + .store(true, Ordering::Relaxed); + self.timer_thread + .queue_timer(FRAME_DURATION, self.timer_callback()); + } + + /// Whether or not the renderer should trigger a message to the embedder to request a + /// repaint. This might be false if: we are animating and the repaint reason is just + /// for a new frame. In that case, the renderer should wait until the frame timeout to + /// ask the embedder to repaint. + pub(crate) fn wait_to_paint(&self, repaint_reason: RepaintReason) -> bool { + if !self.animating.get() || repaint_reason != RepaintReason::NewWebRenderFrame { + return false; + } + + self.waiting_for_frame_timeout.load(Ordering::Relaxed) + } +} + +enum TimerThreadMessage { + Request(TimerEventRequest), + Quit, +} + +/// A thread that manages a [`TimerScheduler`] running in the background of the +/// [`RefreshDriver`]. This is necessary because we need a reliable way of waking up the +/// embedder's main thread, which may just be sleeping until the `EventLoopWaker` asks it +/// to wake up. +/// +/// It would be nice to integrate this somehow into the embedder thread, but it would +/// require both some communication with the embedder and for all embedders to be well +/// behave respecting wakeup timeouts -- a bit too much to ask at the moment. +struct TimerThread { + sender: Sender<TimerThreadMessage>, + join_handle: Option<JoinHandle<()>>, +} + +impl Drop for TimerThread { + fn drop(&mut self) { + let _ = self.sender.send(TimerThreadMessage::Quit); + if let Some(join_handle) = self.join_handle.take() { + let _ = join_handle.join(); + } + } +} + +impl Default for TimerThread { + fn default() -> Self { + let (sender, receiver) = crossbeam_channel::unbounded::<TimerThreadMessage>(); + let join_handle = thread::Builder::new() + .name(String::from("CompositorTimerThread")) + .spawn(move || { + let mut scheduler = TimerScheduler::default(); + + loop { + select! { + recv(receiver) -> message => { + match message { + Ok(TimerThreadMessage::Request(request)) => { + scheduler.schedule_timer(request); + }, + _ => return, + } + }, + recv(scheduler.wait_channel()) -> _message => { + scheduler.dispatch_completed_timers(); + }, + }; + } + }) + .expect("Could not create RefreshDriver timer thread."); + + Self { + sender, + join_handle: Some(join_handle), + } + } +} + +impl TimerThread { + fn queue_timer(&self, duration: Duration, callback: BoxedTimerCallback) { + let _ = self + .sender + .send(TimerThreadMessage::Request(TimerEventRequest { + callback, + source: TimerSource::FromWorker, + id: TimerEventId(0), + duration, + })); + } +} diff --git a/components/compositing/tracing.rs b/components/compositing/tracing.rs index a8bb8b42bb8..65f9bd76c08 100644 --- a/components/compositing/tracing.rs +++ b/components/compositing/tracing.rs @@ -59,6 +59,7 @@ mod from_constellation { Self::GetScreenSize(..) => target!("GetScreenSize"), Self::GetAvailableScreenSize(..) => target!("GetAvailableScreenSize"), Self::CollectMemoryReport(..) => target!("CollectMemoryReport"), + Self::Viewport(..) => target!("Viewport"), } } } diff --git a/components/compositing/webview_renderer.rs b/components/compositing/webview_renderer.rs index b0e91ccb02e..056ffc16b89 100644 --- a/components/compositing/webview_renderer.rs +++ b/components/compositing/webview_renderer.rs @@ -2,12 +2,15 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use std::cell::RefCell; -use std::collections::HashMap; +use std::cell::{Cell, RefCell}; use std::collections::hash_map::Keys; +use std::collections::{HashMap, VecDeque}; use std::rc::Rc; use base::id::{PipelineId, WebViewId}; +use compositing_traits::viewport_description::{ + DEFAULT_ZOOM, MAX_ZOOM, MIN_ZOOM, ViewportDescription, +}; use compositing_traits::{SendableFrameTree, WebViewTrait}; use constellation_traits::{EmbedderToConstellationMessage, ScrollState, WindowSizeType}; use embedder_traits::{ @@ -25,13 +28,9 @@ use webrender_api::units::{ }; use webrender_api::{ExternalScrollId, HitTestFlags, ScrollLocation}; -use crate::compositor::{PipelineDetails, ServoRenderer}; +use crate::compositor::{HitTestError, PipelineDetails, ServoRenderer}; use crate::touch::{TouchHandler, TouchMoveAction, TouchMoveAllowed, TouchSequenceState}; -// Default viewport constraints -const MAX_ZOOM: f32 = 8.0; -const MIN_ZOOM: f32 = 0.1; - #[derive(Clone, Copy)] struct ScrollEvent { /// Scroll by this offset, or to Start or End @@ -44,8 +43,10 @@ struct ScrollEvent { #[derive(Clone, Copy)] enum ScrollZoomEvent { - /// An pinch zoom event that magnifies the view by the given factor. + /// A pinch zoom event that magnifies the view by the given factor. PinchZoom(f32), + /// A zoom event that magnifies the view by the factor parsed from meta tag. + ViewportZoom(f32), /// A scroll event that scrolls the scroll node at the given location by the /// given amount. Scroll(ScrollEvent), @@ -58,7 +59,7 @@ pub(crate) struct ScrollResult { pub offset: LayoutVector2D, } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub(crate) enum PinchZoomResult { DidPinchZoom, DidNotPinchZoom, @@ -89,15 +90,18 @@ pub(crate) struct WebViewRenderer { pub page_zoom: Scale<f32, CSSPixel, DeviceIndependentPixel>, /// "Mobile-style" zoom that does not reflow the page. viewport_zoom: PinchZoomFactor, - /// Viewport zoom constraints provided by @viewport. - min_viewport_zoom: Option<PinchZoomFactor>, - max_viewport_zoom: Option<PinchZoomFactor>, /// The HiDPI scale factor for the `WebView` associated with this renderer. This is controlled /// by the embedding layer. hidpi_scale_factor: Scale<f32, DeviceIndependentPixel, DevicePixel>, /// Whether or not this [`WebViewRenderer`] isn't throttled and has a pipeline with /// active animations or animation frame callbacks. animating: bool, + /// Pending input events queue. Priavte and only this thread pushes events to it. + pending_point_input_events: RefCell<VecDeque<InputEvent>>, + /// WebRender is not ready between `SendDisplayList` and `WebRenderFrameReady` messages. + pub webrender_frame_ready: Cell<bool>, + /// Viewport Description + viewport_description: Option<ViewportDescription>, } impl Drop for WebViewRenderer { @@ -127,11 +131,12 @@ impl WebViewRenderer { global, pending_scroll_zoom_events: Default::default(), page_zoom: Scale::new(1.0), - viewport_zoom: PinchZoomFactor::new(1.0), - min_viewport_zoom: Some(PinchZoomFactor::new(1.0)), - max_viewport_zoom: None, + viewport_zoom: PinchZoomFactor::new(DEFAULT_ZOOM), hidpi_scale_factor: Scale::new(hidpi_scale_factor.0), animating: false, + pending_point_input_events: Default::default(), + webrender_frame_ready: Cell::default(), + viewport_description: None, } } @@ -309,29 +314,89 @@ impl WebViewRenderer { } } - pub(crate) fn dispatch_input_event(&mut self, event: InputEvent) { + pub(crate) fn dispatch_point_input_event(&mut self, mut event: InputEvent) -> bool { // Events that do not need to do hit testing are sent directly to the // constellation to filter down. let Some(point) = event.point() else { - return; + return false; }; + // Delay the event if the epoch is not synchronized yet (new frame is not ready), + // or hit test result would fail and the event is rejected anyway. + if !self.webrender_frame_ready.get() || !self.pending_point_input_events.borrow().is_empty() + { + self.pending_point_input_events + .borrow_mut() + .push_back(event); + return false; + } + // If we can't find a pipeline to send this event to, we cannot continue. let get_pipeline_details = |pipeline_id| self.pipelines.get(&pipeline_id); - let Some(result) = self + let result = match self .global .borrow() .hit_test_at_point(point, get_pipeline_details) - else { - return; + { + Ok(hit_test_results) => hit_test_results, + Err(HitTestError::EpochMismatch) => { + self.pending_point_input_events + .borrow_mut() + .push_back(event); + return false; + }, + _ => { + return false; + }, }; - self.global.borrow_mut().update_cursor(point, &result); + match event { + InputEvent::Touch(ref mut touch_event) => { + touch_event.init_sequence_id(self.touch_handler.current_sequence_id); + }, + InputEvent::MouseButton(_) | InputEvent::MouseMove(_) | InputEvent::Wheel(_) => { + self.global.borrow_mut().update_cursor(point, &result); + }, + _ => unreachable!("Unexpected input event type: {event:?}"), + } if let Err(error) = self.global.borrow().constellation_sender.send( EmbedderToConstellationMessage::ForwardInputEvent(self.id, event, Some(result)), ) { warn!("Sending event to constellation failed ({error:?})."); + false + } else { + true + } + } + + pub(crate) fn dispatch_pending_point_input_events(&self) { + while let Some(event) = self.pending_point_input_events.borrow_mut().pop_front() { + // Events that do not need to do hit testing are sent directly to the + // constellation to filter down. + let Some(point) = event.point() else { + continue; + }; + + // If we can't find a pipeline to send this event to, we cannot continue. + let get_pipeline_details = |pipeline_id| self.pipelines.get(&pipeline_id); + let Ok(result) = self + .global + .borrow() + .hit_test_at_point(point, get_pipeline_details) + else { + // Don't need to process pending input events in this frame any more. + // TODO: Add multiple retry later if needed. + return; + }; + + self.global.borrow_mut().update_cursor(point, &result); + + if let Err(error) = self.global.borrow().constellation_sender.send( + EmbedderToConstellationMessage::ForwardInputEvent(self.id, event, Some(result)), + ) { + warn!("Sending event to constellation failed ({error:?})."); + } } } @@ -401,29 +466,11 @@ impl WebViewRenderer { } } - self.dispatch_input_event(event); + self.dispatch_point_input_event(event); } - fn send_touch_event(&self, mut event: TouchEvent) -> bool { - let get_pipeline_details = |pipeline_id| self.pipelines.get(&pipeline_id); - let Some(result) = self - .global - .borrow() - .hit_test_at_point(event.point, get_pipeline_details) - else { - return false; - }; - - event.init_sequence_id(self.touch_handler.current_sequence_id); - let event = InputEvent::Touch(event); - if let Err(e) = self.global.borrow().constellation_sender.send( - EmbedderToConstellationMessage::ForwardInputEvent(self.id, event, Some(result)), - ) { - warn!("Sending event to constellation failed ({:?}).", e); - false - } else { - true - } + fn send_touch_event(&mut self, event: TouchEvent) -> bool { + self.dispatch_point_input_event(InputEvent::Touch(event)) } pub(crate) fn on_touch_event(&mut self, event: TouchEvent) { @@ -687,13 +734,13 @@ impl WebViewRenderer { /// <http://w3c.github.io/touch-events/#mouse-events> fn simulate_mouse_click(&mut self, point: DevicePoint) { let button = MouseButton::Left; - self.dispatch_input_event(InputEvent::MouseMove(MouseMoveEvent::new(point))); - self.dispatch_input_event(InputEvent::MouseButton(MouseButtonEvent::new( + self.dispatch_point_input_event(InputEvent::MouseMove(MouseMoveEvent::new(point))); + self.dispatch_point_input_event(InputEvent::MouseButton(MouseButtonEvent::new( MouseButtonAction::Down, button, point, ))); - self.dispatch_input_event(InputEvent::MouseButton(MouseButtonEvent::new( + self.dispatch_point_input_event(InputEvent::MouseButton(MouseButtonEvent::new( MouseButtonAction::Up, button, point, @@ -764,7 +811,8 @@ impl WebViewRenderer { let mut combined_magnification = 1.0; for scroll_event in self.pending_scroll_zoom_events.drain(..) { match scroll_event { - ScrollZoomEvent::PinchZoom(magnification) => { + ScrollZoomEvent::PinchZoom(magnification) | + ScrollZoomEvent::ViewportZoom(magnification) => { combined_magnification *= magnification }, ScrollZoomEvent::Scroll(scroll_event_info) => { @@ -858,7 +906,8 @@ impl WebViewRenderer { HitTestFlags::FIND_ALL, None, get_pipeline_details, - ); + ) + .unwrap_or_default(); // Iterate through all hit test results, processing only the first node of each pipeline. // This is needed to propagate the scroll events from a pipeline representing an iframe to @@ -892,11 +941,8 @@ impl WebViewRenderer { } fn set_pinch_zoom_level(&mut self, mut zoom: f32) -> bool { - if let Some(min) = self.min_viewport_zoom { - zoom = f32::max(min.get(), zoom); - } - if let Some(max) = self.max_viewport_zoom { - zoom = f32::min(max.get(), zoom); + if let Some(viewport) = self.viewport_description.as_ref() { + zoom = viewport.clamp_zoom(zoom); } let old_zoom = std::mem::replace(&mut self.viewport_zoom, PinchZoomFactor::new(zoom)); @@ -926,7 +972,12 @@ impl WebViewRenderer { // TODO: Scroll to keep the center in view? self.pending_scroll_zoom_events - .push(ScrollZoomEvent::PinchZoom(magnification)); + .push(ScrollZoomEvent::PinchZoom( + self.viewport_description + .clone() + .unwrap_or_default() + .clamp_zoom(magnification), + )); } fn send_window_size_message(&self) { @@ -993,6 +1044,17 @@ impl WebViewRenderer { let screen_geometry = self.webview.screen_geometry().unwrap_or_default(); (screen_geometry.available_size.to_f32() / self.hidpi_scale_factor).to_i32() } + + pub fn set_viewport_description(&mut self, viewport_description: ViewportDescription) { + self.pending_scroll_zoom_events + .push(ScrollZoomEvent::ViewportZoom( + self.viewport_description + .clone() + .unwrap_or_default() + .clamp_zoom(viewport_description.initial_scale.get()), + )); + self.viewport_description = Some(viewport_description); + } } #[derive(Clone, Copy, Debug, PartialEq)] diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 65d94641322..5b4d244e746 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -148,6 +148,7 @@ use net_traits::pub_domains::reg_host; use net_traits::request::Referrer; use net_traits::storage_thread::{StorageThreadMsg, StorageType}; use net_traits::{self, IpcSend, ReferrerPolicy, ResourceThreads}; +use profile_traits::mem::ProfilerMsg; use profile_traits::{mem, time}; use script_layout_interface::{LayoutFactory, ScriptThreadFactory}; use script_traits::{ @@ -1488,6 +1489,9 @@ where ) => { self.handle_evaluate_javascript(webview_id, evaluation_id, script); }, + EmbedderToConstellationMessage::CreateMemoryReport(sender) => { + self.mem_profiler_chan.send(ProfilerMsg::Report(sender)); + }, } } @@ -2758,7 +2762,11 @@ where } debug!("Exiting Canvas Paint thread."); - if let Err(e) = self.canvas_sender.send(ConstellationCanvasMsg::Exit) { + let (canvas_exit_sender, canvas_exit_receiver) = unbounded(); + if let Err(e) = self + .canvas_sender + .send(ConstellationCanvasMsg::Exit(canvas_exit_sender)) + { warn!("Exit Canvas Paint thread failed ({})", e); } @@ -2800,6 +2808,10 @@ where debug!("Exiting GLPlayer thread."); WindowGLContext::get().exit(); + // Wait for the canvas thread to exit before shutting down the font service, as + // canvas might still be using the system font service before shutting down. + let _ = canvas_exit_receiver.recv(); + debug!("Exiting the system font service thread."); self.system_font_service.exit(); diff --git a/components/constellation/tracing.rs b/components/constellation/tracing.rs index 6237665b87f..99551bd58fc 100644 --- a/components/constellation/tracing.rs +++ b/components/constellation/tracing.rs @@ -78,6 +78,7 @@ mod from_compositor { Self::SetScrollStates(..) => target!("SetScrollStates"), Self::PaintMetric(..) => target!("PaintMetric"), Self::EvaluateJavaScript(..) => target!("EvaluateJavaScript"), + Self::CreateMemoryReport(..) => target!("CreateMemoryReport"), } } } diff --git a/components/devtools/actors/breakpoint.rs b/components/devtools/actors/breakpoint.rs new file mode 100644 index 00000000000..04f2de140b4 --- /dev/null +++ b/components/devtools/actors/breakpoint.rs @@ -0,0 +1,55 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +use serde::Serialize; + +use crate::EmptyReplyMsg; +use crate::actor::{Actor, ActorMessageStatus}; +use crate::protocol::JsonPacketStream; + +#[derive(Serialize)] +pub struct BreakpointListActorMsg { + actor: String, +} + +pub struct BreakpointListActor { + name: String, +} + +impl Actor for BreakpointListActor { + fn name(&self) -> String { + self.name.clone() + } + + fn handle_message( + &self, + _registry: &crate::actor::ActorRegistry, + msg_type: &str, + _msg: &serde_json::Map<String, serde_json::Value>, + stream: &mut std::net::TcpStream, + _stream_id: crate::StreamId, + ) -> Result<crate::actor::ActorMessageStatus, ()> { + Ok(match msg_type { + "setBreakpoint" => { + let msg = EmptyReplyMsg { from: self.name() }; + let _ = stream.write_json_packet(&msg); + + ActorMessageStatus::Processed + }, + "setActiveEventBreakpoints" => { + let msg = EmptyReplyMsg { from: self.name() }; + let _ = stream.write_json_packet(&msg); + + ActorMessageStatus::Processed + }, + _ => ActorMessageStatus::Ignored, + }) + } +} + +impl BreakpointListActor { + pub fn new(name: String) -> Self { + Self { name } + } +} diff --git a/components/devtools/actors/browsing_context.rs b/components/devtools/actors/browsing_context.rs index 81a00e82d47..fc5116131a0 100644 --- a/components/devtools/actors/browsing_context.rs +++ b/components/devtools/actors/browsing_context.rs @@ -82,6 +82,13 @@ struct BrowsingContextTraits { } #[derive(Serialize)] +#[serde(rename_all = "lowercase")] +enum TargetType { + Frame, + // Other target types not implemented yet. +} + +#[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct BrowsingContextActorMsg { actor: String, @@ -104,6 +111,7 @@ pub struct BrowsingContextActorMsg { reflow_actor: String, style_sheets_actor: String, thread_actor: String, + target_type: TargetType, // Part of the official protocol, but not yet implemented. // animations_actor: String, // changes_actor: String, @@ -302,6 +310,7 @@ impl BrowsingContextActor { reflow_actor: self.reflow.clone(), style_sheets_actor: self.style_sheets.clone(), thread_actor: self.thread.clone(), + target_type: TargetType::Frame, } } diff --git a/components/devtools/actors/watcher.rs b/components/devtools/actors/watcher.rs index 061ffc92336..7720daf070d 100644 --- a/components/devtools/actors/watcher.rs +++ b/components/devtools/actors/watcher.rs @@ -19,6 +19,7 @@ use serde::Serialize; use serde_json::{Map, Value}; use self::network_parent::{NetworkParentActor, NetworkParentActorMsg}; +use super::breakpoint::BreakpointListActor; use super::thread::ThreadActor; use super::worker::WorkerMsg; use crate::actor::{Actor, ActorMessageStatus, ActorRegistry}; @@ -362,10 +363,14 @@ impl Actor for WatcherActor { ActorMessageStatus::Processed }, "getBreakpointListActor" => { + let breakpoint_list_name = registry.new_name("breakpoint-list"); + let breakpoint_list = BreakpointListActor::new(breakpoint_list_name.clone()); + registry.register_later(Box::new(breakpoint_list)); + let _ = stream.write_json_packet(&GetBreakpointListActorReply { from: self.name(), breakpoint_list: GetBreakpointListActorReplyInner { - actor: registry.new_name("breakpoint-list"), + actor: breakpoint_list_name, }, }); ActorMessageStatus::Processed diff --git a/components/devtools/lib.rs b/components/devtools/lib.rs index d097cb25e9d..74a45eaf866 100644 --- a/components/devtools/lib.rs +++ b/components/devtools/lib.rs @@ -53,6 +53,7 @@ use crate::protocol::JsonPacketStream; mod actor; /// <https://searchfox.org/mozilla-central/source/devtools/server/actors> mod actors { + pub mod breakpoint; pub mod browsing_context; pub mod console; pub mod device; diff --git a/components/layout/display_list/stacking_context.rs b/components/layout/display_list/stacking_context.rs index 66d8421e5f7..17e8f2ef4fd 100644 --- a/components/layout/display_list/stacking_context.rs +++ b/components/layout/display_list/stacking_context.rs @@ -618,7 +618,7 @@ impl StackingContext { // If it’s larger, we also want to paint areas reachable after scrolling. let painting_area = fragment_tree .initial_containing_block - .union(&fragment_tree.scrollable_overflow) + .union(&fragment_tree.scrollable_overflow()) .to_webrender(); let background_color = @@ -1346,7 +1346,7 @@ impl BoxFragment { let position = self.style.get_box().position; // https://drafts.csswg.org/css2/#clipping // The clip property applies only to absolutely positioned elements - if position != ComputedPosition::Absolute && position != ComputedPosition::Fixed { + if !position.is_absolutely_positioned() { return None; } diff --git a/components/layout/flow/construct.rs b/components/layout/flow/construct.rs index cc3fe0e6f44..d8d6cd5c6ab 100644 --- a/components/layout/flow/construct.rs +++ b/components/layout/flow/construct.rs @@ -744,9 +744,14 @@ impl BlockLevelJob<'_> { self.propagated_data, false, /* is_list_item */ ); + // An outside ::marker must establish a BFC, and can't contain floats. + let block_formatting_context = BlockFormattingContext { + contents: block_container, + contains_floats: false, + }; ArcRefCell::new(BlockLevelBox::OutsideMarker(OutsideMarker { base: LayoutBoxBase::new(info.into(), info.style.clone()), - block_container, + block_formatting_context, list_item_style, })) }, diff --git a/components/layout/flow/mod.rs b/components/layout/flow/mod.rs index 4776b65771c..81343d81111 100644 --- a/components/layout/flow/mod.rs +++ b/components/layout/flow/mod.rs @@ -308,7 +308,7 @@ pub(crate) struct CollapsibleWithParentStartMargin(bool); pub(crate) struct OutsideMarker { pub list_item_style: Arc<ComputedValues>, pub base: LayoutBoxBase, - pub block_container: BlockContainer, + pub block_formatting_context: BlockFormattingContext, } impl OutsideMarker { @@ -317,8 +317,11 @@ impl OutsideMarker { layout_context: &LayoutContext, constraint_space: &ConstraintSpace, ) -> InlineContentSizesResult { - self.base - .inline_content_sizes(layout_context, constraint_space, &self.block_container) + self.base.inline_content_sizes( + layout_context, + constraint_space, + &self.block_formatting_context.contents, + ) } fn layout( @@ -326,8 +329,6 @@ impl OutsideMarker { layout_context: &LayoutContext<'_>, containing_block: &ContainingBlock<'_>, positioning_context: &mut PositioningContext, - sequential_layout_state: Option<&mut SequentialLayoutState>, - collapsible_with_parent_start_margin: Option<CollapsibleWithParentStartMargin>, ) -> Fragment { let constraint_space = ConstraintSpace::new_for_style_and_ratio( &self.base.style, @@ -342,17 +343,11 @@ impl OutsideMarker { style: &self.base.style, }; - // A ::marker can't have a stretch size (must be auto), so this doesn't matter. - // https://drafts.csswg.org/css-sizing-4/#stretch-fit-sizing - let ignore_block_margins_for_stretch = LogicalSides1D::new(false, false); - - let flow_layout = self.block_container.layout( + let flow_layout = self.block_formatting_context.layout( layout_context, positioning_context, &containing_block_for_children, - sequential_layout_state, - collapsible_with_parent_start_margin.unwrap_or(CollapsibleWithParentStartMargin(false)), - ignore_block_margins_for_stretch, + false, /* depends_on_block_constraints */ ); let max_inline_size = @@ -900,13 +895,9 @@ impl BlockLevelBox { BlockLevelBox::OutOfFlowFloatBox(float_box) => Fragment::Float(ArcRefCell::new( float_box.layout(layout_context, positioning_context, containing_block), )), - BlockLevelBox::OutsideMarker(outside_marker) => outside_marker.layout( - layout_context, - containing_block, - positioning_context, - sequential_layout_state, - collapsible_with_parent_start_margin, - ), + BlockLevelBox::OutsideMarker(outside_marker) => { + outside_marker.layout(layout_context, containing_block, positioning_context) + }, }; self.with_base(|base| base.set_fragment(fragment.clone())); diff --git a/components/layout/flow/root.rs b/components/layout/flow/root.rs index fb9884a4f01..fe98dbc3156 100644 --- a/components/layout/flow/root.rs +++ b/components/layout/flow/root.rs @@ -29,7 +29,7 @@ use crate::flow::inline::InlineItem; use crate::flow::{BlockContainer, BlockFormattingContext, BlockLevelBox}; use crate::formatting_contexts::IndependentFormattingContext; use crate::fragment_tree::FragmentTree; -use crate::geom::{LogicalVec2, PhysicalRect, PhysicalSize}; +use crate::geom::{LogicalVec2, PhysicalSize}; use crate::positioned::{AbsolutelyPositionedBox, PositioningContext}; use crate::replaced::ReplacedContents; use crate::style_ext::{Display, DisplayGeneratingBox, DisplayInside}; @@ -392,31 +392,9 @@ impl BoxTree { &mut root_fragments, ); - let scrollable_overflow = root_fragments - .iter() - .fold(PhysicalRect::zero(), |acc, child| { - let child_overflow = child.scrollable_overflow_for_parent(); - - // https://drafts.csswg.org/css-overflow/#scrolling-direction - // We want to clip scrollable overflow on box-start and inline-start - // sides of the scroll container. - // - // FIXME(mrobinson, bug 25564): This should take into account writing - // mode. - let child_overflow = PhysicalRect::new( - euclid::Point2D::zero(), - euclid::Size2D::new( - child_overflow.size.width + child_overflow.origin.x, - child_overflow.size.height + child_overflow.origin.y, - ), - ); - acc.union(&child_overflow) - }); - FragmentTree::new( layout_context, root_fragments, - scrollable_overflow, physical_containing_block, self.viewport_scroll_sensitivity, ) diff --git a/components/layout/fragment_tree/box_fragment.rs b/components/layout/fragment_tree/box_fragment.rs index b7c3a2a3524..eb63038b7d7 100644 --- a/components/layout/fragment_tree/box_fragment.rs +++ b/components/layout/fragment_tree/box_fragment.rs @@ -89,7 +89,7 @@ pub(crate) struct BoxFragment { block_margins_collapsed_with_children: Option<Box<CollapsedBlockMargins>>, /// The scrollable overflow of this box fragment. - pub scrollable_overflow_from_children: PhysicalRect<Au>, + scrollable_overflow: Option<PhysicalRect<Au>>, /// The resolved box insets if this box is `position: sticky`. These are calculated /// during `StackingContextTree` construction because they rely on the size of the @@ -114,11 +114,6 @@ impl BoxFragment { margin: PhysicalSides<Au>, clearance: Option<Au>, ) -> BoxFragment { - let scrollable_overflow_from_children = - children.iter().fold(PhysicalRect::zero(), |acc, child| { - acc.union(&child.scrollable_overflow_for_parent()) - }); - BoxFragment { base: base_fragment_info.into(), style, @@ -131,7 +126,7 @@ impl BoxFragment { clearance, baselines: Baselines::default(), block_margins_collapsed_with_children: None, - scrollable_overflow_from_children, + scrollable_overflow: None, resolved_sticky_insets: AtomicRefCell::default(), background_mode: BackgroundMode::Normal, specific_layout_info: None, @@ -203,13 +198,23 @@ impl BoxFragment { /// Get the scrollable overflow for this [`BoxFragment`] relative to its /// containing block. pub fn scrollable_overflow(&self) -> PhysicalRect<Au> { + self.scrollable_overflow + .expect("Should only call `scrollable_overflow()` after calculating overflow") + } + + pub(crate) fn calculate_scrollable_overflow(&mut self) { + let scrollable_overflow_from_children = self + .children + .iter() + .fold(PhysicalRect::zero(), |acc, child| { + acc.union(&child.calculate_scrollable_overflow_for_parent()) + }); let physical_padding_rect = self.padding_rect(); let content_origin = self.content_rect.origin.to_vector(); - physical_padding_rect.union( - &self - .scrollable_overflow_from_children - .translate(content_origin), - ) + self.scrollable_overflow = Some( + physical_padding_rect + .union(&scrollable_overflow_from_children.translate(content_origin)), + ); } pub(crate) fn set_containing_block(&mut self, containing_block: &PhysicalRect<Au>) { @@ -275,7 +280,12 @@ impl BoxFragment { tree.end_level(); } - pub fn scrollable_overflow_for_parent(&self) -> PhysicalRect<Au> { + pub(crate) fn scrollable_overflow_for_parent(&self) -> PhysicalRect<Au> { + // TODO: Properly handle absolutely positioned fragments. + if self.style.get_box().position.is_absolutely_positioned() { + return PhysicalRect::zero(); + } + let mut overflow = self.border_rect(); if !self.style.establishes_scroll_container(self.base.flags) { // https://www.w3.org/TR/css-overflow-3/#scrollable @@ -328,7 +338,7 @@ impl BoxFragment { /// /// Return the clipped the scrollable overflow based on its scroll origin, determined by overflow direction. /// For an element, the clip rect is the padding rect and for viewport, it is the initial containing block. - pub fn clip_unreachable_scrollable_overflow_region( + pub(crate) fn clip_unreachable_scrollable_overflow_region( &self, scrollable_overflow: PhysicalRect<Au>, clipping_rect: PhysicalRect<Au>, @@ -362,7 +372,7 @@ impl BoxFragment { /// /// Return the clipped the scrollable overflow based on its scroll origin, determined by overflow direction. /// This will coincides with the scrollport if the fragment is a scroll container. - pub fn reachable_scrollable_overflow_region(&self) -> PhysicalRect<Au> { + pub(crate) fn reachable_scrollable_overflow_region(&self) -> PhysicalRect<Au> { self.clip_unreachable_scrollable_overflow_region( self.scrollable_overflow(), self.padding_rect(), @@ -421,9 +431,7 @@ impl BoxFragment { return convert_to_au_or_auto(PhysicalSides::new(top, right, bottom, left)); } - debug_assert!( - position == ComputedPosition::Fixed || position == ComputedPosition::Absolute - ); + debug_assert!(position.is_absolutely_positioned()); let margin_rect = self.margin_rect(); let (top, bottom) = match (&insets.top, &insets.bottom) { diff --git a/components/layout/fragment_tree/fragment.rs b/components/layout/fragment_tree/fragment.rs index c81fd59e36b..10338c78743 100644 --- a/components/layout/fragment_tree/fragment.rs +++ b/components/layout/fragment_tree/fragment.rs @@ -183,19 +183,36 @@ impl Fragment { } } - pub fn scrollable_overflow_for_parent(&self) -> PhysicalRect<Au> { + pub(crate) fn scrollable_overflow_for_parent(&self) -> PhysicalRect<Au> { match self { Fragment::Box(fragment) | Fragment::Float(fragment) => { - fragment.borrow().scrollable_overflow_for_parent() + return fragment.borrow().scrollable_overflow_for_parent(); }, Fragment::AbsoluteOrFixedPositioned(_) => PhysicalRect::zero(), - Fragment::Positioning(fragment) => fragment.borrow().scrollable_overflow, + Fragment::Positioning(fragment) => fragment.borrow().scrollable_overflow_for_parent(), Fragment::Text(fragment) => fragment.borrow().rect, Fragment::Image(fragment) => fragment.borrow().rect, Fragment::IFrame(fragment) => fragment.borrow().rect, } } + pub(crate) fn calculate_scrollable_overflow_for_parent(&self) -> PhysicalRect<Au> { + self.calculate_scrollable_overflow(); + self.scrollable_overflow_for_parent() + } + + pub(crate) fn calculate_scrollable_overflow(&self) { + match self { + Fragment::Box(fragment) | Fragment::Float(fragment) => { + fragment.borrow_mut().calculate_scrollable_overflow() + }, + Fragment::Positioning(fragment) => { + fragment.borrow_mut().calculate_scrollable_overflow() + }, + _ => {}, + } + } + pub(crate) fn cumulative_border_box_rect(&self) -> Option<PhysicalRect<Au>> { match self { Fragment::Box(fragment) | Fragment::Float(fragment) => { diff --git a/components/layout/fragment_tree/fragment_tree.rs b/components/layout/fragment_tree/fragment_tree.rs index ba03a72ac21..b59ace43aa6 100644 --- a/components/layout/fragment_tree/fragment_tree.rs +++ b/components/layout/fragment_tree/fragment_tree.rs @@ -2,14 +2,14 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use std::cell::Cell; + use app_units::Au; use base::print_tree::PrintTree; use compositing_traits::display_list::AxesScrollSensitivity; -use euclid::default::Size2D; use fxhash::FxHashSet; use malloc_size_of_derive::MallocSizeOf; use style::animation::AnimationSetKey; -use webrender_api::units; use super::{BoxFragment, ContainingBlockManager, Fragment}; use crate::ArcRefCell; @@ -30,7 +30,7 @@ pub struct FragmentTree { /// The scrollable overflow rectangle for the entire tree /// <https://drafts.csswg.org/css-overflow/#scrollable> - pub(crate) scrollable_overflow: PhysicalRect<Au>, + scrollable_overflow: Cell<Option<PhysicalRect<Au>>>, /// The containing block used in the layout of this fragment tree. pub(crate) initial_containing_block: PhysicalRect<Au>, @@ -43,13 +43,12 @@ impl FragmentTree { pub(crate) fn new( layout_context: &LayoutContext, root_fragments: Vec<Fragment>, - scrollable_overflow: PhysicalRect<Au>, initial_containing_block: PhysicalRect<Au>, viewport_scroll_sensitivity: AxesScrollSensitivity, ) -> Self { let fragment_tree = Self { root_fragments, - scrollable_overflow, + scrollable_overflow: Cell::default(), initial_containing_block, viewport_scroll_sensitivity, }; @@ -97,11 +96,35 @@ impl FragmentTree { } } - pub fn scrollable_overflow(&self) -> units::LayoutSize { - units::LayoutSize::from_untyped(Size2D::new( - self.scrollable_overflow.size.width.to_f32_px(), - self.scrollable_overflow.size.height.to_f32_px(), - )) + pub(crate) fn scrollable_overflow(&self) -> PhysicalRect<Au> { + self.scrollable_overflow + .get() + .expect("Should only call `scrollable_overflow()` after calculating overflow") + } + + pub(crate) fn calculate_scrollable_overflow(&self) { + self.scrollable_overflow + .set(Some(self.root_fragments.iter().fold( + PhysicalRect::zero(), + |acc, child| { + let child_overflow = child.calculate_scrollable_overflow_for_parent(); + + // https://drafts.csswg.org/css-overflow/#scrolling-direction + // We want to clip scrollable overflow on box-start and inline-start + // sides of the scroll container. + // + // FIXME(mrobinson, bug 25564): This should take into account writing + // mode. + let child_overflow = PhysicalRect::new( + euclid::Point2D::zero(), + euclid::Size2D::new( + child_overflow.size.width + child_overflow.origin.x, + child_overflow.size.height + child_overflow.origin.y, + ), + ); + acc.union(&child_overflow) + }, + ))); } pub(crate) fn find<T>( diff --git a/components/layout/fragment_tree/positioning_fragment.rs b/components/layout/fragment_tree/positioning_fragment.rs index e45a6137bff..5547a9d86a1 100644 --- a/components/layout/fragment_tree/positioning_fragment.rs +++ b/components/layout/fragment_tree/positioning_fragment.rs @@ -22,7 +22,7 @@ pub(crate) struct PositioningFragment { pub children: Vec<Fragment>, /// The scrollable overflow of this anonymous fragment's children. - pub scrollable_overflow: PhysicalRect<Au>, + scrollable_overflow: Option<PhysicalRect<Au>>, /// The style of the fragment. pub style: ServoArc<ComputedValues>, @@ -55,20 +55,12 @@ impl PositioningFragment { rect: PhysicalRect<Au>, children: Vec<Fragment>, ) -> ArcRefCell<Self> { - let content_origin = rect.origin; - let scrollable_overflow = children.iter().fold(PhysicalRect::zero(), |acc, child| { - acc.union( - &child - .scrollable_overflow_for_parent() - .translate(content_origin.to_vector()), - ) - }); ArcRefCell::new(PositioningFragment { base, style, rect, children, - scrollable_overflow, + scrollable_overflow: None, cumulative_containing_block_rect: PhysicalRect::zero(), }) } @@ -81,6 +73,25 @@ impl PositioningFragment { rect.translate(self.cumulative_containing_block_rect.origin.to_vector()) } + pub(crate) fn calculate_scrollable_overflow(&mut self) { + self.scrollable_overflow = Some(self.children.iter().fold( + PhysicalRect::zero(), + |acc, child| { + acc.union( + &child + .calculate_scrollable_overflow_for_parent() + .translate(self.rect.origin.to_vector()), + ) + }, + )); + } + + pub(crate) fn scrollable_overflow_for_parent(&self) -> PhysicalRect<Au> { + self.scrollable_overflow.expect( + "Should only call `scrollable_overflow_for_parent()` after calculating overflow", + ) + } + pub fn print(&self, tree: &mut PrintTree) { tree.new_level(format!( "PositioningFragment\ diff --git a/components/layout/layout_impl.rs b/components/layout/layout_impl.rs index 54edc215389..0fbc8395c35 100644 --- a/components/layout/layout_impl.rs +++ b/components/layout/layout_impl.rs @@ -8,6 +8,7 @@ use std::cell::{Cell, RefCell}; use std::collections::HashMap; use std::fmt::Debug; use std::process; +use std::rc::Rc; use std::sync::{Arc, LazyLock}; use app_units::Au; @@ -142,7 +143,7 @@ pub struct LayoutThread { box_tree: RefCell<Option<Arc<BoxTree>>>, /// The fragment tree. - fragment_tree: RefCell<Option<Arc<FragmentTree>>>, + fragment_tree: RefCell<Option<Rc<FragmentTree>>>, /// The [`StackingContextTree`] cached from previous layouts. stacking_context_tree: RefCell<Option<StackingContextTree>>, @@ -656,7 +657,7 @@ impl LayoutThread { &mut layout_context, viewport_changed, ); - + self.calculate_overflow(damage); self.build_stacking_context_tree(&reflow_request, damage); self.build_display_list(&reflow_request, &mut layout_context); @@ -773,8 +774,11 @@ impl LayoutThread { driver::traverse_dom(&recalc_style_traversal, token, rayon_pool).as_node(); let root_node = root_element.as_node(); - let damage = compute_damage_and_repair_style(layout_context.shared_context(), root_node); - if !viewport_changed && !damage.contains(RestyleDamage::REBUILD_BOX) { + let mut damage = + compute_damage_and_repair_style(layout_context.shared_context(), root_node); + if viewport_changed { + damage = RestyleDamage::REBUILD_BOX; + } else if !damage.contains(RestyleDamage::REBUILD_BOX) { layout_context.style_context.stylist.rule_tree().maybe_gc(); return damage; } @@ -802,15 +806,12 @@ impl LayoutThread { .unwrap() .layout(recalc_style_traversal.context(), viewport_size) }; - let fragment_tree = Arc::new(if let Some(pool) = rayon_pool { + let fragment_tree = Rc::new(if let Some(pool) = rayon_pool { pool.install(run_layout) } else { run_layout() }); - if self.debug.dump_flow_tree { - fragment_tree.print(); - } *self.fragment_tree.borrow_mut() = Some(fragment_tree); // The FragmentTree has been updated, so any existing StackingContext tree that layout @@ -837,6 +838,19 @@ impl LayoutThread { damage } + fn calculate_overflow(&self, damage: RestyleDamage) { + if !damage.contains(RestyleDamage::RECALCULATE_OVERFLOW) { + return; + } + + if let Some(fragment_tree) = &*self.fragment_tree.borrow() { + fragment_tree.calculate_scrollable_overflow(); + if self.debug.dump_flow_tree { + fragment_tree.print(); + } + } + } + fn build_stacking_context_tree(&self, reflow_request: &ReflowRequest, damage: RestyleDamage) { if !reflow_request.reflow_goal.needs_display_list() && !reflow_request.reflow_goal.needs_display() @@ -858,13 +872,19 @@ impl LayoutThread { viewport_size.height.to_f32_px(), ); + let scrollable_overflow = fragment_tree.scrollable_overflow(); + let scrollable_overflow = LayoutSize::from_untyped(Size2D::new( + scrollable_overflow.size.width.to_f32_px(), + scrollable_overflow.size.height.to_f32_px(), + )); + // Build the StackingContextTree. This turns the `FragmentTree` into a // tree of fragments in CSS painting order and also creates all // applicable spatial and clip nodes. *self.stacking_context_tree.borrow_mut() = Some(StackingContextTree::new( fragment_tree, viewport_size, - fragment_tree.scrollable_overflow(), + scrollable_overflow, self.id.into(), fragment_tree.viewport_scroll_sensitivity, self.first_reflow.get(), diff --git a/components/layout/positioned.rs b/components/layout/positioned.rs index 6280864d533..186fc78e3bf 100644 --- a/components/layout/positioned.rs +++ b/components/layout/positioned.rs @@ -305,10 +305,7 @@ impl PositioningContext { } pub(crate) fn push(&mut self, hoisted_box: HoistedAbsolutelyPositionedBox) { - debug_assert!(matches!( - hoisted_box.position(), - Position::Absolute | Position::Fixed - )); + debug_assert!(hoisted_box.position().is_absolutely_positioned()); self.absolutes.push(hoisted_box); } @@ -380,7 +377,7 @@ impl HoistedAbsolutelyPositionedBox { .context .style() .clone_position(); - assert!(position == Position::Fixed || position == Position::Absolute); + assert!(position.is_absolutely_positioned()); position } diff --git a/components/layout/query.rs b/components/layout/query.rs index ca9db9ceaf1..7f304ff2da1 100644 --- a/components/layout/query.rs +++ b/components/layout/query.rs @@ -3,7 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! Utilities for querying the layout, as needed by layout. -use std::sync::Arc; +use std::rc::Rc; use app_units::Au; use euclid::default::{Point2D, Rect}; @@ -80,7 +80,7 @@ pub fn process_client_rect_request(node: ServoLayoutNode<'_>) -> Rect<i32> { /// <https://drafts.csswg.org/cssom-view/#scrolling-area> pub fn process_node_scroll_area_request( requested_node: Option<ServoLayoutNode<'_>>, - fragment_tree: Option<Arc<FragmentTree>>, + fragment_tree: Option<Rc<FragmentTree>>, ) -> Rect<i32> { let Some(tree) = fragment_tree else { return Rect::zero(); diff --git a/components/layout/stylesheets/servo.css b/components/layout/stylesheets/servo.css index c025b19f364..cb206bbcd00 100644 --- a/components/layout/stylesheets/servo.css +++ b/components/layout/stylesheets/servo.css @@ -265,4 +265,8 @@ select { padding: 0 0.25em; /* Don't show a text cursor when hovering selected option */ cursor: default; +} + +slot { + display: contents; }
\ No newline at end of file diff --git a/components/net/fetch/methods.rs b/components/net/fetch/methods.rs index 33d0da952fb..e99776be350 100644 --- a/components/net/fetch/methods.rs +++ b/components/net/fetch/methods.rs @@ -170,8 +170,12 @@ pub async fn fetch_with_cors_cache( // TODO: We don't implement fetchParams as defined in the spec } -fn convert_request_to_csp_request(request: &Request, origin: &ImmutableOrigin) -> csp::Request { - csp::Request { +pub(crate) fn convert_request_to_csp_request(request: &Request) -> Option<csp::Request> { + let origin = match &request.origin { + Origin::Client => return None, + Origin::Origin(origin) => origin, + }; + let csp_request = csp::Request { url: request.url().into_url(), origin: origin.clone().into_url_origin(), redirect_count: request.redirect_count, @@ -190,45 +194,58 @@ fn convert_request_to_csp_request(request: &Request, origin: &ImmutableOrigin) - ParserMetadata::NotParserInserted => csp::ParserMetadata::NotParserInserted, ParserMetadata::Default => csp::ParserMetadata::None, }, - } + }; + Some(csp_request) } /// <https://www.w3.org/TR/CSP/#should-block-request> pub fn should_request_be_blocked_by_csp( - request: &Request, + csp_request: &csp::Request, policy_container: &PolicyContainer, ) -> (csp::CheckResult, Vec<csp::Violation>) { - let origin = match &request.origin { - Origin::Client => return (csp::CheckResult::Allowed, Vec::new()), - Origin::Origin(origin) => origin, - }; - let csp_request = convert_request_to_csp_request(request, origin); - policy_container .csp_list .as_ref() - .map(|c| c.should_request_be_blocked(&csp_request)) + .map(|c| c.should_request_be_blocked(csp_request)) .unwrap_or((csp::CheckResult::Allowed, Vec::new())) } /// <https://www.w3.org/TR/CSP/#report-for-request> pub fn report_violations_for_request_by_csp( - request: &Request, + csp_request: &csp::Request, policy_container: &PolicyContainer, ) -> Vec<csp::Violation> { - let origin = match &request.origin { - Origin::Client => return Vec::new(), - Origin::Origin(origin) => origin, - }; - let csp_request = convert_request_to_csp_request(request, origin); - policy_container .csp_list .as_ref() - .map(|c| c.report_violations_for_request(&csp_request)) + .map(|c| c.report_violations_for_request(csp_request)) .unwrap_or_default() } +fn should_response_be_blocked_by_csp( + csp_request: &csp::Request, + response: &Response, + policy_container: &PolicyContainer, +) -> (csp::CheckResult, Vec<csp::Violation>) { + if response.is_network_error() { + return (csp::CheckResult::Allowed, Vec::new()); + } + let csp_response = csp::Response { + url: response + .actual_response() + .url() + .cloned() + .expect("response must have a url") + .into_url(), + redirect_count: csp_request.redirect_count, + }; + policy_container + .csp_list + .as_ref() + .map(|c| c.should_response_to_request_be_blocked(csp_request, &csp_response)) + .unwrap_or((csp::CheckResult::Allowed, Vec::new())) +} + /// [Main fetch](https://fetch.spec.whatwg.org/#concept-main-fetch) pub async fn main_fetch( fetch_params: &mut FetchParams, @@ -270,13 +287,15 @@ pub async fn main_fetch( RequestPolicyContainer::Client => PolicyContainer::default(), RequestPolicyContainer::PolicyContainer(container) => container.to_owned(), }; + let csp_request = convert_request_to_csp_request(request); + if let Some(csp_request) = csp_request.as_ref() { + // Step 2.2. + let violations = report_violations_for_request_by_csp(csp_request, &policy_container); - // Step 2.2. - let violations = report_violations_for_request_by_csp(request, &policy_container); - - if !violations.is_empty() { - target.process_csp_violations(request, violations); - } + if !violations.is_empty() { + target.process_csp_violations(request, violations); + } + }; // Step 3. // TODO: handle request abort. @@ -309,22 +328,24 @@ pub async fn main_fetch( request.insecure_requests_policy ); } + if let Some(csp_request) = csp_request.as_ref() { + // Step 7. If should request be blocked due to a bad port, should fetching request be blocked + // as mixed content, or should request be blocked by Content Security Policy returns blocked, + // then set response to a network error. + let (check_result, violations) = + should_request_be_blocked_by_csp(csp_request, &policy_container); + + if !violations.is_empty() { + target.process_csp_violations(request, violations); + } - // Step 7. If should request be blocked due to a bad port, should fetching request be blocked - // as mixed content, or should request be blocked by Content Security Policy returns blocked, - // then set response to a network error. - let (check_result, violations) = should_request_be_blocked_by_csp(request, &policy_container); - - if !violations.is_empty() { - target.process_csp_violations(request, violations); - } - - if check_result == csp::CheckResult::Blocked { - warn!("Request blocked by CSP"); - response = Some(Response::network_error(NetworkError::Internal( - "Blocked by Content-Security-Policy".into(), - ))) - } + if check_result == csp::CheckResult::Blocked { + warn!("Request blocked by CSP"); + response = Some(Response::network_error(NetworkError::Internal( + "Blocked by Content-Security-Policy".into(), + ))) + } + }; if should_request_be_blocked_due_to_a_bad_port(&request.current_url()) { response = Some(Response::network_error(NetworkError::Internal( "Request attempted on bad port".into(), @@ -530,6 +551,14 @@ pub async fn main_fetch( should_be_blocked_due_to_mime_type(request.destination, &response.headers); let should_replace_with_mixed_content = !response_is_network_error && should_response_be_blocked_as_mixed_content(request, &response, &context.protocols); + let should_replace_with_csp_error = csp_request.is_some_and(|csp_request| { + let (check_result, violations) = + should_response_be_blocked_by_csp(&csp_request, &response, &policy_container); + if !violations.is_empty() { + target.process_csp_violations(request, violations); + } + check_result == csp::CheckResult::Blocked + }); // Step 15. let mut network_error_response = response @@ -553,7 +582,7 @@ pub async fn main_fetch( // Step 19. If response is not a network error and any of the following returns blocked // * should internalResponse to request be blocked as mixed content - // TODO: * should internalResponse to request be blocked by Content Security Policy + // * should internalResponse to request be blocked by Content Security Policy // * should internalResponse to request be blocked due to its MIME type // * should internalResponse to request be blocked due to nosniff let mut blocked_error_response; @@ -572,6 +601,10 @@ pub async fn main_fetch( blocked_error_response = Response::network_error(NetworkError::Internal("Blocked as mixed content".into())); &blocked_error_response + } else if should_replace_with_csp_error { + blocked_error_response = + Response::network_error(NetworkError::Internal("Blocked due to CSP".into())); + &blocked_error_response } else { internal_response }; diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs index 704901f6940..3e6c2bc0695 100644 --- a/components/net/http_loader.rs +++ b/components/net/http_loader.rs @@ -59,7 +59,7 @@ use net_traits::{ use profile_traits::mem::{Report, ReportKind}; use profile_traits::path; use servo_arc::Arc; -use servo_url::{ImmutableOrigin, ServoUrl}; +use servo_url::{Host, ImmutableOrigin, ServoUrl}; use tokio::sync::mpsc::{ Receiver as TokioReceiver, Sender as TokioSender, UnboundedReceiver, UnboundedSender, channel, unbounded_channel, @@ -223,8 +223,11 @@ fn strict_origin_when_cross_origin( strip_url_for_use_as_referrer(referrer_url, true) } -/// <https://html.spec.whatwg.org/multipage/#concept-site-same-site> +/// <https://html.spec.whatwg.org/multipage/#same-site> fn is_same_site(site_a: &ImmutableOrigin, site_b: &ImmutableOrigin) -> bool { + // First steps are for + // https://html.spec.whatwg.org/multipage/#concept-site-same-site + // // Step 1. If A and B are the same opaque origin, then return true. if !site_a.is_tuple() && !site_b.is_tuple() && site_a == site_b { return true; @@ -244,7 +247,12 @@ fn is_same_site(site_a: &ImmutableOrigin, site_b: &ImmutableOrigin) -> bool { } // Step 4. If A's and B's host values are not equal, then return false. - if host_a != host_b { + // Includes the steps of https://html.spec.whatwg.org/multipage/#obtain-a-site + if let (Host::Domain(domain_a), Host::Domain(domain_b)) = (host_a, host_b) { + if reg_suffix(domain_a) != reg_suffix(domain_b) { + return false; + } + } else if host_a != host_b { return false; } @@ -2564,7 +2572,7 @@ fn set_the_sec_fetch_site_header(r: &mut Request) { header = SecFetchSite::CrossSite; // Step 5.3 If r’s origin is not same site with url’s origin, then break. - if is_same_site(request_origin, &url.origin()) { + if !is_same_site(request_origin, &url.origin()) { break; } diff --git a/components/net/lib.rs b/components/net/lib.rs index 0576c017e59..b236f2bc784 100644 --- a/components/net/lib.rs +++ b/components/net/lib.rs @@ -16,7 +16,6 @@ pub mod http_cache; pub mod http_loader; pub mod image_cache; pub mod local_directory_listing; -pub mod mime_classifier; pub mod protocols; pub mod request_interceptor; pub mod resource_thread; diff --git a/components/net/tests/http_loader.rs b/components/net/tests/http_loader.rs index b1e90276472..3e3adcedda9 100644 --- a/components/net/tests/http_loader.rs +++ b/components/net/tests/http_loader.rs @@ -329,7 +329,7 @@ fn test_request_and_response_data_with_network_messages() { ); headers.insert( HeaderName::from_static("sec-fetch-site"), - HeaderValue::from_static("same-site"), + HeaderValue::from_static("cross-site"), ); headers.insert( HeaderName::from_static("sec-fetch-user"), diff --git a/components/net/tests/main.rs b/components/net/tests/main.rs index ba58c4a4c1d..77bc11d4c61 100644 --- a/components/net/tests/main.rs +++ b/components/net/tests/main.rs @@ -14,7 +14,6 @@ mod filemanager_thread; mod hsts; mod http_cache; mod http_loader; -mod mime_classifier; mod resource_thread; mod subresource_integrity; diff --git a/components/net/websocket_loader.rs b/components/net/websocket_loader.rs index 128436ac47c..8ad7df5d376 100644 --- a/components/net/websocket_loader.rs +++ b/components/net/websocket_loader.rs @@ -43,7 +43,8 @@ use crate::async_runtime::HANDLE; use crate::connector::{CACertificates, TlsConfig, create_tls_config}; use crate::cookie::ServoCookie; use crate::fetch::methods::{ - should_request_be_blocked_by_csp, should_request_be_blocked_due_to_a_bad_port, + convert_request_to_csp_request, should_request_be_blocked_by_csp, + should_request_be_blocked_due_to_a_bad_port, }; use crate::hosts::replace_host; use crate::http_loader::HttpState; @@ -390,14 +391,18 @@ fn connect( RequestPolicyContainer::PolicyContainer(container) => container.to_owned(), }; - let (check_result, violations) = should_request_be_blocked_by_csp(&request, &policy_container); + if let Some(csp_request) = convert_request_to_csp_request(&request) { + let (check_result, violations) = + should_request_be_blocked_by_csp(&csp_request, &policy_container); - if !violations.is_empty() { - let _ = resource_event_sender.send(WebSocketNetworkEvent::ReportCSPViolations(violations)); - } + if !violations.is_empty() { + let _ = + resource_event_sender.send(WebSocketNetworkEvent::ReportCSPViolations(violations)); + } - if check_result == csp::CheckResult::Blocked { - return Err("Blocked by Content-Security-Policy".to_string()); + if check_result == csp::CheckResult::Blocked { + return Err("Blocked by Content-Security-Policy".to_string()); + } } let client = match create_request( diff --git a/components/pixels/lib.rs b/components/pixels/lib.rs index 5978a7ddde3..3dda4d28bde 100644 --- a/components/pixels/lib.rs +++ b/components/pixels/lib.rs @@ -31,7 +31,21 @@ pub enum PixelFormat { BGRA8, } -pub fn rgba8_get_rect(pixels: &[u8], size: Size2D<u64>, rect: Rect<u64>) -> Cow<[u8]> { +// Computes image byte length, returning None if overflow occurred or the total length exceeds +// the maximum image allocation size. +pub fn compute_rgba8_byte_length_if_within_limit(width: usize, height: usize) -> Option<usize> { + // Maximum allowed image allocation size (2^31-1 ~ 2GB). + const MAX_IMAGE_BYTE_LENGTH: usize = 2147483647; + + // The color components of each pixel must be stored in four sequential + // elements in the order of red, green, blue, and then alpha. + 4usize + .checked_mul(width) + .and_then(|v| v.checked_mul(height)) + .filter(|v| *v <= MAX_IMAGE_BYTE_LENGTH) +} + +pub fn rgba8_get_rect(pixels: &[u8], size: Size2D<u32>, rect: Rect<u32>) -> Cow<[u8]> { assert!(!rect.is_empty()); assert!(Rect::from_size(size).contains_rect(&rect)); assert_eq!(pixels.len() % 4, 0); @@ -92,18 +106,18 @@ pub fn multiply_u8_color(a: u8, b: u8) -> u8 { pub fn clip( mut origin: Point2D<i32>, - mut size: Size2D<u64>, - surface: Size2D<u64>, -) -> Option<Rect<u64>> { + mut size: Size2D<u32>, + surface: Size2D<u32>, +) -> Option<Rect<u32>> { if origin.x < 0 { - size.width = size.width.saturating_sub(-origin.x as u64); + size.width = size.width.saturating_sub(-origin.x as u32); origin.x = 0; } if origin.y < 0 { - size.height = size.height.saturating_sub(-origin.y as u64); + size.height = size.height.saturating_sub(-origin.y as u32); origin.y = 0; } - let origin = Point2D::new(origin.x as u64, origin.y as u64); + let origin = Point2D::new(origin.x as u32, origin.y as u32); Rect::new(origin, size) .intersection(&Rect::from_size(surface)) .filter(|rect| !rect.is_empty()) diff --git a/components/profile/mem.rs b/components/profile/mem.rs index b9920f252b4..0aff98b89d0 100644 --- a/components/profile/mem.rs +++ b/components/profile/mem.rs @@ -114,7 +114,6 @@ impl Profiler { let _ = sender.send(MemoryReportResult { results }); true }, - ProfilerMsg::Exit => false, } } diff --git a/components/script/body.rs b/components/script/body.rs index cc7870a0845..ee269fd430a 100644 --- a/components/script/body.rs +++ b/components/script/body.rs @@ -249,7 +249,7 @@ impl TransmitBodyConnectHandler { let rejection_handler = Box::new(TransmitBodyPromiseRejectionHandler { bytes_sender, - stream: rooted_stream, + stream: Dom::from_ref(&rooted_stream.clone()), control_sender, }); @@ -321,11 +321,12 @@ impl Callback for TransmitBodyPromiseHandler { /// The handler of read promises rejection of body streams used in /// <https://fetch.spec.whatwg.org/#concept-request-transmit-body>. #[derive(Clone, JSTraceable, MallocSizeOf)] +#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)] struct TransmitBodyPromiseRejectionHandler { #[ignore_malloc_size_of = "Channels are hard"] #[no_trace] bytes_sender: IpcSender<BodyChunkResponse>, - stream: DomRoot<ReadableStream>, + stream: Dom<ReadableStream>, #[ignore_malloc_size_of = "Channels are hard"] #[no_trace] control_sender: IpcSender<BodyChunkRequest>, diff --git a/components/script/canvas_context.rs b/components/script/canvas_context.rs index ec388e039f1..aadbd656a0c 100644 --- a/components/script/canvas_context.rs +++ b/components/script/canvas_context.rs @@ -48,7 +48,7 @@ pub(crate) trait CanvasContext { true } - fn size(&self) -> Size2D<u64> { + fn size(&self) -> Size2D<u32> { self.canvas().size() } @@ -73,12 +73,12 @@ pub(crate) trait CanvasContext { } pub(crate) trait CanvasHelpers { - fn size(&self) -> Size2D<u64>; + fn size(&self) -> Size2D<u32>; fn canvas(&self) -> Option<&HTMLCanvasElement>; } impl CanvasHelpers for HTMLCanvasElementOrOffscreenCanvas { - fn size(&self) -> Size2D<u64> { + fn size(&self) -> Size2D<u32> { match self { HTMLCanvasElementOrOffscreenCanvas::HTMLCanvasElement(canvas) => { canvas.get_size().cast() @@ -164,7 +164,7 @@ impl CanvasContext for RenderingContext { } } - fn size(&self) -> Size2D<u64> { + fn size(&self) -> Size2D<u32> { match self { RenderingContext::Placeholder(context) => (*context.context().unwrap()).size(), RenderingContext::Context2d(context) => context.size(), @@ -251,7 +251,7 @@ impl CanvasContext for OffscreenRenderingContext { } } - fn size(&self) -> Size2D<u64> { + fn size(&self) -> Size2D<u32> { match self { OffscreenRenderingContext::Context2d(context) => context.size(), } diff --git a/components/script/canvas_state.rs b/components/script/canvas_state.rs index d788d2f5929..139579d2045 100644 --- a/components/script/canvas_state.rs +++ b/components/script/canvas_state.rs @@ -383,7 +383,7 @@ impl CanvasState { } } - pub(crate) fn get_rect(&self, canvas_size: Size2D<u64>, rect: Rect<u64>) -> Vec<u8> { + pub(crate) fn get_rect(&self, canvas_size: Size2D<u32>, rect: Rect<u32>) -> Vec<u8> { assert!(self.origin_is_clean()); assert!(Rect::from_size(canvas_size).contains_rect(&rect)); @@ -531,11 +531,11 @@ impl CanvasState { }; // Step 4. Establish the source and destination rectangles. - let video_size = snapshot.size().to_f64(); - let dw = dw.unwrap_or(video_size.width); - let dh = dh.unwrap_or(video_size.height); - let sw = sw.unwrap_or(video_size.width); - let sh = sh.unwrap_or(video_size.height); + let video_size = snapshot.size(); + let dw = dw.unwrap_or(video_size.width as f64); + let dh = dh.unwrap_or(video_size.height as f64); + let sw = sw.unwrap_or(video_size.width as f64); + let sh = sh.unwrap_or(video_size.height as f64); let (source_rect, dest_rect) = self.adjust_source_dest_rects(video_size, sx, sy, sw, sh, dx, dy, dw, dh); @@ -577,7 +577,7 @@ impl CanvasState { let sw = sw.unwrap_or(canvas_size.width as f64); let sh = sh.unwrap_or(canvas_size.height as f64); - let image_size = Size2D::new(canvas_size.width as f64, canvas_size.height as f64); + let image_size = Size2D::new(canvas_size.width, canvas_size.height); // 2. Establish the source and destination rectangles let (source_rect, dest_rect) = self.adjust_source_dest_rects(image_size, sx, sy, sw, sh, dx, dy, dw, dh); @@ -632,7 +632,7 @@ impl CanvasState { let sw = sw.unwrap_or(canvas_size.width as f64); let sh = sh.unwrap_or(canvas_size.height as f64); - let image_size = Size2D::new(canvas_size.width as f64, canvas_size.height as f64); + let image_size = Size2D::new(canvas_size.width, canvas_size.height); // 2. Establish the source and destination rectangles let (source_rect, dest_rect) = self.adjust_source_dest_rects(image_size, sx, sy, sw, sh, dx, dy, dw, dh); @@ -702,12 +702,12 @@ impl CanvasState { let snapshot = self .fetch_image_data(url, cors_setting) .ok_or(Error::InvalidState)?; - let image_size = snapshot.size().to_f64(); + let image_size = snapshot.size(); - let dw = dw.unwrap_or(image_size.width); - let dh = dh.unwrap_or(image_size.height); - let sw = sw.unwrap_or(image_size.width); - let sh = sh.unwrap_or(image_size.height); + let dw = dw.unwrap_or(image_size.width as f64); + let dh = dh.unwrap_or(image_size.height as f64); + let sw = sw.unwrap_or(image_size.width as f64); + let sh = sh.unwrap_or(image_size.height as f64); // Establish the source and destination rectangles let (source_rect, dest_rect) = @@ -741,7 +741,7 @@ impl CanvasState { #[allow(clippy::too_many_arguments)] fn adjust_source_dest_rects( &self, - image_size: Size2D<f64>, + image_size: Size2D<u32>, sx: f64, sy: f64, sw: f64, @@ -766,7 +766,7 @@ impl CanvasState { // When the source rectangle is outside the source image, // the source rectangle must be clipped to the source image let source_rect_clipped = source_rect - .intersection(&image_rect) + .intersection(&image_rect.to_f64()) .unwrap_or(Rect::zero()); // Width and height ratios between the non clipped and clipped source rectangles @@ -1486,7 +1486,7 @@ impl CanvasState { #[allow(clippy::too_many_arguments)] pub(crate) fn get_image_data( &self, - canvas_size: Size2D<u64>, + canvas_size: Size2D<u32>, global: &GlobalScope, sx: i32, sy: i32, @@ -1506,7 +1506,7 @@ impl CanvasState { } let (origin, size) = adjust_size_sign(Point2D::new(sx, sy), Size2D::new(sw, sh)); - let read_rect = match pixels::clip(origin, size.to_u64(), canvas_size) { + let read_rect = match pixels::clip(origin, size.to_u32(), canvas_size) { Some(rect) => rect, None => { // All the pixels are outside the canvas surface. @@ -1526,7 +1526,7 @@ impl CanvasState { // https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata pub(crate) fn put_image_data( &self, - canvas_size: Size2D<u64>, + canvas_size: Size2D<u32>, imagedata: &ImageData, dx: i32, dy: i32, @@ -1547,7 +1547,7 @@ impl CanvasState { #[allow(unsafe_code, clippy::too_many_arguments)] pub(crate) fn put_image_data_( &self, - canvas_size: Size2D<u64>, + canvas_size: Size2D<u32>, imagedata: &ImageData, dx: i32, dy: i32, @@ -1579,7 +1579,7 @@ impl CanvasState { Point2D::new(dirty_x, dirty_y), Size2D::new(dirty_width, dirty_height), ); - let src_rect = match pixels::clip(src_origin, src_size.to_u64(), imagedata_size.to_u64()) { + let src_rect = match pixels::clip(src_origin, src_size.to_u32(), imagedata_size.to_u32()) { Some(rect) => rect, None => return, }; diff --git a/components/script/devtools.rs b/components/script/devtools.rs index 93212887dc8..945470194e2 100644 --- a/components/script/devtools.rs +++ b/components/script/devtools.rs @@ -132,7 +132,7 @@ fn find_node_by_unique_id( document .upcast::<Node>() .traverse_preorder(ShadowIncluding::Yes) - .find(|candidate| candidate.unique_id() == node_id) + .find(|candidate| candidate.unique_id(pipeline) == node_id) }) } diff --git a/components/script/dom/abortcontroller.rs b/components/script/dom/abortcontroller.rs index 3813cfdd51a..3a7ca17220d 100644 --- a/components/script/dom/abortcontroller.rs +++ b/components/script/dom/abortcontroller.rs @@ -3,24 +3,33 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use dom_struct::dom_struct; -use js::jsapi::Value; -use js::rust::{Handle, HandleObject}; +use js::rust::{HandleObject, HandleValue}; +use crate::dom::abortsignal::AbortSignal; use crate::dom::bindings::codegen::Bindings::AbortControllerBinding::AbortControllerMethods; use crate::dom::bindings::reflector::{Reflector, reflect_dom_object_with_proto}; -use crate::dom::bindings::root::DomRoot; +use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::globalscope::GlobalScope; use crate::script_runtime::{CanGc, JSContext}; +/// <https://dom.spec.whatwg.org/#abortcontroller> #[dom_struct] pub(crate) struct AbortController { reflector_: Reflector, + + /// An AbortController object has an associated signal (an AbortSignal object). + signal: Dom<AbortSignal>, } impl AbortController { + /// <https://dom.spec.whatwg.org/#dom-abortcontroller-abortcontroller> fn new_inherited() -> AbortController { + // The new AbortController() constructor steps are: + // Let signal be a new AbortSignal object. + // Set this’s signal to signal. AbortController { reflector_: Reflector::new(), + signal: Dom::from_ref(&AbortSignal::new_inherited()), } } @@ -36,6 +45,12 @@ impl AbortController { can_gc, ) } + + /// <https://dom.spec.whatwg.org/#abortcontroller-signal-abort> + fn signal_abort(&self, cx: JSContext, reason: HandleValue, can_gc: CanGc) { + // signal abort on controller’s signal with reason if it is given. + self.signal.signal_abort(cx, reason, can_gc); + } } impl AbortControllerMethods<crate::DomTypeHolder> for AbortController { @@ -49,5 +64,15 @@ impl AbortControllerMethods<crate::DomTypeHolder> for AbortController { } /// <https://dom.spec.whatwg.org/#dom-abortcontroller-abort> - fn Abort(&self, _cx: JSContext, _reason: Handle<'_, Value>) {} + fn Abort(&self, cx: JSContext, reason: HandleValue, can_gc: CanGc) { + // The abort(reason) method steps are + // to signal abort on this with reason if it is given. + self.signal_abort(cx, reason, can_gc); + } + + /// <https://dom.spec.whatwg.org/#dom-abortcontroller-signal> + fn Signal(&self) -> DomRoot<AbortSignal> { + // The signal getter steps are to return this’s signal. + self.signal.as_rooted() + } } diff --git a/components/script/dom/abortsignal.rs b/components/script/dom/abortsignal.rs index 57c6e9cd67e..e93a7b64e90 100644 --- a/components/script/dom/abortsignal.rs +++ b/components/script/dom/abortsignal.rs @@ -2,18 +2,37 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use std::cell::RefCell; +use std::mem; + use dom_struct::dom_struct; -use js::jsapi::Heap; -use js::jsval::JSVal; -use js::rust::{HandleObject, MutableHandleValue}; +use js::jsapi::{ExceptionStackBehavior, Heap, JS_SetPendingException}; +use js::jsval::{JSVal, UndefinedValue}; +use js::rust::{HandleObject, HandleValue, MutableHandleValue}; +use script_bindings::inheritance::Castable; use crate::dom::bindings::codegen::Bindings::AbortSignalBinding::AbortSignalMethods; -use crate::dom::bindings::reflector::reflect_dom_object_with_proto; +use crate::dom::bindings::error::{Error, ErrorToJsval}; +use crate::dom::bindings::reflector::{DomGlobal, reflect_dom_object_with_proto}; use crate::dom::bindings::root::DomRoot; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::script_runtime::{CanGc, JSContext}; +/// <https://dom.spec.whatwg.org/#abortcontroller-api-integration> +/// TODO: implement algorithms at call point, +/// in order to integrate the abort signal with its various use cases. +#[derive(JSTraceable, MallocSizeOf)] +#[allow(dead_code)] +enum AbortAlgorithm { + /// <https://dom.spec.whatwg.org/#add-an-event-listener> + DomEventLister, + /// <https://streams.spec.whatwg.org/#readable-stream-pipe-to> + StreamPiping, + /// <https://fetch.spec.whatwg.org/#dom-global-fetch> + Fetch, +} + /// <https://dom.spec.whatwg.org/#abortsignal> #[dom_struct] pub(crate) struct AbortSignal { @@ -22,14 +41,17 @@ pub(crate) struct AbortSignal { /// <https://dom.spec.whatwg.org/#abortsignal-abort-reason> #[ignore_malloc_size_of = "mozjs"] abort_reason: Heap<JSVal>, + + /// <https://dom.spec.whatwg.org/#abortsignal-abort-algorithms> + abort_algorithms: RefCell<Vec<AbortAlgorithm>>, } impl AbortSignal { - #[allow(dead_code)] - fn new_inherited() -> AbortSignal { + pub(crate) fn new_inherited() -> AbortSignal { AbortSignal { eventtarget: EventTarget::new_inherited(), abort_reason: Default::default(), + abort_algorithms: Default::default(), } } @@ -46,24 +68,88 @@ impl AbortSignal { can_gc, ) } + + /// <https://dom.spec.whatwg.org/#abortsignal-signal-abort> + pub(crate) fn signal_abort(&self, cx: JSContext, reason: HandleValue, can_gc: CanGc) { + // If signal is aborted, then return. + if self.Aborted() { + return; + } + + let abort_reason = reason.get(); + + // Set signal’s abort reason to reason if it is given; + if !abort_reason.is_undefined() { + self.abort_reason.set(abort_reason); + } else { + // otherwise to a new "AbortError" DOMException. + rooted!(in(*cx) let mut rooted_error = UndefinedValue()); + Error::Abort.to_jsval(cx, &self.global(), rooted_error.handle_mut(), can_gc); + self.abort_reason.set(rooted_error.get()) + } + + // Let dependentSignalsToAbort be a new list. + // For each dependentSignal of signal’s dependent signals: + // TODO: #36936 + + // Run the abort steps for signal. + self.run_the_abort_steps(can_gc); + + // For each dependentSignal of dependentSignalsToAbort, run the abort steps for dependentSignal. + // TODO: #36936 + } + + /// <https://dom.spec.whatwg.org/#run-the-abort-steps> + fn run_the_abort_steps(&self, can_gc: CanGc) { + // For each algorithm of signal’s abort algorithms: run algorithm. + let algos = mem::take(&mut *self.abort_algorithms.borrow_mut()); + for _algo in algos { + // TODO: match on variant and implement algo steps. + // See the various items of #34866 + } + + // Empty signal’s abort algorithms. + // Done above with `take`. + + // Fire an event named abort at signal. + self.upcast::<EventTarget>() + .fire_event(atom!("abort"), can_gc); + } + + /// <https://dom.spec.whatwg.org/#abortsignal-aborted> + fn aborted(&self) -> bool { + // An AbortSignal object is aborted when its abort reason is not undefined. + !self.abort_reason.get().is_undefined() + } } impl AbortSignalMethods<crate::DomTypeHolder> for AbortSignal { /// <https://dom.spec.whatwg.org/#dom-abortsignal-aborted> fn Aborted(&self) -> bool { - // TODO - false + // The aborted getter steps are to return true if this is aborted; otherwise false. + self.aborted() } /// <https://dom.spec.whatwg.org/#dom-abortsignal-reason> - fn Reason(&self, _: JSContext, _rval: MutableHandleValue) { - // TODO + fn Reason(&self, _cx: JSContext, mut rval: MutableHandleValue) { + // The reason getter steps are to return this’s abort reason. + rval.set(self.abort_reason.get()); } /// <https://dom.spec.whatwg.org/#dom-abortsignal-throwifaborted> #[allow(unsafe_code)] fn ThrowIfAborted(&self) { - // TODO + // The throwIfAborted() method steps are to throw this’s abort reason, if this is aborted. + if self.aborted() { + let cx = GlobalScope::get_cx(); + unsafe { + JS_SetPendingException( + *cx, + self.abort_reason.handle(), + ExceptionStackBehavior::Capture, + ) + }; + } } // <https://dom.spec.whatwg.org/#dom-abortsignal-onabort> diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index dbf0f14ab68..961fb92121d 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -13,7 +13,7 @@ use std::str::FromStr; use std::{fmt, mem}; use content_security_policy as csp; -use cssparser::match_ignore_ascii_case; +use cssparser::{Parser as CssParser, ParserInput as CssParserInput, match_ignore_ascii_case}; use devtools_traits::AttrInfo; use dom_struct::dom_struct; use embedder_traits::InputMethodType; @@ -36,6 +36,8 @@ use style::applicable_declarations::ApplicableDeclarationBlock; use style::attr::{AttrValue, LengthOrPercentageOrAuto}; use style::context::QuirksMode; use style::invalidation::element::restyle_hints::RestyleHint; +use style::media_queries::MediaList; +use style::parser::ParserContext as CssParserContext; use style::properties::longhands::{ self, background_image, border_spacing, font_family, font_size, }; @@ -50,13 +52,14 @@ use style::selector_parser::{ }; use style::shared_lock::{Locked, SharedRwLock}; use style::stylesheets::layer_rule::LayerOrder; -use style::stylesheets::{CssRuleType, UrlExtraData}; +use style::stylesheets::{CssRuleType, Origin as CssOrigin, UrlExtraData}; use style::values::computed::Overflow; use style::values::generics::NonNegative; use style::values::generics::position::PreferredRatio; use style::values::generics::ratio::Ratio; use style::values::{AtomIdent, AtomString, CSSFloat, computed, specified}; use style::{ArcSlice, CaseSensitivityExt, dom_apis, thread_state}; +use style_traits::ParsingMode as CssParsingMode; use stylo_atoms::Atom; use stylo_dom::ElementState; use xml5ever::serialize::TraversalScope::{ @@ -118,7 +121,7 @@ use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlfieldsetelement::HTMLFieldSetElement; use crate::dom::htmlfontelement::{HTMLFontElement, HTMLFontElementLayoutHelpers}; use crate::dom::htmlformelement::FormControlElementHelpers; -use crate::dom::htmlhrelement::{HTMLHRElement, HTMLHRLayoutHelpers}; +use crate::dom::htmlhrelement::{HTMLHRElement, HTMLHRLayoutHelpers, SizePresentationalHint}; use crate::dom::htmliframeelement::{HTMLIFrameElement, HTMLIFrameElementLayoutMethods}; use crate::dom::htmlimageelement::{HTMLImageElement, LayoutHTMLImageElementHelpers}; use crate::dom::htmlinputelement::{HTMLInputElement, LayoutHTMLInputElementHelpers}; @@ -781,6 +784,33 @@ impl Element { .registered_intersection_observers .retain(|reg_obs| *reg_obs.observer != *observer) } + + /// <https://html.spec.whatwg.org/multipage/#matches-the-environment> + pub(crate) fn matches_environment(&self, media_query: &str) -> bool { + let document = self.owner_document(); + let quirks_mode = document.quirks_mode(); + let document_url_data = UrlExtraData(document.url().get_arc()); + // FIXME(emilio): This should do the same that we do for other media + // lists regarding the rule type and such, though it doesn't really + // matter right now... + // + // Also, ParsingMode::all() is wrong, and should be DEFAULT. + let context = CssParserContext::new( + CssOrigin::Author, + &document_url_data, + Some(CssRuleType::Style), + CssParsingMode::all(), + quirks_mode, + /* namespaces = */ Default::default(), + None, + None, + ); + let mut parser_input = CssParserInput::new(media_query); + let mut parser = CssParser::new(&mut parser_input); + let media_list = MediaList::parse(&context, &mut parser); + let result = media_list.evaluate(document.window().layout().device(), quirks_mode); + result + } } /// <https://dom.spec.whatwg.org/#valid-shadow-host-name> @@ -1276,6 +1306,47 @@ impl<'dom> LayoutElementHelpers<'dom> for LayoutDom<'dom, Element> { PropertyDeclaration::PaddingRight(cellpadding), )); } + + // https://html.spec.whatwg.org/multipage/#the-hr-element-2 + if let Some(size_info) = self + .downcast::<HTMLHRElement>() + .and_then(|hr_element| hr_element.get_size_info()) + { + match size_info { + SizePresentationalHint::SetHeightTo(height) => { + hints.push(from_declaration( + shared_lock, + PropertyDeclaration::Height(height), + )); + }, + SizePresentationalHint::SetAllBorderWidthValuesTo(border_width) => { + hints.push(from_declaration( + shared_lock, + PropertyDeclaration::BorderLeftWidth(border_width.clone()), + )); + hints.push(from_declaration( + shared_lock, + PropertyDeclaration::BorderRightWidth(border_width.clone()), + )); + hints.push(from_declaration( + shared_lock, + PropertyDeclaration::BorderTopWidth(border_width.clone()), + )); + hints.push(from_declaration( + shared_lock, + PropertyDeclaration::BorderBottomWidth(border_width), + )); + }, + SizePresentationalHint::SetBottomBorderWidthToZero => { + hints.push(from_declaration( + shared_lock, + PropertyDeclaration::BorderBottomWidth( + specified::border::BorderSideWidth::from_px(0.), + ), + )); + }, + } + } } fn get_span(self) -> Option<u32> { @@ -4430,7 +4501,9 @@ impl SelectorsElement for SelectorWrapper<'_> { // a string containing commas (separating each language tag in // a list) but the pseudo-class instead should be parsing and // storing separate <ident> or <string>s for each language tag. - NonTSPseudoClass::Lang(ref lang) => extended_filtering(&self.get_lang(), lang), + NonTSPseudoClass::Lang(ref lang) => { + extended_filtering(&self.upcast::<Node>().get_lang().unwrap_or_default(), lang) + }, NonTSPseudoClass::ReadOnly => { !Element::state(self).contains(NonTSPseudoClass::ReadWrite.state_flag()) @@ -4770,24 +4843,7 @@ impl Element { } } - // https://html.spec.whatwg.org/multipage/#language - pub(crate) fn get_lang(&self) -> String { - self.upcast::<Node>() - .inclusive_ancestors(ShadowIncluding::Yes) - .filter_map(|node| { - node.downcast::<Element>().and_then(|el| { - el.get_attribute(&ns!(xml), &local_name!("lang")) - .or_else(|| el.get_attribute(&ns!(), &local_name!("lang"))) - .map(|attr| String::from(attr.Value())) - }) - // TODO: Check meta tags for a pragma-set default language - // TODO: Check HTTP Content-Language header - }) - .next() - .unwrap_or(String::new()) - } - - pub(crate) fn state(&self) -> ElementState { + pub fn state(&self) -> ElementState { self.state.get() } diff --git a/components/script/dom/event.rs b/components/script/dom/event.rs index 743ced42a4b..345038a08da 100644 --- a/components/script/dom/event.rs +++ b/components/script/dom/event.rs @@ -1124,7 +1124,13 @@ impl TaskOnce for EventTask { let target = self.target.root(); let bubbles = self.bubbles; let cancelable = self.cancelable; - target.fire_event_with_params(self.name, bubbles, cancelable, CanGc::note()); + target.fire_event_with_params( + self.name, + bubbles, + cancelable, + EventComposed::NotComposed, + CanGc::note(), + ); } } diff --git a/components/script/dom/eventsource.rs b/components/script/dom/eventsource.rs index 7cf7bd6106f..3e0070f91d7 100644 --- a/components/script/dom/eventsource.rs +++ b/components/script/dom/eventsource.rs @@ -61,6 +61,34 @@ enum ReadyState { Closed = 2, } +#[derive(JSTraceable, MallocSizeOf)] +struct DroppableEventSource { + canceller: DomRefCell<FetchCanceller>, +} + +impl DroppableEventSource { + pub(crate) fn new(canceller: DomRefCell<FetchCanceller>) -> Self { + DroppableEventSource { canceller } + } + + pub(crate) fn cancel(&self) { + self.canceller.borrow_mut().cancel(); + } + + pub(crate) fn set_canceller(&self, data: FetchCanceller) { + *self.canceller.borrow_mut() = data; + } +} + +// https://html.spec.whatwg.org/multipage/#garbage-collection-2 +impl Drop for DroppableEventSource { + fn drop(&mut self) { + // If an EventSource object is garbage collected while its connection is still open, + // the user agent must abort any instance of the fetch algorithm opened by this EventSource. + self.cancel(); + } +} + #[dom_struct] pub(crate) struct EventSource { eventtarget: EventTarget, @@ -74,7 +102,7 @@ pub(crate) struct EventSource { ready_state: Cell<ReadyState>, with_credentials: bool, - canceller: DomRefCell<FetchCanceller>, + droppable: DroppableEventSource, } enum ParserState { @@ -480,7 +508,7 @@ impl EventSource { ready_state: Cell::new(ReadyState::Connecting), with_credentials, - canceller: DomRefCell::new(Default::default()), + droppable: DroppableEventSource::new(DomRefCell::new(Default::default())), } } @@ -501,7 +529,7 @@ impl EventSource { // https://html.spec.whatwg.org/multipage/#sse-processing-model:fail-the-connection-3 pub(crate) fn cancel(&self) { - self.canceller.borrow_mut().cancel(); + self.droppable.cancel(); self.fail_the_connection(); } @@ -529,15 +557,6 @@ impl EventSource { } } -// https://html.spec.whatwg.org/multipage/#garbage-collection-2 -impl Drop for EventSource { - fn drop(&mut self) { - // If an EventSource object is garbage collected while its connection is still open, - // the user agent must abort any instance of the fetch algorithm opened by this EventSource. - self.canceller.borrow_mut().cancel(); - } -} - impl EventSourceMethods<crate::DomTypeHolder> for EventSource { // https://html.spec.whatwg.org/multipage/#dom-eventsource fn Constructor( @@ -632,7 +651,7 @@ impl EventSourceMethods<crate::DomTypeHolder> for EventSource { listener.notify_fetch(message.unwrap()); }), ); - *ev.canceller.borrow_mut() = FetchCanceller::new(request.id); + ev.droppable.set_canceller(FetchCanceller::new(request.id)); global .core_resource_thread() .send(CoreResourceMsg::Fetch( @@ -672,7 +691,7 @@ impl EventSourceMethods<crate::DomTypeHolder> for EventSource { fn Close(&self) { let GenerationId(prev_id) = self.generation_id.get(); self.generation_id.set(GenerationId(prev_id + 1)); - self.canceller.borrow_mut().cancel(); + self.droppable.cancel(); self.ready_state.set(ReadyState::Closed); } } diff --git a/components/script/dom/eventtarget.rs b/components/script/dom/eventtarget.rs index 1a5aafb0ae7..15f77f5fcd5 100644 --- a/components/script/dom/eventtarget.rs +++ b/components/script/dom/eventtarget.rs @@ -59,7 +59,7 @@ use crate::dom::bindings::trace::HashMapTracedValues; use crate::dom::document::Document; use crate::dom::element::Element; use crate::dom::errorevent::ErrorEvent; -use crate::dom::event::{Event, EventBubbles, EventCancelable, EventStatus}; +use crate::dom::event::{Event, EventBubbles, EventCancelable, EventComposed, EventStatus}; use crate::dom::globalscope::GlobalScope; use crate::dom::htmlformelement::FormControlElementHelpers; use crate::dom::node::{Node, NodeTraits}; @@ -767,6 +767,7 @@ impl EventTarget { name, EventBubbles::DoesNotBubble, EventCancelable::NotCancelable, + EventComposed::NotComposed, can_gc, ) } @@ -777,6 +778,7 @@ impl EventTarget { name, EventBubbles::Bubbles, EventCancelable::NotCancelable, + EventComposed::NotComposed, can_gc, ) } @@ -787,6 +789,7 @@ impl EventTarget { name, EventBubbles::DoesNotBubble, EventCancelable::Cancelable, + EventComposed::NotComposed, can_gc, ) } @@ -801,19 +804,22 @@ impl EventTarget { name, EventBubbles::Bubbles, EventCancelable::Cancelable, + EventComposed::NotComposed, can_gc, ) } - // https://dom.spec.whatwg.org/#concept-event-fire + /// <https://dom.spec.whatwg.org/#concept-event-fire> pub(crate) fn fire_event_with_params( &self, name: Atom, bubbles: EventBubbles, cancelable: EventCancelable, + composed: EventComposed, can_gc: CanGc, ) -> DomRoot<Event> { let event = Event::new(&self.global(), name, bubbles, cancelable, can_gc); + event.set_composed(composed.into()); event.fire(self, can_gc); event } diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index a34b49f4a65..75abc67aef1 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -2982,10 +2982,13 @@ impl GlobalScope { return p; } - if let Some(snapshot) = canvas.get_image_data() { - let image_bitmap = ImageBitmap::new(self, snapshot, can_gc); - image_bitmap.set_origin_clean(canvas.origin_is_clean()); - p.resolve_native(&(image_bitmap), can_gc); + match canvas.get_image_data() { + Some(snapshot) => { + let image_bitmap = ImageBitmap::new(self, snapshot, can_gc); + image_bitmap.set_origin_clean(canvas.origin_is_clean()); + p.resolve_native(&(image_bitmap), can_gc); + }, + None => p.reject_error(Error::InvalidState, can_gc), } p }, @@ -2996,10 +2999,13 @@ impl GlobalScope { return p; } - if let Some(snapshot) = canvas.get_image_data() { - let image_bitmap = ImageBitmap::new(self, snapshot, can_gc); - image_bitmap.set_origin_clean(canvas.origin_is_clean()); - p.resolve_native(&(image_bitmap), can_gc); + match canvas.get_image_data() { + Some(snapshot) => { + let image_bitmap = ImageBitmap::new(self, snapshot, can_gc); + image_bitmap.set_origin_clean(canvas.origin_is_clean()); + p.resolve_native(&(image_bitmap), can_gc); + }, + None => p.reject_error(Error::InvalidState, can_gc), } p }, diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index 499e91c127b..9c688678039 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -16,7 +16,7 @@ use html5ever::{LocalName, Prefix, local_name, ns}; use image::codecs::jpeg::JpegEncoder; use image::codecs::png::PngEncoder; use image::codecs::webp::WebPEncoder; -use image::{ColorType, ImageEncoder}; +use image::{ColorType, ImageEncoder, ImageError}; #[cfg(feature = "webgpu")] use ipc_channel::ipc::{self as ipcchan}; use js::error::throw_type_error; @@ -362,7 +362,13 @@ impl HTMLCanvasElement { Some(context) => context.get_image_data(), None => { let size = self.get_size(); - if size.width == 0 || size.height == 0 { + if size.is_empty() || + pixels::compute_rgba8_byte_length_if_within_limit( + size.width as usize, + size.height as usize, + ) + .is_none() + { None } else { Some(Snapshot::cleared(size.cast())) @@ -385,22 +391,20 @@ impl HTMLCanvasElement { quality: Option<f64>, snapshot: &Snapshot, encoder: &mut W, - ) { + ) -> Result<(), ImageError> { // We can't use self.Width() or self.Height() here, since the size of the canvas // may have changed since the snapshot was created. Truncating the dimensions to a // u32 can't panic, since the data comes from a canvas which is always smaller than // u32::MAX. let canvas_data = snapshot.data(); - let width = snapshot.size().width as u32; - let height = snapshot.size().height as u32; + let width = snapshot.size().width; + let height = snapshot.size().height; match image_type { EncodedImageType::Png => { // FIXME(nox): https://github.com/image-rs/image-png/issues/86 // FIXME(nox): https://github.com/image-rs/image-png/issues/87 - PngEncoder::new(encoder) - .write_image(canvas_data, width, height, ColorType::Rgba8) - .unwrap(); + PngEncoder::new(encoder).write_image(canvas_data, width, height, ColorType::Rgba8) }, EncodedImageType::Jpeg => { let jpeg_encoder = if let Some(quality) = quality { @@ -418,16 +422,16 @@ impl HTMLCanvasElement { JpegEncoder::new(encoder) }; - jpeg_encoder - .write_image(canvas_data, width, height, ColorType::Rgba8) - .unwrap(); + jpeg_encoder.write_image(canvas_data, width, height, ColorType::Rgba8) }, - EncodedImageType::Webp => { // No quality support because of https://github.com/image-rs/image/issues/1984 - WebPEncoder::new_lossless(encoder) - .write_image(canvas_data, width, height, ColorType::Rgba8) - .unwrap(); + WebPEncoder::new_lossless(encoder).write_image( + canvas_data, + width, + height, + ColorType::Rgba8, + ) }, } } @@ -516,17 +520,22 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement { mime_type: DOMString, quality: HandleValue, ) -> Fallible<USVString> { - // Step 1. + // Step 1: If this canvas element's bitmap's origin-clean flag is set to false, + // then throw a "SecurityError" DOMException. if !self.origin_is_clean() { return Err(Error::Security); } - // Step 2. + // Step 2: If this canvas element's bitmap has no pixels (i.e. either its + // horizontal dimension or its vertical dimension is zero), then return the string + // "data:,". (This is the shortest data: URL; it represents the empty string in a + // text/plain resource.) if self.Width() == 0 || self.Height() == 0 { return Ok(USVString("data:,".into())); } - // Step 3. + // Step 3: Let file be a serialization of this canvas element's bitmap as a file, + // passing type and quality if given. let Some(mut snapshot) = self.get_image_data() else { return Ok(USVString("data:,".into())); }; @@ -551,12 +560,20 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement { &base64::engine::general_purpose::STANDARD, ); - self.encode_for_mime_type( - &image_type, - Self::maybe_quality(quality), - &snapshot, - &mut encoder, - ); + if self + .encode_for_mime_type( + &image_type, + Self::maybe_quality(quality), + &snapshot, + &mut encoder, + ) + .is_err() + { + // Step 4. If file is null, then return "data:,". + return Ok(USVString("data:,".into())); + } + + // Step 5. Return a data: URL representing file. [RFC2397] encoder.into_inner(); Ok(USVString(url)) } @@ -604,26 +621,37 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement { return error!("Expected blob callback, but found none!"); }; - if let Some(mut snapshot) = result { - snapshot.transform( - snapshot::AlphaMode::Transparent{ premultiplied: false }, - snapshot::PixelFormat::RGBA - ); - // Step 4.1 - // If result is non-null, then set result to a serialization of result as a file with - // type and quality if given. - let mut encoded: Vec<u8> = vec![]; - - this.encode_for_mime_type(&image_type, quality, &snapshot, &mut encoded); - let blob_impl = BlobImpl::new_from_bytes(encoded, image_type.as_mime_type()); - // Step 4.2.1 Set result to a new Blob object, created in the relevant realm of this canvas element - let blob = Blob::new(&this.global(), blob_impl, CanGc::note()); - - // Step 4.2.2 Invoke callback with « result » and "report". - let _ = callback.Call__(Some(&blob), ExceptionHandling::Report, CanGc::note()); - } else { + let Some(mut snapshot) = result else { let _ = callback.Call__(None, ExceptionHandling::Report, CanGc::note()); - } + return; + }; + + snapshot.transform( + snapshot::AlphaMode::Transparent{ premultiplied: false }, + snapshot::PixelFormat::RGBA + ); + + // Step 4.1: If result is non-null, then set result to a serialization of + // result as a file with type and quality if given. + // Step 4.2: Queue an element task on the canvas blob serialization task + // source given the canvas element to run these steps: + let mut encoded: Vec<u8> = vec![]; + let blob_impl; + let blob; + let result = match this.encode_for_mime_type(&image_type, quality, &snapshot, &mut encoded) { + Ok(..) => { + // Step 4.2.1: If result is non-null, then set result to a new Blob + // object, created in the relevant realm of this canvas element, + // representing result. [FILEAPI] + blob_impl = BlobImpl::new_from_bytes(encoded, image_type.as_mime_type()); + blob = Blob::new(&this.global(), blob_impl, CanGc::note()); + Some(&*blob) + } + Err(..) => None, + }; + + // Step 4.2.2: Invoke callback with « result » and "report". + let _ = callback.Call__(result, ExceptionHandling::Report, CanGc::note()); })); Ok(()) diff --git a/components/script/dom/htmlhrelement.rs b/components/script/dom/htmlhrelement.rs index c88a0fcf184..8dc11e4e848 100644 --- a/components/script/dom/htmlhrelement.rs +++ b/components/script/dom/htmlhrelement.rs @@ -2,11 +2,17 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use std::str::FromStr; + use dom_struct::dom_struct; use html5ever::{LocalName, Prefix, local_name, ns}; use js::rust::HandleObject; use style::attr::{AttrValue, LengthOrPercentageOrAuto}; use style::color::AbsoluteColor; +use style::values::generics::NonNegative; +use style::values::specified::border::BorderSideWidth; +use style::values::specified::length::Size; +use style::values::specified::{LengthPercentage, NoCalcLength}; use crate::dom::bindings::codegen::Bindings::HTMLHRElementBinding::HTMLHRElementMethods; use crate::dom::bindings::inheritance::Castable; @@ -65,6 +71,18 @@ impl HTMLHRElementMethods<crate::DomTypeHolder> for HTMLHRElement { // https://html.spec.whatwg.org/multipage/#dom-hr-color make_legacy_color_setter!(SetColor, "color"); + // https://html.spec.whatwg.org/multipage/#dom-hr-noshade + make_bool_getter!(NoShade, "noshade"); + + // https://html.spec.whatwg.org/multipage/#dom-hr-noshade + make_bool_setter!(SetNoShade, "noshade"); + + // https://html.spec.whatwg.org/multipage/#dom-hr-size + make_getter!(Size, "size"); + + // https://html.spec.whatwg.org/multipage/#dom-hr-size + make_dimension_setter!(SetSize, "size"); + // https://html.spec.whatwg.org/multipage/#dom-hr-width make_getter!(Width, "width"); @@ -72,9 +90,20 @@ impl HTMLHRElementMethods<crate::DomTypeHolder> for HTMLHRElement { make_dimension_setter!(SetWidth, "width"); } +/// The result of applying the the presentational hint for the `size` attribute. +/// +/// (This attribute can mean different things depending on its value and other attributes) +#[allow(clippy::enum_variant_names)] +pub(crate) enum SizePresentationalHint { + SetHeightTo(Size), + SetAllBorderWidthValuesTo(BorderSideWidth), + SetBottomBorderWidthToZero, +} + pub(crate) trait HTMLHRLayoutHelpers { fn get_color(self) -> Option<AbsoluteColor>; fn get_width(self) -> LengthOrPercentageOrAuto; + fn get_size_info(self) -> Option<SizePresentationalHint>; } impl HTMLHRLayoutHelpers for LayoutDom<'_, HTMLHRElement> { @@ -92,6 +121,35 @@ impl HTMLHRLayoutHelpers for LayoutDom<'_, HTMLHRElement> { .cloned() .unwrap_or(LengthOrPercentageOrAuto::Auto) } + + fn get_size_info(self) -> Option<SizePresentationalHint> { + // https://html.spec.whatwg.org/multipage/#the-hr-element-2 + let element = self.upcast::<Element>(); + let size_value = element + .get_attr_val_for_layout(&ns!(), &local_name!("size")) + .and_then(|value| usize::from_str(value).ok()) + .filter(|value| *value != 0)?; + + let hint = if element + .get_attr_for_layout(&ns!(), &local_name!("color")) + .is_some() || + element + .get_attr_for_layout(&ns!(), &local_name!("noshade")) + .is_some() + { + SizePresentationalHint::SetAllBorderWidthValuesTo(BorderSideWidth::from_px( + size_value as f32 / 2.0, + )) + } else if size_value == 1 { + SizePresentationalHint::SetBottomBorderWidthToZero + } else { + SizePresentationalHint::SetHeightTo(Size::LengthPercentage(NonNegative( + LengthPercentage::Length(NoCalcLength::from_px((size_value - 2) as f32)), + ))) + }; + + Some(hint) + } } impl VirtualMethods for HTMLHRElement { diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index b9819000556..b1258c42cce 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -34,9 +34,8 @@ use servo_url::ServoUrl; use servo_url::origin::MutableOrigin; use style::attr::{AttrValue, LengthOrPercentageOrAuto, parse_integer, parse_length}; use style::context::QuirksMode; -use style::media_queries::MediaList; use style::parser::ParserContext; -use style::stylesheets::{CssRuleType, Origin, UrlExtraData}; +use style::stylesheets::{CssRuleType, Origin}; use style::values::specified::AbsoluteLength; use style::values::specified::length::{Length, NoCalcLength}; use style::values::specified::source_size_list::SourceSizeList; @@ -678,7 +677,7 @@ impl HTMLImageElement { // Step 4.6 if let Some(x) = element.get_attribute(&ns!(), &local_name!("media")) { - if !self.matches_environment(x.value().to_string()) { + if !elem.matches_environment(&x.value()) { continue; } } @@ -722,33 +721,6 @@ impl HTMLImageElement { result } - /// <https://html.spec.whatwg.org/multipage/#matches-the-environment> - fn matches_environment(&self, media_query: String) -> bool { - let document = self.owner_document(); - let quirks_mode = document.quirks_mode(); - let document_url_data = UrlExtraData(document.url().get_arc()); - // FIXME(emilio): This should do the same that we do for other media - // lists regarding the rule type and such, though it doesn't really - // matter right now... - // - // Also, ParsingMode::all() is wrong, and should be DEFAULT. - let context = ParserContext::new( - Origin::Author, - &document_url_data, - Some(CssRuleType::Style), - ParsingMode::all(), - quirks_mode, - /* namespaces = */ Default::default(), - None, - None, - ); - let mut parserInput = ParserInput::new(&media_query); - let mut parser = Parser::new(&mut parserInput); - let media_list = MediaList::parse(&context, &mut parser); - let result = media_list.evaluate(document.window().layout().device(), quirks_mode); - result - } - /// <https://html.spec.whatwg.org/multipage/#normalise-the-source-densities> fn normalise_source_densities(&self, source_set: &mut SourceSet, width: Option<Length>) { // Step 1 diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index f4e7683cf2a..41edb2c22d3 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -5,6 +5,7 @@ use std::borrow::{Borrow, ToOwned}; use std::cell::Cell; use std::default::Default; +use std::str::FromStr; use base::id::WebViewId; use content_security_policy as csp; @@ -12,6 +13,8 @@ use dom_struct::dom_struct; use embedder_traits::EmbedderMsg; use html5ever::{LocalName, Prefix, local_name, ns}; use js::rust::HandleObject; +use mime::Mime; +use net_traits::mime_classifier::{MediaType, MimeClassifier}; use net_traits::policy_container::PolicyContainer; use net_traits::request::{ CorsSettings, Destination, Initiator, InsecureRequestsPolicy, Referrer, RequestBuilder, @@ -22,7 +25,7 @@ use net_traits::{ ResourceTimingType, }; use servo_arc::Arc; -use servo_url::ServoUrl; +use servo_url::{ImmutableOrigin, ServoUrl}; use style::attr::AttrValue; use style::stylesheets::Stylesheet; use stylo_atoms::Atom; @@ -78,6 +81,7 @@ struct LinkProcessingOptions { policy_container: PolicyContainer, source_set: Option<()>, base_url: ServoUrl, + origin: ImmutableOrigin, insecure_requests_policy: InsecureRequestsPolicy, has_trustworthy_ancestor_origin: bool, // Some fields that we don't need yet are missing @@ -113,6 +117,10 @@ pub(crate) struct HTMLLinkElement { request_generation_id: Cell<RequestGenerationId>, /// <https://html.spec.whatwg.org/multipage/#explicitly-enabled> is_explicitly_enabled: Cell<bool>, + /// Whether the previous type matched with the destination + previous_type_matched: Cell<bool>, + /// Whether the previous media environment matched with the media query + previous_media_environment_matched: Cell<bool>, } impl HTMLLinkElement { @@ -133,6 +141,8 @@ impl HTMLLinkElement { any_failed_load: Cell::new(false), request_generation_id: Cell::new(RequestGenerationId(0)), is_explicitly_enabled: Cell::new(false), + previous_type_matched: Cell::new(true), + previous_media_environment_matched: Cell::new(true), } } @@ -236,7 +246,7 @@ impl VirtualMethods for HTMLLinkElement { return; } - if !self.upcast::<Node>().is_connected() || is_removal { + if !self.upcast::<Node>().is_connected() { return; } match *local_name { @@ -245,6 +255,12 @@ impl VirtualMethods for HTMLLinkElement { .set(LinkRelations::for_element(self.upcast())); }, local_name!("href") => { + if is_removal { + return; + } + // https://html.spec.whatwg.org/multipage/#link-type-stylesheet + // When the href attribute of the link element of an external resource link + // that is already browsing-context connected is changed. if self.relations.get().contains(LinkRelations::STYLESHEET) { self.handle_stylesheet_url(&attr.value()); } @@ -254,9 +270,19 @@ impl VirtualMethods for HTMLLinkElement { self.handle_favicon_url(&attr.value(), &sizes); } + // https://html.spec.whatwg.org/multipage/#link-type-prefetch + // When the href attribute of the link element of an external resource link + // that is already browsing-context connected is changed. if self.relations.get().contains(LinkRelations::PREFETCH) { self.fetch_and_process_prefetch_link(&attr.value()); } + + // https://html.spec.whatwg.org/multipage/#link-type-preload + // When the href attribute of the link element of an external resource link + // that is already browsing-context connected is changed. + if self.relations.get().contains(LinkRelations::PRELOAD) { + self.handle_preload_url(); + } }, local_name!("sizes") if self.relations.get().contains(LinkRelations::ICON) => { if let Some(ref href) = get_attr(self.upcast(), &local_name!("href")) { @@ -264,9 +290,73 @@ impl VirtualMethods for HTMLLinkElement { } }, local_name!("crossorigin") => { + // https://html.spec.whatwg.org/multipage/#link-type-prefetch + // When the crossorigin attribute of the link element of an external resource link + // that is already browsing-context connected is set, changed, or removed. if self.relations.get().contains(LinkRelations::PREFETCH) { self.fetch_and_process_prefetch_link(&attr.value()); } + + // https://html.spec.whatwg.org/multipage/#link-type-stylesheet + // When the crossorigin attribute of the link element of an external resource link + // that is already browsing-context connected is set, changed, or removed. + if self.relations.get().contains(LinkRelations::STYLESHEET) { + self.handle_stylesheet_url(&attr.value()); + } + }, + local_name!("as") => { + // https://html.spec.whatwg.org/multipage/#link-type-preload + // When the as attribute of the link element of an external resource link + // that is already browsing-context connected is changed. + if self.relations.get().contains(LinkRelations::PRELOAD) { + if let AttributeMutation::Set(Some(_)) = mutation { + self.handle_preload_url(); + } + } + }, + local_name!("type") => { + // https://html.spec.whatwg.org/multipage/#link-type-stylesheet + // When the type attribute of the link element of an external resource link that + // is already browsing-context connected is set or changed to a value that does + // not or no longer matches the Content-Type metadata of the previous obtained + // external resource, if any. + // + // TODO: Match Content-Type metadata to check if it needs to be updated + if self.relations.get().contains(LinkRelations::STYLESHEET) { + self.handle_stylesheet_url(&attr.value()); + } + + // https://html.spec.whatwg.org/multipage/#link-type-preload + // When the type attribute of the link element of an external resource link that + // is already browsing-context connected, but was previously not obtained due to + // the type attribute specifying an unsupported type for the request destination, + // is set, removed, or changed. + if self.relations.get().contains(LinkRelations::PRELOAD) && + !self.previous_type_matched.get() + { + self.handle_preload_url(); + } + }, + local_name!("media") => { + // https://html.spec.whatwg.org/multipage/#link-type-preload + // When the media attribute of the link element of an external resource link that + // is already browsing-context connected, but was previously not obtained due to + // the media attribute not matching the environment, is changed or removed. + if self.relations.get().contains(LinkRelations::PRELOAD) && + !self.previous_media_environment_matched.get() + { + match mutation { + AttributeMutation::Removed | AttributeMutation::Set(Some(_)) => { + self.handle_preload_url() + }, + _ => {}, + }; + } + + let matches_media_environment = + self.upcast::<Element>().matches_environment(&attr.value()); + self.previous_media_environment_matched + .set(matches_media_environment); }, _ => {}, } @@ -307,6 +397,10 @@ impl VirtualMethods for HTMLLinkElement { if relations.contains(LinkRelations::PREFETCH) { self.fetch_and_process_prefetch_link(&href); } + + if relations.contains(LinkRelations::PRELOAD) { + self.handle_preload_url(); + } } } } @@ -325,6 +419,14 @@ impl VirtualMethods for HTMLLinkElement { } impl HTMLLinkElement { + fn compute_destination_for_attribute(&self) -> Destination { + let element = self.upcast::<Element>(); + element + .get_attribute(&ns!(), &local_name!("as")) + .map(|attr| translate_a_preload_destination(&attr.value())) + .unwrap_or(Destination::None) + } + /// <https://html.spec.whatwg.org/multipage/#create-link-options-from-element> fn processing_options(&self) -> LinkProcessingOptions { let element = self.upcast::<Element>(); @@ -333,10 +435,7 @@ impl HTMLLinkElement { let document = self.upcast::<Node>().owner_doc(); // Step 2. Let options be a new link processing options - let destination = element - .get_attribute(&ns!(), &local_name!("as")) - .map(|attr| translate_a_preload_destination(&attr.value())) - .unwrap_or(Destination::None); + let destination = self.compute_destination_for_attribute(); let mut options = LinkProcessingOptions { href: String::new(), @@ -348,6 +447,7 @@ impl HTMLLinkElement { referrer_policy: referrer_policy_for_element(element), policy_container: document.policy_container().to_owned(), source_set: None, // FIXME + origin: document.borrow().origin().immutable().to_owned(), base_url: document.borrow().base_url(), insecure_requests_policy: document.insecure_requests_policy(), has_trustworthy_ancestor_origin: document.has_trustworthy_ancestor_or_current_origin(), @@ -446,6 +546,10 @@ impl HTMLLinkElement { None => "", }; + if !element.matches_environment(mq_str) { + return; + } + let media = MediaList::parse_media_list(mq_str, document.window()); let im_attribute = element.get_attribute(&ns!(), &local_name!("integrity")); @@ -458,8 +562,6 @@ impl HTMLLinkElement { self.request_generation_id .set(self.request_generation_id.get().increment()); - // TODO: #8085 - Don't load external stylesheets if the node's mq - // doesn't match. let loader = StylesheetLoader::for_element(self.upcast()); loader.load( StylesheetContextSource::LinkElement { media: Some(media) }, @@ -494,6 +596,133 @@ impl HTMLLinkElement { Err(e) => debug!("Parsing url {} failed: {}", href, e), } } + + /// <https://html.spec.whatwg.org/multipage/#link-type-preload:fetch-and-process-the-linked-resource-2> + fn handle_preload_url(&self) { + // Step 1. Update the source set for el. + // TODO + // Step 2. Let options be the result of creating link options from el. + let options = self.processing_options(); + // Step 3. Preload options, with the following steps given a response response: + // Step 3.1 If response is a network error, fire an event named error at el. + // Otherwise, fire an event named load at el. + self.preload(options); + } + + /// <https://html.spec.whatwg.org/multipage/#preload> + fn preload(&self, options: LinkProcessingOptions) { + // Step 1. If options's type doesn't match options's destination, then return. + let type_matches_destination: bool = + HTMLLinkElement::type_matches_destination(&options.link_type, options.destination); + self.previous_type_matched.set(type_matches_destination); + if !type_matches_destination { + return; + } + // Step 2. If options's destination is "image" and options's source set is not null, + // then set options's href to the result of selecting an image source from options's source set. + // TODO + // Step 3. Let request be the result of creating a link request given options. + let url = options.base_url.clone(); + let Some(request) = options.create_link_request(self.owner_window().webview_id()) else { + // Step 4. If request is null, then return. + return; + }; + let document = self.upcast::<Node>().owner_doc(); + // Step 5. Let unsafeEndTime be 0. + // TODO + // Step 6. Let entry be a new preload entry whose integrity metadata is options's integrity. + // TODO + // Step 7. Let key be the result of creating a preload key given request. + // TODO + // Step 8. If options's document is "pending", then set request's initiator type to "early hint". + // TODO + // Step 9. Let controller be null. + // Step 10. Let reportTiming given a Document document be to report timing for controller + // given document's relevant global object. + // Step 11. Set controller to the result of fetching request, with processResponseConsumeBody + // set to the following steps given a response response and null, failure, or a byte sequence bodyBytes: + let fetch_context = PreloadContext { + url, + link: Trusted::new(self), + resource_timing: ResourceFetchTiming::new(ResourceTimingType::Resource), + }; + document.fetch_background(request.clone(), fetch_context); + } + + /// <https://html.spec.whatwg.org/multipage/#match-preload-type> + fn type_matches_destination(mime_type: &str, destination: Option<Destination>) -> bool { + // Step 1. If type is an empty string, then return true. + if mime_type.is_empty() { + return true; + } + // Step 2. If destination is "fetch", then return true. + // + // Fetch is handled as an empty string destination in the spec: + // https://fetch.spec.whatwg.org/#concept-potential-destination-translate + let Some(destination) = destination else { + return false; + }; + if destination == Destination::None { + return true; + } + // Step 3. Let mimeTypeRecord be the result of parsing type. + let Ok(mime_type_record) = Mime::from_str(mime_type) else { + // Step 4. If mimeTypeRecord is failure, then return false. + return false; + }; + // Step 5. If mimeTypeRecord is not supported by the user agent, then return false. + // + // We currently don't check if we actually support the mime type. Only if we can classify + // it according to the spec. + let Some(mime_type) = MimeClassifier::get_media_type(&mime_type_record) else { + return false; + }; + // Step 6. If any of the following are true: + if + // destination is "audio" or "video", and mimeTypeRecord is an audio or video MIME type; + ((destination == Destination::Audio || destination == Destination::Video) && + mime_type == MediaType::AudioVideo) + // destination is a script-like destination and mimeTypeRecord is a JavaScript MIME type; + || (destination.is_script_like() && mime_type == MediaType::JavaScript) + // destination is "image" and mimeTypeRecord is an image MIME type; + || (destination == Destination::Image && mime_type == MediaType::Image) + // destination is "font" and mimeTypeRecord is a font MIME type; + || (destination == Destination::Font && mime_type == MediaType::Font) + // destination is "json" and mimeTypeRecord is a JSON MIME type; + || (destination == Destination::Json && mime_type == MediaType::Json) + // destination is "style" and mimeTypeRecord's essence is text/css; or + || (destination == Destination::Style && mime_type_record == mime::TEXT_CSS) + // destination is "track" and mimeTypeRecord's essence is text/vtt, + || (destination == Destination::Track && mime_type_record.essence_str() == "text/vtt") + { + // then return true. + return true; + } + // Step 7. Return false. + false + } + + fn fire_event_after_response(&self, response: Result<ResourceFetchTiming, NetworkError>) { + if response.is_err() { + self.upcast::<EventTarget>() + .fire_event(atom!("error"), CanGc::note()); + } else { + // TODO(35035): Figure out why we need to queue a task for the load event. Otherwise + // the performance timing data hasn't been saved yet, which fails several preload + // WPT tests that assume that performance timing information is available when + // the load event is fired. + let this = Trusted::new(self); + self.owner_global() + .task_manager() + .performance_timeline_task_source() + .queue(task!(preload_load_event: move || { + let this = this.root(); + this + .upcast::<EventTarget>() + .fire_event(atom!("load"), CanGc::note()); + })); + } + } } impl StylesheetOwner for HTMLLinkElement { @@ -552,6 +781,21 @@ impl HTMLLinkElementMethods<crate::DomTypeHolder> for HTMLLinkElement { .set_tokenlist_attribute(&local_name!("rel"), rel, can_gc); } + // https://html.spec.whatwg.org/multipage/#dom-link-as + make_enumerated_getter!( + As, + "as", + "fetch" | "audio" | "audioworklet" | "document" | "embed" | "font" | "frame" + | "iframe" | "image" | "json" | "manifest" | "object" | "paintworklet" + | "report" | "script" | "serviceworker" | "sharedworker" | "style" | "track" + | "video" | "webidentity" | "worker" | "xslt", + missing => "", + invalid => "" + ); + + // https://html.spec.whatwg.org/multipage/#dom-link-as + make_setter!(SetAs, "as"); + // https://html.spec.whatwg.org/multipage/#dom-link-media make_getter!(Media, "media"); @@ -689,6 +933,8 @@ impl LinkProcessingOptions { self.has_trustworthy_ancestor_origin, self.policy_container, ) + .initiator(Initiator::Link) + .origin(self.origin) .integrity_metadata(self.integrity) .cryptographic_nonce_metadata(self.cryptographic_nonce_metadata) .referrer_policy(self.referrer_policy); @@ -795,3 +1041,77 @@ impl PreInvoke for PrefetchContext { true } } + +struct PreloadContext { + /// The `<link>` element that caused this preload operation + link: Trusted<HTMLLinkElement>, + + resource_timing: ResourceFetchTiming, + + /// The url being preloaded + url: ServoUrl, +} + +impl FetchResponseListener for PreloadContext { + fn process_request_body(&mut self, _: RequestId) {} + + fn process_request_eof(&mut self, _: RequestId) {} + + fn process_response( + &mut self, + _: RequestId, + fetch_metadata: Result<FetchMetadata, NetworkError>, + ) { + _ = fetch_metadata; + } + + fn process_response_chunk(&mut self, _: RequestId, chunk: Vec<u8>) { + _ = chunk; + } + + /// Step 3.1 of <https://html.spec.whatwg.org/multipage/#link-type-preload:fetch-and-process-the-linked-resource-2> + fn process_response_eof( + &mut self, + _: RequestId, + response: Result<ResourceFetchTiming, NetworkError>, + ) { + self.link.root().fire_event_after_response(response); + } + + fn resource_timing_mut(&mut self) -> &mut ResourceFetchTiming { + &mut self.resource_timing + } + + fn resource_timing(&self) -> &ResourceFetchTiming { + &self.resource_timing + } + + fn submit_resource_timing(&mut self) { + submit_timing(self, CanGc::note()) + } + + fn process_csp_violations(&mut self, _request_id: RequestId, violations: Vec<csp::Violation>) { + let global = &self.resource_timing_global(); + global.report_csp_violations(violations, None); + } +} + +impl ResourceTimingListener for PreloadContext { + fn resource_timing_information(&self) -> (InitiatorType, ServoUrl) { + ( + InitiatorType::LocalName(self.url.clone().into_string()), + self.url.clone(), + ) + } + + fn resource_timing_global(&self) -> DomRoot<GlobalScope> { + self.link.root().upcast::<Node>().owner_doc().global() + } +} + +impl PreInvoke for PreloadContext { + fn should_invoke(&self) -> bool { + // Preload requests are never aborted. + true + } +} diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index e2b31e918de..0d54d188e59 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -330,6 +330,34 @@ impl From<MediaStreamOrBlob> for SrcObject { } } +#[derive(JSTraceable, MallocSizeOf)] +struct DroppableHtmlMediaElement { + /// Player Id reported the player thread + player_id: Cell<u64>, + #[ignore_malloc_size_of = "Defined in other crates"] + #[no_trace] + player_context: WindowGLContext, +} + +impl DroppableHtmlMediaElement { + fn new(player_id: Cell<u64>, player_context: WindowGLContext) -> Self { + Self { + player_id, + player_context, + } + } + + pub(crate) fn set_player_id(&self, id: u64) { + self.player_id.set(id); + } +} + +impl Drop for DroppableHtmlMediaElement { + fn drop(&mut self) { + self.player_context + .send(GLPlayerMsg::UnregisterPlayer(self.player_id.get())); + } +} #[dom_struct] #[allow(non_snake_case)] pub(crate) struct HTMLMediaElement { @@ -411,16 +439,12 @@ pub(crate) struct HTMLMediaElement { next_timeupdate_event: Cell<Instant>, /// Latest fetch request context. current_fetch_context: DomRefCell<Option<HTMLMediaElementFetchContext>>, - /// Player Id reported the player thread - id: Cell<u64>, /// Media controls id. /// In order to workaround the lack of privileged JS context, we secure the /// the access to the "privileged" document.servoGetMediaControls(id) API by /// keeping a whitelist of media controls identifiers. media_controls_id: DomRefCell<Option<String>>, - #[ignore_malloc_size_of = "Defined in other crates"] - #[no_trace] - player_context: WindowGLContext, + droppable: DroppableHtmlMediaElement, } /// <https://html.spec.whatwg.org/multipage/#dom-media-networkstate> @@ -488,9 +512,11 @@ impl HTMLMediaElement { text_tracks_list: Default::default(), next_timeupdate_event: Cell::new(Instant::now() + Duration::from_millis(250)), current_fetch_context: DomRefCell::new(None), - id: Cell::new(0), media_controls_id: DomRefCell::new(None), - player_context: document.window().get_player_context(), + droppable: DroppableHtmlMediaElement::new( + Cell::new(0), + document.window().get_player_context(), + ), } } @@ -878,6 +904,9 @@ impl HTMLMediaElement { fn fetch_request(&self, offset: Option<u64>, seek_lock: Option<SeekLock>) { if self.resource_url.borrow().is_none() && self.blob_url.borrow().is_none() { eprintln!("Missing request url"); + if let Some(seek_lock) = seek_lock { + seek_lock.unlock(/* successful seek */ false); + } self.queue_dedicated_media_source_failure_steps(); return; } @@ -923,9 +952,17 @@ impl HTMLMediaElement { *current_fetch_context = Some(HTMLMediaElementFetchContext::new(request.id)); let listener = - HTMLMediaElementFetchListener::new(self, url.clone(), offset.unwrap_or(0), seek_lock); + HTMLMediaElementFetchListener::new(self, request.id, url.clone(), offset.unwrap_or(0)); self.owner_document().fetch_background(request, listener); + + // Since we cancelled the previous fetch, from now on the media element + // will only receive response data from the new fetch that's been + // initiated. This means the player can resume operation, since all subsequent data + // pushes will originate from the new seek offset. + if let Some(seek_lock) = seek_lock { + seek_lock.unlock(/* successful seek */ true); + } } // https://html.spec.whatwg.org/multipage/#concept-media-load-resource @@ -1357,6 +1394,10 @@ impl HTMLMediaElement { task_source.queue_simple_event(self.upcast(), atom!("seeked")); } + fn set_player_id(&self, player_id: u64) { + self.droppable.set_player_id(player_id); + } + /// <https://html.spec.whatwg.org/multipage/#poster-frame> pub(crate) fn process_poster_image_loaded(&self, image: Arc<RasterImage>) { if !self.show_poster.get() { @@ -1414,6 +1455,7 @@ impl HTMLMediaElement { audio_renderer, Box::new(window.get_player_context()), ); + let player_id = player.lock().unwrap().get_id(); *self.player.borrow_mut() = Some(player); @@ -1430,7 +1472,7 @@ impl HTMLMediaElement { trace!("Player event {:?}", event); let this = trusted_node.clone(); task_source.queue(task!(handle_player_event: move || { - this.root().handle_player_event(&event, CanGc::note()); + this.root().handle_player_event(player_id, &event, CanGc::note()); })); }), ); @@ -1451,7 +1493,7 @@ impl HTMLMediaElement { }) .unwrap_or((0, None)); - self.id.set(player_id); + self.set_player_id(player_id); self.video_renderer.lock().unwrap().player_id = Some(player_id); if let Some(image_receiver) = image_receiver { @@ -1514,406 +1556,458 @@ impl HTMLMediaElement { } } - fn handle_player_event(&self, event: &PlayerEvent, can_gc: CanGc) { - match *event { - PlayerEvent::EndOfStream => { - // https://html.spec.whatwg.org/multipage/#media-data-processing-steps-list - // => "If the media data can be fetched but is found by inspection to be in - // an unsupported format, or can otherwise not be rendered at all" - if self.ready_state.get() < ReadyState::HaveMetadata { - self.queue_dedicated_media_source_failure_steps(); - } else { - // https://html.spec.whatwg.org/multipage/#reaches-the-end - match self.direction_of_playback() { - PlaybackDirection::Forwards => { - // Step 1. - if self.Loop() { - self.seek( - self.earliest_possible_position(), - /* approximate_for_speed*/ false, - ); - } else { - // Step 2. - // The **ended playback** condition is implemented inside of - // the HTMLMediaElementMethods::Ended method - - // Step 3. - let this = Trusted::new(self); - - self.owner_global().task_manager().media_element_task_source().queue( - task!(reaches_the_end_steps: move || { - let this = this.root(); - // Step 3.1. - this.upcast::<EventTarget>().fire_event(atom!("timeupdate"), CanGc::note()); - - // Step 3.2. - if this.Ended() && !this.Paused() { - // Step 3.2.1. - this.paused.set(true); - - // Step 3.2.2. - this.upcast::<EventTarget>().fire_event(atom!("pause"), CanGc::note()); - - // Step 3.2.3. - this.take_pending_play_promises(Err(Error::Abort)); - this.fulfill_in_flight_play_promises(|| ()); - } - - // Step 3.3. - this.upcast::<EventTarget>().fire_event(atom!("ended"), CanGc::note()); - }) - ); - - // https://html.spec.whatwg.org/multipage/#dom-media-have_current_data - self.change_ready_state(ReadyState::HaveCurrentData); - } - }, + fn end_of_playback_in_forwards_direction(&self) { + // Step 1. If the media element has a loop attribute specified, then seek to the earliest + // posible position of the media resource and return. + if self.Loop() { + self.seek( + self.earliest_possible_position(), + /* approximate_for_speed*/ false, + ); + return; + } + // Step 2. The ended IDL attribute starts returning true once the event loop returns to + // step 1. + // The **ended playback** condition is implemented inside of + // the HTMLMediaElementMethods::Ended method - PlaybackDirection::Backwards => { - if self.playback_position.get() <= self.earliest_possible_position() { - self.owner_global() - .task_manager() - .media_element_task_source() - .queue_simple_event(self.upcast(), atom!("ended")); - } - }, - } - } - }, - PlayerEvent::Error(ref error) => { - error!("Player error: {:?}", error); + // Step 3. Queue a media element task given the media element and the following steps: + let this = Trusted::new(self); - // If we have already flagged an error condition while processing - // the network response, we should silently skip any observable - // errors originating while decoding the erroneous response. - if self.in_error_state() { - return; + self.owner_global() + .task_manager() + .media_element_task_source() + .queue(task!(reaches_the_end_steps: move || { + let this = this.root(); + // Step 3.1. Fire an event named timeupdate at the media element + this.upcast::<EventTarget>().fire_event(atom!("timeupdate"), CanGc::note()); + + // Step 3.2. If the media element has ended playback, the direction of playback is + // forwards, and paused is false, then: + if this.Ended() && !this.Paused() { + // Step 3.2.1. Set the paused attribute to true + this.paused.set(true); + + // Step 3.2.2. Fire an event named pause at the media element + this.upcast::<EventTarget>().fire_event(atom!("pause"), CanGc::note()); + + // Step 3.2.3. Take pending play promises and reject pending play promises with + // the result and an "AbortError" DOMException + this.take_pending_play_promises(Err(Error::Abort)); + this.fulfill_in_flight_play_promises(|| ()); } - // https://html.spec.whatwg.org/multipage/#loading-the-media-resource:media-data-13 - // 1. The user agent should cancel the fetching process. - if let Some(ref mut current_fetch_context) = - *self.current_fetch_context.borrow_mut() - { - current_fetch_context.cancel(CancelReason::Error); - } - // 2. Set the error attribute to the result of creating a MediaError with MEDIA_ERR_DECODE. - self.error.set(Some(&*MediaError::new( - &self.owner_window(), - MEDIA_ERR_DECODE, - can_gc, - ))); + // Step 3.3. Fire an event named ended at the media element. + this.upcast::<EventTarget>().fire_event(atom!("ended"), CanGc::note()); + })); - // 3. Set the element's networkState attribute to the NETWORK_IDLE value. - self.network_state.set(NetworkState::Idle); + // https://html.spec.whatwg.org/multipage/#dom-media-have_current_data + self.change_ready_state(ReadyState::HaveCurrentData); + } - // 4. Set the element's delaying-the-load-event flag to false. This stops delaying the load event. - self.delay_load_event(false, can_gc); + fn playback_end(&self) { + // https://html.spec.whatwg.org/multipage/#media-data-processing-steps-list + // => "If the media data can be fetched but is found by inspection to be in + // an unsupported format, or can otherwise not be rendered at all" + if self.ready_state.get() < ReadyState::HaveMetadata { + self.queue_dedicated_media_source_failure_steps(); + return; + } - // 5. Fire an event named error at the media element. - self.upcast::<EventTarget>() - .fire_event(atom!("error"), can_gc); + // https://html.spec.whatwg.org/multipage/#reaches-the-end + match self.direction_of_playback() { + PlaybackDirection::Forwards => self.end_of_playback_in_forwards_direction(), - // TODO: 6. Abort the overall resource selection algorithm. - }, - PlayerEvent::VideoFrameUpdated => { - // Check if the frame was resized - if let Some(frame) = self.video_renderer.lock().unwrap().current_frame { - self.handle_resize(Some(frame.width as u32), Some(frame.height as u32)); + PlaybackDirection::Backwards => { + if self.playback_position.get() <= self.earliest_possible_position() { + self.owner_global() + .task_manager() + .media_element_task_source() + .queue_simple_event(self.upcast(), atom!("ended")); } }, - PlayerEvent::MetadataUpdated(ref metadata) => { - // https://html.spec.whatwg.org/multipage/#media-data-processing-steps-list - // => If the media resource is found to have an audio track - if !metadata.audio_tracks.is_empty() { - for (i, _track) in metadata.audio_tracks.iter().enumerate() { - // Step 1. - let kind = match i { - 0 => DOMString::from("main"), - _ => DOMString::new(), - }; - let window = self.owner_window(); - let audio_track = AudioTrack::new( - &window, - DOMString::new(), - kind, - DOMString::new(), - DOMString::new(), - Some(&*self.AudioTracks()), - can_gc, - ); - - // Steps 2. & 3. - self.AudioTracks().add(&audio_track); - - // Step 4 - if let Some(servo_url) = self.resource_url.borrow().as_ref() { - let fragment = MediaFragmentParser::from(servo_url); - if let Some(id) = fragment.id() { - if audio_track.id() == DOMString::from(id) { - self.AudioTracks() - .set_enabled(self.AudioTracks().len() - 1, true); - } - } + } + } - if fragment.tracks().contains(&audio_track.kind().into()) { - self.AudioTracks() - .set_enabled(self.AudioTracks().len() - 1, true); - } - } + fn playback_error(&self, error: &str, can_gc: CanGc) { + error!("Player error: {:?}", error); + + // If we have already flagged an error condition while processing + // the network response, we should silently skip any observable + // errors originating while decoding the erroneous response. + if self.in_error_state() { + return; + } + + // https://html.spec.whatwg.org/multipage/#loading-the-media-resource:media-data-13 + // 1. The user agent should cancel the fetching process. + if let Some(ref mut current_fetch_context) = *self.current_fetch_context.borrow_mut() { + current_fetch_context.cancel(CancelReason::Error); + } + // 2. Set the error attribute to the result of creating a MediaError with MEDIA_ERR_DECODE. + self.error.set(Some(&*MediaError::new( + &self.owner_window(), + MEDIA_ERR_DECODE, + can_gc, + ))); + + // 3. Set the element's networkState attribute to the NETWORK_IDLE value. + self.network_state.set(NetworkState::Idle); + + // 4. Set the element's delaying-the-load-event flag to false. This stops delaying the load event. + self.delay_load_event(false, can_gc); + + // 5. Fire an event named error at the media element. + self.upcast::<EventTarget>() + .fire_event(atom!("error"), can_gc); + + // TODO: 6. Abort the overall resource selection algorithm. + } + + fn playback_metadata_updated( + &self, + metadata: &servo_media::player::metadata::Metadata, + can_gc: CanGc, + ) { + // https://html.spec.whatwg.org/multipage/#media-data-processing-steps-list + // => If the media resource is found to have an audio track + if !metadata.audio_tracks.is_empty() { + for (i, _track) in metadata.audio_tracks.iter().enumerate() { + // Step 1. + let kind = match i { + 0 => DOMString::from("main"), + _ => DOMString::new(), + }; + let window = self.owner_window(); + let audio_track = AudioTrack::new( + &window, + DOMString::new(), + kind, + DOMString::new(), + DOMString::new(), + Some(&*self.AudioTracks()), + can_gc, + ); + + // Steps 2. & 3. + self.AudioTracks().add(&audio_track); - // Step 5. & 6, - if self.AudioTracks().enabled_index().is_none() { + // Step 4 + if let Some(servo_url) = self.resource_url.borrow().as_ref() { + let fragment = MediaFragmentParser::from(servo_url); + if let Some(id) = fragment.id() { + if audio_track.id() == DOMString::from(id) { self.AudioTracks() .set_enabled(self.AudioTracks().len() - 1, true); } + } - // Steps 7. - let event = TrackEvent::new( - self.global().as_window(), - atom!("addtrack"), - false, - false, - &Some(VideoTrackOrAudioTrackOrTextTrack::AudioTrack(audio_track)), - can_gc, - ); - - event - .upcast::<Event>() - .fire(self.upcast::<EventTarget>(), can_gc); + if fragment.tracks().contains(&audio_track.kind().into()) { + self.AudioTracks() + .set_enabled(self.AudioTracks().len() - 1, true); } } - // => If the media resource is found to have a video track - if !metadata.video_tracks.is_empty() { - for (i, _track) in metadata.video_tracks.iter().enumerate() { - // Step 1. - let kind = match i { - 0 => DOMString::from("main"), - _ => DOMString::new(), - }; - let window = self.owner_window(); - let video_track = VideoTrack::new( - &window, - DOMString::new(), - kind, - DOMString::new(), - DOMString::new(), - Some(&*self.VideoTracks()), - can_gc, - ); - - // Steps 2. & 3. - self.VideoTracks().add(&video_track); - - // Step 4. - if let Some(track) = self.VideoTracks().item(0) { - if let Some(servo_url) = self.resource_url.borrow().as_ref() { - let fragment = MediaFragmentParser::from(servo_url); - if let Some(id) = fragment.id() { - if track.id() == DOMString::from(id) { - self.VideoTracks().set_selected(0, true); - } - } else if fragment.tracks().contains(&track.kind().into()) { - self.VideoTracks().set_selected(0, true); - } - } - } + // Step 5. & 6, + if self.AudioTracks().enabled_index().is_none() { + self.AudioTracks() + .set_enabled(self.AudioTracks().len() - 1, true); + } - // Step 5. & 6. - if self.VideoTracks().selected_index().is_none() { - self.VideoTracks() - .set_selected(self.VideoTracks().len() - 1, true); - } + // Steps 7. + let event = TrackEvent::new( + self.global().as_window(), + atom!("addtrack"), + false, + false, + &Some(VideoTrackOrAudioTrackOrTextTrack::AudioTrack(audio_track)), + can_gc, + ); - // Steps 7. - let event = TrackEvent::new( - self.global().as_window(), - atom!("addtrack"), - false, - false, - &Some(VideoTrackOrAudioTrackOrTextTrack::VideoTrack(video_track)), - can_gc, - ); - - event - .upcast::<Event>() - .fire(self.upcast::<EventTarget>(), can_gc); - } - } + event + .upcast::<Event>() + .fire(self.upcast::<EventTarget>(), can_gc); + } + } - // => "Once enough of the media data has been fetched to determine the duration..." + // => If the media resource is found to have a video track + if !metadata.video_tracks.is_empty() { + for (i, _track) in metadata.video_tracks.iter().enumerate() { // Step 1. - // servo-media owns the media timeline. - - // Step 2. - // XXX(ferjm) Update the timeline offset. + let kind = match i { + 0 => DOMString::from("main"), + _ => DOMString::new(), + }; + let window = self.owner_window(); + let video_track = VideoTrack::new( + &window, + DOMString::new(), + kind, + DOMString::new(), + DOMString::new(), + Some(&*self.VideoTracks()), + can_gc, + ); - // Step 3. - self.playback_position.set(0.); + // Steps 2. & 3. + self.VideoTracks().add(&video_track); // Step 4. - let previous_duration = self.duration.get(); - if let Some(duration) = metadata.duration { - self.duration.set(duration.as_secs() as f64); - } else { - self.duration.set(f64::INFINITY); + if let Some(track) = self.VideoTracks().item(0) { + if let Some(servo_url) = self.resource_url.borrow().as_ref() { + let fragment = MediaFragmentParser::from(servo_url); + if let Some(id) = fragment.id() { + if track.id() == DOMString::from(id) { + self.VideoTracks().set_selected(0, true); + } + } else if fragment.tracks().contains(&track.kind().into()) { + self.VideoTracks().set_selected(0, true); + } + } } - if previous_duration != self.duration.get() { - self.owner_global() - .task_manager() - .media_element_task_source() - .queue_simple_event(self.upcast(), atom!("durationchange")); + + // Step 5. & 6. + if self.VideoTracks().selected_index().is_none() { + self.VideoTracks() + .set_selected(self.VideoTracks().len() - 1, true); } - // Step 5. - self.handle_resize(Some(metadata.width), Some(metadata.height)); + // Steps 7. + let event = TrackEvent::new( + self.global().as_window(), + atom!("addtrack"), + false, + false, + &Some(VideoTrackOrAudioTrackOrTextTrack::VideoTrack(video_track)), + can_gc, + ); - // Step 6. - self.change_ready_state(ReadyState::HaveMetadata); + event + .upcast::<Event>() + .fire(self.upcast::<EventTarget>(), can_gc); + } + } - // Step 7. - let mut jumped = false; - - // Step 8. - if self.default_playback_start_position.get() > 0. { - self.seek( - self.default_playback_start_position.get(), - /* approximate_for_speed*/ false, - ); - jumped = true; - } + // => "Once enough of the media data has been fetched to determine the duration..." + // Step 1. + // servo-media owns the media timeline. - // Step 9. - self.default_playback_start_position.set(0.); + // Step 2. + // XXX(ferjm) Update the timeline offset. - // Steps 10 and 11. - if let Some(servo_url) = self.resource_url.borrow().as_ref() { - let fragment = MediaFragmentParser::from(servo_url); - if let Some(start) = fragment.start() { - if start > 0. && start < self.duration.get() { - self.playback_position.set(start); - if !jumped { - self.seek(self.playback_position.get(), false) - } - } + // Step 3. + self.playback_position.set(0.); + + // Step 4. + let previous_duration = self.duration.get(); + if let Some(duration) = metadata.duration { + self.duration.set(duration.as_secs() as f64); + } else { + self.duration.set(f64::INFINITY); + } + if previous_duration != self.duration.get() { + self.owner_global() + .task_manager() + .media_element_task_source() + .queue_simple_event(self.upcast(), atom!("durationchange")); + } + + // Step 5. + self.handle_resize(Some(metadata.width), Some(metadata.height)); + + // Step 6. + self.change_ready_state(ReadyState::HaveMetadata); + + // Step 7. + let mut jumped = false; + + // Step 8. + if self.default_playback_start_position.get() > 0. { + self.seek( + self.default_playback_start_position.get(), + /* approximate_for_speed*/ false, + ); + jumped = true; + } + + // Step 9. + self.default_playback_start_position.set(0.); + + // Steps 10 and 11. + if let Some(servo_url) = self.resource_url.borrow().as_ref() { + let fragment = MediaFragmentParser::from(servo_url); + if let Some(start) = fragment.start() { + if start > 0. && start < self.duration.get() { + self.playback_position.set(start); + if !jumped { + self.seek(self.playback_position.get(), false) } } + } + } - // Step 12 & 13 are already handled by the earlier media track processing. + // Step 12 & 13 are already handled by the earlier media track processing. - // We wait until we have metadata to render the controls, so we render them - // with the appropriate size. - if self.Controls() { - self.render_controls(can_gc); - } + // We wait until we have metadata to render the controls, so we render them + // with the appropriate size. + if self.Controls() { + self.render_controls(can_gc); + } - let global = self.global(); - let window = global.as_window(); + let global = self.global(); + let window = global.as_window(); + + // Update the media session metadata title with the obtained metadata. + window.Navigator().MediaSession().update_title( + metadata + .title + .clone() + .unwrap_or(window.get_url().into_string()), + ); + } - // Update the media session metadata title with the obtained metadata. - window.Navigator().MediaSession().update_title( - metadata - .title - .clone() - .unwrap_or(window.get_url().into_string()), - ); - }, - PlayerEvent::NeedData => { - // The player needs more data. - // If we already have a valid fetch request, we do nothing. - // Otherwise, if we have no request and the previous request was - // cancelled because we got an EnoughData event, we restart - // fetching where we left. - if let Some(ref current_fetch_context) = *self.current_fetch_context.borrow() { - match current_fetch_context.cancel_reason() { - Some(reason) if *reason == CancelReason::Backoff => { - // XXX(ferjm) Ideally we should just create a fetch request from - // where we left. But keeping track of the exact next byte that the - // media backend expects is not the easiest task, so I'm simply - // seeking to the current playback position for now which will create - // a new fetch request for the last rendered frame. - self.seek(self.playback_position.get(), false) - }, - _ => (), - } + fn playback_video_frame_updated(&self) { + // Check if the frame was resized + if let Some(frame) = self.video_renderer.lock().unwrap().current_frame { + self.handle_resize(Some(frame.width as u32), Some(frame.height as u32)); + } + } + + fn playback_need_data(&self) { + // The player needs more data. + // If we already have a valid fetch request, we do nothing. + // Otherwise, if we have no request and the previous request was + // cancelled because we got an EnoughData event, we restart + // fetching where we left. + if let Some(ref current_fetch_context) = *self.current_fetch_context.borrow() { + if let Some(reason) = current_fetch_context.cancel_reason() { + // XXX(ferjm) Ideally we should just create a fetch request from + // where we left. But keeping track of the exact next byte that the + // media backend expects is not the easiest task, so I'm simply + // seeking to the current playback position for now which will create + // a new fetch request for the last rendered frame. + if *reason == CancelReason::Backoff { + self.seek(self.playback_position.get(), false); } - }, - PlayerEvent::EnoughData => { - self.change_ready_state(ReadyState::HaveEnoughData); - - // The player has enough data and it is asking us to stop pushing - // bytes, so we cancel the ongoing fetch request iff we are able - // to restart it from where we left. Otherwise, we continue the - // current fetch request, assuming that some frames will be dropped. - if let Some(ref mut current_fetch_context) = - *self.current_fetch_context.borrow_mut() - { - if current_fetch_context.is_seekable() { - current_fetch_context.cancel(CancelReason::Backoff); - } + return; + } + } + + if let Some(ref mut current_fetch_context) = *self.current_fetch_context.borrow_mut() { + if let Err(e) = { + let mut data_source = current_fetch_context.data_source().borrow_mut(); + data_source.set_locked(false); + data_source.process_into_player_from_queue(self.player.borrow().as_ref().unwrap()) + } { + // If we are pushing too much data and we know that we can + // restart the download later from where we left, we cancel + // the current request. Otherwise, we continue the request + // assuming that we may drop some frames. + if e == PlayerError::EnoughData { + current_fetch_context.cancel(CancelReason::Backoff); + } + } + } + } + + fn playback_enough_data(&self) { + self.change_ready_state(ReadyState::HaveEnoughData); + + // The player has enough data and it is asking us to stop pushing + // bytes, so we cancel the ongoing fetch request iff we are able + // to restart it from where we left. Otherwise, we continue the + // current fetch request, assuming that some frames will be dropped. + if let Some(ref mut current_fetch_context) = *self.current_fetch_context.borrow_mut() { + if current_fetch_context.is_seekable() { + current_fetch_context.cancel(CancelReason::Backoff); + } + } + } + + fn playback_position_changed(&self, position: u64) { + let position = position as f64; + let _ = self + .played + .borrow_mut() + .add(self.playback_position.get(), position); + self.playback_position.set(position); + self.time_marches_on(); + let media_position_state = + MediaPositionState::new(self.duration.get(), self.playbackRate.get(), position); + debug!( + "Sending media session event set position state {:?}", + media_position_state + ); + self.send_media_session_event(MediaSessionEvent::SetPositionState(media_position_state)); + } + + fn playback_seek_done(&self) { + // Continuation of + // https://html.spec.whatwg.org/multipage/#dom-media-seek + + // Step 13. + let task = MediaElementMicrotask::Seeked { + elem: DomRoot::from_ref(self), + generation_id: self.generation_id.get(), + }; + ScriptThread::await_stable_state(Microtask::MediaElement(task)); + } + + fn playback_state_changed(&self, state: &PlaybackState) { + let mut media_session_playback_state = MediaSessionPlaybackState::None_; + match *state { + PlaybackState::Paused => { + media_session_playback_state = MediaSessionPlaybackState::Paused; + if self.ready_state.get() == ReadyState::HaveMetadata { + self.change_ready_state(ReadyState::HaveEnoughData); } }, - PlayerEvent::PositionChanged(position) => { - let position = position as f64; - let _ = self - .played - .borrow_mut() - .add(self.playback_position.get(), position); - self.playback_position.set(position); - self.time_marches_on(); - let media_position_state = - MediaPositionState::new(self.duration.get(), self.playbackRate.get(), position); - debug!( - "Sending media session event set position state {:?}", - media_position_state - ); - self.send_media_session_event(MediaSessionEvent::SetPositionState( - media_position_state, - )); + PlaybackState::Playing => { + media_session_playback_state = MediaSessionPlaybackState::Playing; }, - PlayerEvent::SeekData(p, ref seek_lock) => { - self.fetch_request(Some(p), Some(seek_lock.clone())); + PlaybackState::Buffering => { + // Do not send the media session playback state change event + // in this case as a None_ state is expected to clean up the + // session. + return; }, - PlayerEvent::SeekDone(_) => { - // Continuation of - // https://html.spec.whatwg.org/multipage/#dom-media-seek - - // Step 13. - let task = MediaElementMicrotask::Seeked { - elem: DomRoot::from_ref(self), - generation_id: self.generation_id.get(), - }; - ScriptThread::await_stable_state(Microtask::MediaElement(task)); + _ => {}, + }; + debug!( + "Sending media session event playback state changed to {:?}", + media_session_playback_state + ); + self.send_media_session_event(MediaSessionEvent::PlaybackStateChange( + media_session_playback_state, + )); + } + + fn handle_player_event(&self, player_id: usize, event: &PlayerEvent, can_gc: CanGc) { + // Ignore the asynchronous event from previous player. + if self + .player + .borrow() + .as_ref() + .is_none_or(|player| player.lock().unwrap().get_id() != player_id) + { + return; + } + + match *event { + PlayerEvent::EndOfStream => self.playback_end(), + PlayerEvent::Error(ref error) => self.playback_error(error, can_gc), + PlayerEvent::VideoFrameUpdated => self.playback_video_frame_updated(), + PlayerEvent::MetadataUpdated(ref metadata) => { + self.playback_metadata_updated(metadata, can_gc) }, - PlayerEvent::StateChanged(ref state) => { - let mut media_session_playback_state = MediaSessionPlaybackState::None_; - match *state { - PlaybackState::Paused => { - media_session_playback_state = MediaSessionPlaybackState::Paused; - if self.ready_state.get() == ReadyState::HaveMetadata { - self.change_ready_state(ReadyState::HaveEnoughData); - } - }, - PlaybackState::Playing => { - media_session_playback_state = MediaSessionPlaybackState::Playing; - }, - PlaybackState::Buffering => { - // Do not send the media session playback state change event - // in this case as a None_ state is expected to clean up the - // session. - return; - }, - _ => {}, - }; - debug!( - "Sending media session event playback state changed to {:?}", - media_session_playback_state - ); - self.send_media_session_event(MediaSessionEvent::PlaybackStateChange( - media_session_playback_state, - )); + PlayerEvent::NeedData => self.playback_need_data(), + PlayerEvent::EnoughData => self.playback_enough_data(), + PlayerEvent::PositionChanged(position) => self.playback_position_changed(position), + PlayerEvent::SeekData(p, ref seek_lock) => { + self.fetch_request(Some(p), Some(seek_lock.clone())) }, + PlayerEvent::SeekDone(_) => self.playback_seek_done(), + PlayerEvent::StateChanged(ref state) => self.playback_state_changed(state), } } @@ -2111,13 +2205,6 @@ impl HTMLMediaElement { } } -impl Drop for HTMLMediaElement { - fn drop(&mut self) { - self.player_context - .send(GLPlayerMsg::UnregisterPlayer(self.id.get())); - } -} - impl HTMLMediaElementMethods<crate::DomTypeHolder> for HTMLMediaElement { // https://html.spec.whatwg.org/multipage/#dom-media-networkstate fn NetworkState(&self) -> u16 { @@ -2659,6 +2746,80 @@ enum Resource { Url(ServoUrl), } +#[derive(Debug, MallocSizeOf, PartialEq)] +enum DataBuffer { + Payload(Vec<u8>), + EndOfStream, +} + +#[derive(MallocSizeOf)] +struct BufferedDataSource { + /// During initial setup and seeking (including clearing the buffer queue + /// and resetting the end-of-stream state), the data source should be locked and + /// any request for processing should be ignored until the media player informs us + /// via the NeedData event that it is ready to accept incoming data. + locked: Cell<bool>, + /// Temporary storage for incoming data. + buffers: VecDeque<DataBuffer>, +} + +impl BufferedDataSource { + fn new() -> BufferedDataSource { + BufferedDataSource { + locked: Cell::new(true), + buffers: VecDeque::default(), + } + } + + fn set_locked(&self, locked: bool) { + self.locked.set(locked) + } + + fn add_buffer_to_queue(&mut self, buffer: DataBuffer) { + debug_assert_ne!( + self.buffers.back(), + Some(&DataBuffer::EndOfStream), + "The media backend not expects any further data after end of stream" + ); + + self.buffers.push_back(buffer); + } + + fn process_into_player_from_queue( + &mut self, + player: &Arc<Mutex<dyn Player>>, + ) -> Result<(), PlayerError> { + // Early out if any request for processing should be ignored. + if self.locked.get() { + return Ok(()); + } + + while let Some(buffer) = self.buffers.pop_front() { + match buffer { + DataBuffer::Payload(payload) => { + if let Err(e) = player.lock().unwrap().push_data(payload) { + warn!("Could not push input data to player {:?}", e); + return Err(e); + } + }, + DataBuffer::EndOfStream => { + if let Err(e) = player.lock().unwrap().end_of_stream() { + warn!("Could not signal EOS to player {:?}", e); + return Err(e); + } + }, + } + } + + Ok(()) + } + + fn reset(&mut self) { + self.locked.set(true); + self.buffers.clear(); + } +} + /// Indicates the reason why a fetch request was cancelled. #[derive(Debug, MallocSizeOf, PartialEq)] enum CancelReason { @@ -2672,12 +2833,16 @@ enum CancelReason { #[derive(MallocSizeOf)] pub(crate) struct HTMLMediaElementFetchContext { + /// The fetch request id. + request_id: RequestId, /// Some if the request has been cancelled. cancel_reason: Option<CancelReason>, /// Indicates whether the fetched stream is seekable. is_seekable: bool, /// Indicates whether the fetched stream is origin clean. origin_clean: bool, + /// The buffered data source which to be processed by media backend. + data_source: DomRefCell<BufferedDataSource>, /// Fetch canceller. Allows cancelling the current fetch request by /// manually calling its .cancel() method or automatically on Drop. fetch_canceller: FetchCanceller, @@ -2686,13 +2851,19 @@ pub(crate) struct HTMLMediaElementFetchContext { impl HTMLMediaElementFetchContext { fn new(request_id: RequestId) -> HTMLMediaElementFetchContext { HTMLMediaElementFetchContext { + request_id, cancel_reason: None, is_seekable: false, origin_clean: true, + data_source: DomRefCell::new(BufferedDataSource::new()), fetch_canceller: FetchCanceller::new(request_id), } } + fn request_id(&self) -> RequestId { + self.request_id + } + fn is_seekable(&self) -> bool { self.is_seekable } @@ -2709,11 +2880,16 @@ impl HTMLMediaElementFetchContext { self.origin_clean = false; } + fn data_source(&self) -> &DomRefCell<BufferedDataSource> { + &self.data_source + } + fn cancel(&mut self, reason: CancelReason) { if self.cancel_reason.is_some() { return; } self.cancel_reason = Some(reason); + self.data_source.borrow_mut().reset(); self.fetch_canceller.cancel(); } @@ -2729,6 +2905,8 @@ struct HTMLMediaElementFetchListener { metadata: Option<Metadata>, /// The generation of the media element when this fetch started. generation_id: u32, + /// The fetch request id. + request_id: RequestId, /// Time of last progress notification. next_progress_event: Instant, /// Timing data for this resource. @@ -2737,16 +2915,12 @@ struct HTMLMediaElementFetchListener { url: ServoUrl, /// Expected content length of the media asset being fetched or played. expected_content_length: Option<u64>, - /// Number of the last byte fetched from the network for the ongoing - /// request. It is only reset to 0 if we reach EOS. Seek requests - /// set it to the requested position. Requests triggered after an - /// EnoughData event uses this value to restart the download from - /// the last fetched position. - latest_fetched_content: u64, - /// The media player discards all data pushes until the seek block - /// is released right before pushing the data from the offset requested - /// by a seek request. - seek_lock: Option<SeekLock>, + /// Actual content length of the media asset was fetched. + fetched_content_length: u64, + /// Discarded content length from the network for the ongoing + /// request if range requests are not supported. Seek requests set it + /// to the required position (in bytes). + content_length_to_discard: u64, } // https://html.spec.whatwg.org/multipage/#media-data-processing-steps-list @@ -2758,11 +2932,6 @@ impl FetchResponseListener for HTMLMediaElementFetchListener { fn process_response(&mut self, _: RequestId, metadata: Result<FetchMetadata, NetworkError>) { let elem = self.elem.root(); - if elem.generation_id.get() != self.generation_id || elem.player.borrow().is_none() { - // A new fetch request was triggered, so we ignore this response. - return; - } - if let Ok(FetchMetadata::Filtered { filtered: FilteredMetadata::Opaque | FilteredMetadata::OpaqueRedirect(_), .. @@ -2794,24 +2963,25 @@ impl FetchResponseListener for HTMLMediaElementFetchListener { // We only set the expected input size if it changes. if content_length != self.expected_content_length { if let Some(content_length) = content_length { - if let Err(e) = elem - .player - .borrow() - .as_ref() - .unwrap() - .lock() - .unwrap() - .set_input_size(content_length) - { - warn!("Could not set player input size {:?}", e); - } else { - self.expected_content_length = Some(content_length); - } + self.expected_content_length = Some(content_length); } } } } + // Explicit media player initialization with live/seekable source. + if let Err(e) = elem + .player + .borrow() + .as_ref() + .unwrap() + .lock() + .unwrap() + .set_input_size(self.expected_content_length.unwrap_or_default()) + { + warn!("Could not set player input size {:?}", e); + } + let (status_is_ok, is_seekable) = self.metadata.as_ref().map_or((true, false), |s| { let status = &s.status; ( @@ -2839,52 +3009,51 @@ impl FetchResponseListener for HTMLMediaElementFetchListener { } } - fn process_response_chunk(&mut self, _: RequestId, payload: Vec<u8>) { + fn process_response_chunk(&mut self, _: RequestId, chunk: Vec<u8>) { let elem = self.elem.root(); - // If an error was received previously or if we triggered a new fetch request, - // we skip processing the payload. - if elem.generation_id.get() != self.generation_id || elem.player.borrow().is_none() { - return; - } - if let Some(ref current_fetch_context) = *elem.current_fetch_context.borrow() { + + self.fetched_content_length += chunk.len() as u64; + + // If an error was received previously, we skip processing the payload. + if let Some(ref mut current_fetch_context) = *elem.current_fetch_context.borrow_mut() { if current_fetch_context.cancel_reason().is_some() { return; } - } - - let payload_len = payload.len() as u64; - if let Some(seek_lock) = self.seek_lock.take() { - seek_lock.unlock(/* successful seek */ true); - } + // Discard chunk of the response body if fetch context doesn't + // support range requests. + let payload = if !current_fetch_context.is_seekable() && + self.content_length_to_discard != 0 + { + if chunk.len() as u64 > self.content_length_to_discard { + let shrink_chunk = chunk[self.content_length_to_discard as usize..].to_vec(); + self.content_length_to_discard = 0; + shrink_chunk + } else { + // Completely discard this response chunk. + self.content_length_to_discard -= chunk.len() as u64; + return; + } + } else { + chunk + }; - // Push input data into the player. - if let Err(e) = elem - .player - .borrow() - .as_ref() - .unwrap() - .lock() - .unwrap() - .push_data(payload) - { - // If we are pushing too much data and we know that we can - // restart the download later from where we left, we cancel - // the current request. Otherwise, we continue the request - // assuming that we may drop some frames. - if e == PlayerError::EnoughData { - if let Some(ref mut current_fetch_context) = - *elem.current_fetch_context.borrow_mut() - { + if let Err(e) = { + let mut data_source = current_fetch_context.data_source().borrow_mut(); + data_source.add_buffer_to_queue(DataBuffer::Payload(payload)); + data_source.process_into_player_from_queue(elem.player.borrow().as_ref().unwrap()) + } { + // If we are pushing too much data and we know that we can + // restart the download later from where we left, we cancel + // the current request. Otherwise, we continue the request + // assuming that we may drop some frames. + if e == PlayerError::EnoughData { current_fetch_context.cancel(CancelReason::Backoff); } + return; } - warn!("Could not push input data to player {:?}", e); - return; } - self.latest_fetched_content += payload_len; - // https://html.spec.whatwg.org/multipage/#concept-media-load-resource step 4, // => "If mode is remote" step 2 if Instant::now() > self.next_progress_event { @@ -2903,38 +3072,45 @@ impl FetchResponseListener for HTMLMediaElementFetchListener { status: Result<ResourceFetchTiming, NetworkError>, ) { trace!("process response eof"); - if let Some(seek_lock) = self.seek_lock.take() { - seek_lock.unlock(/* successful seek */ false); - } let elem = self.elem.root(); - if elem.generation_id.get() != self.generation_id || elem.player.borrow().is_none() { - return; - } - // There are no more chunks of the response body forthcoming, so we can // go ahead and notify the media backend not to expect any further data. - if let Err(e) = elem - .player - .borrow() - .as_ref() - .unwrap() - .lock() - .unwrap() - .end_of_stream() - { - warn!("Could not signal EOS to player {:?}", e); - } + if let Some(ref mut current_fetch_context) = *elem.current_fetch_context.borrow_mut() { + // On initial state change READY -> PAUSED the media player perform + // seek to initial position by event with seek segment (TIME format) + // while media stack operates in BYTES format and configuring segment + // start and stop positions without the total size of the stream is not + // possible. As fallback the media player perform seek with BYTES format + // and initiate seek request via "seek-data" callback with required offset. + if self.expected_content_length.is_none() && self.fetched_content_length != 0 { + if let Err(e) = elem + .player + .borrow() + .as_ref() + .unwrap() + .lock() + .unwrap() + .set_input_size(self.fetched_content_length) + { + warn!("Could not set player input size {:?}", e); + } + } + + let mut data_source = current_fetch_context.data_source().borrow_mut(); - // If an error was previously received we skip processing the payload. - if let Some(ref current_fetch_context) = *elem.current_fetch_context.borrow() { + data_source.add_buffer_to_queue(DataBuffer::EndOfStream); + let _ = + data_source.process_into_player_from_queue(elem.player.borrow().as_ref().unwrap()); + + // If an error was previously received we skip processing the payload. if let Some(CancelReason::Error) = current_fetch_context.cancel_reason() { return; } } - if status.is_ok() && self.latest_fetched_content != 0 { + if status.is_ok() && self.fetched_content_length != 0 { elem.upcast::<EventTarget>() .fire_event(atom!("progress"), CanGc::note()); @@ -3015,28 +3191,33 @@ impl ResourceTimingListener for HTMLMediaElementFetchListener { impl PreInvoke for HTMLMediaElementFetchListener { fn should_invoke(&self) -> bool { - //TODO: finish_load needs to run at some point if the generation changes. - self.elem.root().generation_id.get() == self.generation_id + let elem = self.elem.root(); + + if elem.generation_id.get() != self.generation_id || elem.player.borrow().is_none() { + return false; + } + + // A new fetch request was triggered, so we skip processing previous request. + elem.current_fetch_context + .borrow() + .as_ref() + .is_some_and(|context| context.request_id() == self.request_id) } } impl HTMLMediaElementFetchListener { - fn new( - elem: &HTMLMediaElement, - url: ServoUrl, - offset: u64, - seek_lock: Option<SeekLock>, - ) -> Self { + fn new(elem: &HTMLMediaElement, request_id: RequestId, url: ServoUrl, offset: u64) -> Self { Self { elem: Trusted::new(elem), metadata: None, generation_id: elem.generation_id.get(), + request_id, next_progress_event: Instant::now() + Duration::from_millis(350), resource_timing: ResourceFetchTiming::new(ResourceTimingType::Resource), url, expected_content_length: None, - latest_fetched_content: offset, - seek_lock, + fetched_content_length: 0, + content_length_to_discard: offset, } } } diff --git a/components/script/dom/htmlmetaelement.rs b/components/script/dom/htmlmetaelement.rs index e94a5e1ff33..4ec6db7212c 100644 --- a/components/script/dom/htmlmetaelement.rs +++ b/components/script/dom/htmlmetaelement.rs @@ -2,6 +2,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use std::str::FromStr; + +use compositing_traits::CompositorMsg; +use compositing_traits::viewport_description::ViewportDescription; use dom_struct::dom_struct; use html5ever::{LocalName, Prefix, local_name, ns}; use js::rust::HandleObject; @@ -61,6 +65,9 @@ impl HTMLMetaElement { if name == "referrer" { self.apply_referrer(); } + if name == "viewport" { + self.parse_and_send_viewport_if_necessary(); + } // https://html.spec.whatwg.org/multipage/#attr-meta-http-equiv } else if !self.HttpEquiv().is_empty() { // TODO: Implement additional http-equiv candidates @@ -115,6 +122,29 @@ impl HTMLMetaElement { } } + /// <https://drafts.csswg.org/css-viewport/#parsing-algorithm> + fn parse_and_send_viewport_if_necessary(&self) { + // Skip processing if this isn't the top level frame + if !self.owner_window().is_top_level() { + return; + } + let element = self.upcast::<Element>(); + let Some(content) = element.get_attribute(&ns!(), &local_name!("content")) else { + return; + }; + + if let Ok(viewport) = ViewportDescription::from_str(&content.value()) { + self.owner_window() + .compositor_api() + .sender() + .send(CompositorMsg::Viewport( + self.owner_window().webview_id(), + viewport, + )) + .unwrap(); + } + } + /// <https://html.spec.whatwg.org/multipage/#attr-meta-http-equiv-content-security-policy> fn apply_csp_list(&self) { if let Some(parent) = self.upcast::<Node>().GetParentElement() { diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index d1b3cfd3467..b3005b181da 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -70,6 +70,7 @@ use crate::dom::performanceresourcetiming::InitiatorType; use crate::dom::trustedscript::TrustedScript; use crate::dom::trustedscripturl::TrustedScriptURL; use crate::dom::virtualmethods::VirtualMethods; +use crate::dom::window::Window; use crate::fetch::create_a_potential_cors_request; use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener}; use crate::realms::enter_realm; @@ -275,6 +276,7 @@ pub(crate) static SCRIPT_JS_MIMES: StaticStringVec = &[ pub(crate) enum ScriptType { Classic, Module, + ImportMap, } #[derive(JSTraceable, MallocSizeOf)] @@ -770,14 +772,15 @@ impl HTMLScriptElement { // Step 23. Module script credentials mode. let module_credentials_mode = match script_type { ScriptType::Classic => CredentialsMode::CredentialsSameOrigin, - ScriptType::Module => reflect_cross_origin_attribute(element).map_or( - CredentialsMode::CredentialsSameOrigin, - |attr| match &*attr { - "use-credentials" => CredentialsMode::Include, - "anonymous" => CredentialsMode::CredentialsSameOrigin, - _ => CredentialsMode::CredentialsSameOrigin, - }, - ), + ScriptType::Module | ScriptType::ImportMap => reflect_cross_origin_attribute(element) + .map_or( + CredentialsMode::CredentialsSameOrigin, + |attr| match &*attr { + "use-credentials" => CredentialsMode::Include, + "anonymous" => CredentialsMode::CredentialsSameOrigin, + _ => CredentialsMode::CredentialsSameOrigin, + }, + ), }; // Step 24. Let cryptographic nonce be el's [[CryptographicNonce]] internal slot's value. @@ -821,7 +824,13 @@ impl HTMLScriptElement { if let Some(src) = element.get_attribute(&ns!(), &local_name!("src")) { // Step 31. If el has a src content attribute, then: - // TODO: Step 31.1. If el's type is "importmap". + // Step 31.1. If el's type is "importmap". + if script_type == ScriptType::ImportMap { + // then queue an element task on the DOM manipulation task source + // given el to fire an event named error at el, and return. + self.queue_error_event(); + return; + } // Step 31.2. Let src be the value of el's src attribute. let src = src.value(); @@ -904,7 +913,7 @@ impl HTMLScriptElement { doc.add_asap_script(self); }; }, - // TODO: Case "importmap" + ScriptType::ImportMap => (), } } else { // Step 32. If el does not have a src content attribute: @@ -913,18 +922,17 @@ impl HTMLScriptElement { let text_rc = Rc::new(text); - // TODO: Fix step number or match spec text. Is this step 32.1? - let result = Ok(ScriptOrigin::internal( - Rc::clone(&text_rc), - base_url.clone(), - options.clone(), - script_type, - self.global().unminified_js_dir(), - )); - - // TODO: Fix step number or match spec text. Is this step 32.2? + // Step 32.2: Switch on el's type: match script_type { ScriptType::Classic => { + let result = Ok(ScriptOrigin::internal( + Rc::clone(&text_rc), + base_url.clone(), + options.clone(), + script_type, + self.global().unminified_js_dir(), + )); + if was_parser_inserted && doc.get_current_parser() .is_some_and(|parser| parser.script_nesting_level() <= 1) && @@ -958,6 +966,10 @@ impl HTMLScriptElement { can_gc, ); }, + ScriptType::ImportMap => { + // TODO: Let result be the result of creating an import map + // parse result given source text and base URL. + }, } } } @@ -1054,19 +1066,17 @@ impl HTMLScriptElement { } else { document.set_current_script(Some(self)) } - }, - ScriptType::Module => document.set_current_script(None), - } - - match script.type_ { - ScriptType::Classic => { self.run_a_classic_script(&script, can_gc); document.set_current_script(old_script.as_deref()); }, ScriptType::Module => { - assert!(document.GetCurrentScript().is_none()); + document.set_current_script(None); self.run_a_module_script(&script, false, can_gc); }, + ScriptType::ImportMap => { + // TODO: Register an import map given el's relevant + // global object and el's result. + }, } // Step 7. @@ -1517,6 +1527,13 @@ impl HTMLScriptElementMethods<crate::DomTypeHolder> for HTMLScriptElement { .SetTextContent(Some(DOMString::from(value)), can_gc); Ok(()) } + + /// <https://html.spec.whatwg.org/multipage/#dom-script-supports> + fn Supports(_window: &Window, type_: DOMString) -> bool { + // The type argument has to exactly match these values, + // we do not perform an ASCII case-insensitive match. + matches!(type_.str(), "classic" | "module" | "importmap") + } } #[derive(Clone, Copy)] diff --git a/components/script/dom/htmlselectelement.rs b/components/script/dom/htmlselectelement.rs index 0f48c8e923f..2fd8f35c4d8 100644 --- a/components/script/dom/htmlselectelement.rs +++ b/components/script/dom/htmlselectelement.rs @@ -16,6 +16,8 @@ use embedder_traits::{SelectElementOptionOrOptgroup, SelectElementOption}; use euclid::{Size2D, Point2D, Rect}; use embedder_traits::{FormControl as EmbedderFormControl, EmbedderMsg}; +use crate::dom::bindings::refcounted::Trusted; +use crate::dom::event::{EventBubbles, EventCancelable, EventComposed}; use crate::dom::bindings::codegen::GenericBindings::HTMLOptGroupElementBinding::HTMLOptGroupElement_Binding::HTMLOptGroupElementMethods; use crate::dom::activation::Activatable; use crate::dom::attr::Attr; @@ -346,13 +348,6 @@ impl HTMLSelectElement { .SetData(displayed_text.trim().into()); } - pub(crate) fn selection_changed(&self, can_gc: CanGc) { - self.update_shadow_tree(can_gc); - - self.upcast::<EventTarget>() - .fire_bubbling_event(atom!("change"), can_gc); - } - pub(crate) fn selected_option(&self) -> Option<DomRoot<HTMLOptionElement>> { self.list_of_options() .find(|opt_elem| opt_elem.Selected()) @@ -417,12 +412,39 @@ impl HTMLSelectElement { return None; }; - if response.is_some() && response != selected_index { - self.selection_changed(can_gc); - } - response } + + /// <https://html.spec.whatwg.org/multipage/#send-select-update-notifications> + fn send_update_notifications(&self) { + // > When the user agent is to send select update notifications, queue an element task on the + // > user interaction task source given the select element to run these steps: + let this = Trusted::new(self); + self.owner_global() + .task_manager() + .user_interaction_task_source() + .queue(task!(send_select_update_notification: move || { + let this = this.root(); + + // TODO: Step 1. Set the select element's user validity to true. + + // Step 2. Fire an event named input at the select element, with the bubbles and composed + // attributes initialized to true. + this.upcast::<EventTarget>() + .fire_event_with_params( + atom!("input"), + EventBubbles::Bubbles, + EventCancelable::NotCancelable, + EventComposed::Composed, + CanGc::note(), + ); + + // Step 3. Fire an event named change at the select element, with the bubbles attribute initialized + // to true. + this.upcast::<EventTarget>() + .fire_bubbling_event(atom!("change"), CanGc::note()); + })); + } } impl HTMLSelectElementMethods<crate::DomTypeHolder> for HTMLSelectElement { @@ -578,21 +600,28 @@ impl HTMLSelectElementMethods<crate::DomTypeHolder> for HTMLSelectElement { /// <https://html.spec.whatwg.org/multipage/#dom-select-selectedindex> fn SetSelectedIndex(&self, index: i32, can_gc: CanGc) { + let mut selection_did_change = false; + let mut opt_iter = self.list_of_options(); for opt in opt_iter.by_ref().take(index as usize) { + selection_did_change |= opt.Selected(); opt.set_selectedness(false); } - if let Some(opt) = opt_iter.next() { - opt.set_selectedness(true); - opt.set_dirtiness(true); + if let Some(selected_option) = opt_iter.next() { + selection_did_change |= !selected_option.Selected(); + selected_option.set_selectedness(true); + selected_option.set_dirtiness(true); + // Reset remaining <option> elements for opt in opt_iter { + selection_did_change |= opt.Selected(); opt.set_selectedness(false); } } - // TODO: Track whether the selected element actually changed - self.update_shadow_tree(can_gc); + if selection_did_change { + self.update_shadow_tree(can_gc); + } } /// <https://html.spec.whatwg.org/multipage/#dom-cva-willvalidate> @@ -767,7 +796,6 @@ impl Activatable for HTMLSelectElement { true } - /// <https://html.spec.whatwg.org/multipage/#input-activation-behavior> fn activation_behavior(&self, _event: &Event, _target: &EventTarget, can_gc: CanGc) { let Some(selected_value) = self.show_menu(can_gc) else { // The user did not select a value @@ -775,6 +803,7 @@ impl Activatable for HTMLSelectElement { }; self.SetSelectedIndex(selected_value as i32, can_gc); + self.send_update_notifications(); } } diff --git a/components/script/dom/imagedata.rs b/components/script/dom/imagedata.rs index a891064952a..a834abdae78 100644 --- a/components/script/dom/imagedata.rs +++ b/components/script/dom/imagedata.rs @@ -41,14 +41,11 @@ impl ImageData { mut data: Option<Vec<u8>>, can_gc: CanGc, ) -> Fallible<DomRoot<ImageData>> { - // The color components of each pixel must be stored in four sequential - // elements in the order of red, green, blue, and then alpha. - let len = 4u32 - .checked_mul(width) - .and_then(|v| v.checked_mul(height)) - .ok_or(Error::Range( - "The requested image size exceeds the supported range".to_owned(), - ))?; + let len = + pixels::compute_rgba8_byte_length_if_within_limit(width as usize, height as usize) + .ok_or(Error::Range( + "The requested image size exceeds the supported range".to_owned(), + ))?; unsafe { let cx = GlobalScope::get_cx(); @@ -129,18 +126,16 @@ impl ImageData { return Err(Error::IndexSize); } - // The color components of each pixel must be stored in four sequential - // elements in the order of red, green, blue, and then alpha. - // Please note when a too-large ImageData is created using a constructor - // historically throwns an IndexSizeError, instead of RangeError. - let len = 4u32 - .checked_mul(width) - .and_then(|v| v.checked_mul(height)) - .ok_or(Error::IndexSize)?; + // When a constructor is called for an ImageData that is too large, other browsers throw + // IndexSizeError rather than RangeError here, so we do the same. + let len = + pixels::compute_rgba8_byte_length_if_within_limit(width as usize, height as usize) + .ok_or(Error::IndexSize)?; let cx = GlobalScope::get_cx(); - let heap_typed_array = create_heap_buffer_source_with_length::<ClampedU8>(cx, len, can_gc)?; + let heap_typed_array = + create_heap_buffer_source_with_length::<ClampedU8>(cx, len as u32, can_gc)?; let imagedata = Box::new(ImageData { reflector_: Reflector::new(), @@ -159,8 +154,8 @@ impl ImageData { } #[allow(unsafe_code)] - pub(crate) unsafe fn get_rect(&self, rect: Rect<u64>) -> Cow<[u8]> { - pixels::rgba8_get_rect(self.as_slice(), self.get_size().to_u64(), rect) + pub(crate) unsafe fn get_rect(&self, rect: Rect<u32>) -> Cow<[u8]> { + pixels::rgba8_get_rect(self.as_slice(), self.get_size().to_u32(), rect) } pub(crate) fn get_size(&self) -> Size2D<u32> { diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 691b3a38f19..bf36242572f 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -48,7 +48,7 @@ use style::properties::ComputedValues; use style::selector_parser::{SelectorImpl, SelectorParser}; use style::stylesheets::{Stylesheet, UrlExtraData}; use uuid::Uuid; -use xml5ever::serialize as xml_serialize; +use xml5ever::{local_name, serialize as xml_serialize}; use crate::conversions::Convert; use crate::document_loader::DocumentLoader; @@ -738,10 +738,9 @@ impl Node { } pub(crate) fn ranges_is_empty(&self) -> bool { - match self.rare_data().as_ref() { - Some(data) => data.ranges.is_empty(), - None => false, - } + self.rare_data() + .as_ref() + .is_none_or(|data| data.ranges.is_empty()) } #[inline] @@ -1247,13 +1246,13 @@ impl Node { } } - pub(crate) fn unique_id(&self) -> String { + pub(crate) fn unique_id(&self, pipeline: PipelineId) -> String { let mut rare_data = self.ensure_rare_data(); if rare_data.unique_id.is_none() { - let id = UniqueId::new(); - ScriptThread::save_node_id(id.borrow().simple().to_string()); - rare_data.unique_id = Some(id); + let node_id = UniqueId::new(); + ScriptThread::save_node_id(pipeline, node_id.borrow().simple().to_string()); + rare_data.unique_id = Some(node_id); } rare_data .unique_id @@ -1267,6 +1266,7 @@ impl Node { pub(crate) fn summarize(&self, can_gc: CanGc) -> NodeInfo { let USVString(base_uri) = self.BaseURI(); let node_type = self.NodeType(); + let pipeline = self.owner_document().window().pipeline_id(); let maybe_shadow_root = self.downcast::<ShadowRoot>(); let shadow_root_mode = maybe_shadow_root @@ -1274,7 +1274,7 @@ impl Node { .map(ShadowRootMode::convert); let host = maybe_shadow_root .map(ShadowRoot::Host) - .map(|host| host.upcast::<Node>().unique_id()); + .map(|host| host.upcast::<Node>().unique_id(pipeline)); let is_shadow_host = self.downcast::<Element>().is_some_and(|potential_host| { let Some(root) = potential_host.shadow_root() else { return false; @@ -1296,12 +1296,12 @@ impl Node { .map(|style| style.Display().into()); NodeInfo { - unique_id: self.unique_id(), + unique_id: self.unique_id(pipeline), host, base_uri, parent: self .GetParentNode() - .map_or("".to_owned(), |node| node.unique_id()), + .map_or("".to_owned(), |node| node.unique_id(pipeline)), node_type, is_top_level_document: node_type == NodeConstants::DOCUMENT_NODE, node_name: String::from(self.NodeName()), @@ -1455,6 +1455,21 @@ impl Node { .map(|data| data.element_data.borrow().styles.primary().clone()) } + /// <https://html.spec.whatwg.org/multipage/#language> + pub(crate) fn get_lang(&self) -> Option<String> { + self.inclusive_ancestors(ShadowIncluding::Yes) + .filter_map(|node| { + node.downcast::<Element>().and_then(|el| { + el.get_attribute(&ns!(xml), &local_name!("lang")) + .or_else(|| el.get_attribute(&ns!(), &local_name!("lang"))) + .map(|attr| String::from(attr.Value())) + }) + // TODO: Check meta tags for a pragma-set default language + // TODO: Check HTTP Content-Language header + }) + .next() + } + /// <https://dom.spec.whatwg.org/#assign-slotables-for-a-tree> pub(crate) fn assign_slottables_for_a_tree(&self) { // NOTE: This method traverses all descendants of the node and is potentially very @@ -2603,7 +2618,9 @@ impl Node { fn remove(node: &Node, parent: &Node, suppress_observers: SuppressObserver, can_gc: CanGc) { parent.owner_doc().add_script_and_layout_blocker(); - // Step 2. + // Step 1. Let parent be node’s parent. + // Step 2. Assert: parent is non-null. + // NOTE: We get parent as an argument instead assert!( node.GetParentNode() .is_some_and(|node_parent| &*node_parent == parent) @@ -2615,11 +2632,21 @@ impl Node { if parent.ranges_is_empty() { None } else { - // Step 1. + // Step 1. Let parent be node’s parent. + // Step 2. Assert: parent is not null. + // NOTE: We already have the parent. + + // Step 3. Let index be node’s index. let index = node.index(); - // Steps 2-3 are handled in Node::unbind_from_tree. - // Steps 4-5. + + // Steps 4-5 are handled in Node::unbind_from_tree. + + // Step 6. For each live range whose start node is parent and start offset is greater than index, + // decrease its start offset by 1. + // Step 7. For each live range whose end node is parent and end offset is greater than index, + // decrease its end offset by 1. parent.ranges().decrease_above(parent, index, 1); + // Parent had ranges, we needed the index, let's keep track of // it to avoid computing it for other ranges when calling // unbind_from_tree recursively. @@ -3863,7 +3890,12 @@ impl VirtualMethods for Node { /// <https://dom.spec.whatwg.org/#concept-node-remove> fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) { self.super_type().unwrap().unbind_from_tree(context, can_gc); - if !self.ranges_is_empty() { + + // Ranges should only drain to the parent from inclusive non-shadow + // including descendants. If we're in a shadow tree at this point then the + // unbind operation happened further up in the tree and we should not + // drain any ranges. + if !self.is_in_a_shadow_tree() && !self.ranges_is_empty() { self.ranges().drain_to_parent(context, self); } } diff --git a/components/script/dom/offscreencanvas.rs b/components/script/dom/offscreencanvas.rs index b4323ef6b54..cbcffb40e3e 100644 --- a/components/script/dom/offscreencanvas.rs +++ b/components/script/dom/offscreencanvas.rs @@ -72,8 +72,11 @@ impl OffscreenCanvas { ) } - pub(crate) fn get_size(&self) -> Size2D<u64> { - Size2D::new(self.Width(), self.Height()) + pub(crate) fn get_size(&self) -> Size2D<u32> { + Size2D::new( + self.Width().try_into().unwrap_or(u32::MAX), + self.Height().try_into().unwrap_or(u32::MAX), + ) } pub(crate) fn origin_is_clean(&self) -> bool { @@ -92,7 +95,13 @@ impl OffscreenCanvas { Some(context) => context.get_image_data(), None => { let size = self.get_size(); - if size.width == 0 || size.height == 0 { + if size.is_empty() || + pixels::compute_rgba8_byte_length_if_within_limit( + size.width as usize, + size.height as usize, + ) + .is_none() + { None } else { Some(Snapshot::cleared(size)) diff --git a/components/script/dom/range.rs b/components/script/dom/range.rs index 4bf3b7fb72a..a47b060e0f2 100644 --- a/components/script/dom/range.rs +++ b/components/script/dom/range.rs @@ -344,6 +344,58 @@ impl Range { .chain(iter::once(end_clone)) .flat_map(move |node| node.content_boxes(can_gc)) } + + /// <https://dom.spec.whatwg.org/#concept-range-bp-set> + #[allow(clippy::neg_cmp_op_on_partial_ord)] + fn set_the_start_or_end( + &self, + node: &Node, + offset: u32, + start_or_end: StartOrEnd, + ) -> ErrorResult { + // Step 1. If node is a doctype, then throw an "InvalidNodeTypeError" DOMException. + if node.is_doctype() { + return Err(Error::InvalidNodeType); + } + + // Step 2. If offset is greater than node’s length, then throw an "IndexSizeError" DOMException. + if offset > node.len() { + return Err(Error::IndexSize); + } + + // Step 3. Let bp be the boundary point (node, offset). + // NOTE: We don't need this part. + + match start_or_end { + // If these steps were invoked as "set the start" + StartOrEnd::Start => { + // Step 4.1 If range’s root is not equal to node’s root, or if bp is after the range’s end, + // set range’s end to bp. + // Step 4.2 Set range’s start to bp. + self.set_start(node, offset); + if !(self.start() <= self.end()) { + self.set_end(node, offset); + } + }, + // If these steps were invoked as "set the end" + StartOrEnd::End => { + // Step 4.1 If range’s root is not equal to node’s root, or if bp is before the range’s start, + // set range’s start to bp. + // Step 4.2 Set range’s end to bp. + self.set_end(node, offset); + if !(self.end() >= self.start()) { + self.set_start(node, offset); + } + }, + } + + Ok(()) + } +} + +enum StartOrEnd { + Start, + End, } impl RangeMethods<crate::DomTypeHolder> for Range { @@ -365,43 +417,13 @@ impl RangeMethods<crate::DomTypeHolder> for Range { } /// <https://dom.spec.whatwg.org/#dom-range-setstart> - #[allow(clippy::neg_cmp_op_on_partial_ord)] fn SetStart(&self, node: &Node, offset: u32) -> ErrorResult { - if node.is_doctype() { - // Step 1. - Err(Error::InvalidNodeType) - } else if offset > node.len() { - // Step 2. - Err(Error::IndexSize) - } else { - // Step 3. - self.set_start(node, offset); - if !(self.start() <= self.end()) { - // Step 4. - self.set_end(node, offset); - } - Ok(()) - } + self.set_the_start_or_end(node, offset, StartOrEnd::Start) } /// <https://dom.spec.whatwg.org/#dom-range-setend> - #[allow(clippy::neg_cmp_op_on_partial_ord)] fn SetEnd(&self, node: &Node, offset: u32) -> ErrorResult { - if node.is_doctype() { - // Step 1. - Err(Error::InvalidNodeType) - } else if offset > node.len() { - // Step 2. - Err(Error::IndexSize) - } else { - // Step 3. - self.set_end(node, offset); - if !(self.end() >= self.start()) { - // Step 4. - self.set_start(node, offset); - } - Ok(()) - } + self.set_the_start_or_end(node, offset, StartOrEnd::End) } /// <https://dom.spec.whatwg.org/#dom-range-setstartbefore> @@ -1204,6 +1226,7 @@ impl WeakRangeVec { } /// Used for steps 2-3. when removing a node. + /// /// <https://dom.spec.whatwg.org/#concept-node-remove> pub(crate) fn drain_to_parent(&self, context: &UnbindContext, child: &Node) { if self.is_empty() { diff --git a/components/script/dom/readablestream.rs b/components/script/dom/readablestream.rs index d2c1d853f86..5203a5f0a83 100644 --- a/components/script/dom/readablestream.rs +++ b/components/script/dom/readablestream.rs @@ -1926,7 +1926,7 @@ impl ReadableStreamMethods<crate::DomTypeHolder> for ReadableStream { // If ! IsReadableStreamLocked(this) is true, // return a promise rejected with a TypeError exception. let promise = Promise::new(&global, can_gc); - promise.reject_error(Error::Type("stream is not locked".to_owned()), can_gc); + promise.reject_error(Error::Type("stream is locked".to_owned()), can_gc); promise } else { // Return ! ReadableStreamCancel(this, reason). diff --git a/components/script/dom/webgl2renderingcontext.rs b/components/script/dom/webgl2renderingcontext.rs index d2bbf3bba57..8f2bf9c2fcc 100644 --- a/components/script/dom/webgl2renderingcontext.rs +++ b/components/script/dom/webgl2renderingcontext.rs @@ -534,7 +534,7 @@ impl WebGL2RenderingContext { let src_origin = Point2D::new(x, y); let src_size = Size2D::new(width as u32, height as u32); let fb_size = Size2D::new(fb_width as u32, fb_height as u32); - match pixels::clip(src_origin, src_size.to_u64(), fb_size.to_u64()) { + match pixels::clip(src_origin, src_size.to_u32(), fb_size.to_u32()) { Some(rect) => rect.to_u32(), None => return, } @@ -2183,7 +2183,7 @@ impl WebGL2RenderingContextMethods<crate::DomTypeHolder> for WebGL2RenderingCont let src_origin = Point2D::new(x, y); let src_size = Size2D::new(width as u32, height as u32); let fb_size = Size2D::new(fb_width as u32, fb_height as u32); - if pixels::clip(src_origin, src_size.to_u64(), fb_size.to_u64()).is_none() { + if pixels::clip(src_origin, src_size.to_u32(), fb_size.to_u32()).is_none() { return; } } diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 70463ae1528..9b8ee461979 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -3838,7 +3838,7 @@ impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContex let src_origin = Point2D::new(x, y); let src_size = Size2D::new(width as u32, height as u32); let fb_size = Size2D::new(fb_width as u32, fb_height as u32); - let src_rect = match pixels::clip(src_origin, src_size.to_u64(), fb_size.to_u64()) { + let src_rect = match pixels::clip(src_origin, src_size.to_u32(), fb_size.to_u32()) { Some(rect) => rect, None => return, }; diff --git a/components/script/dom/webgpu/gpucanvascontext.rs b/components/script/dom/webgpu/gpucanvascontext.rs index 359b1b14003..9bf43c77bf5 100644 --- a/components/script/dom/webgpu/gpucanvascontext.rs +++ b/components/script/dom/webgpu/gpucanvascontext.rs @@ -167,8 +167,8 @@ impl GPUCanvasContext { // causes FAIL on webgpu:web_platform,canvas,configure:usage:* usage: configuration.usage | GPUTextureUsageConstants::COPY_SRC, size: GPUExtent3D::GPUExtent3DDict(GPUExtent3DDict { - width: size.width as u32, - height: size.height as u32, + width: size.width, + height: size.height, depthOrArrayLayers: 1, }), viewFormats: configuration.viewFormats.clone(), diff --git a/components/script/dom/webxr/xrwebgllayer.rs b/components/script/dom/webxr/xrwebgllayer.rs index 0e93e583c6f..0d32b10cf47 100644 --- a/components/script/dom/webxr/xrwebgllayer.rs +++ b/components/script/dom/webxr/xrwebgllayer.rs @@ -129,10 +129,7 @@ impl XRWebGLLayer { HTMLCanvasElementOrOffscreenCanvas::HTMLCanvasElement(canvas) => canvas.get_size(), HTMLCanvasElementOrOffscreenCanvas::OffscreenCanvas(canvas) => { let size = canvas.get_size(); - Size2D::new( - size.width.try_into().unwrap_or(0), - size.height.try_into().unwrap_or(0), - ) + Size2D::new(size.width, size.height) }, }; Size2D::from_untyped(size) diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index 4e7c136f42b..858cd24d45d 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -797,6 +797,7 @@ impl XMLHttpRequestMethods<crate::DomTypeHolder> for XMLHttpRequest { if self.ready_state.get() == XMLHttpRequestState::Done { self.change_ready_state(XMLHttpRequestState::Unsent, can_gc); self.response_status.set(Err(())); + *self.status.borrow_mut() = HttpStatus::new_error(); self.response.borrow_mut().clear(); self.response_headers.borrow_mut().clear(); } @@ -1188,6 +1189,8 @@ impl XMLHttpRequest { self.discard_subsequent_responses(); self.send_flag.set(false); + *self.status.borrow_mut() = HttpStatus::new_error(); + self.response_headers.borrow_mut().clear(); // XXXManishearth set response to NetworkError self.change_ready_state(XMLHttpRequestState::Done, can_gc); return_if_fetch_was_terminated!(); diff --git a/components/script/dom/xpathresult.rs b/components/script/dom/xpathresult.rs index f4a9ae7a31b..890e559ba97 100644 --- a/components/script/dom/xpathresult.rs +++ b/components/script/dom/xpathresult.rs @@ -54,7 +54,7 @@ impl TryFrom<u16> for XPathResultType { } } -#[derive(JSTraceable, MallocSizeOf)] +#[derive(Debug, JSTraceable, MallocSizeOf)] pub(crate) enum XPathResultValue { Boolean(bool), /// A IEEE-754 double-precision floating point number diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index e138e7114d3..1260fa9867a 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -194,6 +194,8 @@ pub(crate) struct IncompleteParserContexts(RefCell<Vec<(PipelineId, ParserContex unsafe_no_jsmanaged_fields!(TaskQueue<MainThreadScriptMsg>); +type NodeIdSet = HashSet<String>; + #[derive(JSTraceable)] // ScriptThread instances are rooted on creation, so this is okay #[cfg_attr(crown, allow(crown::unrooted_must_root))] @@ -315,8 +317,9 @@ pub struct ScriptThread { #[no_trace] player_context: WindowGLContext, - /// A set of all nodes ever created in this script thread - node_ids: DomRefCell<HashSet<String>>, + /// A map from pipelines to all owned nodes ever created in this script thread + #[no_trace] + pipeline_to_node_ids: DomRefCell<HashMap<PipelineId, NodeIdSet>>, /// Code is running as a consequence of a user interaction is_user_interacting: Cell<bool>, @@ -818,14 +821,25 @@ impl ScriptThread { }) } - pub(crate) fn save_node_id(node_id: String) { + pub(crate) fn save_node_id(pipeline: PipelineId, node_id: String) { with_script_thread(|script_thread| { - script_thread.node_ids.borrow_mut().insert(node_id); + script_thread + .pipeline_to_node_ids + .borrow_mut() + .entry(pipeline) + .or_default() + .insert(node_id); }) } - pub(crate) fn has_node_id(node_id: &str) -> bool { - with_script_thread(|script_thread| script_thread.node_ids.borrow().contains(node_id)) + pub(crate) fn has_node_id(pipeline: PipelineId, node_id: &str) -> bool { + with_script_thread(|script_thread| { + script_thread + .pipeline_to_node_ids + .borrow() + .get(&pipeline) + .is_some_and(|node_ids| node_ids.contains(node_id)) + }) } /// Creates a new script thread. @@ -945,7 +959,7 @@ impl ScriptThread { unminify_css: opts.unminify_css, user_content_manager: state.user_content_manager, player_context: state.player_context, - node_ids: Default::default(), + pipeline_to_node_ids: Default::default(), is_user_interacting: Cell::new(false), #[cfg(feature = "webgpu")] gpu_id_hub: Arc::new(IdentityHub::default()), @@ -2266,13 +2280,12 @@ impl ScriptThread { can_gc, ) }, - WebDriverScriptCommand::FocusElement(element_id, reply) => { - webdriver_handlers::handle_focus_element( + WebDriverScriptCommand::GetElementShadowRoot(element_id, reply) => { + webdriver_handlers::handle_get_element_shadow_root( &documents, pipeline_id, element_id, reply, - can_gc, ) }, WebDriverScriptCommand::ElementClick(element_id, reply) => { @@ -2380,6 +2393,20 @@ impl ScriptThread { WebDriverScriptCommand::GetTitle(reply) => { webdriver_handlers::handle_get_title(&documents, pipeline_id, reply) }, + WebDriverScriptCommand::WillSendKeys( + element_id, + text, + strict_file_interactability, + reply, + ) => webdriver_handlers::handle_will_send_keys( + &documents, + pipeline_id, + element_id, + text, + strict_file_interactability, + reply, + can_gc, + ), _ => (), } } diff --git a/components/script/textinput.rs b/components/script/textinput.rs index 73f6159a9a0..6213b1ef511 100644 --- a/components/script/textinput.rs +++ b/components/script/textinput.rs @@ -998,6 +998,9 @@ impl<T: ClipboardProvider> TextInput<T> { self.insert_string(c.as_str()); return KeyReaction::DispatchInput; } + if matches!(key, Key::Process) { + return KeyReaction::DispatchInput; + } KeyReaction::Nothing }) .unwrap() diff --git a/components/script/timers.rs b/components/script/timers.rs index 0dc1397fbdd..fe542c09a56 100644 --- a/components/script/timers.rs +++ b/components/script/timers.rs @@ -4,7 +4,7 @@ use std::cell::Cell; use std::cmp::{Ord, Ordering}; -use std::collections::HashMap; +use std::collections::{HashMap, VecDeque}; use std::default::Default; use std::rc::Rc; use std::time::{Duration, Instant}; @@ -47,7 +47,7 @@ pub(crate) struct OneshotTimers { global_scope: Dom<GlobalScope>, js_timers: JsTimers, next_timer_handle: Cell<OneshotTimerHandle>, - timers: DomRefCell<Vec<OneshotTimer>>, + timers: DomRefCell<VecDeque<OneshotTimer>>, suspended_since: Cell<Option<Instant>>, /// Initially 0, increased whenever the associated document is reactivated /// by the amount of ms the document was inactive. The current time can be @@ -131,7 +131,7 @@ impl OneshotTimers { global_scope: Dom::from_ref(global_scope), js_timers: JsTimers::default(), next_timer_handle: Cell::new(OneshotTimerHandle(1)), - timers: DomRefCell::new(Vec::new()), + timers: DomRefCell::new(VecDeque::new()), suspended_since: Cell::new(None), suspension_offset: Cell::new(Duration::ZERO), expected_event_id: Cell::new(TimerEventId(0)), @@ -180,7 +180,7 @@ impl OneshotTimers { } fn is_next_timer(&self, handle: OneshotTimerHandle) -> bool { - match self.timers.borrow().last() { + match self.timers.borrow().back() { None => false, Some(max_timer) => max_timer.handle == handle, } @@ -201,7 +201,7 @@ impl OneshotTimers { let base_time = self.base_time(); // Since the event id was the expected one, at least one timer should be due. - if base_time < self.timers.borrow().last().unwrap().scheduled_for { + if base_time < self.timers.borrow().back().unwrap().scheduled_for { warn!("Unexpected timing!"); return; } @@ -213,11 +213,11 @@ impl OneshotTimers { loop { let mut timers = self.timers.borrow_mut(); - if timers.is_empty() || timers.last().unwrap().scheduled_for > base_time { + if timers.is_empty() || timers.back().unwrap().scheduled_for > base_time { break; } - timers_to_run.push(timers.pop().unwrap()); + timers_to_run.push(timers.pop_back().unwrap()); } for timer in timers_to_run { @@ -286,7 +286,7 @@ impl OneshotTimers { } let timers = self.timers.borrow(); - let Some(timer) = timers.last() else { + let Some(timer) = timers.back() else { return; }; diff --git a/components/script/webdriver_handlers.rs b/components/script/webdriver_handlers.rs index 6b4264d945e..322839aa078 100644 --- a/components/script/webdriver_handlers.rs +++ b/components/script/webdriver_handlers.rs @@ -81,7 +81,7 @@ fn find_node_by_unique_id( match documents.find_document(pipeline) { Some(doc) => find_node_by_unique_id_in_document(&doc, node_id), None => { - if ScriptThread::has_node_id(&node_id) { + if ScriptThread::has_node_id(pipeline, &node_id) { Err(ErrorStatus::StaleElementReference) } else { Err(ErrorStatus::NoSuchElement) @@ -94,14 +94,15 @@ pub(crate) fn find_node_by_unique_id_in_document( document: &Document, node_id: String, ) -> Result<DomRoot<Node>, ErrorStatus> { + let pipeline = document.window().pipeline_id(); match document .upcast::<Node>() .traverse_preorder(ShadowIncluding::Yes) - .find(|node| node.unique_id() == node_id) + .find(|node| node.unique_id(pipeline) == node_id) { Some(node) => Ok(node), None => { - if ScriptThread::has_node_id(&node_id) { + if ScriptThread::has_node_id(pipeline, &node_id) { Err(ErrorStatus::StaleElementReference) } else { Err(ErrorStatus::NoSuchElement) @@ -129,7 +130,10 @@ fn matching_links( content == link_text } }) - .map(|node| node.upcast::<Node>().unique_id()) + .map(|node| { + node.upcast::<Node>() + .unique_id(node.owner_doc().window().pipeline_id()) + }) } fn all_matching_links( @@ -329,20 +333,25 @@ unsafe fn jsval_to_webdriver_inner( Ok(WebDriverJSValue::ArrayLike(result)) } else if let Ok(element) = root_from_object::<Element>(*object, cx) { Ok(WebDriverJSValue::Element(WebElement( - element.upcast::<Node>().unique_id(), + element + .upcast::<Node>() + .unique_id(element.owner_document().window().pipeline_id()), ))) } else if let Ok(window) = root_from_object::<Window>(*object, cx) { let window_proxy = window.window_proxy(); if window_proxy.is_browsing_context_discarded() { return Err(WebDriverJSError::StaleElementReference); - } else if window_proxy.browsing_context_id() == window_proxy.webview_id() { - Ok(WebDriverJSValue::Window(WebWindow( - window.Document().upcast::<Node>().unique_id(), - ))) } else { - Ok(WebDriverJSValue::Frame(WebFrame( - window.Document().upcast::<Node>().unique_id(), - ))) + let pipeline = window.pipeline_id(); + if window_proxy.browsing_context_id() == window_proxy.webview_id() { + Ok(WebDriverJSValue::Window(WebWindow( + window.Document().upcast::<Node>().unique_id(pipeline), + ))) + } else { + Ok(WebDriverJSValue::Frame(WebFrame( + window.Document().upcast::<Node>().unique_id(pipeline), + ))) + } } } else if object_has_to_json_property(cx, global_scope, object.handle()) { let name = CString::new("toJSON").unwrap(); @@ -598,7 +607,7 @@ pub(crate) fn handle_find_element_css( .QuerySelector(DOMString::from(selector)) .map_err(|_| ErrorStatus::InvalidSelector) }) - .map(|node| node.map(|x| x.upcast::<Node>().unique_id())), + .map(|node| node.map(|x| x.upcast::<Node>().unique_id(pipeline))), ) .unwrap(); } @@ -640,7 +649,7 @@ pub(crate) fn handle_find_element_tag_name( .elements_iter() .next() }) - .map(|node| node.map(|x| x.upcast::<Node>().unique_id())), + .map(|node| node.map(|x| x.upcast::<Node>().unique_id(pipeline))), ) .unwrap(); } @@ -664,7 +673,7 @@ pub(crate) fn handle_find_elements_css( .map(|nodes| { nodes .iter() - .map(|x| x.upcast::<Node>().unique_id()) + .map(|x| x.upcast::<Node>().unique_id(pipeline)) .collect() }), ) @@ -706,7 +715,7 @@ pub(crate) fn handle_find_elements_tag_name( .map(|nodes| { nodes .elements_iter() - .map(|x| x.upcast::<Node>().unique_id()) + .map(|x| x.upcast::<Node>().unique_id(pipeline)) .collect::<Vec<String>>() }), ) @@ -725,7 +734,7 @@ pub(crate) fn handle_find_element_element_css( find_node_by_unique_id(documents, pipeline, element_id).and_then(|node| { node.query_selector(DOMString::from(selector)) .map_err(|_| ErrorStatus::InvalidSelector) - .map(|node| node.map(|x| x.upcast::<Node>().unique_id())) + .map(|node| node.map(|x| x.upcast::<Node>().unique_id(pipeline))) }), ) .unwrap(); @@ -764,7 +773,7 @@ pub(crate) fn handle_find_element_element_tag_name( .GetElementsByTagName(DOMString::from(selector), can_gc) .elements_iter() .next() - .map(|x| x.upcast::<Node>().unique_id())), + .map(|x| x.upcast::<Node>().unique_id(pipeline))), None => Err(ErrorStatus::UnknownError), }), ) @@ -786,7 +795,7 @@ pub(crate) fn handle_find_element_elements_css( .map(|nodes| { nodes .iter() - .map(|x| x.upcast::<Node>().unique_id()) + .map(|x| x.upcast::<Node>().unique_id(pipeline)) .collect() }) }), @@ -826,7 +835,7 @@ pub(crate) fn handle_find_element_elements_tag_name( Some(element) => Ok(element .GetElementsByTagName(DOMString::from(selector), can_gc) .elements_iter() - .map(|x| x.upcast::<Node>().unique_id()) + .map(|x| x.upcast::<Node>().unique_id(pipeline)) .collect::<Vec<String>>()), None => Err(ErrorStatus::UnknownError), }), @@ -834,24 +843,87 @@ pub(crate) fn handle_find_element_elements_tag_name( .unwrap(); } -pub(crate) fn handle_focus_element( +/// <https://www.w3.org/TR/webdriver2/#dfn-get-element-shadow-root> +pub(crate) fn handle_get_element_shadow_root( documents: &DocumentCollection, pipeline: PipelineId, element_id: String, - reply: IpcSender<Result<(), ErrorStatus>>, + reply: IpcSender<Result<Option<String>, ErrorStatus>>, +) { + reply + .send( + find_node_by_unique_id(documents, pipeline, element_id).and_then(|node| match node + .downcast::<Element>( + ) { + Some(element) => Ok(element + .GetShadowRoot() + .map(|x| x.upcast::<Node>().unique_id(pipeline))), + None => Err(ErrorStatus::NoSuchElement), + }), + ) + .unwrap(); +} + +pub(crate) fn handle_will_send_keys( + documents: &DocumentCollection, + pipeline: PipelineId, + element_id: String, + text: String, + strict_file_interactability: bool, + reply: IpcSender<Result<bool, ErrorStatus>>, can_gc: CanGc, ) { reply .send( find_node_by_unique_id(documents, pipeline, element_id).and_then(|node| { - match node.downcast::<HTMLElement>() { - Some(element) => { - // Need a way to find if this actually succeeded - element.Focus(can_gc); - Ok(()) - }, - None => Err(ErrorStatus::UnknownError), + // Step 6: Let file be true if element is input element + // in the file upload state, or false otherwise + let file_input = node + .downcast::<HTMLInputElement>() + .filter(|&input_element| input_element.input_type() == InputType::File); + + // Step 7: If file is false or the session's strict file interactability + if file_input.is_none() || strict_file_interactability { + match node.downcast::<HTMLElement>() { + Some(element) => { + // Need a way to find if this actually succeeded + element.Focus(can_gc); + }, + None => return Err(ErrorStatus::UnknownError), + } } + + // Step 8 (file input) + if let Some(file_input) = file_input { + // Step 8.1: Let files be the result of splitting text + // on the newline (\n) character. + let files: Vec<DOMString> = text.split("\n").map(|s| s.into()).collect(); + + // Step 8.2 + if files.is_empty() { + return Err(ErrorStatus::InvalidArgument); + } + + // Step 8.3 - 8.4 + if !file_input.Multiple() && files.len() > 1 { + return Err(ErrorStatus::InvalidArgument); + } + + // Step 8.5 + // TODO: Should return invalid argument error if file doesn't exist + + // Step 8.6 - 8.7 + // Input and change event already fired in `htmlinputelement.rs`. + file_input.SelectFiles(files, can_gc); + + // Step 8.8 + return Ok(false); + } + + // TODO: Check non-typeable form control + // TODO: Check content editable + + Ok(true) }), ) .unwrap(); @@ -867,7 +939,7 @@ pub(crate) fn handle_get_active_element( documents .find_document(pipeline) .and_then(|document| document.GetActiveElement()) - .map(|element| element.upcast::<Node>().unique_id()), + .map(|element| element.upcast::<Node>().unique_id(pipeline)), ) .unwrap(); } @@ -1395,7 +1467,7 @@ pub(crate) fn handle_element_click( Ok(None) }, - None => Ok(Some(node.unique_id())), + None => Ok(Some(node.unique_id(pipeline))), } }), ) diff --git a/components/script/xpath/context.rs b/components/script/xpath/context.rs index df78a9a7bec..ff51c92521d 100644 --- a/components/script/xpath/context.rs +++ b/components/script/xpath/context.rs @@ -5,10 +5,14 @@ use std::iter::Enumerate; use std::vec::IntoIter; +use script_bindings::str::DOMString; + use super::Node; +use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use crate::dom::bindings::root::DomRoot; /// The context during evaluation of an XPath expression. +#[derive(Debug)] pub(crate) struct EvaluationCtx { /// Where we started at pub(crate) starting_node: DomRoot<Node>, @@ -20,7 +24,7 @@ pub(crate) struct EvaluationCtx { pub(crate) predicate_nodes: Option<Vec<DomRoot<Node>>>, } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] pub(crate) struct PredicateCtx { pub(crate) index: usize, pub(crate) size: usize, @@ -68,6 +72,12 @@ impl EvaluationCtx { size, } } + + /// Resolve a namespace prefix using the context node's document + pub(crate) fn resolve_namespace(&self, prefix: Option<&str>) -> Option<DOMString> { + self.context_node + .LookupNamespaceURI(prefix.map(DOMString::from)) + } } /// When evaluating predicates, we need to keep track of the current node being evaluated and diff --git a/components/script/xpath/eval.rs b/components/script/xpath/eval.rs index 75d7ac5849c..38d8c2fee90 100644 --- a/components/script/xpath/eval.rs +++ b/components/script/xpath/eval.rs @@ -12,6 +12,7 @@ use super::parser::{ QName as ParserQualName, RelationalOp, StepExpr, UnaryOp, }; use super::{EvaluationCtx, Value}; +use crate::dom::attr::Attr; use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use crate::dom::bindings::inheritance::{Castable, CharacterDataTypeId, NodeTypeId}; use crate::dom::bindings::root::DomRoot; @@ -83,6 +84,22 @@ where } } +impl<T> Evaluatable for Option<T> +where + T: Evaluatable, +{ + fn evaluate(&self, context: &EvaluationCtx) -> Result<Value, Error> { + match self { + Some(expr) => expr.evaluate(context), + None => Ok(Value::Nodeset(vec![])), + } + } + + fn is_primitive(&self) -> bool { + self.as_ref().is_some_and(|t| T::is_primitive(t)) + } +} + impl Evaluatable for Expr { fn evaluate(&self, context: &EvaluationCtx) -> Result<Value, Error> { match self { @@ -230,21 +247,31 @@ impl Evaluatable for PathExpr { } } -impl TryFrom<&ParserQualName> for QualName { +pub(crate) struct QualNameConverter<'a> { + qname: &'a ParserQualName, + context: &'a EvaluationCtx, +} + +impl<'a> TryFrom<QualNameConverter<'a>> for QualName { type Error = Error; - fn try_from(qname: &ParserQualName) -> Result<Self, Self::Error> { - let qname_as_str = qname.to_string(); - if let Ok((ns, prefix, local)) = validate_and_extract(None, &qname_as_str) { + fn try_from(converter: QualNameConverter<'a>) -> Result<Self, Self::Error> { + let qname_as_str = converter.qname.to_string(); + let namespace = converter + .context + .resolve_namespace(converter.qname.prefix.as_deref()); + + if let Ok((ns, prefix, local)) = validate_and_extract(namespace, &qname_as_str) { Ok(QualName { prefix, ns, local }) } else { Err(Error::InvalidQName { - qname: qname.clone(), + qname: converter.qname.clone(), }) } } } +#[derive(Debug)] pub(crate) enum NameTestComparisonMode { /// Namespaces must match exactly XHtml, @@ -294,29 +321,41 @@ pub(crate) fn element_name_test( } } -fn apply_node_test(test: &NodeTest, node: &Node) -> Result<bool, Error> { +fn apply_node_test(context: &EvaluationCtx, test: &NodeTest, node: &Node) -> Result<bool, Error> { let result = match test { NodeTest::Name(qname) => { // Convert the unvalidated "parser QualName" into the proper QualName structure - let wanted_name: QualName = qname.try_into()?; - if matches!(node.type_id(), NodeTypeId::Element(_)) { - let element = node.downcast::<Element>().unwrap(); - let comparison_mode = if node.owner_doc().is_xhtml_document() { - NameTestComparisonMode::XHtml - } else { - NameTestComparisonMode::Html - }; - let element_qualname = QualName::new( - element.prefix().as_ref().cloned(), - element.namespace().clone(), - element.local_name().clone(), - ); - element_name_test(wanted_name, element_qualname, comparison_mode) - } else { - false + let wanted_name: QualName = QualNameConverter { qname, context }.try_into()?; + match node.type_id() { + NodeTypeId::Element(_) => { + let element = node.downcast::<Element>().unwrap(); + let comparison_mode = if node.owner_doc().is_html_document() { + NameTestComparisonMode::Html + } else { + NameTestComparisonMode::XHtml + }; + let element_qualname = QualName::new( + element.prefix().as_ref().cloned(), + element.namespace().clone(), + element.local_name().clone(), + ); + element_name_test(wanted_name, element_qualname, comparison_mode) + }, + NodeTypeId::Attr => { + let attr = node.downcast::<Attr>().unwrap(); + let attr_qualname = QualName::new( + attr.prefix().cloned(), + attr.namespace().clone(), + attr.local_name().clone(), + ); + // attributes are always compared with strict namespace matching + let comparison_mode = NameTestComparisonMode::XHtml; + element_name_test(wanted_name, attr_qualname, comparison_mode) + }, + _ => false, } }, - NodeTest::Wildcard => true, + NodeTest::Wildcard => matches!(node.type_id(), NodeTypeId::Element(_)), NodeTest::Kind(kind) => match kind { KindTest::PI(target) => { if NodeTypeId::CharacterData(CharacterDataTypeId::ProcessingInstruction) == @@ -411,7 +450,7 @@ impl Evaluatable for StepExpr { let filtered_nodes: Vec<DomRoot<Node>> = nodes .into_iter() .map(|node| { - apply_node_test(&axis_step.node_test, &node) + apply_node_test(context, &axis_step.node_test, &node) .map(|matches| matches.then_some(node)) }) .collect::<Result<Vec<_>, _>>()? @@ -489,6 +528,7 @@ impl Evaluatable for PredicateExpr { let v = match eval_result { Ok(Value::Number(v)) => Ok(predicate_ctx.index == v as usize), + Ok(Value::Boolean(v)) => Ok(v), Ok(v) => Ok(v.boolean()), Err(e) => Err(e), }; diff --git a/components/script/xpath/eval_function.rs b/components/script/xpath/eval_function.rs index caf0782c07b..53c14944474 100644 --- a/components/script/xpath/eval_function.rs +++ b/components/script/xpath/eval_function.rs @@ -2,12 +2,15 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use style::Atom; + use super::Value; use super::context::EvaluationCtx; use super::eval::{Error, Evaluatable, try_extract_nodeset}; use super::parser::CoreFunction; use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use crate::dom::bindings::inheritance::{Castable, NodeTypeId}; +use crate::dom::bindings::root::DomRoot; use crate::dom::element::Element; use crate::dom::node::Node; @@ -101,6 +104,31 @@ pub(crate) fn normalize_space(s: &str) -> String { result } +/// <https://www.w3.org/TR/1999/REC-xpath-19991116/#function-lang> +fn lang_matches(context_lang: Option<&str>, target_lang: &str) -> bool { + let Some(context_lang) = context_lang else { + return false; + }; + + let context_lower = context_lang.to_ascii_lowercase(); + let target_lower = target_lang.to_ascii_lowercase(); + + if context_lower == target_lower { + return true; + } + + // Check if context is target with additional suffix + if context_lower.starts_with(&target_lower) { + // Make sure the next character is a hyphen to avoid matching + // e.g. "england" when target is "en" + if let Some(next_char) = context_lower.chars().nth(target_lower.len()) { + return next_char == '-'; + } + } + + false +} + impl Evaluatable for CoreFunction { fn evaluate(&self, context: &EvaluationCtx) -> Result<Value, Error> { match self { @@ -131,7 +159,20 @@ impl Evaluatable for CoreFunction { .collect(); Ok(Value::String(strings?.join(""))) }, - CoreFunction::Id(_expr) => todo!(), + CoreFunction::Id(expr) => { + let args_str = expr.evaluate(context)?.string(); + let args_normalized = normalize_space(&args_str); + let args = args_normalized.split(' '); + + let document = context.context_node.owner_doc(); + let mut result = Vec::new(); + for arg in args { + for element in document.get_elements_with_id(&Atom::from(arg)).iter() { + result.push(DomRoot::from_ref(element.upcast::<Node>())); + } + } + Ok(Value::Nodeset(result)) + }, CoreFunction::LocalName(expr_opt) => { let node = match expr_opt { Some(expr) => expr @@ -256,7 +297,11 @@ impl Evaluatable for CoreFunction { CoreFunction::Not(expr) => Ok(Value::Boolean(!expr.evaluate(context)?.boolean())), CoreFunction::True => Ok(Value::Boolean(true)), CoreFunction::False => Ok(Value::Boolean(false)), - CoreFunction::Lang(_) => Ok(Value::Nodeset(vec![])), // Not commonly used in the DOM, short-circuit it + CoreFunction::Lang(expr) => { + let context_lang = context.context_node.get_lang(); + let lang = expr.evaluate(context)?.string(); + Ok(Value::Boolean(lang_matches(context_lang.as_deref(), &lang))) + }, } } @@ -319,7 +364,7 @@ impl Evaluatable for CoreFunction { } #[cfg(test)] mod tests { - use super::{substring, substring_after, substring_before}; + use super::{lang_matches, substring, substring_after, substring_before}; #[test] fn test_substring_before() { @@ -354,4 +399,18 @@ mod tests { assert_eq!(substring("hello", 0, Some(0)), ""); assert_eq!(substring("hello", 0, Some(-5)), ""); } + + #[test] + fn test_lang_matches() { + assert!(lang_matches(Some("en"), "en")); + assert!(lang_matches(Some("EN"), "en")); + assert!(lang_matches(Some("en"), "EN")); + assert!(lang_matches(Some("en-US"), "en")); + assert!(lang_matches(Some("en-GB"), "en")); + + assert!(!lang_matches(Some("eng"), "en")); + assert!(!lang_matches(Some("fr"), "en")); + assert!(!lang_matches(Some("fr-en"), "en")); + assert!(!lang_matches(None, "en")); + } } diff --git a/components/script/xpath/eval_value.rs b/components/script/xpath/eval_value.rs index de6c13e3454..66f1b92c6d4 100644 --- a/components/script/xpath/eval_value.rs +++ b/components/script/xpath/eval_value.rs @@ -8,7 +8,6 @@ use std::{fmt, string}; use crate::dom::bindings::codegen::Bindings::NodeBinding::Node_Binding::NodeMethods; use crate::dom::bindings::root::DomRoot; -use crate::dom::bindings::utils::AsVoidPtr; use crate::dom::node::Node; /// The primary types of values that an XPath expression returns as a result. @@ -216,7 +215,7 @@ impl NodesetHelpers for Vec<DomRoot<Node>> { } fn document_order(&self) -> Vec<DomRoot<Node>> { let mut nodes: Vec<DomRoot<Node>> = self.clone(); - if nodes.len() == 1 { + if nodes.len() <= 1 { return nodes; } @@ -233,10 +232,13 @@ impl NodesetHelpers for Vec<DomRoot<Node>> { nodes } fn document_order_unique(&self) -> Vec<DomRoot<Node>> { - let mut nodes: Vec<DomRoot<Node>> = self.document_order(); - - nodes.dedup_by_key(|n| n.as_void_ptr()); + let mut seen = HashSet::new(); + let unique_nodes: Vec<DomRoot<Node>> = self + .iter() + .filter(|node| seen.insert(node.to_opaque())) + .cloned() + .collect(); - nodes + unique_nodes.document_order() } } diff --git a/components/script/xpath/parser.rs b/components/script/xpath/parser.rs index b1a4bfcc42d..272fa41dcdf 100644 --- a/components/script/xpath/parser.rs +++ b/components/script/xpath/parser.rs @@ -510,40 +510,45 @@ fn union_expr(input: &str) -> IResult<&str, Expr> { fn path_expr(input: &str) -> IResult<&str, Expr> { alt(( // "//" RelativePathExpr - map(pair(tag("//"), relative_path_expr), |(_, rel_path)| { - Expr::Path(PathExpr { - is_absolute: true, - is_descendant: true, - steps: match rel_path { - Expr::Path(p) => p.steps, - _ => unreachable!(), - }, - }) - }), - // "/" RelativePathExpr? - map(pair(char('/'), opt(relative_path_expr)), |(_, rel_path)| { - Expr::Path(PathExpr { - is_absolute: true, - is_descendant: false, - steps: rel_path - .map(|p| match p { + map( + pair(tag("//"), move |i| relative_path_expr(true, i)), + |(_, rel_path)| { + Expr::Path(PathExpr { + is_absolute: true, + is_descendant: true, + steps: match rel_path { Expr::Path(p) => p.steps, _ => unreachable!(), - }) - .unwrap_or_default(), - }) - }), + }, + }) + }, + ), + // "/" RelativePathExpr? + map( + pair(char('/'), opt(move |i| relative_path_expr(false, i))), + |(_, rel_path)| { + Expr::Path(PathExpr { + is_absolute: true, + is_descendant: false, + steps: rel_path + .map(|p| match p { + Expr::Path(p) => p.steps, + _ => unreachable!(), + }) + .unwrap_or_default(), + }) + }, + ), // RelativePathExpr - relative_path_expr, + move |i| relative_path_expr(false, i), ))(input) } -fn relative_path_expr(input: &str) -> IResult<&str, Expr> { - let (input, first) = step_expr(input)?; +fn relative_path_expr(is_descendant: bool, input: &str) -> IResult<&str, Expr> { + let (input, first) = step_expr(is_descendant, input)?; let (input, steps) = many0(pair( - // ("/" | "//") - ws(alt((value(false, char('/')), value(true, tag("//"))))), - step_expr, + ws(alt((value(true, tag("//")), value(false, char('/'))))), + move |i| step_expr(is_descendant, i), ))(input)?; let mut all_steps = vec![first]; @@ -569,16 +574,18 @@ fn relative_path_expr(input: &str) -> IResult<&str, Expr> { )) } -fn step_expr(input: &str) -> IResult<&str, StepExpr> { +fn step_expr(is_descendant: bool, input: &str) -> IResult<&str, StepExpr> { alt(( map(filter_expr, StepExpr::Filter), - map(axis_step, StepExpr::Axis), + map(|i| axis_step(is_descendant, i), StepExpr::Axis), ))(input) } -fn axis_step(input: &str) -> IResult<&str, AxisStep> { - let (input, (step, predicates)) = - pair(alt((forward_step, reverse_step)), predicate_list)(input)?; +fn axis_step(is_descendant: bool, input: &str) -> IResult<&str, AxisStep> { + let (input, (step, predicates)) = pair( + alt((move |i| forward_step(is_descendant, i), reverse_step)), + predicate_list, + )(input)?; let (axis, node_test) = step; Ok(( @@ -591,13 +598,10 @@ fn axis_step(input: &str) -> IResult<&str, AxisStep> { )) } -fn forward_step(input: &str) -> IResult<&str, (Axis, NodeTest)> { - alt(( - // ForwardAxis NodeTest - pair(forward_axis, node_test), - // AbbrevForwardStep - abbrev_forward_step, - ))(input) +fn forward_step(is_descendant: bool, input: &str) -> IResult<&str, (Axis, NodeTest)> { + alt((pair(forward_axis, node_test), move |i| { + abbrev_forward_step(is_descendant, i) + }))(input) } fn forward_axis(input: &str) -> IResult<&str, Axis> { @@ -615,7 +619,7 @@ fn forward_axis(input: &str) -> IResult<&str, Axis> { Ok((input, axis)) } -fn abbrev_forward_step(input: &str) -> IResult<&str, (Axis, NodeTest)> { +fn abbrev_forward_step(is_descendant: bool, input: &str) -> IResult<&str, (Axis, NodeTest)> { let (input, attr) = opt(char('@'))(input)?; let (input, test) = node_test(input)?; @@ -624,6 +628,8 @@ fn abbrev_forward_step(input: &str) -> IResult<&str, (Axis, NodeTest)> { ( if attr.is_some() { Axis::Attribute + } else if is_descendant { + Axis::DescendantOrSelf } else { Axis::Child }, @@ -704,6 +710,7 @@ fn filter_expr(input: &str) -> IResult<&str, FilterExpr> { fn predicate_list(input: &str) -> IResult<&str, PredicateListExpr> { let (input, predicates) = many0(predicate)(input)?; + Ok((input, PredicateListExpr { predicates })) } @@ -1195,6 +1202,118 @@ mod tests { ], }), ), + ( + "//mu[@xml:id=\"id1\"]//rho[@title][@xml:lang=\"en-GB\"]", + Expr::Path(PathExpr { + is_absolute: true, + is_descendant: true, + steps: vec![ + StepExpr::Axis(AxisStep { + axis: Axis::Child, + node_test: NodeTest::Name(QName { + prefix: None, + local_part: "mu".to_string(), + }), + predicates: PredicateListExpr { + predicates: vec![PredicateExpr { + expr: Expr::Equality( + Box::new(Expr::Path(PathExpr { + is_absolute: false, + is_descendant: false, + steps: vec![StepExpr::Axis(AxisStep { + axis: Axis::Attribute, + node_test: NodeTest::Name(QName { + prefix: Some("xml".to_string()), + local_part: "id".to_string(), + }), + predicates: PredicateListExpr { + predicates: vec![], + }, + })], + })), + EqualityOp::Eq, + Box::new(Expr::Path(PathExpr { + is_absolute: false, + is_descendant: false, + steps: vec![StepExpr::Filter(FilterExpr { + primary: PrimaryExpr::Literal(Literal::String( + "id1".to_string(), + )), + predicates: PredicateListExpr { + predicates: vec![], + }, + })], + })), + ), + }], + }, + }), + StepExpr::Axis(AxisStep { + axis: Axis::DescendantOrSelf, // Represents the second '//' + node_test: NodeTest::Kind(KindTest::Node), + predicates: PredicateListExpr { predicates: vec![] }, + }), + StepExpr::Axis(AxisStep { + axis: Axis::Child, + node_test: NodeTest::Name(QName { + prefix: None, + local_part: "rho".to_string(), + }), + predicates: PredicateListExpr { + predicates: vec![ + PredicateExpr { + expr: Expr::Path(PathExpr { + is_absolute: false, + is_descendant: false, + steps: vec![StepExpr::Axis(AxisStep { + axis: Axis::Attribute, + node_test: NodeTest::Name(QName { + prefix: None, + local_part: "title".to_string(), + }), + predicates: PredicateListExpr { + predicates: vec![], + }, + })], + }), + }, + PredicateExpr { + expr: Expr::Equality( + Box::new(Expr::Path(PathExpr { + is_absolute: false, + is_descendant: false, + steps: vec![StepExpr::Axis(AxisStep { + axis: Axis::Attribute, + node_test: NodeTest::Name(QName { + prefix: Some("xml".to_string()), + local_part: "lang".to_string(), + }), + predicates: PredicateListExpr { + predicates: vec![], + }, + })], + })), + EqualityOp::Eq, + Box::new(Expr::Path(PathExpr { + is_absolute: false, + is_descendant: false, + steps: vec![StepExpr::Filter(FilterExpr { + primary: PrimaryExpr::Literal(Literal::String( + "en-GB".to_string(), + )), + predicates: PredicateListExpr { + predicates: vec![], + }, + })], + })), + ), + }, + ], + }, + }), + ], + }), + ), ]; for (input, expected) in cases { diff --git a/components/script_bindings/build.rs b/components/script_bindings/build.rs index b11e3d1cfdf..d2ff8ceb4a1 100644 --- a/components/script_bindings/build.rs +++ b/components/script_bindings/build.rs @@ -27,7 +27,7 @@ fn main() { println!("cargo::rerun-if-changed=../../third_party/WebIDL/WebIDL.py"); // NB: We aren't handling changes in `third_party/ply` here. - let status = Command::new(find_python()) + let status = find_python() .arg("codegen/run.py") .arg(&css_properties_json) .arg(&out_dir) @@ -78,55 +78,20 @@ impl phf_shared::PhfHash for Bytes<'_> { } } -/// Tries to find a suitable python +/// Tries to find a suitable python, which in Servo is always `uv run python` unless we are running +/// as a descendant of `uv run python`. In that case, we can use either `uv run python` or `python` +/// (uv does not provide a `python3` on Windows). /// -/// Algorithm -/// 1. Trying to find python3/python in $VIRTUAL_ENV (this should be from Servo's venv) -/// 2. Checking PYTHON3 (set by mach) -/// 3. Falling back to the system installation. +/// More details: <https://book.servo.org/hacking/setting-up-your-environment.html#check-tools> /// -/// Note: This function should be kept in sync with the version in `components/servo/build.rs` -fn find_python() -> PathBuf { - let mut candidates = vec![]; - if let Some(venv) = env::var_os("VIRTUAL_ENV") { - let bin_directory = PathBuf::from(venv).join("bin"); +/// Note: This function should be kept in sync with the version in `components/script/build.rs` +fn find_python() -> Command { + let mut command = Command::new("uv"); + command.args(["run", "python"]); - let python3 = bin_directory.join("python3"); - if python3.exists() { - candidates.push(python3); - } - let python = bin_directory.join("python"); - if python.exists() { - candidates.push(python); - } - }; - if let Some(python3) = env::var_os("PYTHON3") { - let python3 = PathBuf::from(python3); - if python3.exists() { - candidates.push(python3); - } + if command.output().is_ok_and(|out| out.status.success()) { + return command; } - let system_python = ["python3", "python"].map(PathBuf::from); - candidates.extend_from_slice(&system_python); - - for name in &candidates { - // Command::new() allows us to omit the `.exe` suffix on windows - if Command::new(name) - .arg("--version") - .output() - .is_ok_and(|out| out.status.success()) - { - return name.to_owned(); - } - } - let candidates = candidates - .into_iter() - .map(|c| c.into_os_string()) - .collect::<Vec<_>>(); - panic!( - "Can't find python (tried {:?})! Try enabling Servo's Python venv, \ - setting the PYTHON3 env var or adding python3 to PATH.", - candidates.join(", ".as_ref()) - ) + panic!("Can't find python (tried `{command:?}`)! Is uv installed and in PATH?") } diff --git a/components/script_bindings/codegen/Bindings.conf b/components/script_bindings/codegen/Bindings.conf index 7cc092e574e..dd034654974 100644 --- a/components/script_bindings/codegen/Bindings.conf +++ b/components/script_bindings/codegen/Bindings.conf @@ -14,6 +14,10 @@ DOMInterfaces = { +'AbortController': { + 'canGc':['Abort'], +}, + 'AbstractRange': { 'weakReferenceable': True, }, diff --git a/components/script_bindings/webidls/AbortController.webidl b/components/script_bindings/webidls/AbortController.webidl index cef49010d3c..bb20ec24955 100644 --- a/components/script_bindings/webidls/AbortController.webidl +++ b/components/script_bindings/webidls/AbortController.webidl @@ -7,7 +7,7 @@ interface AbortController { constructor(); - //[SameObject] readonly attribute AbortSignal signal; + [SameObject] readonly attribute AbortSignal signal; undefined abort(optional any reason); }; diff --git a/components/script_bindings/webidls/HTMLHRElement.webidl b/components/script_bindings/webidls/HTMLHRElement.webidl index 8963d5e8901..45828d4da76 100644 --- a/components/script_bindings/webidls/HTMLHRElement.webidl +++ b/components/script_bindings/webidls/HTMLHRElement.webidl @@ -12,14 +12,9 @@ interface HTMLHRElement : HTMLElement { // https://html.spec.whatwg.org/multipage/#HTMLHRElement-partial partial interface HTMLHRElement { - [CEReactions] - attribute DOMString align; - [CEReactions] - attribute DOMString color; - // [CEReactions] - // attribute boolean noShade; - // [CEReactions] - // attribute DOMString size; - [CEReactions] - attribute DOMString width; + [CEReactions] attribute DOMString align; + [CEReactions] attribute DOMString color; + [CEReactions] attribute boolean noShade; + [CEReactions] attribute DOMString size; + [CEReactions] attribute DOMString width; }; diff --git a/components/script_bindings/webidls/HTMLLinkElement.webidl b/components/script_bindings/webidls/HTMLLinkElement.webidl index 9182ef393f8..db858a022c2 100644 --- a/components/script_bindings/webidls/HTMLLinkElement.webidl +++ b/components/script_bindings/webidls/HTMLLinkElement.webidl @@ -13,7 +13,7 @@ interface HTMLLinkElement : HTMLElement { attribute DOMString? crossOrigin; [CEReactions] attribute DOMString rel; - // [CEReactions] attribute DOMString as; + [CEReactions] attribute DOMString as; [SameObject, PutForwards=value] readonly attribute DOMTokenList relList; [CEReactions] attribute DOMString media; diff --git a/components/script_bindings/webidls/HTMLScriptElement.webidl b/components/script_bindings/webidls/HTMLScriptElement.webidl index 2c7b398b7e3..a21ae6007c4 100644 --- a/components/script_bindings/webidls/HTMLScriptElement.webidl +++ b/components/script_bindings/webidls/HTMLScriptElement.webidl @@ -32,6 +32,8 @@ interface HTMLScriptElement : HTMLElement { [CEReactions] attribute DOMString referrerPolicy; + static boolean supports(DOMString type); + // also has obsolete members }; diff --git a/components/servo/build.rs b/components/servo/build.rs index 0b6b087547b..d610d1cfe36 100644 --- a/components/servo/build.rs +++ b/components/servo/build.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use std::path::{Path, PathBuf}; +use std::path::Path; use std::process::Command; use std::{env, fs}; @@ -10,7 +10,7 @@ fn main() { if cfg!(feature = "media-gstreamer") { println!("cargo:rerun-if-changed=../../python/servo/gstreamer.py"); - let output = Command::new(find_python()) + let output = find_python() .arg("../../python/servo/gstreamer.py") .arg(std::env::var_os("TARGET").unwrap()) .output() @@ -25,47 +25,20 @@ fn main() { } } -/// Tries to find a suitable python +/// Tries to find a suitable python, which in Servo is always `uv run python` unless we are running +/// as a descendant of `uv run python`. In that case, we can use either `uv run python` or `python` +/// (uv does not provide a `python3` on Windows). /// -/// Algorithm -/// 1. Trying to find python3/python in $VIRTUAL_ENV (this should be from servos venv) -/// 2. Checking PYTHON3 (set by mach) -/// 3. Falling back to the system installation. +/// More details: <https://book.servo.org/hacking/setting-up-your-environment.html#check-tools> /// /// Note: This function should be kept in sync with the version in `components/script/build.rs` -fn find_python() -> PathBuf { - let mut candidates = vec![]; - if let Some(venv) = env::var_os("VIRTUAL_ENV") { - // See: https://docs.python.org/3/library/venv.html#how-venvs-work - let bin_dir = if cfg!(windows) { "Scripts" } else { "bin" }; - let bin_directory = PathBuf::from(venv).join(bin_dir); - candidates.push(bin_directory.join("python3")); - candidates.push(bin_directory.join("python")); - } - if let Some(python3) = env::var_os("PYTHON3") { - candidates.push(PathBuf::from(python3)); - } - - let system_python = ["python3", "python"].map(PathBuf::from); - candidates.extend_from_slice(&system_python); +fn find_python() -> Command { + let mut command = Command::new("uv"); + command.args(["run", "python"]); - for name in &candidates { - // Command::new() allows us to omit the `.exe` suffix on windows - if Command::new(name) - .arg("--version") - .output() - .is_ok_and(|out| out.status.success()) - { - return name.to_owned(); - } + if command.output().is_ok_and(|out| out.status.success()) { + return command; } - let candidates = candidates - .into_iter() - .map(|c| c.into_os_string()) - .collect::<Vec<_>>(); - panic!( - "Can't find python (tried {:?})! Try enabling Servo's Python venv, \ - setting the PYTHON3 env var or adding python3 to PATH.", - candidates.join(", ".as_ref()) - ) + + panic!("Can't find python (tried `{command:?}`)! Is uv installed and in PATH?") } diff --git a/components/servo/lib.rs b/components/servo/lib.rs index f2732eaddfe..a188678c024 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -92,6 +92,7 @@ use media::{GlApi, NativeDisplay, WindowGLContext}; use net::protocols::ProtocolRegistry; use net::resource_thread::new_resource_threads; use profile::{mem as profile_mem, time as profile_time}; +use profile_traits::mem::MemoryReportResult; use profile_traits::{mem, time}; use script::{JSEngineSetup, ServiceWorkerManager}; use servo_config::opts::Opts; @@ -417,7 +418,7 @@ impl Servo { // Create the WebXR main thread #[cfg(feature = "webxr")] let mut webxr_main_thread = - webxr::MainThreadRegistry::new(event_loop_waker, webxr_layer_grand_manager) + webxr::MainThreadRegistry::new(event_loop_waker.clone(), webxr_layer_grand_manager) .expect("Failed to create WebXR device registry"); #[cfg(feature = "webxr")] if pref!(dom_webxr_enabled) { @@ -489,6 +490,7 @@ impl Servo { #[cfg(feature = "webxr")] webxr_main_thread, shutdown_state: shutdown_state.clone(), + event_loop_waker, }, opts.debug.convert_mouse_to_touch, ); @@ -632,6 +634,11 @@ impl Servo { log::set_max_level(filter); } + pub fn create_memory_report(&self, snd: IpcSender<MemoryReportResult>) { + self.constellation_proxy + .send(EmbedderToConstellationMessage::CreateMemoryReport(snd)); + } + pub fn start_shutting_down(&self) { if self.shutdown_state.get() != ShutdownState::NotShuttingDown { warn!("Requested shutdown while already shutting down"); diff --git a/components/shared/canvas/canvas.rs b/components/shared/canvas/canvas.rs index 850f5f9bd9a..283be0d458e 100644 --- a/components/shared/canvas/canvas.rs +++ b/components/shared/canvas/canvas.rs @@ -89,8 +89,8 @@ pub enum Canvas2dMsg { Arc(Point2D<f32>, f32, f32, f32, bool), ArcTo(Point2D<f32>, Point2D<f32>, f32), DrawImage(IpcSnapshot, Rect<f64>, Rect<f64>, bool), - DrawEmptyImage(Size2D<f64>, Rect<f64>, Rect<f64>), - DrawImageInOther(CanvasId, Size2D<f64>, Rect<f64>, Rect<f64>, bool), + DrawEmptyImage(Size2D<u32>, Rect<f64>, Rect<f64>), + DrawImageInOther(CanvasId, Size2D<u32>, Rect<f64>, Rect<f64>, bool), BeginPath, BezierCurveTo(Point2D<f32>, Point2D<f32>, Point2D<f32>), ClearRect(Rect<f32>), @@ -102,14 +102,14 @@ pub enum Canvas2dMsg { FillPath(FillOrStrokeStyle, Vec<PathSegment>), FillText(String, f64, f64, Option<f64>, FillOrStrokeStyle, bool), FillRect(Rect<f32>, FillOrStrokeStyle), - GetImageData(Rect<u64>, Size2D<u64>, IpcSender<IpcSnapshot>), + GetImageData(Rect<u32>, Size2D<u32>, IpcSender<IpcSnapshot>), GetTransform(IpcSender<Transform2D<f32>>), IsPointInCurrentPath(f64, f64, FillRule, IpcSender<bool>), IsPointInPath(Vec<PathSegment>, f64, f64, FillRule, IpcSender<bool>), LineTo(Point2D<f32>), MoveTo(Point2D<f32>), MeasureText(String, IpcSender<TextMetrics>), - PutImageData(Rect<u64>, IpcBytesReceiver), + PutImageData(Rect<u32>, IpcBytesReceiver), QuadraticCurveTo(Point2D<f32>, Point2D<f32>), Rect(Rect<f32>), RestoreContext, diff --git a/components/shared/canvas/lib.rs b/components/shared/canvas/lib.rs index 826db54b0f6..df6b0854b9e 100644 --- a/components/shared/canvas/lib.rs +++ b/components/shared/canvas/lib.rs @@ -21,5 +21,5 @@ pub enum ConstellationCanvasMsg { sender: Sender<(CanvasId, ImageKey)>, size: Size2D<u64>, }, - Exit, + Exit(Sender<()>), } diff --git a/components/shared/compositing/lib.rs b/components/shared/compositing/lib.rs index 67ff0046885..8dadf93d628 100644 --- a/components/shared/compositing/lib.rs +++ b/components/shared/compositing/lib.rs @@ -23,6 +23,7 @@ use webrender_api::DocumentId; pub mod display_list; pub mod rendering_context; +pub mod viewport_description; use std::collections::HashMap; use std::sync::{Arc, Mutex}; @@ -42,6 +43,8 @@ use webrender_api::{ ImageKey, NativeFontHandle, PipelineId as WebRenderPipelineId, }; +use crate::viewport_description::ViewportDescription; + /// Sends messages to the compositor. #[derive(Clone)] pub struct CompositorProxy { @@ -176,6 +179,8 @@ pub enum CompositorMsg { /// Measure the current memory usage associated with the compositor. /// The report must be sent on the provided channel once it's complete. CollectMemoryReport(ReportsChan), + /// A top-level frame has parsed a viewport metatag and is sending the new constraints. + Viewport(WebViewId, ViewportDescription), } impl Debug for CompositorMsg { diff --git a/components/shared/compositing/viewport_description.rs b/components/shared/compositing/viewport_description.rs new file mode 100644 index 00000000000..83b29371f84 --- /dev/null +++ b/components/shared/compositing/viewport_description.rs @@ -0,0 +1,175 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +//! This module contains helpers for Viewport + +use std::collections::HashMap; +use std::str::FromStr; + +use euclid::default::Scale; +use serde::{Deserialize, Serialize}; + +/// Default viewport constraints +/// +/// <https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag#initial-scale> +pub const MIN_ZOOM: f32 = 0.1; +/// <https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag#initial-scale> +pub const MAX_ZOOM: f32 = 10.0; +/// <https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag#initial-scale> +pub const DEFAULT_ZOOM: f32 = 1.0; + +/// <https://drafts.csswg.org/css-viewport/#parsing-algorithm> +const SEPARATORS: [char; 2] = [',', ';']; // Comma (0x2c) and Semicolon (0x3b) + +/// A set of viewport descriptors: +/// +/// <https://www.w3.org/TR/css-viewport-1/#viewport-meta> +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +pub struct ViewportDescription { + // https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag#width + // the (minimum width) size of the viewport + // TODO: width Needs to be implemented + // https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag#width + // the (minimum height) size of the viewport + // TODO: height Needs to be implemented + /// <https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag#initial-scale> + /// the zoom level when the page is first loaded + pub initial_scale: Scale<f32>, + + /// <https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag#minimum_scale> + /// how much zoom out is allowed on the page. + pub minimum_scale: Scale<f32>, + + /// <https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag#maximum_scale> + /// how much zoom in is allowed on the page + pub maximum_scale: Scale<f32>, + + /// <https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag#user_scalable> + /// whether zoom in and zoom out actions are allowed on the page + pub user_scalable: UserScalable, +} + +/// The errors that the viewport parsing can generate. +#[derive(Debug)] +pub enum ViewportDescriptionParseError { + /// When viewport attribute string is empty + Empty, +} + +/// A set of User Zoom values: +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +pub enum UserScalable { + /// Zoom is not allowed + No = 0, + /// Zoom is allowed + Yes = 1, +} + +/// Parses a viewport user scalable value. +impl TryFrom<&str> for UserScalable { + type Error = &'static str; + fn try_from(value: &str) -> Result<Self, Self::Error> { + match value.to_lowercase().as_str() { + "yes" => Ok(UserScalable::Yes), + "no" => Ok(UserScalable::No), + _ => match value.parse::<f32>() { + Ok(1.0) => Ok(UserScalable::Yes), + Ok(0.0) => Ok(UserScalable::No), + _ => Err("can't convert character to UserScalable"), + }, + } + } +} + +impl Default for ViewportDescription { + fn default() -> Self { + ViewportDescription { + initial_scale: Scale::new(DEFAULT_ZOOM), + minimum_scale: Scale::new(MIN_ZOOM), + maximum_scale: Scale::new(MAX_ZOOM), + user_scalable: UserScalable::Yes, + } + } +} + +impl ViewportDescription { + /// Iterates over the key-value pairs generated from meta tag and returns a ViewportDescription + fn process_viewport_key_value_pairs(pairs: HashMap<String, String>) -> ViewportDescription { + let mut description = ViewportDescription::default(); + for (key, value) in &pairs { + match key.as_str() { + "initial-scale" => { + if let Some(zoom) = Self::parse_viewport_value_as_zoom(value) { + description.initial_scale = zoom; + } + }, + "minimum-scale" => { + if let Some(zoom) = Self::parse_viewport_value_as_zoom(value) { + description.minimum_scale = zoom; + } + }, + "maximum-scale" => { + if let Some(zoom) = Self::parse_viewport_value_as_zoom(value) { + description.maximum_scale = zoom; + } + }, + "user-scalable" => { + if let Ok(user_zoom_allowed) = value.as_str().try_into() { + description.user_scalable = user_zoom_allowed; + } + }, + _ => (), + } + } + description + } + + /// Parses a viewport zoom value. + fn parse_viewport_value_as_zoom(value: &str) -> Option<Scale<f32>> { + value + .to_lowercase() + .as_str() + .parse::<f32>() + .ok() + .filter(|&n| (0.0..=10.0).contains(&n)) + .map(Scale::new) + } + + /// Constrains a zoom value within the allowed scale range + pub fn clamp_zoom(&self, zoom: f32) -> f32 { + zoom.clamp(self.minimum_scale.get(), self.maximum_scale.get()) + } +} + +/// <https://drafts.csswg.org/css-viewport/#parsing-algorithm> +/// +/// This implementation differs from the specified algorithm, but is equivalent because +/// 1. It uses higher-level string operations to process string instead of character-by-character iteration. +/// 2. Uses trim() operation to handle whitespace instead of explicitly handling throughout the parsing process. +impl FromStr for ViewportDescription { + type Err = ViewportDescriptionParseError; + fn from_str(string: &str) -> Result<Self, Self::Err> { + if string.is_empty() { + return Err(ViewportDescriptionParseError::Empty); + } + + // Parse key-value pairs from the content string + // 1. Split the content string using SEPARATORS + // 2. Split into key-value pair using "=" and trim whitespaces + // 3. Insert into HashMap + let parsed_values = string + .split(SEPARATORS) + .filter_map(|pair| { + let mut parts = pair.split('=').map(str::trim); + if let (Some(key), Some(value)) = (parts.next(), parts.next()) { + Some((key.to_string(), value.to_string())) + } else { + None + } + }) + .collect::<HashMap<String, String>>(); + + Ok(Self::process_viewport_key_value_pairs(parsed_values)) + } +} diff --git a/components/shared/constellation/lib.rs b/components/shared/constellation/lib.rs index fb00d4afdbf..53e924c5ad5 100644 --- a/components/shared/constellation/lib.rs +++ b/components/shared/constellation/lib.rs @@ -26,6 +26,7 @@ use euclid::Vector2D; pub use from_script_message::*; use ipc_channel::ipc::IpcSender; use malloc_size_of_derive::MallocSizeOf; +use profile_traits::mem::MemoryReportResult; use serde::{Deserialize, Serialize}; use servo_url::{ImmutableOrigin, ServoUrl}; pub use structured_data::*; @@ -95,6 +96,8 @@ pub enum EmbedderToConstellationMessage { /// Evaluate a JavaScript string in the context of a `WebView`. When execution is complete or an /// error is encountered, a correpsonding message will be sent to the embedding layer. EvaluateJavaScript(WebViewId, JavaScriptEvaluationId, String), + /// Create a memory report and return it via the ipc sender + CreateMemoryReport(IpcSender<MemoryReportResult>), } /// A description of a paint metric that is sent from the Servo renderer to the diff --git a/components/shared/embedder/input_events.rs b/components/shared/embedder/input_events.rs index 869c4eee004..ff48bd7b7d8 100644 --- a/components/shared/embedder/input_events.rs +++ b/components/shared/embedder/input_events.rs @@ -58,16 +58,16 @@ impl InputEvent { } } - pub fn with_webdriver_message_id(self, webdriver_id: Option<WebDriverMessageId>) -> Self { + pub fn with_webdriver_message_id(mut self, webdriver_id: Option<WebDriverMessageId>) -> Self { match self { InputEvent::EditingAction(..) => {}, InputEvent::Gamepad(..) => {}, InputEvent::Ime(..) => {}, InputEvent::Keyboard(..) => {}, - InputEvent::MouseButton(mut event) => { + InputEvent::MouseButton(ref mut event) => { event.webdriver_id = webdriver_id; }, - InputEvent::MouseMove(mut event) => { + InputEvent::MouseMove(ref mut event) => { event.webdriver_id = webdriver_id; }, InputEvent::Touch(..) => {}, diff --git a/components/shared/embedder/webdriver.rs b/components/shared/embedder/webdriver.rs index 7b0f02bc26a..d28bb6fc6c3 100644 --- a/components/shared/embedder/webdriver.rs +++ b/components/shared/embedder/webdriver.rs @@ -130,7 +130,7 @@ pub enum WebDriverScriptCommand { IpcSender<Result<Vec<String>, ErrorStatus>>, ), FindElementElementsTagName(String, String, IpcSender<Result<Vec<String>, ErrorStatus>>), - FocusElement(String, IpcSender<Result<(), ErrorStatus>>), + GetElementShadowRoot(String, IpcSender<Result<Option<String>, ErrorStatus>>), ElementClick(String, IpcSender<Result<Option<String>, ErrorStatus>>), GetActiveElement(IpcSender<Option<String>>), GetComputedRole(String, IpcSender<Result<Option<String>, ErrorStatus>>), @@ -161,6 +161,8 @@ pub enum WebDriverScriptCommand { IsEnabled(String, IpcSender<Result<bool, ErrorStatus>>), IsSelected(String, IpcSender<Result<bool, ErrorStatus>>), GetTitle(IpcSender<String>), + /// Match the element type before sending the event for webdriver `element send keys`. + WillSendKeys(String, String, bool, IpcSender<Result<bool, ErrorStatus>>), } #[derive(Debug, Deserialize, Serialize)] diff --git a/components/shared/net/lib.rs b/components/shared/net/lib.rs index 0126bdbcd80..0a490fa3bcf 100644 --- a/components/shared/net/lib.rs +++ b/components/shared/net/lib.rs @@ -40,6 +40,7 @@ pub mod blob_url_store; pub mod filemanager_thread; pub mod http_status; pub mod image_cache; +pub mod mime_classifier; pub mod policy_container; pub mod pub_domains; pub mod quality; diff --git a/components/net/mime_classifier.rs b/components/shared/net/mime_classifier.rs index a98c4428b87..7e5408ba56e 100644 --- a/components/net/mime_classifier.rs +++ b/components/shared/net/mime_classifier.rs @@ -3,7 +3,8 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use mime::{self, Mime}; -use net_traits::LoadContext; + +use crate::LoadContext; pub struct MimeClassifier { image_classifier: GroupedClassifier, @@ -16,11 +17,15 @@ pub struct MimeClassifier { font_classifier: GroupedClassifier, } +#[derive(PartialEq)] pub enum MediaType { Xml, Html, AudioVideo, Image, + JavaScript, + Json, + Font, } pub enum ApacheBugFlag { @@ -99,7 +104,11 @@ impl MimeClassifier { Some(MediaType::AudioVideo) => { self.audio_video_classifier.classify(data) }, - Some(MediaType::Xml) | None => None, + Some(MediaType::JavaScript) | + Some(MediaType::Font) | + Some(MediaType::Json) | + Some(MediaType::Xml) | + None => None, } .unwrap_or(supplied_type.clone()) }, @@ -215,20 +224,24 @@ impl MimeClassifier { .expect("BinaryOrPlaintextClassifier always succeeds") } + /// <https://mimesniff.spec.whatwg.org/#xml-mime-type> fn is_xml(mt: &Mime) -> bool { mt.suffix() == Some(mime::XML) || - (mt.type_() == mime::APPLICATION && mt.subtype() == mime::XML) || - (mt.type_() == mime::TEXT && mt.subtype() == mime::XML) + *mt == mime::TEXT_XML || + (mt.type_() == mime::APPLICATION && mt.subtype() == mime::XML) } + /// <https://mimesniff.spec.whatwg.org/#html-mime-type> fn is_html(mt: &Mime) -> bool { - mt.type_() == mime::TEXT && mt.subtype() == mime::HTML + *mt == mime::TEXT_HTML } + /// <https://mimesniff.spec.whatwg.org/#image-mime-type> fn is_image(mt: &Mime) -> bool { mt.type_() == mime::IMAGE } + /// <https://mimesniff.spec.whatwg.org/#audio-or-video-mime-type> fn is_audio_video(mt: &Mime) -> bool { mt.type_() == mime::AUDIO || mt.type_() == mime::VIDEO || @@ -241,7 +254,53 @@ impl MimeClassifier { mt.type_() == mime::STAR && mt.subtype() == mime::STAR } - fn get_media_type(mime: &Mime) -> Option<MediaType> { + /// <https://mimesniff.spec.whatwg.org/#javascript-mime-type> + fn is_javascript(mt: &Mime) -> bool { + (mt.type_() == mime::APPLICATION && + (["ecmascript", "javascript", "x-ecmascript", "x-javascript"] + .contains(&mt.subtype().as_str()))) || + (mt.type_() == mime::TEXT && + ([ + "ecmascript", + "javascript", + "javascript1.0", + "javascript1.1", + "javascript1.2", + "javascript1.3", + "javascript1.4", + "javascript1.5", + "jscript", + "livescript", + "x-ecmascript", + "x-javascript", + ] + .contains(&mt.subtype().as_str()))) + } + + /// <https://mimesniff.spec.whatwg.org/#json-mime-type> + fn is_json(mt: &Mime) -> bool { + mt.suffix() == Some(mime::JSON) || + (mt.subtype() == mime::JSON && + (mt.type_() == mime::APPLICATION || mt.type_() == mime::TEXT)) + } + + /// <https://mimesniff.spec.whatwg.org/#font-mime-type> + fn is_font(mt: &Mime) -> bool { + mt.type_() == mime::FONT || + (mt.type_() == mime::APPLICATION && + ([ + "font-cff", + "font-off", + "font-sfnt", + "font-ttf", + "font-woff", + "vnd.ms-fontobject", + "vnd.ms-opentype", + ] + .contains(&mt.subtype().as_str()))) + } + + pub fn get_media_type(mime: &Mime) -> Option<MediaType> { if MimeClassifier::is_xml(mime) { Some(MediaType::Xml) } else if MimeClassifier::is_html(mime) { @@ -250,6 +309,12 @@ impl MimeClassifier { Some(MediaType::Image) } else if MimeClassifier::is_audio_video(mime) { Some(MediaType::AudioVideo) + } else if MimeClassifier::is_javascript(mime) { + Some(MediaType::JavaScript) + } else if MimeClassifier::is_font(mime) { + Some(MediaType::Font) + } else if MimeClassifier::is_json(mime) { + Some(MediaType::Json) } else { None } diff --git a/components/net/tests/mime_classifier.rs b/components/shared/net/tests/mime_classifier.rs index b4e6ae6e9ab..79a122ac8bf 100644 --- a/components/net/tests/mime_classifier.rs +++ b/components/shared/net/tests/mime_classifier.rs @@ -8,8 +8,8 @@ use std::io::{self, Read}; use std::path::{self, PathBuf}; use mime::{self, Mime}; -use net::mime_classifier::{ApacheBugFlag, MimeClassifier, Mp4Matcher, NoSniffFlag}; use net_traits::LoadContext; +use net_traits::mime_classifier::{ApacheBugFlag, MimeClassifier, Mp4Matcher, NoSniffFlag}; fn read_file(path: &path::Path) -> io::Result<Vec<u8>> { let mut file = File::open(path)?; diff --git a/components/net/tests/parsable_mime/application/font-woff/test.wof b/components/shared/net/tests/parsable_mime/application/font-woff/test.wof index a1393ebee1d..a1393ebee1d 100755 --- a/components/net/tests/parsable_mime/application/font-woff/test.wof +++ b/components/shared/net/tests/parsable_mime/application/font-woff/test.wof diff --git a/components/net/tests/parsable_mime/application/ogg/small.ogg b/components/shared/net/tests/parsable_mime/application/ogg/small.ogg Binary files differindex 0d7f43eb795..0d7f43eb795 100644 --- a/components/net/tests/parsable_mime/application/ogg/small.ogg +++ b/components/shared/net/tests/parsable_mime/application/ogg/small.ogg diff --git a/components/net/tests/parsable_mime/application/pdf/test.pdf b/components/shared/net/tests/parsable_mime/application/pdf/test.pdf index e7c6e62775f..055169fe34b 100644 --- a/components/net/tests/parsable_mime/application/pdf/test.pdf +++ b/components/shared/net/tests/parsable_mime/application/pdf/test.pdf @@ -1,157 +1,157 @@ -%PDF-1.2
-%
-
-9 0 obj
-<<
-/Length 10 0 R
-/Filter /FlateDecode
->>
-stream
+%PDF-1.2 +% + +9 0 obj +<< +/Length 10 0 R +/Filter /FlateDecode +>> +stream H͐J0 {f$Mn-[&jeۤ~$}ɅIjs~X-],$Y)'Nu1!V?? -b1Rbb҉H[TD:#&حXi$qnf]a{أq|JLs]QIj%9`Uitez$OeBĒүR@zܗg<
-endstream
-endobj
-10 0 obj
-246
-endobj
-4 0 obj
-<<
-/Type /Page
-/Parent 5 0 R
-/Resources <<
-/Font <<
-/F0 6 0 R
-/F1 7 0 R
->>
-/ProcSet 2 0 R
->>
-/Contents 9 0 R
->>
-endobj
-6 0 obj
-<<
-/Type /Font
-/Subtype /TrueType
-/Name /F0
-/BaseFont /Arial
-/Encoding /WinAnsiEncoding
->>
-endobj
-7 0 obj
-<<
-/Type /Font
-/Subtype /TrueType
-/Name /F1
-/BaseFont /BookAntiqua,Bold
-/FirstChar 31
-/LastChar 255
-/Widths [ 750 250 278 402 606 500 889 833 227 333 333 444 606 250 333 250
-296 500 500 500 500 500 500 500 500 500 500 250 250 606 606 606
-444 747 778 667 722 833 611 556 833 833 389 389 778 611 1000 833
-833 611 833 722 611 667 778 778 1000 667 667 667 333 606 333 606
-500 333 500 611 444 611 500 389 556 611 333 333 611 333 889 611
-556 611 611 389 444 333 611 556 833 500 556 500 310 606 310 606
-750 500 750 333 500 500 1000 500 500 333 1000 611 389 1000 750 750
-750 750 278 278 500 500 606 500 1000 333 998 444 389 833 750 750
-667 250 278 500 500 606 500 606 500 333 747 438 500 606 333 747
-500 400 549 361 361 333 576 641 250 333 361 488 500 889 890 889
-444 778 778 778 778 778 778 1000 722 611 611 611 611 389 389 389
-389 833 833 833 833 833 833 833 606 833 778 778 778 778 667 611
-611 500 500 500 500 500 500 778 444 500 500 500 500 333 333 333
-333 556 611 556 556 556 556 556 549 556 611 611 611 611 556 611
-556 ]
-/Encoding /WinAnsiEncoding
-/FontDescriptor 8 0 R
->>
-endobj
-8 0 obj
-<<
-/Type /FontDescriptor
-/FontName /BookAntiqua,Bold
-/Flags 16418
-/FontBBox [ -250 -260 1236 930 ]
-/MissingWidth 750
-/StemV 146
-/StemH 146
-/ItalicAngle 0
-/CapHeight 930
-/XHeight 651
-/Ascent 930
-/Descent 260
-/Leading 210
-/MaxWidth 1030
-/AvgWidth 460
->>
-endobj
-2 0 obj
-[ /PDF /Text ]
-endobj
-5 0 obj
-<<
-/Kids [4 0 R ]
-/Count 1
-/Type /Pages
-/MediaBox [ 0 0 612 792 ]
->>
-endobj
-1 0 obj
-<<
-/Creator (1725.fm)
-/CreationDate (1-Jan-3 18:15PM)
-/Title (1725.PDF)
-/Author (Unknown)
-/Producer (Acrobat PDFWriter 3.02 for Windows)
-/Keywords ()
-/Subject ()
->>
-endobj
-3 0 obj
-<<
-/Pages 5 0 R
-/Type /Catalog
-/DefaultGray 11 0 R
-/DefaultRGB 12 0 R
->>
-endobj
-11 0 obj
-[/CalGray
-<<
-/WhitePoint [0.9505 1 1.0891 ]
-/Gamma 0.2468
->>
-]
-endobj
-12 0 obj
-[/CalRGB
-<<
-/WhitePoint [0.9505 1 1.0891 ]
-/Gamma [0.2468 0.2468 0.2468 ]
-/Matrix [0.4361 0.2225 0.0139 0.3851 0.7169 0.0971 0.1431 0.0606 0.7141 ]
->>
-]
-endobj
-xref
-0 13
-0000000000 65535 f
-0000002172 00000 n
-0000002046 00000 n
-0000002363 00000 n
-0000000375 00000 n
-0000002080 00000 n
-0000000518 00000 n
-0000000633 00000 n
-0000001760 00000 n
-0000000021 00000 n
-0000000352 00000 n
-0000002460 00000 n
-0000002548 00000 n
-trailer
-<<
-/Size 13
-/Root 3 0 R
-/Info 1 0 R
-/ID [<47149510433dd4882f05f8c124223734><47149510433dd4882f05f8c124223734>]
->>
-startxref
-2726
-%%EOF
+b1Rbb҉H[TD:#&حXi$qnf]a{أq|JLs]QIj%9`Uitez$OeBĒүR@zܗg< +endstream +endobj +10 0 obj +246 +endobj +4 0 obj +<< +/Type /Page +/Parent 5 0 R +/Resources << +/Font << +/F0 6 0 R +/F1 7 0 R +>> +/ProcSet 2 0 R +>> +/Contents 9 0 R +>> +endobj +6 0 obj +<< +/Type /Font +/Subtype /TrueType +/Name /F0 +/BaseFont /Arial +/Encoding /WinAnsiEncoding +>> +endobj +7 0 obj +<< +/Type /Font +/Subtype /TrueType +/Name /F1 +/BaseFont /BookAntiqua,Bold +/FirstChar 31 +/LastChar 255 +/Widths [ 750 250 278 402 606 500 889 833 227 333 333 444 606 250 333 250 +296 500 500 500 500 500 500 500 500 500 500 250 250 606 606 606 +444 747 778 667 722 833 611 556 833 833 389 389 778 611 1000 833 +833 611 833 722 611 667 778 778 1000 667 667 667 333 606 333 606 +500 333 500 611 444 611 500 389 556 611 333 333 611 333 889 611 +556 611 611 389 444 333 611 556 833 500 556 500 310 606 310 606 +750 500 750 333 500 500 1000 500 500 333 1000 611 389 1000 750 750 +750 750 278 278 500 500 606 500 1000 333 998 444 389 833 750 750 +667 250 278 500 500 606 500 606 500 333 747 438 500 606 333 747 +500 400 549 361 361 333 576 641 250 333 361 488 500 889 890 889 +444 778 778 778 778 778 778 1000 722 611 611 611 611 389 389 389 +389 833 833 833 833 833 833 833 606 833 778 778 778 778 667 611 +611 500 500 500 500 500 500 778 444 500 500 500 500 333 333 333 +333 556 611 556 556 556 556 556 549 556 611 611 611 611 556 611 +556 ] +/Encoding /WinAnsiEncoding +/FontDescriptor 8 0 R +>> +endobj +8 0 obj +<< +/Type /FontDescriptor +/FontName /BookAntiqua,Bold +/Flags 16418 +/FontBBox [ -250 -260 1236 930 ] +/MissingWidth 750 +/StemV 146 +/StemH 146 +/ItalicAngle 0 +/CapHeight 930 +/XHeight 651 +/Ascent 930 +/Descent 260 +/Leading 210 +/MaxWidth 1030 +/AvgWidth 460 +>> +endobj +2 0 obj +[ /PDF /Text ] +endobj +5 0 obj +<< +/Kids [4 0 R ] +/Count 1 +/Type /Pages +/MediaBox [ 0 0 612 792 ] +>> +endobj +1 0 obj +<< +/Creator (1725.fm) +/CreationDate (1-Jan-3 18:15PM) +/Title (1725.PDF) +/Author (Unknown) +/Producer (Acrobat PDFWriter 3.02 for Windows) +/Keywords () +/Subject () +>> +endobj +3 0 obj +<< +/Pages 5 0 R +/Type /Catalog +/DefaultGray 11 0 R +/DefaultRGB 12 0 R +>> +endobj +11 0 obj +[/CalGray +<< +/WhitePoint [0.9505 1 1.0891 ] +/Gamma 0.2468 +>> +] +endobj +12 0 obj +[/CalRGB +<< +/WhitePoint [0.9505 1 1.0891 ] +/Gamma [0.2468 0.2468 0.2468 ] +/Matrix [0.4361 0.2225 0.0139 0.3851 0.7169 0.0971 0.1431 0.0606 0.7141 ] +>> +] +endobj +xref +0 13 +0000000000 65535 f +0000002172 00000 n +0000002046 00000 n +0000002363 00000 n +0000000375 00000 n +0000002080 00000 n +0000000518 00000 n +0000000633 00000 n +0000001760 00000 n +0000000021 00000 n +0000000352 00000 n +0000002460 00000 n +0000002548 00000 n +trailer +<< +/Size 13 +/Root 3 0 R +/Info 1 0 R +/ID [<47149510433dd4882f05f8c124223734><47149510433dd4882f05f8c124223734>] +>> +startxref +2726 +%%EOF diff --git a/components/net/tests/parsable_mime/application/postscript/test.ps b/components/shared/net/tests/parsable_mime/application/postscript/test.ps index c273ffa3f0f..c273ffa3f0f 100755 --- a/components/net/tests/parsable_mime/application/postscript/test.ps +++ b/components/shared/net/tests/parsable_mime/application/postscript/test.ps diff --git a/components/net/tests/parsable_mime/application/vnd.ms-fontobject/vnd.ms-fontobject b/components/shared/net/tests/parsable_mime/application/vnd.ms-fontobject/vnd.ms-fontobject Binary files differindex 1b84f4c37c1..1b84f4c37c1 100755 --- a/components/net/tests/parsable_mime/application/vnd.ms-fontobject/vnd.ms-fontobject +++ b/components/shared/net/tests/parsable_mime/application/vnd.ms-fontobject/vnd.ms-fontobject diff --git a/components/net/tests/parsable_mime/application/x-gzip/test.gz b/components/shared/net/tests/parsable_mime/application/x-gzip/test.gz Binary files differindex 3b99b73e6f0..3b99b73e6f0 100644 --- a/components/net/tests/parsable_mime/application/x-gzip/test.gz +++ b/components/shared/net/tests/parsable_mime/application/x-gzip/test.gz diff --git a/components/net/tests/parsable_mime/application/x-rar-compressed/test.rar b/components/shared/net/tests/parsable_mime/application/x-rar-compressed/test.rar Binary files differindex 920bd4d8a8c..920bd4d8a8c 100755 --- a/components/net/tests/parsable_mime/application/x-rar-compressed/test.rar +++ b/components/shared/net/tests/parsable_mime/application/x-rar-compressed/test.rar diff --git a/components/net/tests/parsable_mime/application/zip/test.zip b/components/shared/net/tests/parsable_mime/application/zip/test.zip index 5c74c9658c6..5c74c9658c6 100755 --- a/components/net/tests/parsable_mime/application/zip/test.zip +++ b/components/shared/net/tests/parsable_mime/application/zip/test.zip diff --git a/components/net/tests/parsable_mime/audio/aiff/test.aif b/components/shared/net/tests/parsable_mime/audio/aiff/test.aif Binary files differindex ad2e35df40b..ad2e35df40b 100644 --- a/components/net/tests/parsable_mime/audio/aiff/test.aif +++ b/components/shared/net/tests/parsable_mime/audio/aiff/test.aif diff --git a/components/net/tests/parsable_mime/audio/basic/test.au b/components/shared/net/tests/parsable_mime/audio/basic/test.au Binary files differindex d4e53deb74a..d4e53deb74a 100644 --- a/components/net/tests/parsable_mime/audio/basic/test.au +++ b/components/shared/net/tests/parsable_mime/audio/basic/test.au diff --git a/components/net/tests/parsable_mime/audio/midi/test.mid b/components/shared/net/tests/parsable_mime/audio/midi/test.mid Binary files differindex a52838c62bc..a52838c62bc 100644 --- a/components/net/tests/parsable_mime/audio/midi/test.mid +++ b/components/shared/net/tests/parsable_mime/audio/midi/test.mid diff --git a/components/net/tests/parsable_mime/audio/mpeg/test.mp3 b/components/shared/net/tests/parsable_mime/audio/mpeg/test.mp3 Binary files differindex 50786790311..50786790311 100644 --- a/components/net/tests/parsable_mime/audio/mpeg/test.mp3 +++ b/components/shared/net/tests/parsable_mime/audio/mpeg/test.mp3 diff --git a/components/net/tests/parsable_mime/audio/wave/test.wav b/components/shared/net/tests/parsable_mime/audio/wave/test.wav Binary files differindex f96276c063c..f96276c063c 100644 --- a/components/net/tests/parsable_mime/audio/wave/test.wav +++ b/components/shared/net/tests/parsable_mime/audio/wave/test.wav diff --git a/components/net/tests/parsable_mime/image/bmp/test.bmp b/components/shared/net/tests/parsable_mime/image/bmp/test.bmp Binary files differindex 8a1b10bae5e..8a1b10bae5e 100644 --- a/components/net/tests/parsable_mime/image/bmp/test.bmp +++ b/components/shared/net/tests/parsable_mime/image/bmp/test.bmp diff --git a/components/net/tests/parsable_mime/image/gif/test87a b/components/shared/net/tests/parsable_mime/image/gif/test87a Binary files differindex 8d49c776420..8d49c776420 100644 --- a/components/net/tests/parsable_mime/image/gif/test87a +++ b/components/shared/net/tests/parsable_mime/image/gif/test87a diff --git a/components/net/tests/parsable_mime/image/gif/test89a.gif b/components/shared/net/tests/parsable_mime/image/gif/test89a.gif Binary files differindex 0e2995e0821..0e2995e0821 100644 --- a/components/net/tests/parsable_mime/image/gif/test89a.gif +++ b/components/shared/net/tests/parsable_mime/image/gif/test89a.gif diff --git a/components/net/tests/parsable_mime/image/jpeg/test.jpg b/components/shared/net/tests/parsable_mime/image/jpeg/test.jpg Binary files differindex 7f758f65d13..7f758f65d13 100644 --- a/components/net/tests/parsable_mime/image/jpeg/test.jpg +++ b/components/shared/net/tests/parsable_mime/image/jpeg/test.jpg diff --git a/components/net/tests/parsable_mime/image/png/test.png b/components/shared/net/tests/parsable_mime/image/png/test.png Binary files differindex cc81374d4f5..cc81374d4f5 100644 --- a/components/net/tests/parsable_mime/image/png/test.png +++ b/components/shared/net/tests/parsable_mime/image/png/test.png diff --git a/components/net/tests/parsable_mime/image/webp/test.webp b/components/shared/net/tests/parsable_mime/image/webp/test.webp Binary files differindex ad88e62f94c..ad88e62f94c 100755 --- a/components/net/tests/parsable_mime/image/webp/test.webp +++ b/components/shared/net/tests/parsable_mime/image/webp/test.webp diff --git a/components/net/tests/parsable_mime/image/x-icon/test.ico b/components/shared/net/tests/parsable_mime/image/x-icon/test.ico Binary files differindex a2d0ee49098..a2d0ee49098 100644 --- a/components/net/tests/parsable_mime/image/x-icon/test.ico +++ b/components/shared/net/tests/parsable_mime/image/x-icon/test.ico diff --git a/components/net/tests/parsable_mime/image/x-icon/test_cursor.ico b/components/shared/net/tests/parsable_mime/image/x-icon/test_cursor.ico Binary files differindex 6029d6684d5..6029d6684d5 100644 --- a/components/net/tests/parsable_mime/image/x-icon/test_cursor.ico +++ b/components/shared/net/tests/parsable_mime/image/x-icon/test_cursor.ico diff --git a/components/net/tests/parsable_mime/text/html/text_html_a_20.html b/components/shared/net/tests/parsable_mime/text/html/text_html_a_20.html index 1b9619279a7..1b9619279a7 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_a_20.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_a_20.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_a_20_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_a_20_u.html index 887a1280650..887a1280650 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_a_20_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_a_20_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_a_3e.html b/components/shared/net/tests/parsable_mime/text/html/text_html_a_3e.html index 610cd08fea4..610cd08fea4 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_a_3e.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_a_3e.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_a_3e_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_a_3e_u.html index 48528fdf341..48528fdf341 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_a_3e_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_a_3e_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_b_20.html b/components/shared/net/tests/parsable_mime/text/html/text_html_b_20.html index 5977d2eeaab..5977d2eeaab 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_b_20.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_b_20.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_b_20_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_b_20_u.html index a8a963b95f0..a8a963b95f0 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_b_20_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_b_20_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_b_3e.html b/components/shared/net/tests/parsable_mime/text/html/text_html_b_3e.html index dc79cd5d568..dc79cd5d568 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_b_3e.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_b_3e.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_b_3e_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_b_3e_u.html index 0d72d281aec..0d72d281aec 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_b_3e_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_b_3e_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_body_20.html b/components/shared/net/tests/parsable_mime/text/html/text_html_body_20.html index c72b1ad3bec..c72b1ad3bec 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_body_20.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_body_20.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_body_20_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_body_20_u.html index 1d76ebb0f47..1d76ebb0f47 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_body_20_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_body_20_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_body_3e.html b/components/shared/net/tests/parsable_mime/text/html/text_html_body_3e.html index 4a66f59ef95..4a66f59ef95 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_body_3e.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_body_3e.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_body_3e_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_body_3e_u.html index b431695f3ab..b431695f3ab 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_body_3e_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_body_3e_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_br_20.html b/components/shared/net/tests/parsable_mime/text/html/text_html_br_20.html index d04df680012..d04df680012 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_br_20.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_br_20.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_br_20_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_br_20_u.html index 1c0f0ce13ba..1c0f0ce13ba 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_br_20_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_br_20_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_br_3e.html b/components/shared/net/tests/parsable_mime/text/html/text_html_br_3e.html index 1d40ef06566..1d40ef06566 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_br_3e.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_br_3e.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_br_3e_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_br_3e_u.html index c4eae116f03..c4eae116f03 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_br_3e_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_br_3e_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_comment_20.html b/components/shared/net/tests/parsable_mime/text/html/text_html_comment_20.html index e9612efc73c..e9612efc73c 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_comment_20.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_comment_20.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_comment_20_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_comment_20_u.html index e9612efc73c..e9612efc73c 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_comment_20_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_comment_20_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_comment_3e.html b/components/shared/net/tests/parsable_mime/text/html/text_html_comment_3e.html index 44a94ca5a7a..44a94ca5a7a 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_comment_3e.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_comment_3e.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_comment_3e_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_comment_3e_u.html index 44a94ca5a7a..44a94ca5a7a 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_comment_3e_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_comment_3e_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_div_20.html b/components/shared/net/tests/parsable_mime/text/html/text_html_div_20.html index 2ed34363b2f..2ed34363b2f 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_div_20.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_div_20.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_div_20_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_div_20_u.html index b98886efd83..b98886efd83 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_div_20_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_div_20_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_div_3e.html b/components/shared/net/tests/parsable_mime/text/html/text_html_div_3e.html index ccf4ca8d70a..ccf4ca8d70a 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_div_3e.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_div_3e.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_div_3e_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_div_3e_u.html index c117f0f4cdd..c117f0f4cdd 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_div_3e_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_div_3e_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_doctype_20.html b/components/shared/net/tests/parsable_mime/text/html/text_html_doctype_20.html index dbeb5a41c2a..dbeb5a41c2a 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_doctype_20.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_doctype_20.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_doctype_20_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_doctype_20_u.html index acede44dffb..acede44dffb 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_doctype_20_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_doctype_20_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_doctype_3e.html b/components/shared/net/tests/parsable_mime/text/html/text_html_doctype_3e.html index 6a22ea8b978..6a22ea8b978 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_doctype_3e.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_doctype_3e.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_doctype_3e_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_doctype_3e_u.html index 8b16e40458e..8b16e40458e 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_doctype_3e_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_doctype_3e_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_font_20.html b/components/shared/net/tests/parsable_mime/text/html/text_html_font_20.html index a18fa850617..a18fa850617 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_font_20.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_font_20.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_font_20_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_font_20_u.html index 6a31d2a8aba..6a31d2a8aba 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_font_20_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_font_20_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_font_3e.html b/components/shared/net/tests/parsable_mime/text/html/text_html_font_3e.html index 3605840fc5a..3605840fc5a 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_font_3e.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_font_3e.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_font_3e_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_font_3e_u.html index 1181517947b..1181517947b 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_font_3e_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_font_3e_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_h1_20.html b/components/shared/net/tests/parsable_mime/text/html/text_html_h1_20.html index 3ed0eb125ff..3ed0eb125ff 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_h1_20.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_h1_20.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_h1_20_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_h1_20_u.html index f517b61487e..f517b61487e 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_h1_20_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_h1_20_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_h1_3e.html b/components/shared/net/tests/parsable_mime/text/html/text_html_h1_3e.html index af0bf8c56b9..af0bf8c56b9 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_h1_3e.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_h1_3e.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_h1_3e_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_h1_3e_u.html index bae85229fcf..bae85229fcf 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_h1_3e_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_h1_3e_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_head_20.html b/components/shared/net/tests/parsable_mime/text/html/text_html_head_20.html index eb322c946e0..eb322c946e0 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_head_20.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_head_20.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_head_20_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_head_20_u.html index 899655a5a2c..899655a5a2c 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_head_20_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_head_20_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_head_3e.html b/components/shared/net/tests/parsable_mime/text/html/text_html_head_3e.html index 058c7dce4a9..058c7dce4a9 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_head_3e.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_head_3e.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_head_3e_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_head_3e_u.html index 8a33d623daa..8a33d623daa 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_head_3e_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_head_3e_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_iframe_20.html b/components/shared/net/tests/parsable_mime/text/html/text_html_iframe_20.html index e632915590a..e632915590a 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_iframe_20.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_iframe_20.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_iframe_20_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_iframe_20_u.html index 527a06e415c..527a06e415c 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_iframe_20_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_iframe_20_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_iframe_3e.html b/components/shared/net/tests/parsable_mime/text/html/text_html_iframe_3e.html index 9db0efd47d4..9db0efd47d4 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_iframe_3e.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_iframe_3e.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_iframe_3e_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_iframe_3e_u.html index e3512c8a5c2..e3512c8a5c2 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_iframe_3e_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_iframe_3e_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_p_20.html b/components/shared/net/tests/parsable_mime/text/html/text_html_p_20.html index a099441be2b..a099441be2b 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_p_20.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_p_20.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_p_20_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_p_20_u.html index ff4befbde7b..ff4befbde7b 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_p_20_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_p_20_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_p_3e.html b/components/shared/net/tests/parsable_mime/text/html/text_html_p_3e.html index 98db18913d0..98db18913d0 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_p_3e.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_p_3e.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_p_3e_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_p_3e_u.html index 9d99a59ed08..9d99a59ed08 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_p_3e_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_p_3e_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_page_20.html b/components/shared/net/tests/parsable_mime/text/html/text_html_page_20.html index bb1c4572b25..bb1c4572b25 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_page_20.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_page_20.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_page_20_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_page_20_u.html index b3300d9f4e4..b3300d9f4e4 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_page_20_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_page_20_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_page_3e.html b/components/shared/net/tests/parsable_mime/text/html/text_html_page_3e.html index e6a49c51924..e6a49c51924 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_page_3e.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_page_3e.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_page_3e_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_page_3e_u.html index 2b8ee203d25..2b8ee203d25 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_page_3e_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_page_3e_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_script_20.html b/components/shared/net/tests/parsable_mime/text/html/text_html_script_20.html index 620c629266c..620c629266c 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_script_20.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_script_20.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_script_20_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_script_20_u.html index bd2c58e676c..bd2c58e676c 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_script_20_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_script_20_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_script_3e.html b/components/shared/net/tests/parsable_mime/text/html/text_html_script_3e.html index d59535f70cd..d59535f70cd 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_script_3e.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_script_3e.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_script_3e_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_script_3e_u.html index 625c13820f4..625c13820f4 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_script_3e_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_script_3e_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_style_20.html b/components/shared/net/tests/parsable_mime/text/html/text_html_style_20.html index 57bc2a1ecd7..57bc2a1ecd7 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_style_20.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_style_20.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_style_20_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_style_20_u.html index 8163eca3c60..8163eca3c60 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_style_20_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_style_20_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_style_3e.html b/components/shared/net/tests/parsable_mime/text/html/text_html_style_3e.html index 229d5f951bd..229d5f951bd 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_style_3e.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_style_3e.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_style_3e_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_style_3e_u.html index 12d686e4953..12d686e4953 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_style_3e_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_style_3e_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_table_20.html b/components/shared/net/tests/parsable_mime/text/html/text_html_table_20.html index 27cccc6acd6..27cccc6acd6 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_table_20.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_table_20.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_table_20_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_table_20_u.html index 556b46e7fc4..556b46e7fc4 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_table_20_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_table_20_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_table_3e.html b/components/shared/net/tests/parsable_mime/text/html/text_html_table_3e.html index 351ee543af8..351ee543af8 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_table_3e.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_table_3e.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_table_3e_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_table_3e_u.html index 6259870bfcf..6259870bfcf 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_table_3e_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_table_3e_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_title_20.html b/components/shared/net/tests/parsable_mime/text/html/text_html_title_20.html index f7d151658d9..f7d151658d9 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_title_20.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_title_20.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_title_20_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_title_20_u.html index 03a072d8ac0..03a072d8ac0 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_title_20_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_title_20_u.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_title_3e.html b/components/shared/net/tests/parsable_mime/text/html/text_html_title_3e.html index fedf57b9e4f..fedf57b9e4f 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_title_3e.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_title_3e.html diff --git a/components/net/tests/parsable_mime/text/html/text_html_title_3e_u.html b/components/shared/net/tests/parsable_mime/text/html/text_html_title_3e_u.html index 5fbf8a75c47..5fbf8a75c47 100644 --- a/components/net/tests/parsable_mime/text/html/text_html_title_3e_u.html +++ b/components/shared/net/tests/parsable_mime/text/html/text_html_title_3e_u.html diff --git a/components/net/tests/parsable_mime/text/plain/utf16bebom.txt b/components/shared/net/tests/parsable_mime/text/plain/utf16bebom.txt Binary files differindex 9fb50d49fb8..9fb50d49fb8 100644 --- a/components/net/tests/parsable_mime/text/plain/utf16bebom.txt +++ b/components/shared/net/tests/parsable_mime/text/plain/utf16bebom.txt diff --git a/components/net/tests/parsable_mime/text/plain/utf16lebom.txt b/components/shared/net/tests/parsable_mime/text/plain/utf16lebom.txt Binary files differindex d79d81725ec..d79d81725ec 100644 --- a/components/net/tests/parsable_mime/text/plain/utf16lebom.txt +++ b/components/shared/net/tests/parsable_mime/text/plain/utf16lebom.txt diff --git a/components/net/tests/parsable_mime/text/plain/utf8bom.txt b/components/shared/net/tests/parsable_mime/text/plain/utf8bom.txt index 56ad8a265ef..56ad8a265ef 100644 --- a/components/net/tests/parsable_mime/text/plain/utf8bom.txt +++ b/components/shared/net/tests/parsable_mime/text/plain/utf8bom.txt diff --git a/components/net/tests/parsable_mime/text/xml/feed.atom b/components/shared/net/tests/parsable_mime/text/xml/feed.atom index 893c3f27a8e..893c3f27a8e 100755 --- a/components/net/tests/parsable_mime/text/xml/feed.atom +++ b/components/shared/net/tests/parsable_mime/text/xml/feed.atom diff --git a/components/net/tests/parsable_mime/text/xml/feed.rss b/components/shared/net/tests/parsable_mime/text/xml/feed.rss index 9dc94d32b51..57ea10d5b4e 100644 --- a/components/net/tests/parsable_mime/text/xml/feed.rss +++ b/components/shared/net/tests/parsable_mime/text/xml/feed.rss @@ -1,151 +1,151 @@ -<?xml version="1.0" encoding="windows-1252"?>
-<rss version="2.0">
- <channel>
- <title>FeedForAll Sample Feed</title>
- <description>RSS is a fascinating technology. The uses for RSS are expanding daily. Take a closer look at how various industries are using the benefits of RSS in their businesses.</description>
- <link>http://www.feedforall.com/industry-solutions.htm</link>
- <category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category>
- <copyright>Copyright 2004 NotePage, Inc.</copyright>
- <docs>http://blogs.law.harvard.edu/tech/rss</docs>
- <language>en-us</language>
- <lastBuildDate>Tue, 19 Oct 2004 13:39:14 -0400</lastBuildDate>
- <managingEditor>marketing@feedforall.com</managingEditor>
- <pubDate>Tue, 19 Oct 2004 13:38:55 -0400</pubDate>
- <webMaster>webmaster@feedforall.com</webMaster>
- <generator>FeedForAll Beta1 (0.0.1.8)</generator>
- <image>
- <url>http://www.feedforall.com/ffalogo48x48.gif</url>
- <title>FeedForAll Sample Feed</title>
- <link>http://www.feedforall.com/industry-solutions.htm</link>
- <description>FeedForAll Sample Feed</description>
- <width>48</width>
- <height>48</height>
- </image>
- <item>
- <title>RSS Solutions for Restaurants</title>
- <description><b>FeedForAll </b>helps Restaurant's communicate with customers. Let your customers know the latest specials or events.<br>
-<br>
-RSS feed uses include:<br>
-<i><font color="#FF0000">Daily Specials <br>
-Entertainment <br>
-Calendar of Events </i></font></description>
- <link>http://www.feedforall.com/restaurant.htm</link>
- <category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category>
- <comments>http://www.feedforall.com/forum</comments>
- <pubDate>Tue, 19 Oct 2004 11:09:11 -0400</pubDate>
- </item>
- <item>
- <title>RSS Solutions for Schools and Colleges</title>
- <description>FeedForAll helps Educational Institutions communicate with students about school wide activities, events, and schedules.<br>
-<br>
-RSS feed uses include:<br>
-<i><font color="#0000FF">Homework Assignments <br>
-School Cancellations <br>
-Calendar of Events <br>
-Sports Scores <br>
-Clubs/Organization Meetings <br>
-Lunches Menus </i></font></description>
- <link>http://www.feedforall.com/schools.htm</link>
- <category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category>
- <comments>http://www.feedforall.com/forum</comments>
- <pubDate>Tue, 19 Oct 2004 11:09:09 -0400</pubDate>
- </item>
- <item>
- <title>RSS Solutions for Computer Service Companies</title>
- <description>FeedForAll helps Computer Service Companies communicate with clients about cyber security and related issues. <br>
-<br>
-Uses include:<br>
-<i><font color="#0000FF">Cyber Security Alerts <br>
-Specials<br>
-Job Postings </i></font></description>
- <link>http://www.feedforall.com/computer-service.htm</link>
- <category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category>
- <comments>http://www.feedforall.com/forum</comments>
- <pubDate>Tue, 19 Oct 2004 11:09:07 -0400</pubDate>
- </item>
- <item>
- <title>RSS Solutions for Governments</title>
- <description>FeedForAll helps Governments communicate with the general public about positions on various issues, and keep the community aware of changes in important legislative issues. <b><i><br>
-</b></i><br>
-RSS uses Include:<br>
-<i><font color="#00FF00">Legislative Calendar<br>
-Votes<br>
-Bulletins</i></font></description>
- <link>http://www.feedforall.com/government.htm</link>
- <category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category>
- <comments>http://www.feedforall.com/forum</comments>
- <pubDate>Tue, 19 Oct 2004 11:09:05 -0400</pubDate>
- </item>
- <item>
- <title>RSS Solutions for Politicians</title>
- <description>FeedForAll helps Politicians communicate with the general public about positions on various issues, and keep the community notified of their schedule. <br>
-<br>
-Uses Include:<br>
-<i><font color="#FF0000">Blogs<br>
-Speaking Engagements <br>
-Statements<br>
- </i></font></description>
- <link>http://www.feedforall.com/politics.htm</link>
- <category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category>
- <comments>http://www.feedforall.com/forum</comments>
- <pubDate>Tue, 19 Oct 2004 11:09:03 -0400</pubDate>
- </item>
- <item>
- <title>RSS Solutions for Meteorologists</title>
- <description>FeedForAll helps Meteorologists communicate with the general public about storm warnings and weather alerts, in specific regions. Using RSS meteorologists are able to quickly disseminate urgent and life threatening weather warnings. <br>
-<br>
-Uses Include:<br>
-<i><font color="#0000FF">Weather Alerts<br>
-Plotting Storms<br>
-School Cancellations </i></font></description>
- <link>http://www.feedforall.com/weather.htm</link>
- <category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category>
- <comments>http://www.feedforall.com/forum</comments>
- <pubDate>Tue, 19 Oct 2004 11:09:01 -0400</pubDate>
- </item>
- <item>
- <title>RSS Solutions for Realtors & Real Estate Firms</title>
- <description>FeedForAll helps Realtors and Real Estate companies communicate with clients informing them of newly available properties, and open house announcements. RSS helps to reach a targeted audience and spread the word in an inexpensive, professional manner. <font color="#0000FF"><br>
-</font><br>
-Feeds can be used for:<br>
-<i><font color="#FF0000">Open House Dates<br>
-New Properties For Sale<br>
-Mortgage Rates</i></font></description>
- <link>http://www.feedforall.com/real-estate.htm</link>
- <category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category>
- <comments>http://www.feedforall.com/forum</comments>
- <pubDate>Tue, 19 Oct 2004 11:08:59 -0400</pubDate>
- </item>
- <item>
- <title>RSS Solutions for Banks / Mortgage Companies</title>
- <description>FeedForAll helps <b>Banks, Credit Unions and Mortgage companies</b> communicate with the general public about rate changes in a prompt and professional manner. <br>
-<br>
-Uses include:<br>
-<i><font color="#0000FF">Mortgage Rates<br>
-Foreign Exchange Rates <br>
-Bank Rates<br>
-Specials</i></font></description>
- <link>http://www.feedforall.com/banks.htm</link>
- <category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category>
- <comments>http://www.feedforall.com/forum</comments>
- <pubDate>Tue, 19 Oct 2004 11:08:57 -0400</pubDate>
- </item>
- <item>
- <title>RSS Solutions for Law Enforcement</title>
- <description><b>FeedForAll</b> helps Law Enforcement Professionals communicate with the general public and other agencies in a prompt and efficient manner. Using RSS police are able to quickly disseminate urgent and life threatening information. <br>
-<br>
-Uses include:<br>
-<i><font color="#0000FF">Amber Alerts<br>
-Sex Offender Community Notification <br>
-Weather Alerts <br>
-Scheduling <br>
-Security Alerts <br>
-Police Report <br>
-Meetings</i></font></description>
- <link>http://www.feedforall.com/law-enforcement.htm</link>
- <category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category>
- <comments>http://www.feedforall.com/forum</comments>
- <pubDate>Tue, 19 Oct 2004 11:08:56 -0400</pubDate>
- </item>
- </channel>
+<?xml version="1.0" encoding="windows-1252"?> +<rss version="2.0"> + <channel> + <title>FeedForAll Sample Feed</title> + <description>RSS is a fascinating technology. The uses for RSS are expanding daily. Take a closer look at how various industries are using the benefits of RSS in their businesses.</description> + <link>http://www.feedforall.com/industry-solutions.htm</link> + <category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category> + <copyright>Copyright 2004 NotePage, Inc.</copyright> + <docs>http://blogs.law.harvard.edu/tech/rss</docs> + <language>en-us</language> + <lastBuildDate>Tue, 19 Oct 2004 13:39:14 -0400</lastBuildDate> + <managingEditor>marketing@feedforall.com</managingEditor> + <pubDate>Tue, 19 Oct 2004 13:38:55 -0400</pubDate> + <webMaster>webmaster@feedforall.com</webMaster> + <generator>FeedForAll Beta1 (0.0.1.8)</generator> + <image> + <url>http://www.feedforall.com/ffalogo48x48.gif</url> + <title>FeedForAll Sample Feed</title> + <link>http://www.feedforall.com/industry-solutions.htm</link> + <description>FeedForAll Sample Feed</description> + <width>48</width> + <height>48</height> + </image> + <item> + <title>RSS Solutions for Restaurants</title> + <description><b>FeedForAll </b>helps Restaurant's communicate with customers. Let your customers know the latest specials or events.<br> +<br> +RSS feed uses include:<br> +<i><font color="#FF0000">Daily Specials <br> +Entertainment <br> +Calendar of Events </i></font></description> + <link>http://www.feedforall.com/restaurant.htm</link> + <category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category> + <comments>http://www.feedforall.com/forum</comments> + <pubDate>Tue, 19 Oct 2004 11:09:11 -0400</pubDate> + </item> + <item> + <title>RSS Solutions for Schools and Colleges</title> + <description>FeedForAll helps Educational Institutions communicate with students about school wide activities, events, and schedules.<br> +<br> +RSS feed uses include:<br> +<i><font color="#0000FF">Homework Assignments <br> +School Cancellations <br> +Calendar of Events <br> +Sports Scores <br> +Clubs/Organization Meetings <br> +Lunches Menus </i></font></description> + <link>http://www.feedforall.com/schools.htm</link> + <category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category> + <comments>http://www.feedforall.com/forum</comments> + <pubDate>Tue, 19 Oct 2004 11:09:09 -0400</pubDate> + </item> + <item> + <title>RSS Solutions for Computer Service Companies</title> + <description>FeedForAll helps Computer Service Companies communicate with clients about cyber security and related issues. <br> +<br> +Uses include:<br> +<i><font color="#0000FF">Cyber Security Alerts <br> +Specials<br> +Job Postings </i></font></description> + <link>http://www.feedforall.com/computer-service.htm</link> + <category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category> + <comments>http://www.feedforall.com/forum</comments> + <pubDate>Tue, 19 Oct 2004 11:09:07 -0400</pubDate> + </item> + <item> + <title>RSS Solutions for Governments</title> + <description>FeedForAll helps Governments communicate with the general public about positions on various issues, and keep the community aware of changes in important legislative issues. <b><i><br> +</b></i><br> +RSS uses Include:<br> +<i><font color="#00FF00">Legislative Calendar<br> +Votes<br> +Bulletins</i></font></description> + <link>http://www.feedforall.com/government.htm</link> + <category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category> + <comments>http://www.feedforall.com/forum</comments> + <pubDate>Tue, 19 Oct 2004 11:09:05 -0400</pubDate> + </item> + <item> + <title>RSS Solutions for Politicians</title> + <description>FeedForAll helps Politicians communicate with the general public about positions on various issues, and keep the community notified of their schedule. <br> +<br> +Uses Include:<br> +<i><font color="#FF0000">Blogs<br> +Speaking Engagements <br> +Statements<br> + </i></font></description> + <link>http://www.feedforall.com/politics.htm</link> + <category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category> + <comments>http://www.feedforall.com/forum</comments> + <pubDate>Tue, 19 Oct 2004 11:09:03 -0400</pubDate> + </item> + <item> + <title>RSS Solutions for Meteorologists</title> + <description>FeedForAll helps Meteorologists communicate with the general public about storm warnings and weather alerts, in specific regions. Using RSS meteorologists are able to quickly disseminate urgent and life threatening weather warnings. <br> +<br> +Uses Include:<br> +<i><font color="#0000FF">Weather Alerts<br> +Plotting Storms<br> +School Cancellations </i></font></description> + <link>http://www.feedforall.com/weather.htm</link> + <category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category> + <comments>http://www.feedforall.com/forum</comments> + <pubDate>Tue, 19 Oct 2004 11:09:01 -0400</pubDate> + </item> + <item> + <title>RSS Solutions for Realtors & Real Estate Firms</title> + <description>FeedForAll helps Realtors and Real Estate companies communicate with clients informing them of newly available properties, and open house announcements. RSS helps to reach a targeted audience and spread the word in an inexpensive, professional manner. <font color="#0000FF"><br> +</font><br> +Feeds can be used for:<br> +<i><font color="#FF0000">Open House Dates<br> +New Properties For Sale<br> +Mortgage Rates</i></font></description> + <link>http://www.feedforall.com/real-estate.htm</link> + <category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category> + <comments>http://www.feedforall.com/forum</comments> + <pubDate>Tue, 19 Oct 2004 11:08:59 -0400</pubDate> + </item> + <item> + <title>RSS Solutions for Banks / Mortgage Companies</title> + <description>FeedForAll helps <b>Banks, Credit Unions and Mortgage companies</b> communicate with the general public about rate changes in a prompt and professional manner. <br> +<br> +Uses include:<br> +<i><font color="#0000FF">Mortgage Rates<br> +Foreign Exchange Rates <br> +Bank Rates<br> +Specials</i></font></description> + <link>http://www.feedforall.com/banks.htm</link> + <category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category> + <comments>http://www.feedforall.com/forum</comments> + <pubDate>Tue, 19 Oct 2004 11:08:57 -0400</pubDate> + </item> + <item> + <title>RSS Solutions for Law Enforcement</title> + <description><b>FeedForAll</b> helps Law Enforcement Professionals communicate with the general public and other agencies in a prompt and efficient manner. Using RSS police are able to quickly disseminate urgent and life threatening information. <br> +<br> +Uses include:<br> +<i><font color="#0000FF">Amber Alerts<br> +Sex Offender Community Notification <br> +Weather Alerts <br> +Scheduling <br> +Security Alerts <br> +Police Report <br> +Meetings</i></font></description> + <link>http://www.feedforall.com/law-enforcement.htm</link> + <category domain="www.dmoz.com">Computers/Software/Internet/Site Management/Content Management</category> + <comments>http://www.feedforall.com/forum</comments> + <pubDate>Tue, 19 Oct 2004 11:08:56 -0400</pubDate> + </item> + </channel> </rss>
\ No newline at end of file diff --git a/components/net/tests/parsable_mime/text/xml/rdf_rss.xml b/components/shared/net/tests/parsable_mime/text/xml/rdf_rss.xml index 4c58f82974e..4c58f82974e 100644 --- a/components/net/tests/parsable_mime/text/xml/rdf_rss.xml +++ b/components/shared/net/tests/parsable_mime/text/xml/rdf_rss.xml diff --git a/components/net/tests/parsable_mime/text/xml/rdf_rss_ko_1.xml b/components/shared/net/tests/parsable_mime/text/xml/rdf_rss_ko_1.xml index f6e486c5960..f6e486c5960 100644 --- a/components/net/tests/parsable_mime/text/xml/rdf_rss_ko_1.xml +++ b/components/shared/net/tests/parsable_mime/text/xml/rdf_rss_ko_1.xml diff --git a/components/net/tests/parsable_mime/text/xml/rdf_rss_ko_2.xml b/components/shared/net/tests/parsable_mime/text/xml/rdf_rss_ko_2.xml index be8414382e5..be8414382e5 100644 --- a/components/net/tests/parsable_mime/text/xml/rdf_rss_ko_2.xml +++ b/components/shared/net/tests/parsable_mime/text/xml/rdf_rss_ko_2.xml diff --git a/components/net/tests/parsable_mime/text/xml/rdf_rss_ko_3.xml b/components/shared/net/tests/parsable_mime/text/xml/rdf_rss_ko_3.xml index 5f0f03f1e2d..5f0f03f1e2d 100644 --- a/components/net/tests/parsable_mime/text/xml/rdf_rss_ko_3.xml +++ b/components/shared/net/tests/parsable_mime/text/xml/rdf_rss_ko_3.xml diff --git a/components/net/tests/parsable_mime/text/xml/rdf_rss_ko_4.xml b/components/shared/net/tests/parsable_mime/text/xml/rdf_rss_ko_4.xml index c06a80cf1f8..c06a80cf1f8 100644 --- a/components/net/tests/parsable_mime/text/xml/rdf_rss_ko_4.xml +++ b/components/shared/net/tests/parsable_mime/text/xml/rdf_rss_ko_4.xml diff --git a/components/net/tests/parsable_mime/text/xml/test.xml b/components/shared/net/tests/parsable_mime/text/xml/test.xml index 8fe8c0e91cf..8fe8c0e91cf 100644 --- a/components/net/tests/parsable_mime/text/xml/test.xml +++ b/components/shared/net/tests/parsable_mime/text/xml/test.xml diff --git a/components/net/tests/parsable_mime/unknown/binary_file b/components/shared/net/tests/parsable_mime/unknown/binary_file Binary files differindex ecf3bbcdf3e..ecf3bbcdf3e 100644 --- a/components/net/tests/parsable_mime/unknown/binary_file +++ b/components/shared/net/tests/parsable_mime/unknown/binary_file diff --git a/components/net/tests/parsable_mime/unknown/open_type b/components/shared/net/tests/parsable_mime/unknown/open_type index 9117b12600f..9117b12600f 100644 --- a/components/net/tests/parsable_mime/unknown/open_type +++ b/components/shared/net/tests/parsable_mime/unknown/open_type diff --git a/components/net/tests/parsable_mime/unknown/true_type.ttf b/components/shared/net/tests/parsable_mime/unknown/true_type.ttf Binary files differindex c0142fea093..c0142fea093 100644 --- a/components/net/tests/parsable_mime/unknown/true_type.ttf +++ b/components/shared/net/tests/parsable_mime/unknown/true_type.ttf diff --git a/components/net/tests/parsable_mime/unknown/true_type_collection.ttc b/components/shared/net/tests/parsable_mime/unknown/true_type_collection.ttc index 42d3cef1e6d..42d3cef1e6d 100644 --- a/components/net/tests/parsable_mime/unknown/true_type_collection.ttc +++ b/components/shared/net/tests/parsable_mime/unknown/true_type_collection.ttc diff --git a/components/net/tests/parsable_mime/video/avi/test.avi b/components/shared/net/tests/parsable_mime/video/avi/test.avi Binary files differindex f6cd837a924..f6cd837a924 100644 --- a/components/net/tests/parsable_mime/video/avi/test.avi +++ b/components/shared/net/tests/parsable_mime/video/avi/test.avi diff --git a/components/net/tests/parsable_mime/video/mp4/test.mp4 b/components/shared/net/tests/parsable_mime/video/mp4/test.mp4 Binary files differindex 1fc478842f5..1fc478842f5 100644 --- a/components/net/tests/parsable_mime/video/mp4/test.mp4 +++ b/components/shared/net/tests/parsable_mime/video/mp4/test.mp4 diff --git a/components/net/tests/parsable_mime/video/webm/test.webm b/components/shared/net/tests/parsable_mime/video/webm/test.webm Binary files differindex da946da5290..da946da5290 100644 --- a/components/net/tests/parsable_mime/video/webm/test.webm +++ b/components/shared/net/tests/parsable_mime/video/webm/test.webm diff --git a/components/shared/snapshot/lib.rs b/components/shared/snapshot/lib.rs index 7f0111f7a79..590de3666ad 100644 --- a/components/shared/snapshot/lib.rs +++ b/components/shared/snapshot/lib.rs @@ -87,7 +87,7 @@ pub type IpcSnapshot = Snapshot<IpcSharedMemory>; /// <https://gpuweb.github.io/gpuweb/#abstract-opdef-get-a-copy-of-the-image-contents-of-a-context> #[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)] pub struct Snapshot<T = Data> { - size: Size2D<u64>, + size: Size2D<u32>, /// internal data (can be any format it will be converted on use if needed) data: T, /// RGBA/BGRA (reflect internal data) @@ -97,7 +97,7 @@ pub struct Snapshot<T = Data> { } impl<T> Snapshot<T> { - pub const fn size(&self) -> Size2D<u64> { + pub const fn size(&self) -> Size2D<u32> { self.size } @@ -131,7 +131,7 @@ impl Snapshot<Data> { } /// Returns snapshot with provided size that is black transparent alpha - pub fn cleared(size: Size2D<u64>) -> Self { + pub fn cleared(size: Size2D<u32>) -> Self { Self { size, data: Data::Owned(vec![0; size.area() as usize * 4]), @@ -143,7 +143,7 @@ impl Snapshot<Data> { } pub fn from_vec( - size: Size2D<u64>, + size: Size2D<u32>, format: PixelFormat, alpha_mode: AlphaMode, data: Vec<u8>, @@ -157,7 +157,7 @@ impl Snapshot<Data> { } pub fn from_shared_memory( - size: Size2D<u64>, + size: Size2D<u32>, format: PixelFormat, alpha_mode: AlphaMode, ism: IpcSharedMemory, @@ -177,7 +177,7 @@ impl Snapshot<Data> { /// This is safe if data is owned by this process only /// (ownership is transferred on send) pub unsafe fn from_shared_memory( - size: Size2D<u64>, + size: Size2D<u32>, format: PixelFormat, alpha_mode: AlphaMode, ism: IpcSharedMemory, diff --git a/components/webdriver_server/actions.rs b/components/webdriver_server/actions.rs index f33310ac001..b84cbb4c2f8 100644 --- a/components/webdriver_server/actions.rs +++ b/components/webdriver_server/actions.rs @@ -2,9 +2,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; +use std::thread; use std::time::{Duration, Instant}; -use std::{cmp, thread}; use constellation_traits::EmbedderToConstellationMessage; use embedder_traits::{MouseButtonAction, WebDriverCommandMsg, WebDriverScriptCommand}; @@ -12,10 +12,11 @@ use ipc_channel::ipc; use keyboard_types::webdriver::KeyInputState; use webdriver::actions::{ ActionSequence, ActionsType, GeneralAction, KeyAction, KeyActionItem, KeyDownAction, - KeyUpAction, NullActionItem, PointerAction, PointerActionItem, PointerActionParameters, - PointerDownAction, PointerMoveAction, PointerOrigin, PointerType, PointerUpAction, WheelAction, - WheelActionItem, WheelScrollAction, + KeyUpAction, NullActionItem, PointerAction, PointerActionItem, PointerDownAction, + PointerMoveAction, PointerOrigin, PointerType, PointerUpAction, WheelAction, WheelActionItem, + WheelScrollAction, }; +use webdriver::command::ActionsParameters; use webdriver::error::{ErrorStatus, WebDriverError}; use crate::{Handler, WebElement, wait_for_script_response}; @@ -24,11 +25,32 @@ use crate::{Handler, WebElement, wait_for_script_response}; static POINTERMOVE_INTERVAL: u64 = 17; static WHEELSCROLL_INTERVAL: u64 = 17; -// https://w3c.github.io/webdriver/#dfn-input-source-state +// A single action, corresponding to an `action object` in the spec. +// In the spec, `action item` refers to a plain JSON object. +// However, we use the name ActionItem here +// to be consistent with type names from webdriver crate. +pub(crate) enum ActionItem { + Null(NullActionItem), + Key(KeyActionItem), + Pointer(PointerActionItem), + Wheel(WheelActionItem), +} + +// A set of actions with multiple sources executed within a single tick. +// The order in which they are performed is not guaranteed. +// The `id` is used to identify the source of the actions. +pub(crate) type TickActions = HashMap<String, ActionItem>; + +// Consumed by the `dispatch_actions` method. +pub(crate) type ActionsByTick = Vec<TickActions>; + +/// <https://w3c.github.io/webdriver/#dfn-input-source-state> pub(crate) enum InputSourceState { Null, + #[allow(dead_code)] Key(KeyInputState), Pointer(PointerInputState), + #[allow(dead_code)] Wheel, } @@ -44,13 +66,9 @@ pub(crate) struct PointerInputState { } impl PointerInputState { - pub fn new(subtype: &PointerType) -> PointerInputState { + pub fn new(subtype: PointerType) -> PointerInputState { PointerInputState { - subtype: match subtype { - PointerType::Mouse => PointerType::Mouse, - PointerType::Pen => PointerType::Pen, - PointerType::Touch => PointerType::Touch, - }, + subtype, pressed: HashSet::new(), x: 0.0, y: 0.0, @@ -58,48 +76,44 @@ impl PointerInputState { } } -// https://w3c.github.io/webdriver/#dfn-computing-the-tick-duration -fn compute_tick_duration(tick_actions: &ActionSequence) -> u64 { - let mut duration = 0; - match &tick_actions.actions { - ActionsType::Null { actions } => { - for action in actions.iter() { - let NullActionItem::General(GeneralAction::Pause(pause_action)) = action; - duration = cmp::max(duration, pause_action.duration.unwrap_or(0)); - } - }, - ActionsType::Pointer { - parameters: _, - actions, - } => { - for action in actions.iter() { - let action_duration = match action { - PointerActionItem::General(GeneralAction::Pause(action)) => action.duration, - PointerActionItem::Pointer(PointerAction::Move(action)) => action.duration, - _ => None, - }; - duration = cmp::max(duration, action_duration.unwrap_or(0)); - } - }, - ActionsType::Key { actions: _ } => (), - ActionsType::Wheel { actions } => { - for action in actions.iter() { - let action_duration = match action { - WheelActionItem::General(GeneralAction::Pause(action)) => action.duration, - WheelActionItem::Wheel(WheelAction::Scroll(action)) => action.duration, - }; - duration = cmp::max(duration, action_duration.unwrap_or(0)); +/// <https://w3c.github.io/webdriver/#dfn-computing-the-tick-duration> +fn compute_tick_duration(tick_actions: &TickActions) -> u64 { + // Step 1. Let max duration be 0. + // Step 2. For each action in tick actions: + tick_actions + .iter() + .filter_map(|(_, action_item)| { + // If action object has subtype property set to "pause" or + // action object has type property set to "pointer" and subtype property set to "pointerMove", + // or action object has type property set to "wheel" and subtype property set to "scroll", + // let duration be equal to the duration property of action object. + match action_item { + ActionItem::Null(NullActionItem::General(GeneralAction::Pause(pause_action))) | + ActionItem::Key(KeyActionItem::General(GeneralAction::Pause(pause_action))) | + ActionItem::Pointer(PointerActionItem::General(GeneralAction::Pause( + pause_action, + ))) | + ActionItem::Wheel(WheelActionItem::General(GeneralAction::Pause(pause_action))) => { + pause_action.duration + }, + ActionItem::Pointer(PointerActionItem::Pointer(PointerAction::Move(action))) => { + action.duration + }, + ActionItem::Wheel(WheelActionItem::Wheel(WheelAction::Scroll(action))) => { + action.duration + }, + _ => None, } - }, - } - duration + }) + .max() + .unwrap_or(0) } impl Handler { - // https://w3c.github.io/webdriver/#dfn-dispatch-actions + /// <https://w3c.github.io/webdriver/#dfn-dispatch-actions> pub(crate) fn dispatch_actions( &self, - actions_by_tick: &[ActionSequence], + actions_by_tick: ActionsByTick, ) -> Result<(), ErrorStatus> { // Step 1. Wait for an action queue token with input state. let new_token = self.id_generator.next(); @@ -116,11 +130,8 @@ impl Handler { res } - // https://w3c.github.io/webdriver/#dfn-dispatch-actions-inner - fn dispatch_actions_inner( - &self, - actions_by_tick: &[ActionSequence], - ) -> Result<(), ErrorStatus> { + /// <https://w3c.github.io/webdriver/#dfn-dispatch-actions-inner> + fn dispatch_actions_inner(&self, actions_by_tick: ActionsByTick) -> Result<(), ErrorStatus> { // Step 1. For each item tick actions in actions by tick for tick_actions in actions_by_tick.iter() { // Step 1.2. Let tick duration be the result of @@ -133,19 +144,33 @@ impl Handler { // Step 1.4. Wait for // The user agent event loop has spun enough times to process the DOM events // generated by the last invocation of the dispatch tick actions steps. - // - // To ensure we wait for all events to be processed, only the last event in - // this tick action step holds the message id. - // Whenever a new event is generated, the message id is passed to it. - // - // TO-DO: remove the first match after webdriver_id is implemented in all commands - match tick_actions.actions { - ActionsType::Key { .. } | ActionsType::Wheel { .. } | ActionsType::Null { .. } => { - return Ok(()); - }, - _ => {}, - } + self.wait_for_user_agent_handling_complete(tick_actions)?; + } + // Step 2. Return success with data null. + dbg!("Dispatch actions completed successfully"); + Ok(()) + } + + fn wait_for_user_agent_handling_complete( + &self, + tick_actions: &TickActions, + ) -> Result<(), ErrorStatus> { + // TODO: Add matches! for wheel and key actions + // after implmenting webdriver id for wheel and key events. + let count_non_null_actions_in_tick = tick_actions + .iter() + .filter(|(_, action)| { + matches!(action, ActionItem::Pointer(PointerActionItem::Pointer(_))) + }) + .count(); + + // To ensure we wait for all events to be processed, only the last event + // in each tick action step holds the message id. + // Whenever a new event is generated, the message id is passed to it. + // + // Wait for count_non_null_actions_in_tick number of responses + for _ in 0..count_non_null_actions_in_tick { match self.constellation_receiver.recv() { Ok(response) => { let current_waiting_id = self @@ -165,8 +190,86 @@ impl Handler { }; } - // Step 2. Return success with data null. - dbg!("Dispatch actions completed successfully"); + Ok(()) + } + + /// <https://w3c.github.io/webdriver/#dfn-dispatch-tick-actions> + fn dispatch_tick_actions( + &self, + tick_actions: &TickActions, + tick_duration: u64, + ) -> Result<(), ErrorStatus> { + // Step 1. For each action object in tick actions: + // Step 1.1. Let input_id be the value of the id property of action object. + for (input_id, action) in tick_actions.iter() { + // Step 6. Let subtype be action object's subtype. + // Steps 7, 8. Try to run specific algorithm based on the action type. + match action { + ActionItem::Null(NullActionItem::General(_)) => { + self.dispatch_general_action(input_id); + }, + ActionItem::Key(KeyActionItem::General(_)) => { + self.dispatch_general_action(input_id); + }, + ActionItem::Key(KeyActionItem::Key(KeyAction::Down(keydown_action))) => { + self.dispatch_keydown_action(input_id, keydown_action); + + // Step 9. If subtype is "keyDown", append a copy of action + // object with the subtype property changed to "keyUp" to + // input state's input cancel list. + self.session() + .unwrap() + .input_cancel_list + .borrow_mut() + .push(ActionItem::Key(KeyActionItem::Key(KeyAction::Up( + KeyUpAction { + value: keydown_action.value.clone(), + }, + )))); + }, + ActionItem::Key(KeyActionItem::Key(KeyAction::Up(keyup_action))) => { + self.dispatch_keyup_action(input_id, keyup_action); + }, + ActionItem::Pointer(PointerActionItem::General(_)) => { + self.dispatch_general_action(input_id); + }, + ActionItem::Pointer(PointerActionItem::Pointer(PointerAction::Down( + pointer_down_action, + ))) => { + self.dispatch_pointerdown_action(input_id, pointer_down_action); + + // Step 10. If subtype is "pointerDown", append a copy of action + // object with the subtype property changed to "pointerUp" to + // input state's input cancel list. + self.session().unwrap().input_cancel_list.borrow_mut().push( + ActionItem::Pointer(PointerActionItem::Pointer(PointerAction::Up( + PointerUpAction { + button: pointer_down_action.button, + ..Default::default() + }, + ))), + ); + }, + ActionItem::Pointer(PointerActionItem::Pointer(PointerAction::Move( + pointer_move_action, + ))) => { + self.dispatch_pointermove_action(input_id, pointer_move_action, tick_duration)?; + }, + ActionItem::Pointer(PointerActionItem::Pointer(PointerAction::Up( + pointer_up_action, + ))) => { + self.dispatch_pointerup_action(input_id, pointer_up_action); + }, + ActionItem::Wheel(WheelActionItem::General(_)) => { + self.dispatch_general_action(input_id); + }, + ActionItem::Wheel(WheelActionItem::Wheel(WheelAction::Scroll(scroll_action))) => { + self.dispatch_scroll_action(scroll_action, tick_duration)?; + }, + _ => {}, + } + } + Ok(()) } @@ -181,143 +284,7 @@ impl Handler { // Nothing to be done } - // https://w3c.github.io/webdriver/#dfn-dispatch-tick-actions - fn dispatch_tick_actions( - &self, - tick_actions: &ActionSequence, - tick_duration: u64, - ) -> Result<(), ErrorStatus> { - let source_id = &tick_actions.id; - match &tick_actions.actions { - ActionsType::Null { actions } => { - for _action in actions.iter() { - self.dispatch_general_action(source_id); - } - }, - ActionsType::Key { actions } => { - for action in actions.iter() { - match action { - KeyActionItem::General(_action) => { - self.dispatch_general_action(source_id); - }, - KeyActionItem::Key(action) => { - self.session() - .unwrap() - .input_state_table - .borrow_mut() - .entry(source_id.to_string()) - .or_insert(InputSourceState::Key(KeyInputState::new())); - match action { - KeyAction::Down(action) => { - self.dispatch_keydown_action(source_id, action); - // Step 9. If subtype is "keyDown", append a copy of action - // object with the subtype property changed to "keyUp" to - // input state's input cancel list. - self.session().unwrap().input_cancel_list.borrow_mut().push( - ActionSequence { - id: source_id.into(), - actions: ActionsType::Key { - actions: vec![KeyActionItem::Key(KeyAction::Up( - KeyUpAction { - value: action.value.clone(), - }, - ))], - }, - }, - ); - }, - KeyAction::Up(action) => { - self.dispatch_keyup_action(source_id, action) - }, - }; - }, - } - } - }, - ActionsType::Pointer { - parameters, - actions, - } => { - for action in actions.iter() { - match action { - PointerActionItem::General(_action) => { - self.dispatch_general_action(source_id); - }, - PointerActionItem::Pointer(action) => { - self.session() - .unwrap() - .input_state_table - .borrow_mut() - .entry(source_id.to_string()) - .or_insert(InputSourceState::Pointer(PointerInputState::new( - ¶meters.pointer_type, - ))); - match action { - PointerAction::Cancel => (), - PointerAction::Down(action) => { - self.dispatch_pointerdown_action(source_id, action); - - // Step 10. If subtype is "pointerDown", append a copy of action - // object with the subtype property changed to "pointerUp" to - // input state's input cancel list. - self.session().unwrap().input_cancel_list.borrow_mut().push( - ActionSequence { - id: source_id.into(), - actions: ActionsType::Pointer { - parameters: PointerActionParameters { - pointer_type: parameters.pointer_type, - }, - actions: vec![PointerActionItem::Pointer( - PointerAction::Up(PointerUpAction { - button: action.button, - ..Default::default() - }), - )], - }, - }, - ); - }, - PointerAction::Move(action) => self.dispatch_pointermove_action( - source_id, - action, - tick_duration, - )?, - PointerAction::Up(action) => { - self.dispatch_pointerup_action(source_id, action) - }, - } - }, - } - } - }, - ActionsType::Wheel { actions } => { - for action in actions.iter() { - match action { - WheelActionItem::General(_action) => { - self.dispatch_general_action(source_id) - }, - WheelActionItem::Wheel(action) => { - self.session() - .unwrap() - .input_state_table - .borrow_mut() - .entry(source_id.to_string()) - .or_insert(InputSourceState::Wheel); - match action { - WheelAction::Scroll(action) => { - self.dispatch_scroll_action(action, tick_duration)? - }, - } - }, - } - } - }, - } - - Ok(()) - } - - // https://w3c.github.io/webdriver/#dfn-dispatch-a-keydown-action + /// <https://w3c.github.io/webdriver/#dfn-dispatch-a-keydown-action> fn dispatch_keydown_action(&self, source_id: &str, action: &KeyDownAction) { let session = self.session().unwrap(); @@ -340,7 +307,7 @@ impl Handler { .unwrap(); } - // https://w3c.github.io/webdriver/#dfn-dispatch-a-keyup-action + /// <https://w3c.github.io/webdriver/#dfn-dispatch-a-keyup-action> fn dispatch_keyup_action(&self, source_id: &str, action: &KeyUpAction) { let session = self.session().unwrap(); @@ -393,7 +360,7 @@ impl Handler { .unwrap(); } - // https://w3c.github.io/webdriver/#dfn-dispatch-a-pointerup-action + /// <https://w3c.github.io/webdriver/#dfn-dispatch-a-pointerup-action> pub(crate) fn dispatch_pointerup_action(&self, source_id: &str, action: &PointerUpAction) { let session = self.session().unwrap(); @@ -423,7 +390,7 @@ impl Handler { .unwrap(); } - // https://w3c.github.io/webdriver/#dfn-dispatch-a-pointermove-action + /// <https://w3c.github.io/webdriver/#dfn-dispatch-a-pointermove-action> pub(crate) fn dispatch_pointermove_action( &self, source_id: &str, @@ -738,4 +705,94 @@ impl Handler { None => Err(ErrorStatus::UnknownError), } } + + /// <https://w3c.github.io/webdriver/#dfn-extract-an-action-sequence> + pub(crate) fn extract_an_action_sequence(&self, params: ActionsParameters) -> ActionsByTick { + // Step 1. Let actions be the result of getting a property named "actions" from parameters. + // Step 2 (ignored because params is already validated earlier). If actions is not a list, + // return an error with status InvalidArgument. + let actions = params.actions; + + self.actions_by_tick_from_sequence(actions) + } + + pub(crate) fn actions_by_tick_from_sequence( + &self, + actions: Vec<ActionSequence>, + ) -> ActionsByTick { + // Step 3. Let actions by tick be an empty list. + let mut actions_by_tick: ActionsByTick = Vec::new(); + + // Step 4. For each value action sequence corresponding to an indexed property in actions + for action_sequence in actions { + // Store id before moving action_sequence + let id = action_sequence.id.clone(); + // Step 4.1. Let source actions be the result of trying to process an input source action sequence + let source_actions = self.process_an_input_source_action_sequence(action_sequence); + + // Step 4.2.2. Ensure we have enough ticks to hold all actions + while actions_by_tick.len() < source_actions.len() { + actions_by_tick.push(HashMap::new()); + } + + // Step 4.2.3. + for (tick_index, action_item) in source_actions.into_iter().enumerate() { + actions_by_tick[tick_index].insert(id.clone(), action_item); + } + } + + actions_by_tick + } + + /// <https://w3c.github.io/webdriver/#dfn-process-an-input-source-action-sequence> + pub(crate) fn process_an_input_source_action_sequence( + &self, + action_sequence: ActionSequence, + ) -> Vec<ActionItem> { + // Step 2. Let id be the value of the id property of action sequence. + let id = action_sequence.id.clone(); + + let mut input_state_table = self.session().unwrap().input_state_table.borrow_mut(); + + match action_sequence.actions { + ActionsType::Null { + actions: null_actions, + } => { + input_state_table + .entry(id) + .or_insert(InputSourceState::Null); + null_actions.into_iter().map(ActionItem::Null).collect() + }, + ActionsType::Key { + actions: key_actions, + } => { + input_state_table + .entry(id) + .or_insert(InputSourceState::Key(KeyInputState::new())); + key_actions.into_iter().map(ActionItem::Key).collect() + }, + ActionsType::Pointer { + parameters: _, + actions: pointer_actions, + } => { + input_state_table + .entry(id) + .or_insert(InputSourceState::Pointer(PointerInputState::new( + PointerType::Mouse, + ))); + pointer_actions + .into_iter() + .map(ActionItem::Pointer) + .collect() + }, + ActionsType::Wheel { + actions: wheel_actions, + } => { + input_state_table + .entry(id) + .or_insert(InputSourceState::Wheel); + wheel_actions.into_iter().map(ActionItem::Wheel).collect() + }, + } + } } diff --git a/components/webdriver_server/lib.rs b/components/webdriver_server/lib.rs index eb3e7bf17ec..5d5159f7232 100644 --- a/components/webdriver_server/lib.rs +++ b/components/webdriver_server/lib.rs @@ -64,7 +64,7 @@ use webdriver::response::{ }; use webdriver::server::{self, Session, SessionTeardownKind, WebDriverHandler}; -use crate::actions::{InputSourceState, PointerInputState}; +use crate::actions::{ActionItem, InputSourceState, PointerInputState}; #[derive(Default)] pub struct WebDriverMessageIdGenerator { @@ -171,7 +171,7 @@ pub struct WebDriverSession { input_state_table: RefCell<HashMap<String, InputSourceState>>, /// <https://w3c.github.io/webdriver/#dfn-input-cancel-list> - input_cancel_list: RefCell<Vec<ActionSequence>>, + input_cancel_list: RefCell<Vec<ActionItem>>, } impl WebDriverSession { @@ -1214,6 +1214,28 @@ impl Handler { } } + fn handle_get_shadow_root(&self, element: WebElement) -> WebDriverResult<WebDriverResponse> { + let (sender, receiver) = ipc::channel().unwrap(); + let cmd = WebDriverScriptCommand::GetElementShadowRoot(element.to_string(), sender); + self.browsing_context_script_command(cmd)?; + match wait_for_script_response(receiver)? { + Ok(value) => { + if value.is_none() { + return Err(WebDriverError::new( + ErrorStatus::NoSuchShadowRoot, + "No shadow root found for the element", + )); + } + let value_resp = serde_json::to_value( + value.map(|x| serde_json::to_value(WebElement(x)).unwrap()), + )?; + let shadow_root_value = json!({ SHADOW_ROOT_IDENTIFIER: value_resp }); + Ok(WebDriverResponse::Generic(ValueResponse(shadow_root_value))) + }, + Err(error) => Err(WebDriverError::new(error, "")), + } + } + // https://w3c.github.io/webdriver/webdriver-spec.html#get-element-rect fn handle_element_rect(&self, element: &WebElement) -> WebDriverResult<WebDriverResponse> { let (sender, receiver) = ipc::channel().unwrap(); @@ -1480,20 +1502,22 @@ impl Handler { fn handle_perform_actions( &mut self, - parameters: &ActionsParameters, + parameters: ActionsParameters, ) -> WebDriverResult<WebDriverResponse> { - match self.dispatch_actions(¶meters.actions) { + // Step 5. Let actions by tick be the result of trying to extract an action sequence + let actions_by_tick = self.extract_an_action_sequence(parameters); + + // Step 6. Dispatch actions + match self.dispatch_actions(actions_by_tick) { Ok(_) => Ok(WebDriverResponse::Void), Err(error) => Err(WebDriverError::new(error, "")), } } + /// <https://w3c.github.io/webdriver/#dfn-release-actions> fn handle_release_actions(&mut self) -> WebDriverResult<WebDriverResponse> { - let input_cancel_list = self.session().unwrap().input_cancel_list.borrow(); - if let Err(error) = self.dispatch_actions(&input_cancel_list) { - return Err(WebDriverError::new(error, "")); - } - + // TODO: The previous implementation of this function was different from the spec. + // Need to re-implement this to match the spec. let session = self.session()?; session.input_state_table.borrow_mut().clear(); @@ -1617,14 +1641,23 @@ impl Handler { let (sender, receiver) = ipc::channel().unwrap(); - let cmd = WebDriverScriptCommand::FocusElement(element.to_string(), sender); + let cmd = WebDriverScriptCommand::WillSendKeys( + element.to_string(), + keys.text.to_string(), + self.session()?.strict_file_interactability, + sender, + ); let cmd_msg = WebDriverCommandMsg::ScriptCommand(browsing_context_id, cmd); self.constellation_chan .send(EmbedderToConstellationMessage::WebDriverCommand(cmd_msg)) .unwrap(); // TODO: distinguish the not found and not focusable cases - wait_for_script_response(receiver)?.map_err(|error| WebDriverError::new(error, ""))?; + // File input and non-typeable form control should have + // been handled in `webdriver_handler.rs`. + if !wait_for_script_response(receiver)?.map_err(|error| WebDriverError::new(error, ""))? { + return Ok(WebDriverResponse::Void); + } let input_events = send_keys(&keys.text); @@ -1655,7 +1688,7 @@ impl Handler { // Step 8.1 self.session_mut()?.input_state_table.borrow_mut().insert( id.clone(), - InputSourceState::Pointer(PointerInputState::new(&PointerType::Mouse)), + InputSourceState::Pointer(PointerInputState::new(PointerType::Mouse)), ); // Step 8.7. Construct a pointer move action. @@ -1702,7 +1735,11 @@ impl Handler { }, }; - let _ = self.dispatch_actions(&[action_sequence]); + let actions_by_tick = self.actions_by_tick_from_sequence(vec![action_sequence]); + + if let Err(e) = self.dispatch_actions(actions_by_tick) { + log::error!("handle_element_click: dispatch_actions failed: {:?}", e); + } // Step 8.17 Remove an input source with input state and input id. self.session_mut()? @@ -1921,6 +1958,7 @@ impl WebDriverHandler<ServoExtensionRoute> for Handler { WebDriverCommand::FindElementElements(ref element, ref parameters) => { self.handle_find_elements_from_element(element, parameters) }, + WebDriverCommand::GetShadowRoot(element) => self.handle_get_shadow_root(element), WebDriverCommand::GetNamedCookie(name) => self.handle_get_cookie(name), WebDriverCommand::GetCookies => self.handle_get_cookies(), WebDriverCommand::GetActiveElement => self.handle_active_element(), @@ -1940,7 +1978,9 @@ impl WebDriverHandler<ServoExtensionRoute> for Handler { self.handle_element_css(element, name) }, WebDriverCommand::GetPageSource => self.handle_get_page_source(), - WebDriverCommand::PerformActions(ref x) => self.handle_perform_actions(x), + WebDriverCommand::PerformActions(actions_parameters) => { + self.handle_perform_actions(actions_parameters) + }, WebDriverCommand::ReleaseActions => self.handle_release_actions(), WebDriverCommand::ExecuteScript(ref x) => self.handle_execute_script(x), WebDriverCommand::ExecuteAsyncScript(ref x) => self.handle_execute_async_script(x), diff --git a/ports/servoshell/Cargo.toml b/ports/servoshell/Cargo.toml index aa1e6259a37..034e383c7f0 100644 --- a/ports/servoshell/Cargo.toml +++ b/ports/servoshell/Cargo.toml @@ -90,8 +90,8 @@ hilog = "0.2.0" ipc-channel = { workspace = true, features = ["force-inprocess"] } napi-derive-ohos = "1.0.4" napi-ohos = "1.0.4" -ohos-ime = "0.2" -ohos-ime-sys = "0.1.4" +ohos-ime = "0.4.0" +ohos-ime-sys = "0.2.0" ohos-vsync = "0.1.3" xcomponent-sys = { version = "0.3.1", features = ["api-12", "keyboard-types"] } diff --git a/ports/servoshell/desktop/app.rs b/ports/servoshell/desktop/app.rs index 7bbac47cda3..4f3ce2266c5 100644 --- a/ports/servoshell/desktop/app.rs +++ b/ports/servoshell/desktop/app.rs @@ -42,13 +42,17 @@ pub struct App { preferences: Preferences, servoshell_preferences: ServoShellPreferences, suspended: Cell<bool>, - windows: HashMap<WindowId, Rc<dyn WindowPortsMethods>>, minibrowser: Option<Minibrowser>, waker: Box<dyn EventLoopWaker>, initial_url: ServoUrl, t_start: Instant, t: Instant, state: AppState, + + // This is the last field of the struct to ensure that windows are dropped *after* all other + // references to the relevant rendering contexts have been destroyed. + // (https://github.com/servo/servo/issues/36711) + windows: HashMap<WindowId, Rc<dyn WindowPortsMethods>>, } /// Action to be taken by the caller of [`App::handle_events`]. diff --git a/ports/servoshell/desktop/egui_glue.rs b/ports/servoshell/desktop/egui_glue.rs index 09ef3735cf8..e27a659dd24 100644 --- a/ports/servoshell/desktop/egui_glue.rs +++ b/ports/servoshell/desktop/egui_glue.rs @@ -39,6 +39,7 @@ pub use egui_winit; pub use egui_winit::EventResponse; use egui_winit::winit; use winit::event_loop::ActiveEventLoop; +use winit::window::Theme; /// Use [`egui`] from a [`glow`] app based on [`winit`]. pub struct EguiGlow { @@ -63,6 +64,7 @@ impl EguiGlow { }) .unwrap(); + let theme = event_loop.system_theme().unwrap_or(Theme::Light); let egui_ctx = egui::Context::default(); Self { egui_winit: egui_winit::State::new( @@ -70,7 +72,7 @@ impl EguiGlow { ViewportId::ROOT, event_loop, None, - event_loop.system_theme(), + Some(theme), None, ), egui_ctx, diff --git a/ports/servoshell/desktop/headed_window.rs b/ports/servoshell/desktop/headed_window.rs index 6095b5c02e7..a1c7576a8c9 100644 --- a/ports/servoshell/desktop/headed_window.rs +++ b/ports/servoshell/desktop/headed_window.rs @@ -49,7 +49,6 @@ use crate::desktop::keyutils::CMD_OR_CONTROL; use crate::prefs::ServoShellPreferences; pub struct Window { - winit_window: winit::window::Window, screen_size: Size2D<u32, DeviceIndependentPixel>, inner_size: Cell<PhysicalSize<u32>>, toolbar_height: Cell<Length<f32, DeviceIndependentPixel>>, @@ -72,6 +71,11 @@ pub struct Window { /// The `RenderingContext` of Servo itself. This is used to render Servo results /// temporarily until they can be blitted into the egui scene. rendering_context: Rc<OffscreenRenderingContext>, + + // Keep this as the last field of the struct to ensure that the rendering context is + // dropped first. + // (https://github.com/servo/servo/issues/36711) + winit_window: winit::window::Window, } impl Window { diff --git a/ports/servoshell/egl/app_state.rs b/ports/servoshell/egl/app_state.rs index 486b01060e8..114c9c5f4d0 100644 --- a/ports/servoshell/egl/app_state.rs +++ b/ports/servoshell/egl/app_state.rs @@ -152,6 +152,24 @@ impl WebViewDelegate for RunningAppState { self.callbacks .host_callbacks .notify_load_status_changed(load_status); + + #[cfg(feature = "tracing")] + if load_status == LoadStatus::Complete { + #[cfg(feature = "tracing-hitrace")] + let (snd, recv) = ipc_channel::ipc::channel().expect("Could not create channel"); + self.servo.create_memory_report(snd); + std::thread::spawn(move || { + let result = recv.recv().expect("Could not get memory report"); + let reports = result + .results + .first() + .expect("We should have some memory report"); + for report in &reports.reports { + let path = String::from("servo_memory_profiling:") + &report.path.join("/"); + hitrace::trace_metric_str(&path, report.size as i64); + } + }); + } } fn notify_closed(&self, webview: WebView) { @@ -620,11 +638,27 @@ impl RunningAppState { } pub fn ime_insert_text(&self, text: String) { - self.active_webview() - .notify_input_event(InputEvent::Ime(ImeEvent::Composition(CompositionEvent { + // In OHOS, we get empty text after the intended text. + if text.is_empty() { + return; + } + let active_webview = self.active_webview(); + active_webview.notify_input_event(InputEvent::Keyboard(KeyboardEvent { + state: KeyState::Down, + key: Key::Process, + ..KeyboardEvent::default() + })); + active_webview.notify_input_event(InputEvent::Ime(ImeEvent::Composition( + CompositionEvent { state: CompositionState::End, data: text, - }))); + }, + ))); + active_webview.notify_input_event(InputEvent::Keyboard(KeyboardEvent { + state: KeyState::Up, + key: Key::Process, + ..KeyboardEvent::default() + })); self.perform_updates(); } diff --git a/ports/servoshell/egl/ohos.rs b/ports/servoshell/egl/ohos.rs index ceccbdbe900..a1b76758a9a 100644 --- a/ports/servoshell/egl/ohos.rs +++ b/ports/servoshell/egl/ohos.rs @@ -867,14 +867,14 @@ impl HostTrait for HostCallbacks { let mut ime_proxy = self.ime_proxy.borrow_mut(); let ime = ime_proxy.get_or_insert_with(|| { let attach_options = AttachOptions::new(true); - let editor = RawTextEditorProxy::new(); - let configbuilder = ohos_ime::TextConfigBuilder::new(); let options = convert_ime_options(input_type, multiline); - let text_config = configbuilder + let text_config = ohos_ime::TextConfigBuilder::new() .input_type(options.input_type) .enterkey_type(options.enterkey_type) .build(); - ImeProxy::new(editor, attach_options, Box::new(ServoIme { text_config })) + let editor = RawTextEditorProxy::new(Box::new(ServoIme { text_config })) + .expect("Failed to create RawTextEditorProxy"); + ImeProxy::new(editor, attach_options).expect("Failed to create IME proxy") }); match ime.show_keyboard() { Ok(()) => debug!("IME show keyboard - success"), diff --git a/python/servo/build_commands.py b/python/servo/build_commands.py index e2a5ffc6a1a..e34fa2a2687 100644 --- a/python/servo/build_commands.py +++ b/python/servo/build_commands.py @@ -40,6 +40,7 @@ from servo.platform.build_target import BuildTarget SUPPORTED_ASAN_TARGETS = [ "aarch64-apple-darwin", "aarch64-unknown-linux-gnu", + "aarch64-unknown-linux-ohos", "x86_64-apple-darwin", "x86_64-unknown-linux-gnu", ] @@ -109,6 +110,8 @@ class MachCommands(CommandBase): opts += ["-v"] if very_verbose: opts += ["-vv"] + if with_asan: + self.config["build"]["with_asan"] = True env = self.build_env() self.ensure_bootstrapped() @@ -136,6 +139,10 @@ class MachCommands(CommandBase): opts += ["-Zbuild-std"] kwargs["target_override"] = target_triple + # With asan we also want frame pointers + if "force-frame-pointers" not in env["RUSTFLAGS"]: + env["RUSTFLAGS"] += " -C force-frame-pointers=yes" + # Note: We want to use the same clang/LLVM version as rustc. rustc_llvm_version = get_rustc_llvm_version() if rustc_llvm_version is None: @@ -144,11 +151,14 @@ class MachCommands(CommandBase): target_clang = f"clang-{llvm_major}" target_cxx = f"clang++-{llvm_major}" if shutil.which(target_clang) is None or shutil.which(target_cxx) is None: - raise RuntimeError(f"--with-asan requires `{target_clang}` and `{target_cxx}` to be in PATH") - env.setdefault("TARGET_CC", target_clang) - env.setdefault("TARGET_CXX", target_cxx) - # TODO: We should also parse the LLVM version from the clang compiler we chose. - # It's unclear if the major version being the same is sufficient. + env.setdefault("TARGET_CC", target_clang) + env.setdefault("TARGET_CXX", target_cxx) + else: + # libasan can be compatible across multiple compiler versions and has a + # runtime check, which would fail if we used incompatible compilers, so + # we can try and fallback to the default clang. + env.setdefault("TARGET_CC", "clang") + env.setdefault("TARGET_CXX", "clang++") # We need to use `TARGET_CFLAGS`, since we don't want to compile host dependencies with ASAN, # since that causes issues when building build-scripts / proc macros. @@ -156,7 +166,6 @@ class MachCommands(CommandBase): env.setdefault("TARGET_CXXFLAGS", "") env["TARGET_CFLAGS"] += " -fsanitize=address" env["TARGET_CXXFLAGS"] += " -fsanitize=address" - env["TARGET_LDFLAGS"] = "-static-libasan" # By default build mozjs from source to enable ASAN with mozjs. env.setdefault("MOZJS_FROM_SOURCE", "1") @@ -190,7 +199,9 @@ class MachCommands(CommandBase): built_binary = self.get_binary_path(build_type, asan=with_asan) if not no_package and self.target.needs_packaging(): - rv = Registrar.dispatch("package", context=self.context, build_type=build_type, flavor=flavor) + rv = Registrar.dispatch( + "package", context=self.context, build_type=build_type, flavor=flavor, with_asan=with_asan + ) if rv: return rv diff --git a/python/servo/command_base.py b/python/servo/command_base.py index abd193eda49..f0f28e5488e 100644 --- a/python/servo/command_base.py +++ b/python/servo/command_base.py @@ -305,6 +305,7 @@ class CommandBase(object): self.config["build"].setdefault("incremental", None) self.config["build"].setdefault("webgl-backtrace", False) self.config["build"].setdefault("dom-backtrace", False) + self.config["build"].setdefault("with_asan", False) self.config.setdefault("android", {}) self.config["android"].setdefault("sdk", "") @@ -803,15 +804,16 @@ class CommandBase(object): "--manifest-path", path.join(self.context.topdir, "ports", "servoshell", "Cargo.toml"), ] - if target_override: - args += ["--target", target_override] - elif self.target.is_cross_build(): + + if self.target.is_cross_build(): args += ["--target", self.target.triple()] if type(self.target) in [AndroidTarget, OpenHarmonyTarget]: # Note: in practice `cargo rustc` should just be used unconditionally. assert command != "build", "For Android / OpenHarmony `cargo rustc` must be used instead of cargo build" if command == "rustc": args += ["--lib", "--crate-type=cdylib"] + elif target_override: + args += ["--target", target_override] features = [] diff --git a/python/servo/package_commands.py b/python/servo/package_commands.py index 5e63e6549c0..9bc4d70232d 100644 --- a/python/servo/package_commands.py +++ b/python/servo/package_commands.py @@ -184,6 +184,9 @@ class PackageCommands(CommandBase): "-p", f"buildMode={build_mode}", ] + if with_asan: + hvigor_command.extend(["-p", "ohos-debug-asan=true"]) + # Detect if PATH already has hvigor, or else fallback to npm installation # provided via HVIGOR_PATH if "HVIGOR_PATH" not in env: diff --git a/python/servo/platform/build_target.py b/python/servo/platform/build_target.py index 5f0f500ad58..536b10a8d3d 100644 --- a/python/servo/platform/build_target.py +++ b/python/servo/platform/build_target.py @@ -350,9 +350,8 @@ class OpenHarmonyTarget(CrossBuildTarget): env[f"CXX_{clang_target_triple_underscore}"] = ndk_clangxx # rustc linker env[f"CARGO_TARGET_{rust_target_triple.upper()}_LINKER"] = ndk_clang - # We could also use a cross-compile wrapper - env["RUSTFLAGS"] += f" -Clink-arg=--target={clang_target_triple}" - env["RUSTFLAGS"] += f" -Clink-arg=--sysroot={ohos_sysroot_posix}" + + link_args = ["-fuse-ld=lld", f"--target={clang_target_triple}", f"--sysroot={ohos_sysroot_posix}"] env["HOST_CFLAGS"] = "" env["HOST_CXXFLAGS"] = "" @@ -398,6 +397,49 @@ class OpenHarmonyTarget(CrossBuildTarget): bindgen_extra_clangs_args = bindgen_extra_clangs_args + " " + ohos_cflags_str env[bindgen_extra_clangs_args_var] = bindgen_extra_clangs_args + # On OpenHarmony we add some additional flags when asan is enabled + if config["build"]["with_asan"]: + # Lookup `<sdk>/native/llvm/lib/clang/15.0.4/lib/aarch64-linux-ohos/libclang_rt.asan.so` + lib_clang = llvm_toolchain.joinpath("lib", "clang") + children = [f.path for f in os.scandir(lib_clang) if f.is_dir()] + if len(children) != 1: + raise RuntimeError(f"Expected exactly 1 libclang version: `{children}`") + lib_clang_version_dir = pathlib.Path(children[0]) + libclang_arch = lib_clang_version_dir.joinpath("lib", clang_target_triple).resolve() + libasan_so_path = libclang_arch.joinpath("libclang_rt.asan.so") + libasan_preinit_path = libclang_arch.joinpath("libclang_rt.asan-preinit.a") + if not libasan_so_path.exists(): + raise RuntimeError(f"Couldn't find ASAN runtime library at {libasan_so_path}") + link_args.extend( + [ + "-fsanitize=address", + "--rtlib=compiler-rt", + "-shared-libasan", + str(libasan_so_path), + "-Wl,--whole-archive", + "-Wl," + str(libasan_preinit_path), + "-Wl,--no-whole-archive", + ] + ) + + # Use the clangrt from the NDK to use the same library for both C++ and Rust. + env["RUSTFLAGS"] += " -Zexternal-clangrt" + + asan_compile_flags = ( + " -fsanitize=address -shared-libasan -fno-omit-frame-pointer -fsanitize-recover=address" + ) + + arch_asan_ignore_list = lib_clang_version_dir.joinpath("share", "asan_ignorelist.txt") + if arch_asan_ignore_list.exists(): + asan_compile_flags += " -fsanitize-system-ignorelist=" + str(arch_asan_ignore_list) + else: + print(f"Warning: Couldn't find system ASAN ignorelist at `{arch_asan_ignore_list}`") + env["TARGET_CFLAGS"] += asan_compile_flags + env["TARGET_CXXFLAGS"] += asan_compile_flags + + link_args = [f"-Clink-arg={arg}" for arg in link_args] + env["RUSTFLAGS"] += " " + " ".join(link_args) + def binary_name(self) -> str: return "libservoshell.so" diff --git a/python/wpt/run.py b/python/wpt/run.py index 0901fb546b4..4d221f816e3 100644 --- a/python/wpt/run.py +++ b/python/wpt/run.py @@ -304,5 +304,7 @@ def write_unexpected_only_raw_log( with open(raw_log_file) as input: for line in input.readlines(): data = json.loads(line) - if data["action"] in ["suite_start", "suite_end"] or ("test" in data and data["test"] in tests): + if data["action"] in ["suite_start", "suite_end", "add_subsuite"] or ( + "test" in data and data["test"] in tests + ): output.write(line) diff --git a/servo-tidy.toml b/servo-tidy.toml index f716e85175f..9281d287867 100644 --- a/servo-tidy.toml +++ b/servo-tidy.toml @@ -6,7 +6,7 @@ check-alphabetical-order = true [ignore] # Files that are ignored for all tidy and lint checks. files = [ - "./components/net/tests/parsable_mime/text", + "./components/shared/net/tests/parsable_mime/text", "./resources/hsts_preload.fstmap", "./tests/wpt/meta/MANIFEST.json", "./tests/wpt/mozilla/meta/MANIFEST.json", diff --git a/support/hitrace-bencher/runs.json b/support/hitrace-bencher/runs.json index 2513e3f57d1..63c64f41a66 100644 --- a/support/hitrace-bencher/runs.json +++ b/support/hitrace-bencher/runs.json @@ -25,6 +25,28 @@ "start_fn_partial": "on_surface_created_cb", "end_fn_partial": "PageLoadEndedPrompt" } + ], + "point_filters": [ + { + "name": "Explicit", + "match_str": "explicit" + }, + { + "name": "Resident", + "match_str": "resident" + }, + { + "name": "LayoutThread", + "match_str": "layout-thread" + }, + { + "name": "image-cache", + "match_str": "image-cache" + }, + { + "name": "JS", + "match_str": "js" + } ] }, { @@ -39,7 +61,28 @@ "start_fn_partial": "on_surface_created_cb", "end_fn_partial": "PageLoadEndedPrompt" } + ], + "point_filters": [ + { + "name": "Explicit", + "match_str": "explicit" + }, + { + "name": "Resident", + "match_str": "resident" + }, + { + "name": "LayoutThread", + "match_str": "layout-thread" + }, + { + "name": "image-cache", + "match_str": "image-cache" + }, + { + "name": "JS", + "match_str": "js" + } ] } ] - diff --git a/tests/wpt/include.ini b/tests/wpt/include.ini index 8ea1e50b8d0..2f7cfcbab3f 100644 --- a/tests/wpt/include.ini +++ b/tests/wpt/include.ini @@ -92,8 +92,6 @@ skip: true skip: true [css-scrollbars] skip: true - [css-shadow-parts] - skip: true [css-shapes] skip: true [css-size-adjust] @@ -204,6 +202,8 @@ skip: true skip: false [pointerevents] skip: false +[preload] + skip: false [quirks] skip: false [referrer-policy] diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json index 8830b07e2a8..8c88bd5d094 100644 --- a/tests/wpt/meta/MANIFEST.json +++ b/tests/wpt/meta/MANIFEST.json @@ -761,6 +761,13 @@ {} ] ], + "chrome-420329041-crash.html": [ + "2b236a371e524da0ac5669ad7fc5f45259c089c5", + [ + null, + {} + ] + ], "grid-anchor-center-crash.html": [ "bab4eed6b66dfb846ef451f14ced6eb2a0867cc1", [ @@ -2841,6 +2848,17 @@ ] ] }, + "css-gaps": { + "grid": { + "grid-gap-decorations-041-crash.html": [ + "be3e2280b5f52dcc60a4fe418ae67af3ec23da6b", + [ + null, + {} + ] + ] + } + }, "css-grid": { "abspos": { "abspos-in-flexbox-in-grid-crash.html": [ @@ -3899,6 +3917,13 @@ {} ] ], + "repeated-table-column.html": [ + "0d6a1accfd122c38180f8d20904a7e16a131dd41", + [ + null, + {} + ] + ], "repeated-table-footer-in-caption-nested-multicol.html": [ "d630abe8bbb1e752d3a7c559e4c49864233c44f9", [ @@ -5953,6 +5978,13 @@ ], "scoped": { "crashtests": { + "participating-scope.html": [ + "26979e58458d0a27679f6aa079f38f71eddc03df", + [ + null, + {} + ] + ], "shadow-dom.html": [ "a2faafc1694e15f5c513655e57e320325bd4f45a", [ @@ -6975,13 +7007,6 @@ {} ] ], - "indent-outdent-after-closing-editable-dialog-element.html": [ - "7f73de048d714c99ce47ae4da61d7128e53216e8", - [ - null, - {} - ] - ], "insert-image-with-joining-header-element-and-body.html": [ "cf5b2df225be06c833fea6d3bf2ceab6b1231018", [ @@ -8178,6 +8203,13 @@ {} ] ], + "select-highlight-crash.html": [ + "a45120a245984408b65b1e99f1cfba265dad78fc", + [ + null, + {} + ] + ], "select-listitems-crash.html": [ "cdda243877f1e3c699410dd67e25548880b868b9", [ @@ -8462,6 +8494,13 @@ {} ] ], + "popover-root-crash.html": [ + "86498607730f883920419ac4815dce128196d9f5", + [ + null, + {} + ] + ], "popover-undefined-remove-crash.html": [ "3c273ea6f344d179a3d010d20f0779b3721abb40", [ @@ -23715,6 +23754,13 @@ null, {} ] + ], + "ua-shadow-contents-manual.html": [ + "23908ca927426be40895156d26b94fdbc40b090d", + [ + null, + {} + ] ] }, "images": { @@ -68767,6 +68813,32 @@ {} ] ], + "list-style-applies-to-016.html": [ + "71faf850c98ab9a7d8101f2eb23e01bef697c504", + [ + null, + [ + [ + "/css/reference/single_square_list_marker.xht", + "==" + ] + ], + {} + ] + ], + "list-style-applies-to-017.html": [ + "b5f06365bbe9ddb2749d1bb5bf7c0da4e1559abd", + [ + null, + [ + [ + "/css/reference/single_square_list_marker.xht", + "==" + ] + ], + {} + ] + ], "list-style-image-004.xht": [ "f16fdd9b9444fd8e909ca6bbb2b9233f013408e0", [ @@ -68806,6 +68878,214 @@ {} ] ], + "list-style-image-applies-to-001.xht": [ + "4f533018d84ed9761d14e2cc0f0431b8f517d8c9", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-image-applies-to-ref-1.html", + "==" + ] + ], + {} + ] + ], + "list-style-image-applies-to-002.xht": [ + "1d0534742398aab18dcddcf9457b0beefcdee517", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-image-applies-to-ref-1.html", + "==" + ] + ], + {} + ] + ], + "list-style-image-applies-to-003.xht": [ + "6753ebb2c6638d69cb4dd3b5169f0fe4d61f3d20", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-image-applies-to-ref-1.html", + "==" + ] + ], + {} + ] + ], + "list-style-image-applies-to-004.xht": [ + "750db4a8f671d6487b509ce15640da159aa300b9", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-image-applies-to-ref-1.html", + "==" + ] + ], + {} + ] + ], + "list-style-image-applies-to-005.xht": [ + "3becba1c96ac6b59d5bd5cd03408f36881fa0141", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-image-applies-to-ref-2.html", + "==" + ] + ], + {} + ] + ], + "list-style-image-applies-to-006.xht": [ + "6a3f0685cd891def8ade4f0641d75be346409065", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-image-applies-to-ref-2.html", + "==" + ] + ], + {} + ] + ], + "list-style-image-applies-to-007.xht": [ + "06e0a22520613caadaf9ca4442200c1c295e99e9", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-image-applies-to-ref-1.html", + "==" + ] + ], + {} + ] + ], + "list-style-image-applies-to-008.xht": [ + "36e26233cc500aebd47690ca6340af295dd44397", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-image-applies-to-ref-1.html", + "==" + ] + ], + {} + ] + ], + "list-style-image-applies-to-009.xht": [ + "26df20ea56f15c83a4a43337b348a6cffa469668", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-image-applies-to-ref-1.html", + "==" + ] + ], + {} + ] + ], + "list-style-image-applies-to-010.xht": [ + "f8f0021ace68cf5cba0eedbb42144a14604479ac", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-image-applies-to-ref-1.html", + "==" + ] + ], + {} + ] + ], + "list-style-image-applies-to-012.xht": [ + "9060209849ace281c91dbd6b757efcdf422bc307", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-image-applies-to-ref-1.html", + "==" + ] + ], + {} + ] + ], + "list-style-image-applies-to-013.xht": [ + "72c20d870c59a7aa8e4a95830b37f3e4039b87a3", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-image-applies-to-ref-1.html", + "==" + ] + ], + {} + ] + ], + "list-style-image-applies-to-014.xht": [ + "b0b5aa462b703949b2191a8c24690a8daaaed660", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-image-applies-to-ref-1.html", + "==" + ] + ], + {} + ] + ], + "list-style-image-applies-to-015.xht": [ + "c18eb3dab46e62a0bf715500c022ac143bd5fe2f", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-image-applies-to-ref-1.html", + "==" + ] + ], + {} + ] + ], + "list-style-image-applies-to-016.html": [ + "e79700053dcde5eb60b13ad7559f472c2fb7c299", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-image-applies-to-ref-1.html", + "==" + ] + ], + {} + ] + ], + "list-style-image-applies-to-017.html": [ + "bb20b720d327dbdf475fe28d3b229069f1322827", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-image-applies-to-ref-1.html", + "==" + ] + ], + {} + ] + ], "list-style-position-018.xht": [ "8c3f614beba4d25d1a11396e657499fed5f089b3", [ @@ -68845,6 +69125,214 @@ {} ] ], + "list-style-position-applies-to-001.xht": [ + "aa5bd87601f202131c3b5c3c13797c6d411d48bc", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-position-applies-to-ref-1.html", + "==" + ] + ], + {} + ] + ], + "list-style-position-applies-to-002.xht": [ + "51667f2d5e497d7853d62b5b2bb3560577c1224d", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-position-applies-to-ref-1.html", + "==" + ] + ], + {} + ] + ], + "list-style-position-applies-to-003.xht": [ + "d7725da936a5724502b26cc65678cc49ad1a485e", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-position-applies-to-ref-1.html", + "==" + ] + ], + {} + ] + ], + "list-style-position-applies-to-004.xht": [ + "7806141d7f537c9626daab6216b74cc48ba5accf", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-position-applies-to-ref-1.html", + "==" + ] + ], + {} + ] + ], + "list-style-position-applies-to-005.xht": [ + "97235df74ea91de60f3284b38e3243ac2d715c53", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-position-applies-to-ref-2.html", + "==" + ] + ], + {} + ] + ], + "list-style-position-applies-to-006.xht": [ + "7253af46b8d5fac9fc35197dce7f2fe79b30f525", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-position-applies-to-ref-2.html", + "==" + ] + ], + {} + ] + ], + "list-style-position-applies-to-007.xht": [ + "956fcb6f3b253ca936275f2ad7e02dcababd9ac2", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-position-applies-to-ref-1.html", + "==" + ] + ], + {} + ] + ], + "list-style-position-applies-to-008.xht": [ + "df7c23e38678c20869a83fc49b98c72a528e2054", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-position-applies-to-ref-3.html", + "==" + ] + ], + {} + ] + ], + "list-style-position-applies-to-009.xht": [ + "f981ec2c859db0c40dd0d75c0f95a39779f0d1d0", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-position-applies-to-ref-3.html", + "==" + ] + ], + {} + ] + ], + "list-style-position-applies-to-010.xht": [ + "57881f8d80f0cea3d83d8f10efae284112268739", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-position-applies-to-ref-3.html", + "==" + ] + ], + {} + ] + ], + "list-style-position-applies-to-012.xht": [ + "da9eebf3dcb2475728fda56e8d9a3f40c091ecc7", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-position-applies-to-ref-1.html", + "==" + ] + ], + {} + ] + ], + "list-style-position-applies-to-013.xht": [ + "9237a8d2d748067baa30471cb223c094d28a3220", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-position-applies-to-ref-1.html", + "==" + ] + ], + {} + ] + ], + "list-style-position-applies-to-014.xht": [ + "94847350c8f22d23c1214ff31bba35a83f0b46a1", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-position-applies-to-ref-1.html", + "==" + ] + ], + {} + ] + ], + "list-style-position-applies-to-015.xht": [ + "49f2f09d09ce7cc1fca7360e95dafb0d11692798", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-position-applies-to-ref-4.html", + "==" + ] + ], + {} + ] + ], + "list-style-position-applies-to-016.html": [ + "ea5b43d61129ab75e7f5f21ce95768df0467f147", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-position-applies-to-ref-3.html", + "==" + ] + ], + {} + ] + ], + "list-style-position-applies-to-017.html": [ + "71a2a037ed8a837c91a909709d16e1cc669ae00e", + [ + null, + [ + [ + "/css/CSS2/lists/list-style-position-applies-to-ref-5.html", + "==" + ] + ], + {} + ] + ], "list-style-type-applies-to-001.xht": [ "3b8c9d842df5163c020a4bf2bbb19bad33eb18a9", [ @@ -69001,6 +69489,32 @@ {} ] ], + "list-style-type-applies-to-016.html": [ + "407f426d48af04f02b73860641be6d23299d8aa9", + [ + null, + [ + [ + "/css/reference/single_square_list_marker.xht", + "==" + ] + ], + {} + ] + ], + "list-style-type-applies-to-017.html": [ + "29e450bcbc4b449009c89c6c69538e0d630481f6", + [ + null, + [ + [ + "/css/reference/single_square_list_marker.xht", + "==" + ] + ], + {} + ] + ], "reset-counter-001.xht": [ "e1654073beb97ab8a576de700a7fb57f9a4a704b", [ @@ -136900,6 +137414,35 @@ } ] ], + "corner-shape-img.html": [ + "82662d255623d387080bcc8be2e33570f0ed4c62", + [ + null, + [ + [ + "/css/css-borders/tentative/corner-shape/corner-shape-img-ref.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 64 + ], + [ + 0, + 100 + ] + ] + ] + ] + } + ] + ], "corner-shape-inset-shadow.html": [ "7a83caff70c08b74d5d6c2540684c49f8e893f72", [ @@ -136988,7 +137531,7 @@ ] ], "corner-shape-render-fuzzy.html": [ - "12cd2546bf484282a8cab7163c610b5b88d0b9f8", + "2d4b56f831b91eb70fd44abc02000213664a480b", [ "css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html?border-radius=30%&corner-shape=superellipse(-1.5)&box-shadow=10px%2010px%200%2010px%20black", [ @@ -137250,10 +137793,10 @@ } ], [ - "css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html?corner-shape=superellipse(0.8)&border-radius=40px&border-width=10px&border-left-color=purple", + "css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html?corner-shape=superellipse(0.8)&border-radius=40px&border-width=10px", [ [ - "/css/css-borders/tentative/corner-shape/corner-shape-any-ref.html?corner-shape=superellipse(0.8)&border-radius=40px&border-width=10px&border-left-color=purple", + "/css/css-borders/tentative/corner-shape/corner-shape-any-ref.html?corner-shape=superellipse(0.8)&border-radius=40px&border-width=10px", "==" ] ], @@ -137485,7 +138028,7 @@ ] ], "corner-shape-render-precise.html": [ - "5293589222a3f2d918bdbfeecd11280f667578c2", + "4a0c575b3b7cef4cbfb1dea4efc53ec40e01ef13", [ "css/css-borders/tentative/corner-shape/corner-shape-render-precise.html?border-radius=50%&corner-shape=bevel&box-shadow=10px%2010px%200%2010px%20black", [ @@ -137669,6 +138212,32 @@ } ], [ + "css/css-borders/tentative/corner-shape/corner-shape-render-precise.html?corner-shape=notch&border-radius=30px&border-width=30px", + [ + [ + "/css/css-borders/tentative/corner-shape/corner-shape-any-ref.html?corner-shape=notch&border-radius=30px&border-width=30px", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 180 + ], + [ + 0, + 350 + ] + ] + ] + ] + } + ], + [ "css/css-borders/tentative/corner-shape/corner-shape-render-precise.html?corner-shape=square&border-bottom-left-radius=5px", [ [ @@ -137877,10 +138446,10 @@ } ], [ - "css/css-borders/tentative/corner-shape/corner-shape-render-precise.html?corner-top-left-shape=bevel&border-width=10px&border-color=black", + "css/css-borders/tentative/corner-shape/corner-shape-render-precise.html?corner-top-left-shape=bevel&border-width=10px", [ [ - "/css/css-borders/tentative/corner-shape/corner-shape-any-ref.html?corner-top-left-shape=bevel&border-width=10px&border-color=black", + "/css/css-borders/tentative/corner-shape/corner-shape-any-ref.html?corner-top-left-shape=bevel&border-width=10px", "==" ] ], @@ -138007,10 +138576,10 @@ } ], [ - "css/css-borders/tentative/corner-shape/corner-shape-render-precise.html?corner-top-right-shape=bevel&border-width=10px&border-color=black", + "css/css-borders/tentative/corner-shape/corner-shape-render-precise.html?corner-top-right-shape=bevel&border-width=10px", [ [ - "/css/css-borders/tentative/corner-shape/corner-shape-any-ref.html?corner-top-right-shape=bevel&border-width=10px&border-color=black", + "/css/css-borders/tentative/corner-shape/corner-shape-any-ref.html?corner-top-right-shape=bevel&border-width=10px", "==" ] ], @@ -176879,19 +177448,6 @@ {} ] ], - "flexbox_columns.html": [ - "d39c2db55f2a144e5ab9efa713572bd27da72c07", - [ - null, - [ - [ - "/css/css-flexbox/flexbox_columns-ref.html", - "==" - ] - ], - {} - ] - ], "flexbox_direction-column-reverse.html": [ "8d2cd330e4c65c46a4ff2c8e36811c88c7bdc4e6", [ @@ -186558,6 +187114,21 @@ ] ] }, + "css-forms": { + "datetime-stacking-context.html": [ + "4754cacf09d6cc1c9aaccbb760e32ca8991e6502", + [ + null, + [ + [ + "/css/css-forms/datetime-stacking-context-ref.html", + "==" + ] + ], + {} + ] + ] + }, "css-gaps": { "agnostic": { "gap-decorations-003.html": [ @@ -187383,6 +187954,32 @@ {} ] ], + "grid-gap-decorations-040.html": [ + "4bab26db550308a111608e3b0af6d15735c6d041", + [ + null, + [ + [ + "/css/css-gaps/grid/grid-gap-decorations-040-ref.html", + "==" + ] + ], + {} + ] + ], + "grid-gap-decorations-042.html": [ + "5b2b4936980641296cf1c97f80b4bdbecd19ce2f", + [ + null, + [ + [ + "/css/css-gaps/grid/grid-gap-decorations-042-ref.html", + "==" + ] + ], + {} + ] + ], "grid-gap-decorations-38.html": [ "8b87bcd4860ac50a1c2f3de98cec9599bebb77a3", [ @@ -192381,6 +192978,19 @@ {} ] ], + "grid-item-inline-contribution-004.html": [ + "a4e3cd6f3a47d18efc2a27d1f1e410d5ef92cff5", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "grid-item-margins-and-writing-modes-001.html": [ "5209940a9699d6a108f815f81eb4d3b4527dcf79", [ @@ -211752,6 +212362,37 @@ ] }, "css-masking": { + "animations": { + "clip-path-interpolation-shape-arc-direction-agnostic-radius.html": [ + "aa91e1828a7841c4036f6c2d15639ebd2f1bf4e4", + [ + null, + [ + [ + "/css/css-masking/animations/clip-path-interpolation-shape-arc-direction-agnostic-radius-ref.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 10 + ], + [ + 0, + 360 + ] + ] + ] + ] + } + ] + ] + }, "clip": { "clip-absolute-positioned-001.html": [ "c5b0d9001c442012aea33142d47ca1a8d68e319e", @@ -215146,6 +215787,35 @@ {} ] ], + "clip-path-shape-011.html": [ + "fc1927591e086bf341fcd9fa87a86429e1862053", + [ + null, + [ + [ + "/css/css-masking/clip-path/reference/clip-path-shape-arc-ref.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 64 + ], + [ + 0, + 128 + ] + ] + ] + ] + } + ] + ], "clip-path-shape-foreignobject-non-zero-xy.html": [ "4e221f36e4cb7bc698f1929dcc09096114ab2693", [ @@ -250746,6 +251416,19 @@ {} ] ], + "image-max-width-and-height-behaves-as-auto.html": [ + "dcb00ba6a5cdcc1c310e26792172da0490b927c4", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ], "image-min-max-content-intrinsic-size-change-001.html": [ "b7c57bb7abe161bf66cdec988953ba1d2c0035ab", [ @@ -251815,6 +252498,84 @@ {} ] ], + "responsive-iframe-cross-origin-no-match-element.sub.tentative.html": [ + "08dda4e6b7660bdea83681b52fa15ae93ad32ceb", + [ + null, + [ + [ + "/css/css-sizing/responsive-iframe-unsized-ref.html", + "==" + ] + ], + {} + ] + ], + "responsive-iframe-cross-origin-not-embedded-sized.sub.tentative.html": [ + "d9b33973a04c7eb3f8a4756f4d15fda0970bae0d", + [ + null, + [ + [ + "/css/css-sizing/responsive-iframe-unsized-ref.html", + "==" + ] + ], + {} + ] + ], + "responsive-iframe-cross-origin.sub.tentative.html": [ + "22f6f1d1581af4bc515877dee2f8d119274817e3", + [ + null, + [ + [ + "/css/css-sizing/responsive-iframe-ref.html", + "==" + ] + ], + {} + ] + ], + "responsive-iframe-no-match-element.html": [ + "685eb60f123fb54066cca118ab5cb29cfcd89db9", + [ + null, + [ + [ + "/css/css-sizing/responsive-iframe-unsized-ref.html", + "==" + ] + ], + {} + ] + ], + "responsive-iframe-not-embedded-sized.tentative.html": [ + "0d1f91c5789afd8e9af69c2f19204dc0cae60bf3", + [ + null, + [ + [ + "/css/css-sizing/responsive-iframe-unsized-ref.html", + "==" + ] + ], + {} + ] + ], + "responsive-iframe.tentative.html": [ + "229cf01844968e7aa55c165b128435ea455a40d6", + [ + null, + [ + [ + "/css/css-sizing/responsive-iframe-ref.html", + "==" + ] + ], + {} + ] + ], "slice-intrinsic-size.html": [ "05ce6e46304adda6aab773147e8a32d2564680b6", [ @@ -263486,6 +264247,19 @@ {} ] ], + "text-autospace-edit-001.html": [ + "80c46f54d20ff9249a49d73e55b331a8368df4e1", + [ + null, + [ + [ + "/css/css-text/text-autospace/text-autospace-edit-001-ref.html", + "==" + ] + ], + {} + ] + ], "text-autospace-first-line-001.html": [ "0e0f848b062747e6cb36ec4899d2bbfff10fcb44", [ @@ -263580,6 +264354,19 @@ ], {} ] + ], + "text-autospace-vs-001.html": [ + "31c7bbf6073ffac1f614846c6c033cca7ff7d4b4", + [ + null, + [ + [ + "/css/css-text/text-autospace/text-autospace-vs-001-ref.html", + "==" + ] + ], + {} + ] ] }, "text-encoding": { @@ -272836,6 +273623,19 @@ {} ] ], + "word-break-keep-all-u002d.html": [ + "df3ebb3f22111f4935d3787674a18c7a833083c1", + [ + null, + [ + [ + "/css/css-text/word-break/reference/word-break-keep-all-u002d-ref.html", + "==" + ] + ], + {} + ] + ], "word-break-manual-001.html": [ "09d803b0fc1f75f2f253687c5c9dc3305d77616f", [ @@ -306974,7 +307774,7 @@ ] ], "auto-name-from-id.html": [ - "d3430c93a1d2043146e7205c2734a2b8b19af2e0", + "20080d7623a9ce4880d7a065cf729f0f2b3470e1", [ null, [ @@ -307975,6 +308775,35 @@ } ] ], + "inline-child-with-composited-filter.html": [ + "36ba9803e1edb2c87d8d3e57b5f2589d349df964", + [ + null, + [ + [ + "/css/css-view-transitions/inline-child-with-filter-ref.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 2 + ], + [ + 0, + 2400 + ] + ] + ] + ] + } + ] + ], "inline-child-with-filter.html": [ "61f0f1f6a8c389cd7298c56d8c2e35c3f101027b", [ @@ -308031,7 +308860,7 @@ ] ], "inline-with-offset-from-containing-block.html": [ - "31f8449ff630fe6844eb16b46e445ec840d550d8", + "77fb0570966e47909b7b9d06f1330adcd5233ac8", [ null, [ @@ -308051,7 +308880,7 @@ ], [ 0, - 1500 + 1633 ] ] ] @@ -309600,7 +310429,7 @@ ] ], "nested-exit.tentative.html": [ - "83570762061638bd2a780922e45cf39da100d713", + "847058be2b4a1659fb4d512e0906b55fa96c4a38", [ null, [ @@ -309774,7 +310603,7 @@ ] ], "rounded-border-clipper.html": [ - "239bcdd791db41383dd66765269590d84627a0a3", + "098e5566585930a89378c5a8a6ede536fea9e124", [ null, [ @@ -309902,7 +310731,7 @@ ] ], "new-content-captures-different-size.html": [ - "eeb7347981daac829fd17d85ada19730fe22af32", + "0a754c651ffa2f0e7cbd957ab4ad2b8bb35f2cd2", [ null, [ @@ -309922,7 +310751,7 @@ ], [ 0, - 15000 + 15393 ] ] ] @@ -311275,7 +312104,7 @@ ] ], "pseudo-with-classes-view-transition-group.html": [ - "f9fe20222589283591cee10fa33f88d8d47f15ad", + "14717728b15ec9023a1fdeb0dc41c639588d7fee", [ null, [ @@ -311438,7 +312267,7 @@ ], "scoped": { "nested-scope.html": [ - "9fff44e5e732edd1946adf414a8f23668022edda", + "b9cc25c3338912ae91da453c20924dd5cc90e294", [ null, [ @@ -312471,6 +313300,19 @@ {} ] ], + "height.html": [ + "f608765bcf1f60857bba1ab8a4db820e68577941", + [ + null, + [ + [ + "/css/css-viewport/zoom/green-square-100px.html", + "==" + ] + ], + {} + ] + ], "iframe-zoom-nested.html": [ "9dc99a0fa55ea28e4a7e36ecd90166aef64771fb", [ @@ -312511,7 +313353,7 @@ ] ], "inherited-length.html": [ - "d83111a43528b7f0cf08732084330a43148d998b", + "571b533d5d6fd81ba8a334fa23ed21a120daecc5", [ null, [ @@ -312575,6 +313417,58 @@ {} ] ], + "max-height.html": [ + "6a0dcd826e245f82e76ee2bff177ff0270299701", + [ + null, + [ + [ + "/css/css-viewport/zoom/green-square-100px.html", + "==" + ] + ], + {} + ] + ], + "max-width.html": [ + "b6d4139e30a9754eac02ad85c4348adacf793158", + [ + null, + [ + [ + "/css/css-viewport/zoom/green-square-100px.html", + "==" + ] + ], + {} + ] + ], + "min-height.html": [ + "31a47d92b213baf1fe8ae3d88607b41e29a4c577", + [ + null, + [ + [ + "/css/css-viewport/zoom/green-square-100px.html", + "==" + ] + ], + {} + ] + ], + "min-width.html": [ + "bd1cda23d3a3b0d0197c63ea536b2b5c85d2b66f", + [ + null, + [ + [ + "/css/css-viewport/zoom/green-square-100px.html", + "==" + ] + ], + {} + ] + ], "relative-units-from-parent.html": [ "57df82b6f1c5b8cd9ef405cdc1097826de0e061f", [ @@ -323706,6 +324600,19 @@ {} ] ], + "orthogonal-cell-001.html": [ + "12e996ac902b138e53936f39f7c2237978f9a1ae", + [ + null, + [ + [ + "/css/css-writing-modes/orthogonal-cell-001-ref.html", + "==" + ] + ], + {} + ] + ], "orthogonal-child-with-border.html": [ "877cce5a710f5f5e613c02f581c216070fdd0f41", [ @@ -339456,6 +340363,19 @@ {} ] ], + "visited-nested.html": [ + "57220446c8688a3a12fcb36aeb00b904c901fd3d", + [ + null, + [ + [ + "/css/selectors/visited-nested-ref.html", + "==" + ] + ], + {} + ] + ], "xml-class-selector.xml": [ "5666c0065d6262e0ca3c586d145a67e7f9c2a3cf", [ @@ -339469,20 +340389,7 @@ {} ] ] - }, - "visited-nested.html": [ - "57220446c8688a3a12fcb36aeb00b904c901fd3d", - [ - null, - [ - [ - "/css/visited-nested-ref.html", - "==" - ] - ], - {} - ] - ] + } }, "custom-elements": { "form-associated": { @@ -351498,6 +352405,32 @@ {} ] ], + "size-with-color-or-noshade.html": [ + "db1d583934e6df482cde846eda757e010e7d0310", + [ + null, + [ + [ + "/html/rendering/non-replaced-elements/the-hr-element-0/size-with-color-or-noshade-ref.html", + "==" + ] + ], + {} + ] + ], + "size.html": [ + "2162131b853ed77917ab373f4fb2c70c536e453c", + [ + null, + [ + [ + "/html/rendering/non-replaced-elements/the-hr-element-0/size-ref.html", + "==" + ] + ], + {} + ] + ], "width.html": [ "a436d2ae25a6b03f320bda066f32c374b84e0d92", [ @@ -356825,6 +357758,34 @@ {} ] ], + "permission-icon": { + "icon-hidden-reftest.html": [ + "79055da1badfc827e5cc02ed3be7db3842b49855", + [ + null, + [ + [ + "/html/semantics/permission-element/permission-icon/standard-location-permission-element-ref.html", + "!=" + ] + ], + {} + ] + ], + "icon-unique-per-type-reftest.html": [ + "d51b1c4d398a42c8e59f047c0e457c533eae16ee", + [ + null, + [ + [ + "/html/semantics/permission-element/permission-icon/standard-location-permission-element-ref.html", + "!=" + ] + ], + {} + ] + ] + }, "pseudo-elements-in-div.tentative.html": [ "24a2be07fabae34fd969fa89c233b2a209c0c08f", [ @@ -364728,6 +365689,19 @@ {} ] ], + "image-modify-href-4.svg": [ + "f7e550e5defb0b1eba85edad430b0cef760223e6", + [ + null, + [ + [ + "/svg/embedded/reference/green-rect-100x100.svg", + "==" + ] + ], + {} + ] + ], "image-remove-href-1.svg": [ "f35fa08f561dc38363d5c83918ec789fbc523b60", [ @@ -376553,6 +377527,10 @@ [] ], "permissions-policy": { + "WEB_FEATURES.yml": [ + "da7599308cc01a95696e952d02553df47ba3f6bf", + [] + ], "ch-ua-high-entropy-values-disabled-by-permissions-policy.https.sub.html.headers": [ "fcf474880843e220faff943f8946f83b514208a4", [] @@ -395794,7 +396772,7 @@ ], "resources": { "container-timing-helpers.js": [ - "a80ad964fef311f55062631d5548a6d8f0eecb3f", + "8b3f21dff56f9cef78b8a7c4df785a5b366034e5", [] ], "square100.png": [ @@ -397312,7 +398290,7 @@ [] ], "script-src-strict_dynamic_parser_inserted.html.headers": [ - "b7918c93323eff9db66ad26a73b78798d35e5f7b", + "9d0b3b93d44db43be7d19c34483bc1e63ef777a0", [] ], "script-src-strict_dynamic_parser_inserted_correct_nonce.html.headers": [ @@ -397723,7 +398701,7 @@ }, "cookie-store": { "META.yml": [ - "68c30024552f526e2d34f42eb22416ac3b585114", + "4bbc6311bdceece7580ba9c38344081e0b4aba57", [] ], "README.md": [ @@ -397736,7 +398714,7 @@ [] ], "cookie-test-helpers.js": [ - "8e23ff2c4225da41788542908fae6593860146ce", + "82ca135f88e423440c3c3fd2bb02df4ed39aa436", [] ], "cookie_helper.py": [ @@ -405046,6 +406024,14 @@ "e73b120d2b33e01f8eb6a65bacdaef86d4c69cf3", [] ], + "list-style-image-applies-to-ref-1.html": [ + "3895bcc91974c1f511fa5932c08c3080d16303a2", + [] + ], + "list-style-image-applies-to-ref-2.html": [ + "6d7a9d5b35e50d9c83948b2a4863e52cb824b2e6", + [] + ], "list-style-position-018-ref.xht": [ "f12226453602f4ffb50b72493d167ae66aea4d6f", [] @@ -405058,6 +406044,26 @@ "dd988a747101471b55e575922d77efcdf5594887", [] ], + "list-style-position-applies-to-ref-1.html": [ + "a879e21ba440ba9e850d06597f35f48c1b61a0b3", + [] + ], + "list-style-position-applies-to-ref-2.html": [ + "fc0fee30ab685f092ac36a3021f1cebeb0def1f0", + [] + ], + "list-style-position-applies-to-ref-3.html": [ + "6e1af0004c377e26cd93417ea735e56105252908", + [] + ], + "list-style-position-applies-to-ref-4.html": [ + "bb39e6b44acca5008811359a2ae9cb5e1b75f7ef", + [] + ], + "list-style-position-applies-to-ref-5.html": [ + "05012d42540a807ee3292b7ee653351ece676d37", + [] + ], "support": { "1x1-green.png": [ "b98ca0ba0a03c580ac339e4a3653539cfa8edc71", @@ -418479,6 +419485,10 @@ "1eb6cbd8df349f0a27b1575b8a77583c95b44a42", [] ], + "corner-shape-img-ref.html": [ + "565698f79ec3fe89a9078a2c6277b38f494dfd99", + [] + ], "corner-shape-inset-shadow-ref.html": [ "fa36c9d6ecc527fee37bb589c3c5194df1ff2291", [] @@ -418497,11 +419507,11 @@ ], "resources": { "corner-shape.js": [ - "4757a43ad051f42a88ddefeba344bcea0b9a0149", + "c08a95c7d7511e84eb92015d13578e23ad2f2ec5", [] ], "corner-utils.js": [ - "ad3b235addff11e418d78e372b20c09a2ebd4a19", + "b6f329e82484f14f853c999dbd99a15771db1e8d", [] ], "resolve-corner-style.js": [ @@ -423743,10 +424753,6 @@ "3c8e1f475a337e111b7290465b67ede2b35ac4bb", [] ], - "flexbox_columns-ref.html": [ - "b8c7a22569882c3687441af49ed683dcc37634bd", - [] - ], "flexbox_direction-column-ref.html": [ "9b91d50345528741a8cf3d889bc8212282e678cb", [] @@ -432682,6 +433688,12 @@ ] } }, + "css-forms": { + "datetime-stacking-context-ref.html": [ + "95bee383d2117d1c054e4706abfd130149d31fc8", + [] + ] + }, "css-gaps": { "agnostic": { "gap-decorations-001-ref.html": [ @@ -432911,6 +433923,14 @@ "grid-gap-decorations-037-ref.html": [ "4a2ee5bd5c6fbdb25e5a70eac56a9b0bbac5d56f", [] + ], + "grid-gap-decorations-040-ref.html": [ + "2988cf534a969828f1e0b9756a8bf52747966ee8", + [] + ], + "grid-gap-decorations-042-ref.html": [ + "ed44f7a2de37d31d57391731b2b8d7f7886790ad", + [] ] }, "multicol": { @@ -437413,6 +438433,10 @@ "WEB_FEATURES.yml": [ "758ef35275eeacc96b6e584f672f86c4b170e0e1", [] + ], + "clip-path-interpolation-shape-arc-direction-agnostic-radius-ref.html": [ + "2869d38a982b23d72ae49543d16d01bda6f28b21", + [] ] }, "clip": { @@ -437823,6 +438847,10 @@ "b74e6abdd9e7c02adf5392f02854ee61f05bc38f", [] ], + "clip-path-shape-arc-ref.html": [ + "9cbe55de210580ce38096bf106493d10f33dc7cd", + [] + ], "clip-path-shape-control-points-ref.html": [ "ebcc87bcf6482b22974787ae80df052b0c67ee02", [] @@ -438436,7 +439464,7 @@ [] ], "column-height-009-ref.html": [ - "034440ebd5c81be43f0d871d3adb276b2a735768", + "4696d79695bdd6a5901e4d0d00fffc4935438163", [] ], "column-pseudo-background-color-ref.html": [ @@ -441818,6 +442846,10 @@ ] }, "overlay": { + "WEB_FEATURES.yml": [ + "a1a4402ee421efa24e9b02a2337c90812759a4e2", + [] + ], "green-ref.html": [ "bef7405e96f8181f88fb073ebd212b4af6382e33", [] @@ -445127,6 +446159,24 @@ "11afa34a654ec071c00971b11a2261ff95397904", [] ], + "resources": { + "iframe-contents-unsized.html": [ + "db1931a27d5a7ff84d30edf370688d0c33b139b9", + [] + ], + "iframe-contents.html": [ + "3b7406e1e4064bc0f9f829907bfe462c8b6d3891", + [] + ] + }, + "responsive-iframe-ref.html": [ + "c446474f71a9e0f443ef7f57226a16a1d25f8444", + [] + ], + "responsive-iframe-unsized-ref.html": [ + "2fa633e086dceeb9e05063eb92783295351b4d44", + [] + ], "slice-intrinsic-size-ref.html": [ "ca4887af7a862b6629a579b306638263ca5192b3", [] @@ -448188,6 +449238,10 @@ "d26fae09b03fc19fc561abcc4ab4487b3be91b3f", [] ], + "text-autospace-edit-001-ref.html": [ + "ca95e197462730462dbd403871173d6b9873c3b0", + [] + ], "text-autospace-first-line-001-ref.html": [ "4adf09f200df40141453a89171fa1392740cfbd3", [] @@ -448219,6 +449273,10 @@ "text-autospace-vertical-upright-001-ref.html": [ "1c9caec112a3f9e132a8b612f748a23556a56de2", [] + ], + "text-autospace-vs-001-ref.html": [ + "b02b4f7a20deeffd4f72b8ed8aa5103e3e2e6518", + [] ] }, "text-encoding": { @@ -449599,6 +450657,10 @@ "cbfd3476089a962634e21ead1122f105f3f58c92", [] ], + "word-break-keep-all-u002d-ref.html": [ + "4a6553cfe838e41c67f0ccaa9d7e04b6904a1e62", + [] + ], "word-break-manual-001-ref.html": [ "f51208ab95fd4aaa804684673f09acf1492ded4d", [] @@ -454721,6 +455783,10 @@ "bf99b25f76b176520715a245ef3abf01258fdc5a", [] ], + "inline-child-with-composited-filter-ref.html": [ + "9dd26f2c3b1afb49d60bedb5e721dcb1f193d423", + [] + ], "inline-child-with-filter-ref.html": [ "44a41f1bf93366e06f2eae0cbfcd4acb126d192f", [] @@ -454884,7 +455950,7 @@ [] ], "auto-name-from-id.html": [ - "71ea52a273e3fca98440cdefc50c77c722663a21", + "dc2cf8fd29b2cf46e1c4c57aa2c34f6272a51b20", [] ], "chromium-paint-holding-timeout.html": [ @@ -454998,7 +456064,7 @@ ], "resources": { "compute-common.css": [ - "20337ccce5f3387e7e70e6fb219544369b74aa06", + "d8f46179b40fd8d55b2bdc125a04cf26aadf0fba", [] ], "compute-test.js": [ @@ -455279,7 +456345,7 @@ [] ], "nested-scope-ref.html": [ - "804741cd6db993392ba8785e8c87f9c16894af41", + "951c0928687dcd6edb32e8e3aa7307bf3d6b3923", [] ] }, @@ -456091,6 +457157,10 @@ "28f0e333282a714715f8e593ac810ff3704d029e", [] ], + "orthogonal-cell-001-ref.html": [ + "f50121ef16d240e2991a9626b1dfe4e72a893fb3", + [] + ], "orthogonal-containing-block-height-changes-ref.html": [ "b7d32e4dc27ba972345f6dc9be81b4079ed54574", [] @@ -460673,6 +461743,10 @@ "64300b13f4291f416eac17f70ff62e2febf604fe", [] ], + "visited-nested-ref.html": [ + "22f4ecf0d7bbcef307fd679ae0905f9b5318f690", + [] + ], "xml-class-selector-ref.xml": [ "6b44280737ab254649036ff50808b764bc87cc67", [] @@ -460923,11 +461997,7 @@ "e7775276038f307b7cdb0a75d19ee24f67619c2a", [] ] - }, - "visited-nested-ref.html": [ - "22f4ecf0d7bbcef307fd679ae0905f9b5318f690", - [] - ] + } }, "custom-elements": { "META.yml": [ @@ -466607,7 +467677,7 @@ ], "resources": { "fetch-private-http.html": [ - "e372d90b26a02bdfa0b9a34c9c8ad956b5d0cc02", + "517629b758e89d4e07f2278d0ae7cb1a45b19c17", [] ], "fetch-private.html": [ @@ -466615,7 +467685,7 @@ [] ], "fetch-public-http-wrong-address-space.html": [ - "1d149d00cb351b9aaa4402b9b8b7d975d56a9acb", + "c15a87ff7b9206576710b5763a64ac6a9a704d71", [] ], "support.sub.js": [ @@ -479883,6 +480953,14 @@ "5cd35c83ada3470ad7a16d14a5028b01596bb60c", [] ], + "size-ref.html": [ + "03a21eb45737ef46247d8bdd61fe5ea0dcefef3e", + [] + ], + "size-with-color-or-noshade-ref.html": [ + "d6300e250d97d113e9ef358daa300de4bd593850", + [] + ], "width-ref.html": [ "71e7651c1ab6927f1be436ef8ff749f920924562", [] @@ -482744,6 +483822,12 @@ "8b48bb93febed1c7fd88f62fe747b3379b349e22", [] ], + "permission-icon": { + "standard-location-permission-element-ref.html": [ + "15ffe751c51b3f8caeaa8b93f1286a3950c9a815", + [] + ] + }, "pseudo-elements-in-div-ref.html": [ "8e6267f9aa350333cef620d248dfce40b85b43e2", [] @@ -486210,7 +487294,7 @@ "system-state-and-capabilities": { "the-navigator-object": { "WEB_FEATURES.yml": [ - "a1af3e21a48f5941a078209963d1ae7bc379dd59", + "7a364e140958e3cea3be9fd13654afc504006664", [] ], "resources": { @@ -488484,6 +489568,10 @@ "6f93db15a74e052913a277e5130226280a3f9311", [] ], + "scoped-custom-elements-registry.idl": [ + "46ca2d6b9c45805d8aa684af7fe91af6dd5d7919", + [] + ], "screen-capture.idl": [ "db9282ce0a57bb3b84ea45f5ed2d7e69bc3a8a32", [] @@ -489198,6 +490286,10 @@ "10c6aa36cecf918928298102d1934c2ff79d01f2", [] ], + "WEB_FEATURES.yml": [ + "335b072c1868c1817dbe7ed6c1901907aa8decbc", + [] + ], "resources": { "slow-image.py": [ "d9f09b8bca78dd1e054fdfcb108fe9066a31db3b", @@ -489214,7 +490306,7 @@ } }, "lint.ignore": [ - "10b5dadba749857f16dc92f348fff31b4400dca3", + "60b0f65a6f43a560c5d86ffe937359d5c9717597", [] ], "loading": { @@ -492288,7 +493380,7 @@ [] ], "nel.sub.js": [ - "26ddd897c2fb72b3e48fe572bcfba745729ddfe1", + "f9dfec1dad8c774e2dc04ff7787edaab3554cc96", [] ], "no-policy-pass.png": [ @@ -497060,6 +498152,10 @@ "edb4759954d4c3829ddc0aa2ecac84ef7d241e37", [] ], + "testdriver-actions.js.headers": [ + "5e8f640c6659d176eaca4c71cc1798b7285540b7", + [] + ], "testdriver-vendor.js": [ "3e88403636396c439759705c751433b28e05f3ab", [] @@ -501328,13 +502424,23 @@ [] ], "soft-navigation-helper.js": [ - "48e7b58d8d1a6a0f05a5c4e30efc3faca83eedaf", + "5860738225b8ed03a2063b1c2b9eef7884f33ee5", [] ], "soft-navigation-test-helper.js": [ "a572f55e66dbce825d399f61c4a2dfa34df9b4ca", [] ] + }, + "smoke": { + "tentative": { + "resources": { + "other_window.html": [ + "406d39c3691853a03731287b2a02f215dcbf721c", + [] + ] + } + } } }, "speculation-rules": { @@ -501383,13 +502489,17 @@ [] ], "executor.sub.html": [ - "bb2d58dc9c9cfac6d98380b0b587bc242fbd5e11", + "b89c45e4f5c25b274925afd6569d6384d5183fe4", [] ], "executor.sub.html.headers": [ "4030ea1d3ddb186a2b5361eb1a3f2404a45531fc", [] ], + "post-navigation-handler.py": [ + "1749517710ed19eda399f01321e1ffcedfc9b09b", + [] + ], "prefetch.py": [ "14ac4d1699ea0c52ac4b40f0a4a0f71c99147073", [] @@ -501610,6 +502720,10 @@ "10a48df58cf9dd9f13eca87e69c54098af1b64b0", [] ], + "image-with-headers-stash.py": [ + "dcb8838d4a167d91ded325e7d3fc6b50055c7746", + [] + ], "indexedb-utils.js": [ "7c57000d5cf48a3bbf74c0b0d8f812922f0575ef", [] @@ -513897,7 +515011,7 @@ [] ], "base.py": [ - "7cea14c7a44b04b1174949816a29bd7d30ef8b16", + "707b539ec769696948b6ee9e4c35991b1f1afad8", [] ], "bufferhandler.py": [ @@ -515242,11 +516356,11 @@ [] ], "firefox_android.py": [ - "7bb2e57d417941bbb1710d6c11b8412f45d6fa7d", + "d0cd7411af0e29a14a3d2e7dfb955988f8a875f1", [] ], "headless_shell.py": [ - "b6f7a40f8a92c347add74a5f69f9996107df46cc", + "ccd5620365a03a2a6543087f6046086f1cc7a52c", [] ], "ladybird.py": [ @@ -515272,11 +516386,11 @@ ] }, "servo.py": [ - "266aec8fced6eb4cc5ca12a15cb8d938220e65ed", + "07441780ccc7682c6b7616271aeb9a40310a433a", [] ], "servodriver.py": [ - "5011a8fd8592d32af1a8313dd4ba6535a9cc384a", + "f72f2257a3817e33817dc7a190da8e61cf6442da", [] ], "webkit.py": [ @@ -515322,7 +516436,7 @@ [] ], "executorchrome.py": [ - "1e588d5bfbfd26334fbcf980e0fe8f0bea804f87", + "3284e6c8091b7c17ebe6fe158ba4ff09afb628da", [] ], "executoredge.py": [ @@ -515497,7 +516611,7 @@ [] ], "testrunner.py": [ - "19c814bb6c94fb11ddd2b132cf5d156e58956c7b", + "be310944fd878b4bcf74e6f052e2a8cc99d3e157", [] ], "tests": { @@ -516192,7 +517306,7 @@ ], "resources": { "block-text-node-insertion.js": [ - "e9797756417e1c2a42158edab6bb25b37e7d518a", + "dd85483a44fa4df26a2f890f06416b6ab5babca8", [] ] }, @@ -516571,6 +517685,10 @@ "META.yml": [ "c994748e0f27bcc75019ad7a20816ee138d15f91", [] + ], + "WEB_FEATURES.yml": [ + "2d331cf4060d293c912f564e28b8fff089cfeb09", + [] ] }, "uievents": { @@ -517255,6 +518373,10 @@ "b92b53ee45cd98933a3c2fbcf404478eb8f66a06", [] ], + "urlpattern-generate-test-data.json": [ + "c118f0a73b5fe108ab1a1f39d41148648daa7baa", + [] + ], "urlpattern-hasregexpgroups-tests.js": [ "4be886e4a5390d7d43356d853cc00c7bbb23d361", [] @@ -524436,6 +525558,10 @@ "58ee7cca1ab3e9856e380eaccde042d5700c2603", [] ], + "WEB_FEATURES.yml": [ + "1687ef742e2b51872debc6da074022449c2215df", + [] + ], "Worker-creation-happens-in-parallel.https.html.headers": [ "4b06ac7cc63e8af6f7d6a882b960184c9a4ea281", [] @@ -525631,6 +526757,14 @@ "b73781244ebd3fcad445f0227e33411ac08a5205", [] ] + }, + "tentative": { + "resources": { + "shared-worker-memory.js": [ + "b1504f38c504c0003d2aa179cfae5702ab318563", + [] + ] + } } }, "worklets": { @@ -568178,6 +569312,13 @@ {} ] ], + "containertiming-with-child-ignore-and-child-img.html": [ + "b4fa9754c1025e255a678d298d3c3db1c30c2b4c", + [ + null, + {} + ] + ], "containertiming-with-child-img.html": [ "03f0e113902d0d4117a38870dfd22defe99c4653", [ @@ -568192,6 +569333,20 @@ {} ] ], + "containertiming-with-ignore-and-child-img.html": [ + "20e9e4a92180d36c3a4130139330ea3229227105", + [ + null, + {} + ] + ], + "ignore-with-containertiming-and-child-img.html": [ + "841b4441d4df846317c246a461022cffe875fab3", + [ + null, + {} + ] + ], "img-not-child-of-container-timing.html": [ "751342a7ceb1eaa2a98d1c07dc4000c34d14e4fd", [ @@ -568648,7 +569803,7 @@ ] ], "default-src-sri_hash.sub.html": [ - "87fce5961fd1854303377ee939b21b6275b312cf", + "87389c306a53fdffa9806ba05f08a097713bcc37", [ null, {} @@ -573246,7 +574401,7 @@ ] ], "script-src-sri_hash.sub.html": [ - "9216e2b0d4971fc46d0010e8dfa7375845187a8d", + "e290911183d0b9a5dccf4a6a2eaa3b12ee25c682", [ null, {} @@ -573351,7 +574506,7 @@ ] ], "script-src-strict_dynamic_parser_inserted.html": [ - "c5e33dc4253dbf3ce2b0c6cb2fca4b0306d68244", + "9a8ad7a4ef2b5592af70d4dcc56f291e75da8e1b", [ null, {} @@ -575838,7 +576993,7 @@ ] ], "cookieStore_special_names.https.any.js": [ - "e2a3df7fe33f3d4325cb1f602d5582dba97da627", + "1e12674a7f7ce9b1fbc5aa46e53be9c6bc08c084", [ "cookie-store/cookieStore_special_names.https.any.html", { @@ -575926,7 +577081,7 @@ ] ], "encoding.https.any.js": [ - "941639bdaec01d0eb619a5850b1d878bdf77f695", + "f5d2ca15e717a0837f1e08031ab682db5aa965ea", [ "cookie-store/encoding.https.any.html", { @@ -575967,7 +577122,7 @@ ] ], "httponly_cookies.https.window.js": [ - "605e94e67440aaedbcaa39f185270fe77b316ad3", + "836f47da3f6e0f8f2c89445d1b2fbdfdf9ddc9e6", [ "cookie-store/httponly_cookies.https.window.html", { @@ -579951,7 +581106,7 @@ ] ], "anchor-scope-basic.html": [ - "47cb3b8d86a106f37af3e32149b79fbd9c8c2056", + "ffe3b45ba0de4d119576bc8b2d307ed55c9ea7f0", [ null, {} @@ -585012,7 +586167,7 @@ ] ], "parsing.html": [ - "2447891f2c4b163cc30eaaa2c6542d9a80a2b4cf", + "688043039de4c9a3d9ee58480a3185509ce72814", [ null, {} @@ -586103,6 +587258,13 @@ {} ] ], + "style-query-registered-custom-rem-change.html": [ + "33808fbe198935daf3ad4efc769483cfbc625c8e", + [ + null, + {} + ] + ], "style-query-unset-on-root.html": [ "89c5cc038a8f1fcee5f0fd0de116c679c666788b", [ @@ -595126,8 +596288,15 @@ {} ] ], + "HighlightRegistry-highlightsFromPoint-ranges.html": [ + "24cf8aa6dfec302877e445ebf81dca76357cea06", + [ + null, + {} + ] + ], "HighlightRegistry-highlightsFromPoint.html": [ - "5bb81bea69ac5960db16e3f9ec3bb208f43a7200", + "5b4e7704a4df5c01d3effa1c519e39b450bbe30a", [ null, {} @@ -596807,7 +597976,7 @@ ] ], "clip-path-interpolation-shape.html": [ - "6d85c2a06b491bbc54e7cfba6705fd9b6af2098f", + "f725e1fc6fa0cbde5928c1e45e5e7c5f72b1a7dd", [ null, {} @@ -597020,7 +598189,7 @@ ] ], "clip-path-shape-parsing.html": [ - "5a4c7415bb40632989c87ee1fbe51540f94af8e2", + "b889ee018056c5db7611cc70de823482ed5cac36", [ null, {} @@ -597895,7 +599064,7 @@ ] ], "column-rule-color-invalid.html": [ - "015defb7560038b03fc4d5f18a04a1d0e094a03d", + "da8dba0a73c9c7829766cd2fad39bfa79fbc6c40", [ null, {} @@ -597937,7 +599106,7 @@ ] ], "column-rule-style-invalid.html": [ - "db367c273f4f2e4bb59893d56388f119cb90ea40", + "e8f2ab60c47748c4a8088024bbcf30eb2c9c16b2", [ null, {} @@ -597965,7 +599134,7 @@ ] ], "column-rule-width-invalid.html": [ - "0bdbbecb8cada68b8243566b265029ee98c55571", + "77f55e09d931cf91618cc7be5a9a9f46c85960dc", [ null, {} @@ -605455,6 +606624,13 @@ null, {} ] + ], + "from-element.tentative.html": [ + "fe99ccb23d9c279011e15f66cbbe20cd87e31568", + [ + null, + {} + ] ] } }, @@ -611439,7 +612615,7 @@ ] ], "transition-zero-duration-with-delay.html": [ - "0b6b9c37a9b2a1c225889c1f362beb9d559c25d7", + "308d8f3784feb674566b64e0b52ae78d43ac55e2", [ null, {} @@ -612667,14 +613843,14 @@ ] ], "column-rule-style.html": [ - "8e56f62171485661197a617bfe688e4f4e922569", + "7098270a3921df847c907842cd7b64cea43d261b", [ null, {} ] ], "column-rule-width.html": [ - "bd3c0ac8f43d1770d04e46913066c6feddee8a08", + "8f09d1cb45aa55c8677810a5911160609514372e", [ null, {} @@ -615461,7 +616637,7 @@ ] ], "if-conditionals.html": [ - "caead7864d550f8732eff919c1b555c8f759508d", + "f6d981798ae7a03f97b4fd089ee02141c7f90813", [ null, {} @@ -615925,6 +617101,13 @@ {} ] ], + "sibling-function-container-query-invalidation.html": [ + "c0d6d913af049d6d316ab664e0d93556bff01e7c", + [ + null, + {} + ] + ], "sibling-function-container-query.html": [ "addcf0b2d48f5c444a9f93264a2136342c4b48d6", [ @@ -615982,7 +617165,7 @@ ] ], "sibling-index-keyframe-registered-properties-dynamic.html": [ - "77af5434a1c4903928194bec4174745a3bd1efeb", + "ac2ed1a8af1b1cddbae8ce18f7afaa7897466a67", [ null, {} @@ -616521,7 +617704,7 @@ }, "css-view-transitions": { "auto-name-get-animations.html": [ - "0442255542c0349438ef7e951da7c6b47928c858", + "b684349a5f9caf390d0a376727dda85602104f28", [ null, {} @@ -617243,6 +618426,13 @@ ] ], "zoom": { + "length-implicit-and-explicit-inheritance.html": [ + "003c7b61c0909f494f02a68e20fad2c152b96a34", + [ + null, + {} + ] + ], "parsing": { "zoom-computed-with-sign-expression.html": [ "8029fd3a65e542749792a48100161f18fd25fee9", @@ -621223,7 +622413,7 @@ ] ], "offset-path-interpolation-008.html": [ - "5fb7c7c333c89f4107e2824390c73862be8107d0", + "ff7d4a108c77f65363d91d9e4bc52eed500913c1", [ null, {} @@ -621365,14 +622555,14 @@ ] ], "offset-path-shape-computed.html": [ - "c9ecc3acb06c065913f8b7538fdf81bff6c802df", + "6ced1ad395ad46206bf63da5ec871d5481185312", [ null, {} ] ], "offset-path-shape-parsing.html": [ - "013cea2c8211d97a5e90c42379cf5aadfe8b59fd", + "4a3d9f169151c3d9a9f7f997410405ad36de2410", [ null, {} @@ -630517,6 +631707,13 @@ {} ] ], + "fn-id.html": [ + "617ff7216d84d56f8cef3f8ca08e902dd67f487d", + [ + null, + {} + ] + ], "fn-lang.html": [ "1fbd0a2ee4d419275c6d78f54e3425135cf838a1", [ @@ -633824,13 +635021,6 @@ } ] ], - "move-inserted-node-from-DOMNodeInserted-during-exec-command-insertHTML.html": [ - "41e012a62e9617f372f85d0a0cedefe8ad42fbd6", - [ - null, - {} - ] - ], "no-beforeinput-when-no-selection.html": [ "098a95863a606393502d4e2fc517fcb8ad144d35", [ @@ -661675,7 +662865,7 @@ "content-encoding": { "br": { "bad-br-body.https.any.js": [ - "43ea90a336cd04df56b4f29f57182d2860481938", + "af5df674da6dcf957d0c5fb69d3538a12096c005", [ "fetch/content-encoding/br/bad-br-body.https.any.html", { @@ -661799,7 +662989,7 @@ }, "gzip": { "bad-gzip-body.any.js": [ - "17bc1261a3f5c36a9797c5a171990c522cfe7598", + "77a183f408b34c75eb3d3e0a1635daad79ff1355", [ "fetch/content-encoding/gzip/bad-gzip-body.any.html", { @@ -661956,7 +663146,7 @@ }, "zstd": { "bad-zstd-body.https.any.js": [ - "3f32e4dfba786511d845c3e913e59b818d0f292b", + "c59980c2c6fb694080417cdd6db1b237f70715b2", [ "fetch/content-encoding/zstd/bad-zstd-body.https.any.html", { @@ -667031,29 +668221,6 @@ } ] ], - "mixed-content-fetch.tentative.https.window.js": [ - "dbae5193b5cb02e3b0eba3531483aac372ba8700", - [ - "fetch/private-network-access/mixed-content-fetch.tentative.https.window.html", - { - "script_metadata": [ - [ - "script", - "/common/utils.js" - ], - [ - "script", - "resources/support.sub.js" - ], - [ - "timeout", - "long" - ] - ], - "timeout": "long" - } - ] - ], "nested-worker.tentative.https.window.js": [ "3eeb435badb2d00404e0e214e1d42c4be2817f8a", [ @@ -667414,185 +668581,6 @@ } ] ], - "window-open-existing.tentative.https.window.js": [ - "6a2a624fc8032d03b626109ee7f825f7acf5874c", - [ - "fetch/private-network-access/window-open-existing.tentative.https.window.html?include=from-local", - { - "script_metadata": [ - [ - "script", - "/common/subset-tests-by-key.js" - ], - [ - "script", - "/common/dispatcher/dispatcher.js" - ], - [ - "script", - "/common/utils.js" - ], - [ - "script", - "resources/support.sub.js" - ], - [ - "timeout", - "long" - ], - [ - "variant", - "?include=from-local" - ], - [ - "variant", - "?include=from-private" - ], - [ - "variant", - "?include=from-public" - ], - [ - "variant", - "?include=from-treat-as-public" - ] - ], - "timeout": "long" - } - ], - [ - "fetch/private-network-access/window-open-existing.tentative.https.window.html?include=from-private", - { - "script_metadata": [ - [ - "script", - "/common/subset-tests-by-key.js" - ], - [ - "script", - "/common/dispatcher/dispatcher.js" - ], - [ - "script", - "/common/utils.js" - ], - [ - "script", - "resources/support.sub.js" - ], - [ - "timeout", - "long" - ], - [ - "variant", - "?include=from-local" - ], - [ - "variant", - "?include=from-private" - ], - [ - "variant", - "?include=from-public" - ], - [ - "variant", - "?include=from-treat-as-public" - ] - ], - "timeout": "long" - } - ], - [ - "fetch/private-network-access/window-open-existing.tentative.https.window.html?include=from-public", - { - "script_metadata": [ - [ - "script", - "/common/subset-tests-by-key.js" - ], - [ - "script", - "/common/dispatcher/dispatcher.js" - ], - [ - "script", - "/common/utils.js" - ], - [ - "script", - "resources/support.sub.js" - ], - [ - "timeout", - "long" - ], - [ - "variant", - "?include=from-local" - ], - [ - "variant", - "?include=from-private" - ], - [ - "variant", - "?include=from-public" - ], - [ - "variant", - "?include=from-treat-as-public" - ] - ], - "timeout": "long" - } - ], - [ - "fetch/private-network-access/window-open-existing.tentative.https.window.html?include=from-treat-as-public", - { - "script_metadata": [ - [ - "script", - "/common/subset-tests-by-key.js" - ], - [ - "script", - "/common/dispatcher/dispatcher.js" - ], - [ - "script", - "/common/utils.js" - ], - [ - "script", - "resources/support.sub.js" - ], - [ - "timeout", - "long" - ], - [ - "variant", - "?include=from-local" - ], - [ - "variant", - "?include=from-private" - ], - [ - "variant", - "?include=from-public" - ], - [ - "variant", - "?include=from-treat-as-public" - ] - ], - "timeout": "long" - } - ] - ], "window-open-existing.tentative.window.js": [ "5a6cd4c5cfd20c931a37c4f98524a4a59c0d07c9", [ @@ -683042,6 +684030,13 @@ {} ] ], + "focus-contenteditable-element-in-iframe-scroll-into-view.html": [ + "1c03382201eb05785a003d068bf0e14150e10608", + [ + null, + {} + ] + ], "focus-double-sync-calls.html": [ "8d5f5c8a79fc6c65556e151fed9610a9cb915f98", [ @@ -727275,6 +728270,13 @@ {} ] ], + "slot-element-default-display.html": [ + "825efaa1a97d898c9cb2b7db1c18b3213c8ed214", + [ + null, + {} + ] + ], "slot-element-focusable.tentative.html": [ "b6d2449e890b31a9fc50712422c0dbca5e3e33a0", [ @@ -733167,7 +734169,7 @@ ] ], "image-decode-path-changes-svg.tentative.html": [ - "1bc53a1f18e56fbd2f586b91cf78e00c846eecbb", + "3ef59c37a8500f64bc60011174560f4aca0bea5d", [ null, { @@ -733203,7 +734205,7 @@ ] ], "image-decode-with-quick-attach-svg.tentative.html": [ - "0fc49e603606e9233d0b3ae59757aec149c8aaf2", + "fbc7143eceead959bc34270b55ad850044215ece", [ null, { @@ -733583,7 +734585,7 @@ ] ], "naturalWidth-naturalHeight-unavailable.tentative.html": [ - "df9eb374b5adc003c93830ab4605b2adad0ae84d", + "ae6fa0e432853d111aa63bd87f43206acec86024", [ null, {} @@ -738076,8 +739078,8 @@ } ] ], - "negative-offset-and-margin.tentative.html": [ - "0b3d8dc98812e01e7255cc166fa0bc0704f0eac4", + "negative-offset.tentative.html": [ + "c1424ad9cc80e27fac9f0693defd87dd273ad2e2", [ null, {} @@ -738091,7 +739093,7 @@ ] ], "no-focus.tentative.html": [ - "9646788518323b331ac7278dd0afb754392ef6be", + "1bf29634605cc55210fef4a04cfaaa2c436fcd09", [ null, { @@ -739150,34 +740152,6 @@ {} ] ], - "042.html": [ - "df3a2f88f29f2e8035d8c778c3397ad464688e18", - [ - null, - {} - ] - ], - "043.html": [ - "bcfd90cba47880efa48f9e809f37209f5f024dd6", - [ - null, - {} - ] - ], - "044.html": [ - "8d412079e45f9f8a3d074d707db39a55e1d8b946", - [ - null, - {} - ] - ], - "045.html": [ - "254e0d13662786d8542d03de3547b39ecf684ede", - [ - null, - {} - ] - ], "046.html": [ "4f145d63e1d619df2df429ec6fd713e77e303cb3", [ @@ -739236,20 +740210,6 @@ {} ] ], - "054.html": [ - "29ede23414ec57950717a05e375cbc15547c0b4d", - [ - null, - {} - ] - ], - "055.html": [ - "c837d78174b108d8b90cca4dccbc91bef8e1efad", - [ - null, - {} - ] - ], "056.html": [ "e2d0868034e1b243e610b3e3afdea18d78c418c8", [ @@ -740205,7 +741165,7 @@ ] ], "invalid-content-type.any.js": [ - "d15fa3f1b7090dc0e309097c497dcd3626301c31", + "d0bb6aa9fb17fe49d85bef83486edf4148ac970d", [ "html/semantics/scripting-1/the-script-element/json-module/invalid-content-type.any.html", { @@ -740374,7 +741334,7 @@ ] ], "valid-content-type.html": [ - "3232b84d271e0faa49fd600eac9f4394db7f5630", + "fdeba93ba893176df88fe69f54606b4d01020436", [ null, {} @@ -743326,6 +744286,13 @@ "timeout": "long" } ] + ], + "source-attribute-retargeting.tentative.html": [ + "885b75a3387a8f61f8f25fdd93d60fe3027b5599", + [ + null, + {} + ] ] }, "interest-target": { @@ -771861,6 +772828,15 @@ } ] ], + "get-persistendeviceid-from-pointer-mouse-event.tentative.html": [ + "66fb63d54d1acedc17e9a522eefebe0fba76f943", + [ + null, + { + "testdriver": true + } + ] + ], "pointer-event-has-persistentdeviceid-from-pointer-event-init.tentative.html": [ "c3fc4270f6177c94ccd191a29d86b77a220f3577", [ @@ -773801,7 +774777,7 @@ ] ], "preload-csp.sub.html": [ - "a1b57b78b415f76678064ff9e00d32a4f6d14f6c", + "2238d6cafe80ff7733ea34d5ef365790b9f7a8df", [ null, {} @@ -787240,6 +788216,13 @@ null, {} ] + ], + "zoom.html": [ + "77b4bc49fa7e8e4d13083f8ef97ced833e627a85", + [ + null, + {} + ] ] }, "resource-timing": { @@ -787411,7 +788394,7 @@ ] ], "content-encoding.https.html": [ - "0d67bfc7d4f9a9c471272a8a475655d1c5225552", + "80473552f08b0c5f857533bdebf7a168283d5953", [ null, {} @@ -790725,7 +791708,7 @@ ] ], "animation-trigger-repeat.tentative.html": [ - "cfbe9d3c9334148789d4cebc7a01a2f9e848b22d", + "6c01e762e5acd18a1def36673c93d7fcdedf4964", [ null, {} @@ -796656,7 +797639,7 @@ ] ], "HighlightRegistry-highlightsFromPoint.html": [ - "5244f923e3404064987ce16d0fd1e9215ad768c3", + "4098bc5a9941f23405d754e786351320e14125d6", [ null, {} @@ -799842,7 +800825,7 @@ ] ], "first-interaction-not-softnav.tentative.html": [ - "e02620218368d71ff10196c9ff75a13a361f5d90", + "2c9e2aa7c014025ca409da94172d6e0d61d106d7", [ null, { @@ -799886,15 +800869,6 @@ } ] ], - "innertext.tentative.html": [ - "7716488f25a08ea62635fceec679d97650d1f383", - [ - null, - { - "testdriver": true - } - ] - ], "interaction-with-paint-before-back.tentative.html": [ "effccbfd762434c84b672173b122b07272542fe5", [ @@ -800088,7 +801062,7 @@ ] ], "dom.html": [ - "66d23b22788c4749d7b990b89b0cef612872f5f4", + "2e3c3809df68ba4093247e2d4e3fe114f8c9f729", [ null, { @@ -800113,6 +801087,15 @@ "testdriver": true } ] + ], + "window-open-cross-scheduling.html": [ + "1a41be6ddd2d716c4012b5524e8a30b9821ec3e3", + [ + null, + { + "testdriver": true + } + ] ] } }, @@ -800552,6 +801535,15 @@ {} ] ], + "no-prefetch-for-post.https.html": [ + "7739f4f8c7105b2c4e9ed4671081b00d0c0b8c6e", + [ + null, + { + "timeout": "long" + } + ] + ], "no-vary-search": { "prefetch-single-with-hint.https.html": [ "f2d8b3090e1f8447f86bd62a6f24ca9daae06ec7", @@ -801544,6 +802536,15 @@ } ] ], + "headers.https.html": [ + "2ef6b5ce072866d3c88ce7a86fcea6436de3364a", + [ + null, + { + "timeout": "long" + } + ] + ], "iframe-added-post-activation.https.html": [ "d22b511e108d8b7c7f0b63f28e5bf485eca98758", [ @@ -821758,14 +822759,14 @@ ] ], "block-text-node-insertion-into-script-element.html": [ - "65b40b933ff8417ad5147ce29d68bc19707bc0b9", + "1a1256d05a8c996d078ca287950660fd5d1e9071", [ null, {} ] ], "block-text-node-insertion-into-svg-script-element.html": [ - "f4ff24350355a29f033489d51bf4a021d9673dd2", + "18c6af8f5efcf72c11876b4f2740cdddd5cf1c84", [ null, {} @@ -822761,13 +823762,6 @@ }, "legacy-domevents-tests": { "approved": { - "ProcessingInstruction.DOMCharacterDataModified.html": [ - "2da0a389e2e3bc51861fef752b11a629203897d0", - [ - null, - {} - ] - ], "dispatchEvent.click.checkbox.html": [ "8cb548f84c60eb6b528c1049884649b26c4f18ba", [ @@ -822775,13 +823769,6 @@ {} ] ], - "domnodeinserted.html": [ - "e5064d8d46cd9aad4768aa81dacb18b989e2c993", - [ - null, - {} - ] - ], "stopImmediatePropagation.effect.html": [ "a414d60298acece6dce5d970e6f0448a99fd65da", [ @@ -826089,6 +827076,53 @@ } ] ], + "urlpattern-generate.tentative.any.js": [ + "1f6962942d88f88684c5302175202e0278d3d971", + [ + "urlpattern/urlpattern-generate.tentative.any.html", + { + "script_metadata": [ + [ + "global", + "window,worker" + ] + ] + } + ], + [ + "urlpattern/urlpattern-generate.tentative.any.serviceworker.html", + { + "script_metadata": [ + [ + "global", + "window,worker" + ] + ] + } + ], + [ + "urlpattern/urlpattern-generate.tentative.any.sharedworker.html", + { + "script_metadata": [ + [ + "global", + "window,worker" + ] + ] + } + ], + [ + "urlpattern/urlpattern-generate.tentative.any.worker.html", + { + "script_metadata": [ + [ + "global", + "window,worker" + ] + ] + } + ] + ], "urlpattern-hasregexpgroups.any.js": [ "33133d2511b065ca94cc5e793066cc8111b4d6e6", [ @@ -855408,7 +856442,7 @@ ] ], "cumulative_sum.https.any.js": [ - "85e1ab427d208f76aae62bff8c603b0d891f7180", + "34a625152b26a3183a7cd62c38883a684ac93908", [ "webnn/conformance_tests/cumulative_sum.https.any.html?cpu", { @@ -859164,7 +860198,7 @@ ] ], "linear.https.any.js": [ - "9231aaf9ecad0996b8dfb9530c4a7f55b2aa8e06", + "1f13fe170d46fa157035bd6e14de6eb68462c7a4", [ "webnn/conformance_tests/linear.https.any.html?cpu", { @@ -861597,7 +862631,7 @@ ] ], "qdq_subgraph.https.any.js": [ - "ac384c917b33dda2243779a396d0d557c40003dc", + "996a6b472c5689bc082388d5c267d2f5fe460080", [ "webnn/conformance_tests/qdq_subgraph.https.any.html?cpu", { @@ -865938,7 +866972,7 @@ ] ], "subgraph.https.any.js": [ - "9b21d6e4f9453fb72c3f7a6850c5690cc9ed87cf", + "8a0b7faa92f938282c7a6bb02ac61ef6730f021d", [ "webnn/conformance_tests/subgraph.https.any.html?cpu", { @@ -882769,7 +883803,7 @@ ] ], "RTCConfiguration-iceServers.html": [ - "bc7831361ab5f417b46a507b0e5977bef9bedd49", + "65a6015f52a7233260ab8405fb43bc347fa0ff4b", [ null, {} @@ -884728,7 +885762,7 @@ ] ], "RTCEncodedAudioFrame-metadata.https.html": [ - "df4577c5614a82afd7b02d988d0f15caa3b9e848", + "1e148fe1b29a167e6451162125b7390151ec90bd", [ null, { @@ -897592,7 +898626,7 @@ ] ], "remote-close.any.js": [ - "b7fd321914a4e6f9bf70d431bca591a7c5460675", + "c3e7ad5f9fbef1494ed7594dc7d497e9f867361a", [ "websockets/stream/tentative/remote-close.any.html?default", { @@ -898012,6 +899046,429 @@ ] } ] + ], + "write.any.js": [ + "43af7da614c675fcc0571d7edff3515a92774caf", + [ + "websockets/stream/tentative/write.any.html?default", + { + "script_metadata": [ + [ + "script", + "../../constants.sub.js" + ], + [ + "script", + "resources/url-constants.js" + ], + [ + "script", + "/common/gc.js" + ], + [ + "global", + "window,worker" + ], + [ + "variant", + "?default" + ], + [ + "variant", + "?wss" + ], + [ + "variant", + "?wpt_flags=h2" + ] + ] + } + ], + [ + "websockets/stream/tentative/write.any.html?wpt_flags=h2", + { + "script_metadata": [ + [ + "script", + "../../constants.sub.js" + ], + [ + "script", + "resources/url-constants.js" + ], + [ + "script", + "/common/gc.js" + ], + [ + "global", + "window,worker" + ], + [ + "variant", + "?default" + ], + [ + "variant", + "?wss" + ], + [ + "variant", + "?wpt_flags=h2" + ] + ] + } + ], + [ + "websockets/stream/tentative/write.any.html?wss", + { + "script_metadata": [ + [ + "script", + "../../constants.sub.js" + ], + [ + "script", + "resources/url-constants.js" + ], + [ + "script", + "/common/gc.js" + ], + [ + "global", + "window,worker" + ], + [ + "variant", + "?default" + ], + [ + "variant", + "?wss" + ], + [ + "variant", + "?wpt_flags=h2" + ] + ] + } + ], + [ + "websockets/stream/tentative/write.any.serviceworker.html?default", + { + "script_metadata": [ + [ + "script", + "../../constants.sub.js" + ], + [ + "script", + "resources/url-constants.js" + ], + [ + "script", + "/common/gc.js" + ], + [ + "global", + "window,worker" + ], + [ + "variant", + "?default" + ], + [ + "variant", + "?wss" + ], + [ + "variant", + "?wpt_flags=h2" + ] + ] + } + ], + [ + "websockets/stream/tentative/write.any.serviceworker.html?wpt_flags=h2", + { + "script_metadata": [ + [ + "script", + "../../constants.sub.js" + ], + [ + "script", + "resources/url-constants.js" + ], + [ + "script", + "/common/gc.js" + ], + [ + "global", + "window,worker" + ], + [ + "variant", + "?default" + ], + [ + "variant", + "?wss" + ], + [ + "variant", + "?wpt_flags=h2" + ] + ] + } + ], + [ + "websockets/stream/tentative/write.any.serviceworker.html?wss", + { + "script_metadata": [ + [ + "script", + "../../constants.sub.js" + ], + [ + "script", + "resources/url-constants.js" + ], + [ + "script", + "/common/gc.js" + ], + [ + "global", + "window,worker" + ], + [ + "variant", + "?default" + ], + [ + "variant", + "?wss" + ], + [ + "variant", + "?wpt_flags=h2" + ] + ] + } + ], + [ + "websockets/stream/tentative/write.any.sharedworker.html?default", + { + "script_metadata": [ + [ + "script", + "../../constants.sub.js" + ], + [ + "script", + "resources/url-constants.js" + ], + [ + "script", + "/common/gc.js" + ], + [ + "global", + "window,worker" + ], + [ + "variant", + "?default" + ], + [ + "variant", + "?wss" + ], + [ + "variant", + "?wpt_flags=h2" + ] + ] + } + ], + [ + "websockets/stream/tentative/write.any.sharedworker.html?wpt_flags=h2", + { + "script_metadata": [ + [ + "script", + "../../constants.sub.js" + ], + [ + "script", + "resources/url-constants.js" + ], + [ + "script", + "/common/gc.js" + ], + [ + "global", + "window,worker" + ], + [ + "variant", + "?default" + ], + [ + "variant", + "?wss" + ], + [ + "variant", + "?wpt_flags=h2" + ] + ] + } + ], + [ + "websockets/stream/tentative/write.any.sharedworker.html?wss", + { + "script_metadata": [ + [ + "script", + "../../constants.sub.js" + ], + [ + "script", + "resources/url-constants.js" + ], + [ + "script", + "/common/gc.js" + ], + [ + "global", + "window,worker" + ], + [ + "variant", + "?default" + ], + [ + "variant", + "?wss" + ], + [ + "variant", + "?wpt_flags=h2" + ] + ] + } + ], + [ + "websockets/stream/tentative/write.any.worker.html?default", + { + "script_metadata": [ + [ + "script", + "../../constants.sub.js" + ], + [ + "script", + "resources/url-constants.js" + ], + [ + "script", + "/common/gc.js" + ], + [ + "global", + "window,worker" + ], + [ + "variant", + "?default" + ], + [ + "variant", + "?wss" + ], + [ + "variant", + "?wpt_flags=h2" + ] + ] + } + ], + [ + "websockets/stream/tentative/write.any.worker.html?wpt_flags=h2", + { + "script_metadata": [ + [ + "script", + "../../constants.sub.js" + ], + [ + "script", + "resources/url-constants.js" + ], + [ + "script", + "/common/gc.js" + ], + [ + "global", + "window,worker" + ], + [ + "variant", + "?default" + ], + [ + "variant", + "?wss" + ], + [ + "variant", + "?wpt_flags=h2" + ] + ] + } + ], + [ + "websockets/stream/tentative/write.any.worker.html?wss", + { + "script_metadata": [ + [ + "script", + "../../constants.sub.js" + ], + [ + "script", + "resources/url-constants.js" + ], + [ + "script", + "/common/gc.js" + ], + [ + "global", + "window,worker" + ], + [ + "variant", + "?default" + ], + [ + "variant", + "?wss" + ], + [ + "variant", + "?wpt_flags=h2" + ] + ] + } + ] ] } }, @@ -905189,6 +906646,15 @@ {} ] ], + "tentative": { + "SharedWorker-extendedLifetime.html": [ + "3c76eddd7647991ae171b4d5e4766af5d156dd9a", + [ + null, + {} + ] + ] + }, "worker-performance.worker.js": [ "c913b2e7375067c1a21bdc655f394b5c27bc5aed", [ @@ -916093,104 +917559,6 @@ {} ] ], - "list-style-image-applies-to-001.xht": [ - "2c82821505bc65183bc09b518908e87f2533e110", - [ - null, - {} - ] - ], - "list-style-image-applies-to-002.xht": [ - "7af1787b87dea123b9d61372873156e2d105db97", - [ - null, - {} - ] - ], - "list-style-image-applies-to-003.xht": [ - "1e7e58f4627accac29406e5d8c098b0464205279", - [ - null, - {} - ] - ], - "list-style-image-applies-to-004.xht": [ - "cc859de9a8295b2bb9de98cc61a8967987537058", - [ - null, - {} - ] - ], - "list-style-image-applies-to-005.xht": [ - "74d1b127923cd19d98084dc2c8d576dfa5ec58f3", - [ - null, - {} - ] - ], - "list-style-image-applies-to-006.xht": [ - "81ca729695b15e352a543a027881a42b00f81c24", - [ - null, - {} - ] - ], - "list-style-image-applies-to-007.xht": [ - "63a8d63c7829b14513b312a14cae353633b392a1", - [ - null, - {} - ] - ], - "list-style-image-applies-to-008.xht": [ - "6d8bd5638bf3f5b54c5dac8e49dfde46f2f8acb2", - [ - null, - {} - ] - ], - "list-style-image-applies-to-009.xht": [ - "cc2270bc9f02d4e0836d32d37c26f8922128656c", - [ - null, - {} - ] - ], - "list-style-image-applies-to-010.xht": [ - "78a81194285defc7e16e7e50c637f57dc381f8c0", - [ - null, - {} - ] - ], - "list-style-image-applies-to-012.xht": [ - "b81db5533c742f72e2f3eb5c9802190fa207f219", - [ - null, - {} - ] - ], - "list-style-image-applies-to-013.xht": [ - "8a8c3e3da81364a11988353771baf0911b233411", - [ - null, - {} - ] - ], - "list-style-image-applies-to-014.xht": [ - "01347df407e73135ba3ab7a602cf66609f5ada99", - [ - null, - {} - ] - ], - "list-style-image-applies-to-015.xht": [ - "7eedb682640e9c817ae64e9a0ef44868fa538671", - [ - null, - {} - ] - ], "list-style-image-available-001.xht": [ "dbb6b45abbdeb5ed7cc3f91393a177057b18a434", [ @@ -916240,104 +917608,6 @@ {} ] ], - "list-style-position-applies-to-001.xht": [ - "9889dd769564c224e90135ce884f3923e9704930", - [ - null, - {} - ] - ], - "list-style-position-applies-to-002.xht": [ - "a8c8a41aa58b5503ebf893d672ec3fff1bace311", - [ - null, - {} - ] - ], - "list-style-position-applies-to-003.xht": [ - "d53761ba36c9bca250916c974783caf014f25ac1", - [ - null, - {} - ] - ], - "list-style-position-applies-to-004.xht": [ - "23d74ebd673698f388b94ca70c129847b5726ab6", - [ - null, - {} - ] - ], - "list-style-position-applies-to-005.xht": [ - "9ec866bef8a58f66ee0eb676d9a4c8c3d83c3f16", - [ - null, - {} - ] - ], - "list-style-position-applies-to-006.xht": [ - "d60ed2c7f876f7cb8117b0a3cf10e728adae28e3", - [ - null, - {} - ] - ], - "list-style-position-applies-to-007.xht": [ - "c223dbabd81fbe2a7b5a9b893b2668394dbe875d", - [ - null, - {} - ] - ], - "list-style-position-applies-to-008.xht": [ - "1f2e347de86b5e66817eba7c01b771a6ef897425", - [ - null, - {} - ] - ], - "list-style-position-applies-to-009.xht": [ - "90ff3b23562f82ad9150fb1897a4ce9be53529a1", - [ - null, - {} - ] - ], - "list-style-position-applies-to-010.xht": [ - "ae5dbfbc362daac99771c8d7fcd99675afa83cab", - [ - null, - {} - ] - ], - "list-style-position-applies-to-012.xht": [ - "25e79b3a594ebd8d9e5a1af7df4fbd607ee8ee6c", - [ - null, - {} - ] - ], - "list-style-position-applies-to-013.xht": [ - "5dde30618c940c9e833aece9e73a628f419c5f39", - [ - null, - {} - ] - ], - "list-style-position-applies-to-014.xht": [ - "b5502348702ac9a92975e901b28d873bb6687d60", - [ - null, - {} - ] - ], - "list-style-position-applies-to-015.xht": [ - "53eb07dd3b7283f60b2f7ed0c80e1ef2264155f7", - [ - null, - {} - ] - ], "list-style-position-inside-002.xht": [ "bfd661367fa8a20914fb15c21d7abba41cb32934", [ diff --git a/tests/wpt/meta/content-security-policy/connect-src/connect-src-syncxmlhttprequest-redirect-to-blocked.sub.html.ini b/tests/wpt/meta/content-security-policy/connect-src/connect-src-syncxmlhttprequest-redirect-to-blocked.sub.html.ini deleted file mode 100644 index e6156eab928..00000000000 --- a/tests/wpt/meta/content-security-policy/connect-src/connect-src-syncxmlhttprequest-redirect-to-blocked.sub.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[connect-src-syncxmlhttprequest-redirect-to-blocked.sub.html] - [Expecting logs: ["PASS Sync XMLHttpRequest.send() did not follow the disallowed redirect.","TEST COMPLETE","violated-directive=connect-src"\]] - expected: FAIL diff --git a/tests/wpt/meta/content-security-policy/connect-src/connect-src-xmlhttprequest-redirect-to-blocked.sub.html.ini b/tests/wpt/meta/content-security-policy/connect-src/connect-src-xmlhttprequest-redirect-to-blocked.sub.html.ini deleted file mode 100644 index 9b86b6b2d9c..00000000000 --- a/tests/wpt/meta/content-security-policy/connect-src/connect-src-xmlhttprequest-redirect-to-blocked.sub.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[connect-src-xmlhttprequest-redirect-to-blocked.sub.html] - [Expecting logs: ["PASS XMLHttpRequest.send() did not follow the disallowed redirect.","TEST COMPLETE","violated-directive=connect-src"\]] - expected: FAIL diff --git a/tests/wpt/meta/content-security-policy/font-src/font-match-allowed.sub.html.ini b/tests/wpt/meta/content-security-policy/font-src/font-match-allowed.sub.html.ini deleted file mode 100644 index 6c90dc5033b..00000000000 --- a/tests/wpt/meta/content-security-policy/font-src/font-match-allowed.sub.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[font-match-allowed.sub.html] - expected: TIMEOUT - [Test font loads if it matches font-src.] - expected: TIMEOUT diff --git a/tests/wpt/meta/content-security-policy/font-src/font-mismatch-blocked.sub.html.ini b/tests/wpt/meta/content-security-policy/font-src/font-mismatch-blocked.sub.html.ini deleted file mode 100644 index 39efa2c9cb2..00000000000 --- a/tests/wpt/meta/content-security-policy/font-src/font-mismatch-blocked.sub.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[font-mismatch-blocked.sub.html] - expected: TIMEOUT - [Test font does not load if it does not match font-src.] - expected: TIMEOUT diff --git a/tests/wpt/meta/content-security-policy/font-src/font-none-blocked.sub.html.ini b/tests/wpt/meta/content-security-policy/font-src/font-none-blocked.sub.html.ini deleted file mode 100644 index 911f745bb2c..00000000000 --- a/tests/wpt/meta/content-security-policy/font-src/font-none-blocked.sub.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[font-none-blocked.sub.html] - expected: TIMEOUT - [Test font does not load if it does not match font-src.] - expected: TIMEOUT diff --git a/tests/wpt/meta/content-security-policy/font-src/font-self-allowed.html.ini b/tests/wpt/meta/content-security-policy/font-src/font-self-allowed.html.ini deleted file mode 100644 index 3f0903770c4..00000000000 --- a/tests/wpt/meta/content-security-policy/font-src/font-self-allowed.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[font-self-allowed.html] - expected: TIMEOUT - [Test font loads if it matches font-src.] - expected: TIMEOUT diff --git a/tests/wpt/meta/content-security-policy/gen/top.http-rp/script-src-self/script-tag.http.html.ini b/tests/wpt/meta/content-security-policy/gen/top.http-rp/script-src-self/script-tag.http.html.ini index 5891a18681e..0c6a81792db 100644 --- a/tests/wpt/meta/content-security-policy/gen/top.http-rp/script-src-self/script-tag.http.html.ini +++ b/tests/wpt/meta/content-security-policy/gen/top.http-rp/script-src-self/script-tag.http.html.ini @@ -1,6 +1,3 @@ [script-tag.http.html] [Content Security Policy: Expects blocked for script-tag to same-http origin and swap-origin redirection from http context.] expected: FAIL - - [Content Security Policy: Expects blocked for script-tag to same-http origin and swap-origin redirection from http context.: securitypolicyviolation] - expected: FAIL diff --git a/tests/wpt/meta/content-security-policy/gen/top.http-rp/script-src-self/script-tag.https.html.ini b/tests/wpt/meta/content-security-policy/gen/top.http-rp/script-src-self/script-tag.https.html.ini index 699a0dd6238..b5c643337e2 100644 --- a/tests/wpt/meta/content-security-policy/gen/top.http-rp/script-src-self/script-tag.https.html.ini +++ b/tests/wpt/meta/content-security-policy/gen/top.http-rp/script-src-self/script-tag.https.html.ini @@ -1,6 +1,3 @@ [script-tag.https.html] [Content Security Policy: Expects blocked for script-tag to same-https origin and swap-origin redirection from https context.] expected: FAIL - - [Content Security Policy: Expects blocked for script-tag to same-https origin and swap-origin redirection from https context.: securitypolicyviolation] - expected: FAIL diff --git a/tests/wpt/meta/content-security-policy/gen/top.meta/script-src-self/script-tag.http.html.ini b/tests/wpt/meta/content-security-policy/gen/top.meta/script-src-self/script-tag.http.html.ini index 5891a18681e..0c6a81792db 100644 --- a/tests/wpt/meta/content-security-policy/gen/top.meta/script-src-self/script-tag.http.html.ini +++ b/tests/wpt/meta/content-security-policy/gen/top.meta/script-src-self/script-tag.http.html.ini @@ -1,6 +1,3 @@ [script-tag.http.html] [Content Security Policy: Expects blocked for script-tag to same-http origin and swap-origin redirection from http context.] expected: FAIL - - [Content Security Policy: Expects blocked for script-tag to same-http origin and swap-origin redirection from http context.: securitypolicyviolation] - expected: FAIL diff --git a/tests/wpt/meta/content-security-policy/gen/top.meta/script-src-self/script-tag.https.html.ini b/tests/wpt/meta/content-security-policy/gen/top.meta/script-src-self/script-tag.https.html.ini index 699a0dd6238..b5c643337e2 100644 --- a/tests/wpt/meta/content-security-policy/gen/top.meta/script-src-self/script-tag.https.html.ini +++ b/tests/wpt/meta/content-security-policy/gen/top.meta/script-src-self/script-tag.https.html.ini @@ -1,6 +1,3 @@ [script-tag.https.html] [Content Security Policy: Expects blocked for script-tag to same-https origin and swap-origin redirection from https context.] expected: FAIL - - [Content Security Policy: Expects blocked for script-tag to same-https origin and swap-origin redirection from https context.: securitypolicyviolation] - expected: FAIL diff --git a/tests/wpt/meta/content-security-policy/generic/wildcard-host-part.sub.window.js.ini b/tests/wpt/meta/content-security-policy/generic/wildcard-host-part.sub.window.js.ini deleted file mode 100644 index 7770d4e4454..00000000000 --- a/tests/wpt/meta/content-security-policy/generic/wildcard-host-part.sub.window.js.ini +++ /dev/null @@ -1,2 +0,0 @@ -[wildcard-host-part.sub.window.html] - expected: CRASH diff --git a/tests/wpt/meta/content-security-policy/inside-worker/dedicatedworker-connect-src.html.ini b/tests/wpt/meta/content-security-policy/inside-worker/dedicatedworker-connect-src.html.ini index ad01d630c28..72db221f4dd 100644 --- a/tests/wpt/meta/content-security-policy/inside-worker/dedicatedworker-connect-src.html.ini +++ b/tests/wpt/meta/content-security-policy/inside-worker/dedicatedworker-connect-src.html.ini @@ -1,7 +1,4 @@ [dedicatedworker-connect-src.html] - [Same-origin => cross-origin 'fetch()' in http: with connect-src 'self'] - expected: FAIL - [Reports match in http: with connect-src 'self'] expected: FAIL diff --git a/tests/wpt/meta/content-security-policy/reporting/report-original-url.sub.html.ini b/tests/wpt/meta/content-security-policy/reporting/report-original-url.sub.html.ini index 66a2ee93f3b..f160ad3d25d 100644 --- a/tests/wpt/meta/content-security-policy/reporting/report-original-url.sub.html.ini +++ b/tests/wpt/meta/content-security-policy/reporting/report-original-url.sub.html.ini @@ -1,10 +1,3 @@ [report-original-url.sub.html] - expected: TIMEOUT - [Block after redirect, same-origin = original URL in report] - expected: TIMEOUT - - [Block after redirect, cross-origin = original URL in report] - expected: TIMEOUT - [Violation report status OK.] expected: FAIL diff --git a/tests/wpt/meta/content-security-policy/securitypolicyviolation/img-src-redirect.sub.html.ini b/tests/wpt/meta/content-security-policy/securitypolicyviolation/img-src-redirect.sub.html.ini deleted file mode 100644 index 95cb135df4e..00000000000 --- a/tests/wpt/meta/content-security-policy/securitypolicyviolation/img-src-redirect.sub.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[img-src-redirect.sub.html] - [The blocked URI in the security policy violation event should be the original URI before redirects.] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/lists/list-style-applies-to-017.html.ini b/tests/wpt/meta/css/CSS2/lists/list-style-applies-to-017.html.ini new file mode 100644 index 00000000000..6e491d93275 --- /dev/null +++ b/tests/wpt/meta/css/CSS2/lists/list-style-applies-to-017.html.ini @@ -0,0 +1,2 @@ +[list-style-applies-to-017.html] + expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/lists/list-style-image-applies-to-017.html.ini b/tests/wpt/meta/css/CSS2/lists/list-style-image-applies-to-017.html.ini new file mode 100644 index 00000000000..2433ef7b9cb --- /dev/null +++ b/tests/wpt/meta/css/CSS2/lists/list-style-image-applies-to-017.html.ini @@ -0,0 +1,2 @@ +[list-style-image-applies-to-017.html] + expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/lists/list-style-type-applies-to-017.html.ini b/tests/wpt/meta/css/CSS2/lists/list-style-type-applies-to-017.html.ini new file mode 100644 index 00000000000..5a422c4fcc5 --- /dev/null +++ b/tests/wpt/meta/css/CSS2/lists/list-style-type-applies-to-017.html.ini @@ -0,0 +1,2 @@ +[list-style-type-applies-to-017.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-backgrounds/background-attachment-353.html.ini b/tests/wpt/meta/css/css-backgrounds/background-attachment-353.html.ini index 83ae5d7a9f7..d1af9d7d555 100644 --- a/tests/wpt/meta/css/css-backgrounds/background-attachment-353.html.ini +++ b/tests/wpt/meta/css/css-backgrounds/background-attachment-353.html.ini @@ -1,2 +1,2 @@ [background-attachment-353.html] - expected: TIMEOUT + expected: FAIL diff --git a/tests/wpt/meta/css/css-backgrounds/background-image-first-letter.html.ini b/tests/wpt/meta/css/css-backgrounds/background-image-first-letter.html.ini index 68e18ef1217..97d17f09f95 100644 --- a/tests/wpt/meta/css/css-backgrounds/background-image-first-letter.html.ini +++ b/tests/wpt/meta/css/css-backgrounds/background-image-first-letter.html.ini @@ -1,2 +1,2 @@ [background-image-first-letter.html] - expected: TIMEOUT + expected: FAIL diff --git a/tests/wpt/meta/css/css-backgrounds/background-image-first-line.html.ini b/tests/wpt/meta/css/css-backgrounds/background-image-first-line.html.ini index 994c6756cf8..98e9448ed30 100644 --- a/tests/wpt/meta/css/css-backgrounds/background-image-first-line.html.ini +++ b/tests/wpt/meta/css/css-backgrounds/background-image-first-line.html.ini @@ -1,2 +1,2 @@ [background-image-first-line.html] - expected: TIMEOUT + expected: FAIL diff --git a/tests/wpt/meta/css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html.ini b/tests/wpt/meta/css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html.ini index 11dc161d87a..34de05fc1cc 100644 --- a/tests/wpt/meta/css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html.ini +++ b/tests/wpt/meta/css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html.ini @@ -78,3 +78,6 @@ [corner-shape-render-fuzzy.html?border-radius=50%&corner-top-right-shape=scoop&corner-bottom-left-shape=scoop&corner-top-left-shape=notch&corner-bottom-right-shape=notch&border-width=10px] expected: FAIL + +[corner-shape-render-fuzzy.html?corner-shape=superellipse(0.8)&border-radius=40px&border-width=10px] + expected: FAIL diff --git a/tests/wpt/meta/css/css-borders/tentative/corner-shape/corner-shape-render-precise.html.ini b/tests/wpt/meta/css/css-borders/tentative/corner-shape/corner-shape-render-precise.html.ini index 68682a3e807..1fda8aa0448 100644 --- a/tests/wpt/meta/css/css-borders/tentative/corner-shape/corner-shape-render-precise.html.ini +++ b/tests/wpt/meta/css/css-borders/tentative/corner-shape/corner-shape-render-precise.html.ini @@ -37,9 +37,6 @@ [corner-shape-render-precise.html?corner-top-left-shape=bevel&border-width=10px&border-color=black] expected: FAIL -[corner-shape-render-precise.html?corner-bottom-right-shape=bevel&corner-bottom-left-shape=bevel] - expected: FAIL - [corner-shape-render-precise.html?corner-shape=superellipse(8)&border-radius=10px&box-shadow=10px 10px 0 10px black] expected: FAIL @@ -90,3 +87,6 @@ [corner-shape-render-precise.html?corner-shape=superellipse(-2)&border-top-left-radius=40%&border-width=20px] expected: FAIL + +[corner-shape-render-precise.html?corner-shape=notch&border-radius=30px&border-width=30px] + expected: FAIL diff --git a/tests/wpt/meta/css/css-conditional/container-queries/style-query-registered-custom-rem-change.html.ini b/tests/wpt/meta/css/css-conditional/container-queries/style-query-registered-custom-rem-change.html.ini new file mode 100644 index 00000000000..ee69bd41b83 --- /dev/null +++ b/tests/wpt/meta/css/css-conditional/container-queries/style-query-registered-custom-rem-change.html.ini @@ -0,0 +1,3 @@ +[style-query-registered-custom-rem-change.html] + [Changing the :root font-size to 10px makes 1rem * 10 evaluate to 100px] + expected: FAIL diff --git a/tests/wpt/meta/css/css-gaps/grid/grid-gap-decorations-040.html.ini b/tests/wpt/meta/css/css-gaps/grid/grid-gap-decorations-040.html.ini new file mode 100644 index 00000000000..961df8f5b9b --- /dev/null +++ b/tests/wpt/meta/css/css-gaps/grid/grid-gap-decorations-040.html.ini @@ -0,0 +1,2 @@ +[grid-gap-decorations-040.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-masking/clip-path/clip-path-fixed-scroll.html.ini b/tests/wpt/meta/css/css-masking/clip-path/clip-path-fixed-scroll.html.ini deleted file mode 100644 index 7addfba3787..00000000000 --- a/tests/wpt/meta/css/css-masking/clip-path/clip-path-fixed-scroll.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[clip-path-fixed-scroll.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-masking/clip-path/clip-path-shape-011.html.ini b/tests/wpt/meta/css/css-masking/clip-path/clip-path-shape-011.html.ini new file mode 100644 index 00000000000..7598b3ef8ec --- /dev/null +++ b/tests/wpt/meta/css/css-masking/clip-path/clip-path-shape-011.html.ini @@ -0,0 +1,2 @@ +[clip-path-shape-011.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-overflow/overflow-video.html.ini b/tests/wpt/meta/css/css-overflow/overflow-video.html.ini deleted file mode 100644 index 1d0a9d754d6..00000000000 --- a/tests/wpt/meta/css/css-overflow/overflow-video.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[overflow-video.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/all-hosts.html.ini b/tests/wpt/meta/css/css-shadow-parts/all-hosts.html.ini new file mode 100644 index 00000000000..8fce3b78803 --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/all-hosts.html.ini @@ -0,0 +1,6 @@ +[all-hosts.html] + [::part with host selector styles in first host] + expected: FAIL + + [::part with host selector styles in second host] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/animation-part.html.ini b/tests/wpt/meta/css/css-shadow-parts/animation-part.html.ini new file mode 100644 index 00000000000..5609256d589 --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/animation-part.html.ini @@ -0,0 +1,2 @@ +[animation-part.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/both-part-and-exportparts.html.ini b/tests/wpt/meta/css/css-shadow-parts/both-part-and-exportparts.html.ini new file mode 100644 index 00000000000..44fae3819a5 --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/both-part-and-exportparts.html.ini @@ -0,0 +1,3 @@ +[both-part-and-exportparts.html] + [::part() rules match elements having both @part and @exportparts] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/complex-matching.html.ini b/tests/wpt/meta/css/css-shadow-parts/complex-matching.html.ini new file mode 100644 index 00000000000..6c473570671 --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/complex-matching.html.ini @@ -0,0 +1,3 @@ +[complex-matching.html] + [Complex selector for host works] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/double-forward.html.ini b/tests/wpt/meta/css/css-shadow-parts/double-forward.html.ini new file mode 100644 index 00000000000..2ca3e6ea37d --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/double-forward.html.ini @@ -0,0 +1,3 @@ +[double-forward.html] + [Part in inner host is forwarded through the middle host for styling by document style sheet] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/exportparts-different-scope.html.ini b/tests/wpt/meta/css/css-shadow-parts/exportparts-different-scope.html.ini new file mode 100644 index 00000000000..b6e6d38d30c --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/exportparts-different-scope.html.ini @@ -0,0 +1,2 @@ +[exportparts-different-scope.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/exportparts-multiple.html.ini b/tests/wpt/meta/css/css-shadow-parts/exportparts-multiple.html.ini new file mode 100644 index 00000000000..cb8e5c6ac20 --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/exportparts-multiple.html.ini @@ -0,0 +1,3 @@ +[exportparts-multiple.html] + [Forwarding part under multiple names should work] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/grouping-with-checked.html.ini b/tests/wpt/meta/css/css-shadow-parts/grouping-with-checked.html.ini new file mode 100644 index 00000000000..f39eba9208a --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/grouping-with-checked.html.ini @@ -0,0 +1,12 @@ +[grouping-with-checked.html] + [Styles applied to ::part(...)] + expected: FAIL + + [Styles applied to ::part(...):checked] + expected: FAIL + + [Styles applied via grouped selector including matched ::part(...):checked] + expected: FAIL + + [Styles applied via grouped selector including unmatched ::part(...):checked] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/grouping-with-disabled.html.ini b/tests/wpt/meta/css/css-shadow-parts/grouping-with-disabled.html.ini new file mode 100644 index 00000000000..3d6b92b5b8e --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/grouping-with-disabled.html.ini @@ -0,0 +1,12 @@ +[grouping-with-disabled.html] + [Styles applied to ::part(...)] + expected: FAIL + + [Styles applied to ::part(...):disabled] + expected: FAIL + + [Styles applied via grouped selector including matched ::part(...):disabled] + expected: FAIL + + [Styles applied via grouped selector including unmatched ::part(...):disabled] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/host-part-001.html.ini b/tests/wpt/meta/css/css-shadow-parts/host-part-001.html.ini new file mode 100644 index 00000000000..d52687ff32f --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/host-part-001.html.ini @@ -0,0 +1,3 @@ +[host-part-001.html] + [:host::part works] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/host-part-002.html.ini b/tests/wpt/meta/css/css-shadow-parts/host-part-002.html.ini new file mode 100644 index 00000000000..ad2c732963f --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/host-part-002.html.ini @@ -0,0 +1,3 @@ +[host-part-002.html] + [:host::part has correct cascading behavior] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/host-part-nesting.html.ini b/tests/wpt/meta/css/css-shadow-parts/host-part-nesting.html.ini new file mode 100644 index 00000000000..aacd37b4934 --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/host-part-nesting.html.ini @@ -0,0 +1,3 @@ +[host-part-nesting.html] + [:host::part works in nesting] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/idlharness.html.ini b/tests/wpt/meta/css/css-shadow-parts/idlharness.html.ini new file mode 100644 index 00000000000..cc4dd4679ca --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/idlharness.html.ini @@ -0,0 +1,12 @@ +[idlharness.html] + [Element interface: attribute part] + expected: FAIL + + [Element interface: element must inherit property "part" with the proper type] + expected: FAIL + + [Element interface: htmlElement must inherit property "part" with the proper type] + expected: FAIL + + [Element interface: svgElement must inherit property "part" with the proper type] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/inner-host.html.ini b/tests/wpt/meta/css/css-shadow-parts/inner-host.html.ini new file mode 100644 index 00000000000..5c34edcb01f --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/inner-host.html.ini @@ -0,0 +1,3 @@ +[inner-host.html] + [Part in outer host is styled by document style sheet] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/interaction-with-nested-pseudo-class.html.ini b/tests/wpt/meta/css/css-shadow-parts/interaction-with-nested-pseudo-class.html.ini new file mode 100644 index 00000000000..6d8dd62ca0c --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/interaction-with-nested-pseudo-class.html.ini @@ -0,0 +1,2 @@ +[interaction-with-nested-pseudo-class.html] + expected: TIMEOUT diff --git a/tests/wpt/meta/css/css-shadow-parts/interaction-with-pseudo-elements.html.ini b/tests/wpt/meta/css/css-shadow-parts/interaction-with-pseudo-elements.html.ini new file mode 100644 index 00000000000..1a36ec9273d --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/interaction-with-pseudo-elements.html.ini @@ -0,0 +1,18 @@ +[interaction-with-pseudo-elements.html] + [::before in selected host is styled] + expected: FAIL + + [::after in selected host is styled] + expected: FAIL + + [::placeholder in selected host is styled] + expected: FAIL + + [::selection in selected host is styled] + expected: FAIL + + [::first-line in selected host is styled] + expected: FAIL + + [::first-letter in selected host is styled] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/invalidation-change-exportparts-forward.html.ini b/tests/wpt/meta/css/css-shadow-parts/invalidation-change-exportparts-forward.html.ini new file mode 100644 index 00000000000..3cb69c11c77 --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/invalidation-change-exportparts-forward.html.ini @@ -0,0 +1,3 @@ +[invalidation-change-exportparts-forward.html] + [Part in selected host changed color] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/invalidation-change-part-name-forward.html.ini b/tests/wpt/meta/css/css-shadow-parts/invalidation-change-part-name-forward.html.ini new file mode 100644 index 00000000000..14c48dbeb23 --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/invalidation-change-part-name-forward.html.ini @@ -0,0 +1,3 @@ +[invalidation-change-part-name-forward.html] + [Part in selected host changed color] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/invalidation-change-part-name-idl-domtokenlist.html.ini b/tests/wpt/meta/css/css-shadow-parts/invalidation-change-part-name-idl-domtokenlist.html.ini new file mode 100644 index 00000000000..c086b128d2e --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/invalidation-change-part-name-idl-domtokenlist.html.ini @@ -0,0 +1,3 @@ +[invalidation-change-part-name-idl-domtokenlist.html] + [Part in selected host changed color via part IDL DOMTokenList attribute.] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/invalidation-change-part-name-idl-setter.html.ini b/tests/wpt/meta/css/css-shadow-parts/invalidation-change-part-name-idl-setter.html.ini new file mode 100644 index 00000000000..2269f6e697a --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/invalidation-change-part-name-idl-setter.html.ini @@ -0,0 +1,3 @@ +[invalidation-change-part-name-idl-setter.html] + [Part in selected host changed color via part IDL attribute setter.] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/invalidation-change-part-name.html.ini b/tests/wpt/meta/css/css-shadow-parts/invalidation-change-part-name.html.ini new file mode 100644 index 00000000000..97e25417c56 --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/invalidation-change-part-name.html.ini @@ -0,0 +1,3 @@ +[invalidation-change-part-name.html] + [Part in selected host changed color] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/invalidation-complex-selector-forward.html.ini b/tests/wpt/meta/css/css-shadow-parts/invalidation-complex-selector-forward.html.ini new file mode 100644 index 00000000000..b016daa81eb --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/invalidation-complex-selector-forward.html.ini @@ -0,0 +1,3 @@ +[invalidation-complex-selector-forward.html] + [Part in selected host changed color] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/invalidation-complex-selector.html.ini b/tests/wpt/meta/css/css-shadow-parts/invalidation-complex-selector.html.ini new file mode 100644 index 00000000000..772668059f2 --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/invalidation-complex-selector.html.ini @@ -0,0 +1,3 @@ +[invalidation-complex-selector.html] + [Part in selected host changed color] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/multiple-parts.html.ini b/tests/wpt/meta/css/css-shadow-parts/multiple-parts.html.ini new file mode 100644 index 00000000000..fc47c2d1237 --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/multiple-parts.html.ini @@ -0,0 +1,3 @@ +[multiple-parts.html] + [Double-part in selected host is styled] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/multiple-scopes.html.ini b/tests/wpt/meta/css/css-shadow-parts/multiple-scopes.html.ini new file mode 100644 index 00000000000..bd075e5632c --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/multiple-scopes.html.ini @@ -0,0 +1,27 @@ +[multiple-scopes.html] + [exported part selector matches from outer scope] + expected: FAIL + + [non-exported part selector does not match from outer scope] + expected: FAIL + + [pseudo-element selector alone does not match from outer scope] + expected: FAIL + + [exported part selector (for outer scope) does not match from middle scope] + expected: FAIL + + [correct part selector matches from middle scope] + expected: FAIL + + [pseudo-element selector alone does not match from middle scope] + expected: FAIL + + [selector with ::part(exported name) does not match from inner scope that exports the part] + expected: FAIL + + [selector with ::part(original name) does not match from inner scope that exports the part] + expected: FAIL + + [pseudo-element selector alone matches from inner scope] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/part-mutation-pseudo.html.ini b/tests/wpt/meta/css/css-shadow-parts/part-mutation-pseudo.html.ini new file mode 100644 index 00000000000..599855cc88b --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/part-mutation-pseudo.html.ini @@ -0,0 +1,3 @@ +[part-mutation-pseudo.html] + [Part in selected host changed color] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/part-name-idl.html.ini b/tests/wpt/meta/css/css-shadow-parts/part-name-idl.html.ini new file mode 100644 index 00000000000..27699f0b592 --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/part-name-idl.html.ini @@ -0,0 +1,12 @@ +[part-name-idl.html] + [Access to .part returns an empty DOMTokenList.] + expected: FAIL + + [Multiple names give a DOMTokenList with multiple entries.] + expected: FAIL + + [DOMTokenList created by access is persisted.] + expected: FAIL + + [Changes in DOMTokenList are refected in attribute.] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/part-nested-pseudo.html.ini b/tests/wpt/meta/css/css-shadow-parts/part-nested-pseudo.html.ini new file mode 100644 index 00000000000..1cc6eac641c --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/part-nested-pseudo.html.ini @@ -0,0 +1,2 @@ +[part-nested-pseudo.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/precedence-part-vs-part.html.ini b/tests/wpt/meta/css/css-shadow-parts/precedence-part-vs-part.html.ini new file mode 100644 index 00000000000..48b47fd2c73 --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/precedence-part-vs-part.html.ini @@ -0,0 +1,3 @@ +[precedence-part-vs-part.html] + [Style from document overrides style from outer CE] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/pseudo-classes-after-part.html.ini b/tests/wpt/meta/css/css-shadow-parts/pseudo-classes-after-part.html.ini new file mode 100644 index 00000000000..d37678023dd --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/pseudo-classes-after-part.html.ini @@ -0,0 +1,141 @@ +[pseudo-classes-after-part.html] + ["::part(mypart):active" should be a valid selector] + expected: FAIL + + ["::part(mypart):active-view-transition" should be a valid selector] + expected: FAIL + + ["::part(mypart):active-view-transition-type(mytype)" should be a valid selector] + expected: FAIL + + ["::part(mypart):any-link" should be a valid selector] + expected: FAIL + + ["::part(mypart):autofill" should be a valid selector] + expected: FAIL + + ["::part(mypart):checked" should be a valid selector] + expected: FAIL + + ["::part(mypart):default" should be a valid selector] + expected: FAIL + + ["::part(mypart):defined" should be a valid selector] + expected: FAIL + + ["::part(mypart):dir(ltr)" should be a valid selector] + expected: FAIL + + ["::part(mypart):disabled" should be a valid selector] + expected: FAIL + + ["::part(mypart):enabled" should be a valid selector] + expected: FAIL + + ["::part(mypart):focus" should be a valid selector] + expected: FAIL + + ["::part(mypart):focus-visible" should be a valid selector] + expected: FAIL + + ["::part(mypart):focus-within" should be a valid selector] + expected: FAIL + + ["::part(mypart):fullscreen" should be a valid selector] + expected: FAIL + + ["::part(mypart):future" should be a valid selector] + expected: FAIL + + ["::part(mypart):hover" should be a valid selector] + expected: FAIL + + ["::part(mypart):indeterminate" should be a valid selector] + expected: FAIL + + ["::part(mypart):in-range" should be a valid selector] + expected: FAIL + + ["::part(mypart):invalid" should be a valid selector] + expected: FAIL + + ["::part(mypart):lang(en)" should be a valid selector] + expected: FAIL + + ["::part(mypart):link" should be a valid selector] + expected: FAIL + + ["::part(mypart):modal" should be a valid selector] + expected: FAIL + + ["::part(mypart):open" should be a valid selector] + expected: FAIL + + ["::part(mypart):optional" should be a valid selector] + expected: FAIL + + ["::part(mypart):out-of-range" should be a valid selector] + expected: FAIL + + ["::part(mypart):past" should be a valid selector] + expected: FAIL + + ["::part(mypart):paused" should be a valid selector] + expected: FAIL + + ["::part(mypart):picture-in-picture" should be a valid selector] + expected: FAIL + + ["::part(mypart):placeholder-shown" should be a valid selector] + expected: FAIL + + ["::part(mypart):playing" should be a valid selector] + expected: FAIL + + ["::part(mypart):popover-open" should be a valid selector] + expected: FAIL + + ["::part(mypart):read-only" should be a valid selector] + expected: FAIL + + ["::part(mypart):read-write" should be a valid selector] + expected: FAIL + + ["::part(mypart):required" should be a valid selector] + expected: FAIL + + ["::part(mypart):state(mystate)" should be a valid selector] + expected: FAIL + + ["::part(mypart):target" should be a valid selector] + expected: FAIL + + ["::part(mypart):user-invalid" should be a valid selector] + expected: FAIL + + ["::part(mypart):user-valid" should be a valid selector] + expected: FAIL + + ["::part(mypart):valid" should be a valid selector] + expected: FAIL + + ["::part(mypart):visited" should be a valid selector] + expected: FAIL + + ["::part(mypart):xr-overlay" should be a valid selector] + expected: FAIL + + ["::part(mypart):not(:hover)" should be a valid selector] + expected: FAIL + + ["::part(mypart):is(:hover)" should be a valid selector] + expected: FAIL + + ["::part(mypart):where(:hover)" should be a valid selector] + expected: FAIL + + ["::part(mypart):is(:first-child)" should be a valid selector] + expected: FAIL + + ["::part(mypart):where(:first-child)" should be a valid selector] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/pseudo-elements-after-part.html.ini b/tests/wpt/meta/css/css-shadow-parts/pseudo-elements-after-part.html.ini new file mode 100644 index 00000000000..02f53015dc9 --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/pseudo-elements-after-part.html.ini @@ -0,0 +1,126 @@ +[pseudo-elements-after-part.html] + ["::part(mypart)::after" should be a valid selector] + expected: FAIL + + ["::part(mypart)::backdrop" should be a valid selector] + expected: FAIL + + ["::part(mypart)::before" should be a valid selector] + expected: FAIL + + ["::part(mypart)::cue" should be a valid selector] + expected: FAIL + + ["::part(mypart)::details-content" should be a valid selector] + expected: FAIL + + ["::part(mypart)::file-selector-button" should be a valid selector] + expected: FAIL + + ["::part(mypart)::first-letter" should be a valid selector] + expected: FAIL + + ["::part(mypart)::first-line" should be a valid selector] + expected: FAIL + + ["::part(mypart)::grammar-error" should be a valid selector] + expected: FAIL + + ["::part(mypart)::highlight(myhighlight)" should be a valid selector] + expected: FAIL + + ["::part(mypart)::marker" should be a valid selector] + expected: FAIL + + ["::part(mypart)::placeholder" should be a valid selector] + expected: FAIL + + ["::part(mypart)::search-text" should be a valid selector] + expected: FAIL + + ["::part(mypart)::selection" should be a valid selector] + expected: FAIL + + ["::part(mypart)::spelling-error" should be a valid selector] + expected: FAIL + + ["::part(mypart)::target-text" should be a valid selector] + expected: FAIL + + ["::part(mypart)::view-transition" should be a valid selector] + expected: FAIL + + ["::part(mypart)::view-transition-group(*)" should be a valid selector] + expected: FAIL + + ["::part(mypart)::view-transition-image-pair(*)" should be a valid selector] + expected: FAIL + + ["::part(mypart)::view-transition-new(*)" should be a valid selector] + expected: FAIL + + ["::part(mypart)::view-transition-old(*)" should be a valid selector] + expected: FAIL + + [computed style for ::part()::after] + expected: FAIL + + [computed style for ::part()::backdrop] + expected: FAIL + + [computed style for ::part()::before] + expected: FAIL + + [computed style for ::part()::details-content] + expected: FAIL + + [computed style for ::part()::file-selector-button] + expected: FAIL + + [computed style for ::part()::first-letter] + expected: FAIL + + [computed style for ::part()::first-line] + expected: FAIL + + [computed style for ::part()::grammar-error] + expected: FAIL + + [computed style for ::part()::highlight(myhighlight)] + expected: FAIL + + [computed style for ::part()::placeholder] + expected: FAIL + + [computed style for ::part()::search-text] + expected: FAIL + + [computed style for ::part()::selection] + expected: FAIL + + [computed style for ::part()::spelling-error] + expected: FAIL + + [computed style for ::part()::target-text] + expected: FAIL + + [::part styles with ::part(mypart)::after {\n display: block;\n content: "";\n height: 77px;\n } and <div part='mypart'></div>] + expected: FAIL + + [::part styles with ::part(mypart)::before {\n display: block;\n content: "";\n height: 46px;\n } and <div part='mypart'></div>] + expected: FAIL + + [::part styles with ::part(mypart)::details-content {\n height: 371px;\n } and <details part='mypart'><summary style="height:47px">summary</summary>details</details>] + expected: FAIL + + [::part styles with ::part(mypart)::file-selector-button {\n height: 94px;\n padding: 0;\n margin: 0;\n border: none;\n appearance: none;\n } and <input type=file part=mypart>] + expected: FAIL + + [::part styles with ::part(mypart) {\n font: 20px/1 Ahem;\n }\n ::part(mypart)::first-letter {\n font-size: 86px;\n } and <div part=mypart>X<br>X</div>] + expected: FAIL + + [::part styles with ::part(mypart) {\n font: 20px/1 Ahem;\n }\n ::part(mypart)::first-line {\n font-size: 86px;\n } and <div part=mypart>X<br>X</div>] + expected: FAIL + + [::part styles with ::part(mypart)::marker {\n font: 63px/1.0 Ahem;\n content: "X";\n } and <li style="list-style-position: inside" part="mypart"></li>] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/serialization.html.ini b/tests/wpt/meta/css/css-shadow-parts/serialization.html.ini new file mode 100644 index 00000000000..bf16109e185 --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/serialization.html.ini @@ -0,0 +1,9 @@ +[serialization.html] + [Escape start parenthesis in ::part name.] + expected: FAIL + + [Escape start space in ::part name.] + expected: FAIL + + [Collapse spaces in ::part names list.] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/simple-forward-shorthand.html.ini b/tests/wpt/meta/css/css-shadow-parts/simple-forward-shorthand.html.ini new file mode 100644 index 00000000000..ea340dff75c --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/simple-forward-shorthand.html.ini @@ -0,0 +1,3 @@ +[simple-forward-shorthand.html] + [Part in inner host is forwarded, under the same name, for styling by document style sheet] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/simple-forward.html.ini b/tests/wpt/meta/css/css-shadow-parts/simple-forward.html.ini new file mode 100644 index 00000000000..757dfe7d435 --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/simple-forward.html.ini @@ -0,0 +1,3 @@ +[simple-forward.html] + [Part in inner host is forwarded for styling by document style sheet] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/simple-inline.html.ini b/tests/wpt/meta/css/css-shadow-parts/simple-inline.html.ini new file mode 100644 index 00000000000..4121d642be0 --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/simple-inline.html.ini @@ -0,0 +1,3 @@ +[simple-inline.html] + [Part in selected host is styled] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/simple.html.ini b/tests/wpt/meta/css/css-shadow-parts/simple.html.ini new file mode 100644 index 00000000000..9c3278c9e3a --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/simple.html.ini @@ -0,0 +1,3 @@ +[simple.html] + [Part in selected host is styled] + expected: FAIL diff --git a/tests/wpt/meta/css/css-shadow-parts/style-sharing.html.ini b/tests/wpt/meta/css/css-shadow-parts/style-sharing.html.ini new file mode 100644 index 00000000000..1bb66f211bf --- /dev/null +++ b/tests/wpt/meta/css/css-shadow-parts/style-sharing.html.ini @@ -0,0 +1,3 @@ +[style-sharing.html] + [Part in selected host does not incorrectly share style with non-part] + expected: FAIL diff --git a/tests/wpt/meta/css/css-sizing/responsive-iframe-cross-origin.sub.tentative.html.ini b/tests/wpt/meta/css/css-sizing/responsive-iframe-cross-origin.sub.tentative.html.ini new file mode 100644 index 00000000000..9682a816732 --- /dev/null +++ b/tests/wpt/meta/css/css-sizing/responsive-iframe-cross-origin.sub.tentative.html.ini @@ -0,0 +1,2 @@ +[responsive-iframe-cross-origin.sub.tentative.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-sizing/responsive-iframe.tentative.html.ini b/tests/wpt/meta/css/css-sizing/responsive-iframe.tentative.html.ini new file mode 100644 index 00000000000..768b6a9e977 --- /dev/null +++ b/tests/wpt/meta/css/css-sizing/responsive-iframe.tentative.html.ini @@ -0,0 +1,2 @@ +[responsive-iframe.tentative.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-tables/table-cell-overflow-auto-scrolled.html.ini b/tests/wpt/meta/css/css-tables/table-cell-overflow-auto-scrolled.html.ini new file mode 100644 index 00000000000..55805c45ee2 --- /dev/null +++ b/tests/wpt/meta/css/css-tables/table-cell-overflow-auto-scrolled.html.ini @@ -0,0 +1,2 @@ +[table-cell-overflow-auto-scrolled.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-text/text-autospace/text-autospace-vs-001.html.ini b/tests/wpt/meta/css/css-text/text-autospace/text-autospace-vs-001.html.ini new file mode 100644 index 00000000000..04071c4d8b3 --- /dev/null +++ b/tests/wpt/meta/css/css-text/text-autospace/text-autospace-vs-001.html.ini @@ -0,0 +1,2 @@ +[text-autospace-vs-001.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-text/word-break/word-break-keep-all-u002d.html.ini b/tests/wpt/meta/css/css-text/word-break/word-break-keep-all-u002d.html.ini new file mode 100644 index 00000000000..5de432ffdee --- /dev/null +++ b/tests/wpt/meta/css/css-text/word-break/word-break-keep-all-u002d.html.ini @@ -0,0 +1,2 @@ +[word-break-keep-all-u002d.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-values/if-conditionals.html.ini b/tests/wpt/meta/css/css-values/if-conditionals.html.ini index aa2285ad06e..25afac97880 100644 --- a/tests/wpt/meta/css/css-values/if-conditionals.html.ini +++ b/tests/wpt/meta/css/css-values/if-conditionals.html.ini @@ -442,3 +442,126 @@ [CSS Values and Units Test: CSS inline if() function 147] expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 148] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 149] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 150] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 151] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 152] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 153] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 154] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 155] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 156] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 157] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 158] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 159] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 160] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 161] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 162] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 163] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 164] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 165] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 166] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 167] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 168] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 169] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 170] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 171] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 172] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 173] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 174] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 175] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 176] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 177] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 178] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 179] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 180] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 181] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 182] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 183] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 184] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 185] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 186] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 187] + expected: FAIL + + [CSS Values and Units Test: CSS inline if() function 188] + expected: FAIL diff --git a/tests/wpt/meta/css/css-values/tree-counting/sibling-function-container-query-invalidation.html.ini b/tests/wpt/meta/css/css-values/tree-counting/sibling-function-container-query-invalidation.html.ini new file mode 100644 index 00000000000..4d74ed1e63c --- /dev/null +++ b/tests/wpt/meta/css/css-values/tree-counting/sibling-function-container-query-invalidation.html.ini @@ -0,0 +1,12 @@ +[sibling-function-container-query-invalidation.html] + [sibling-index() in @container width query matching after removal] + expected: FAIL + + [sibling-count() in @container width query matching after removal] + expected: FAIL + + [sibling-index() in @container style() query matching after removal] + expected: FAIL + + [sibling-count() in @container style() query matching after removal] + expected: FAIL diff --git a/tests/wpt/meta/css/css-values/tree-counting/sibling-index-keyframe-registered-properties-dynamic.html.ini b/tests/wpt/meta/css/css-values/tree-counting/sibling-index-keyframe-registered-properties-dynamic.html.ini index 807d5e54ab4..4be76b217d3 100644 --- a/tests/wpt/meta/css/css-values/tree-counting/sibling-index-keyframe-registered-properties-dynamic.html.ini +++ b/tests/wpt/meta/css/css-values/tree-counting/sibling-index-keyframe-registered-properties-dynamic.html.ini @@ -52,3 +52,9 @@ [Removing a preceding sibling of #target reduces the sibling-index() for --color] expected: FAIL + + [Initially, the sibling-index() is 3 for --list] + expected: FAIL + + [Removing a preceding sibling of #target reduces the sibling-index() for --list] + expected: FAIL diff --git a/tests/wpt/meta/custom-elements/registries/idlharness.window.js.ini b/tests/wpt/meta/custom-elements/registries/idlharness.window.js.ini index 44fbd51d205..e033f991a62 100644 --- a/tests/wpt/meta/custom-elements/registries/idlharness.window.js.ini +++ b/tests/wpt/meta/custom-elements/registries/idlharness.window.js.ini @@ -1,3 +1,42 @@ [idlharness.window.html] [idl_test setup] expected: FAIL + + [idl_test validation] + expected: FAIL + + [Partial interface CustomElementRegistry: member names are unique] + expected: FAIL + + [Partial interface HTMLTemplateElement: member names are unique] + expected: FAIL + + [Partial interface Element: member names are unique] + expected: FAIL + + [Partial dictionary ShadowRootInit: member names are unique] + expected: FAIL + + [Partial dictionary ElementCreationOptions: member names are unique] + expected: FAIL + + [Document includes DocumentOrShadowRoot: member names are unique] + expected: FAIL + + [ShadowRoot includes DocumentOrShadowRoot: member names are unique] + expected: FAIL + + [HTMLTemplateElement interface: attribute shadowRootCustomElementRegistry] + expected: FAIL + + [CustomElementRegistry interface: operation initialize(Node)] + expected: FAIL + + [Document interface: attribute customElementRegistry] + expected: FAIL + + [ShadowRoot interface: attribute customElementRegistry] + expected: FAIL + + [Element interface: attribute customElementRegistry] + expected: FAIL diff --git a/tests/wpt/meta/dom/ranges/Range-in-shadow-after-the-shadow-removed.html.ini b/tests/wpt/meta/dom/ranges/Range-in-shadow-after-the-shadow-removed.html.ini deleted file mode 100644 index b2003b5c788..00000000000 --- a/tests/wpt/meta/dom/ranges/Range-in-shadow-after-the-shadow-removed.html.ini +++ /dev/null @@ -1,14 +0,0 @@ -[Range-in-shadow-after-the-shadow-removed.html?mode=closed] - [Range in shadow should stay in the shadow after the host is removed] - expected: FAIL - - [Range in shadow should stay in the shadow after the host parent is removed] - expected: FAIL - - -[Range-in-shadow-after-the-shadow-removed.html?mode=open] - [Range in shadow should stay in the shadow after the host is removed] - expected: FAIL - - [Range in shadow should stay in the shadow after the host parent is removed] - expected: FAIL diff --git a/tests/wpt/meta/domxpath/fn-lang.html.ini b/tests/wpt/meta/domxpath/fn-lang.html.ini deleted file mode 100644 index 31754463dcc..00000000000 --- a/tests/wpt/meta/domxpath/fn-lang.html.ini +++ /dev/null @@ -1,21 +0,0 @@ -[fn-lang.html] - [lang("en"): <root><match lang="en"></match></root>] - expected: FAIL - - [lang("en"): <root><match lang="EN"></match></root>] - expected: FAIL - - [lang("en"): <root><match lang="en-us"></match></root>] - expected: FAIL - - [lang("en"): <root><unmatch></unmatch></root>] - expected: FAIL - - [lang("ja"): <root lang="ja"><match></match></root>] - expected: FAIL - - [lang("ja"): <root lang="ja-jp"><unmatch lang="ja_JP"></unmatch></root>] - expected: FAIL - - [lang("ko"): <root><unmatch lang="Ko"></unmatch></root>] - expected: FAIL diff --git a/tests/wpt/meta/domxpath/node-sets.html.ini b/tests/wpt/meta/domxpath/node-sets.html.ini deleted file mode 100644 index 856f22dd655..00000000000 --- a/tests/wpt/meta/domxpath/node-sets.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[node-sets.html] - [| operator should evaluate both sides of expressions with the same context node] - expected: FAIL diff --git a/tests/wpt/meta/domxpath/text-html-attributes.html.ini b/tests/wpt/meta/domxpath/text-html-attributes.html.ini index 803f418282a..7257f61a118 100644 --- a/tests/wpt/meta/domxpath/text-html-attributes.html.ini +++ b/tests/wpt/meta/domxpath/text-html-attributes.html.ini @@ -1,13 +1,7 @@ [text-html-attributes.html] - [Select html element based on attribute] - expected: FAIL - [Select html element based on attribute mixed case] expected: FAIL - [Select both HTML and SVG elements based on attribute] - expected: FAIL - [Select HTML element with non-ascii attribute 1] expected: FAIL @@ -23,9 +17,6 @@ [Select both HTML and SVG elements based on mixed case attribute] expected: FAIL - [Select SVG elements with refX attribute] - expected: FAIL - [Select SVG element with non-ascii attribute 1] expected: FAIL diff --git a/tests/wpt/meta/domxpath/xml_xpath_runner.html.ini b/tests/wpt/meta/domxpath/xml_xpath_runner.html.ini deleted file mode 100644 index e7d698afb6b..00000000000 --- a/tests/wpt/meta/domxpath/xml_xpath_runner.html.ini +++ /dev/null @@ -1,3072 +0,0 @@ -[xml_xpath_runner.html] - [XPath tests] - expected: FAIL - - [XPath tests 1] - expected: FAIL - - [XPath tests 2] - expected: FAIL - - [XPath tests 3] - expected: FAIL - - [XPath tests 4] - expected: FAIL - - [XPath tests 5] - expected: FAIL - - [XPath tests 6] - expected: FAIL - - [XPath tests 7] - expected: FAIL - - [XPath tests 8] - expected: FAIL - - [XPath tests 9] - expected: FAIL - - [XPath tests 10] - expected: FAIL - - [XPath tests 11] - expected: FAIL - - [XPath tests 12] - expected: FAIL - - [XPath tests 13] - expected: FAIL - - [XPath tests 14] - expected: FAIL - - [XPath tests 15] - expected: FAIL - - [XPath tests 16] - expected: FAIL - - [XPath tests 17] - expected: FAIL - - [XPath tests 18] - expected: FAIL - - [XPath tests 19] - expected: FAIL - - [XPath tests 20] - expected: FAIL - - [XPath tests 21] - expected: FAIL - - [XPath tests 22] - expected: FAIL - - [XPath tests 23] - expected: FAIL - - [XPath tests 24] - expected: FAIL - - [XPath tests 25] - expected: FAIL - - [XPath tests 26] - expected: FAIL - - [XPath tests 27] - expected: FAIL - - [XPath tests 28] - expected: FAIL - - [XPath tests 29] - expected: FAIL - - [XPath tests 30] - expected: FAIL - - [XPath tests 31] - expected: FAIL - - [XPath tests 32] - expected: FAIL - - [XPath tests 33] - expected: FAIL - - [XPath tests 34] - expected: FAIL - - [XPath tests 35] - expected: FAIL - - [XPath tests 36] - expected: FAIL - - [XPath tests 37] - expected: FAIL - - [XPath tests 38] - expected: FAIL - - [XPath tests 39] - expected: FAIL - - [XPath tests 40] - expected: FAIL - - [XPath tests 41] - expected: FAIL - - [XPath tests 42] - expected: FAIL - - [XPath tests 43] - expected: FAIL - - [XPath tests 44] - expected: FAIL - - [XPath tests 45] - expected: FAIL - - [XPath tests 46] - expected: FAIL - - [XPath tests 47] - expected: FAIL - - [XPath tests 48] - expected: FAIL - - [XPath tests 49] - expected: FAIL - - [XPath tests 50] - expected: FAIL - - [XPath tests 51] - expected: FAIL - - [XPath tests 52] - expected: FAIL - - [XPath tests 53] - expected: FAIL - - [XPath tests 54] - expected: FAIL - - [XPath tests 55] - expected: FAIL - - [XPath tests 56] - expected: FAIL - - [XPath tests 57] - expected: FAIL - - [XPath tests 58] - expected: FAIL - - [XPath tests 59] - expected: FAIL - - [XPath tests 60] - expected: FAIL - - [XPath tests 61] - expected: FAIL - - [XPath tests 62] - expected: FAIL - - [XPath tests 63] - expected: FAIL - - [XPath tests 64] - expected: FAIL - - [XPath tests 65] - expected: FAIL - - [XPath tests 66] - expected: FAIL - - [XPath tests 67] - expected: FAIL - - [XPath tests 68] - expected: FAIL - - [XPath tests 69] - expected: FAIL - - [XPath tests 70] - expected: FAIL - - [XPath tests 71] - expected: FAIL - - [XPath tests 72] - expected: FAIL - - [XPath tests 73] - expected: FAIL - - [XPath tests 74] - expected: FAIL - - [XPath tests 75] - expected: FAIL - - [XPath tests 76] - expected: FAIL - - [XPath tests 77] - expected: FAIL - - [XPath tests 78] - expected: FAIL - - [XPath tests 79] - expected: FAIL - - [XPath tests 80] - expected: FAIL - - [XPath tests 81] - expected: FAIL - - [XPath tests 82] - expected: FAIL - - [XPath tests 83] - expected: FAIL - - [XPath tests 84] - expected: FAIL - - [XPath tests 85] - expected: FAIL - - [XPath tests 86] - expected: FAIL - - [XPath tests 87] - expected: FAIL - - [XPath tests 88] - expected: FAIL - - [XPath tests 89] - expected: FAIL - - [XPath tests 90] - expected: FAIL - - [XPath tests 91] - expected: FAIL - - [XPath tests 92] - expected: FAIL - - [XPath tests 93] - expected: FAIL - - [XPath tests 94] - expected: FAIL - - [XPath tests 95] - expected: FAIL - - [XPath tests 96] - expected: FAIL - - [XPath tests 97] - expected: FAIL - - [XPath tests 98] - expected: FAIL - - [XPath tests 99] - expected: FAIL - - [XPath tests 100] - expected: FAIL - - [XPath tests 101] - expected: FAIL - - [XPath tests 102] - expected: FAIL - - [XPath tests 103] - expected: FAIL - - [XPath tests 104] - expected: FAIL - - [XPath tests 105] - expected: FAIL - - [XPath tests 106] - expected: FAIL - - [XPath tests 107] - expected: FAIL - - [XPath tests 108] - expected: FAIL - - [XPath tests 109] - expected: FAIL - - [XPath tests 110] - expected: FAIL - - [XPath tests 111] - expected: FAIL - - [XPath tests 112] - expected: FAIL - - [XPath tests 113] - expected: FAIL - - [XPath tests 114] - expected: FAIL - - [XPath tests 115] - expected: FAIL - - [XPath tests 116] - expected: FAIL - - [XPath tests 117] - expected: FAIL - - [XPath tests 118] - expected: FAIL - - [XPath tests 119] - expected: FAIL - - [XPath tests 120] - expected: FAIL - - [XPath tests 121] - expected: FAIL - - [XPath tests 122] - expected: FAIL - - [XPath tests 123] - expected: FAIL - - [XPath tests 124] - expected: FAIL - - [XPath tests 125] - expected: FAIL - - [XPath tests 126] - expected: FAIL - - [XPath tests 127] - expected: FAIL - - [XPath tests 128] - expected: FAIL - - [XPath tests 129] - expected: FAIL - - [XPath tests 130] - expected: FAIL - - [XPath tests 131] - expected: FAIL - - [XPath tests 132] - expected: FAIL - - [XPath tests 133] - expected: FAIL - - [XPath tests 134] - expected: FAIL - - [XPath tests 135] - expected: FAIL - - [XPath tests 136] - expected: FAIL - - [XPath tests 137] - expected: FAIL - - [XPath tests 138] - expected: FAIL - - [XPath tests 139] - expected: FAIL - - [XPath tests 140] - expected: FAIL - - [XPath tests 141] - expected: FAIL - - [XPath tests 142] - expected: FAIL - - [XPath tests 143] - expected: FAIL - - [XPath tests 144] - expected: FAIL - - [XPath tests 145] - expected: FAIL - - [XPath tests 146] - expected: FAIL - - [XPath tests 147] - expected: FAIL - - [XPath tests 148] - expected: FAIL - - [XPath tests 149] - expected: FAIL - - [XPath tests 150] - expected: FAIL - - [XPath tests 151] - expected: FAIL - - [XPath tests 152] - expected: FAIL - - [XPath tests 153] - expected: FAIL - - [XPath tests 154] - expected: FAIL - - [XPath tests 155] - expected: FAIL - - [XPath tests 156] - expected: FAIL - - [XPath tests 157] - expected: FAIL - - [XPath tests 158] - expected: FAIL - - [XPath tests 159] - expected: FAIL - - [XPath tests 160] - expected: FAIL - - [XPath tests 161] - expected: FAIL - - [XPath tests 162] - expected: FAIL - - [XPath tests 163] - expected: FAIL - - [XPath tests 164] - expected: FAIL - - [XPath tests 165] - expected: FAIL - - [XPath tests 166] - expected: FAIL - - [XPath tests 167] - expected: FAIL - - [XPath tests 168] - expected: FAIL - - [XPath tests 169] - expected: FAIL - - [XPath tests 170] - expected: FAIL - - [XPath tests 171] - expected: FAIL - - [XPath tests 172] - expected: FAIL - - [XPath tests 173] - expected: FAIL - - [XPath tests 174] - expected: FAIL - - [XPath tests 175] - expected: FAIL - - [XPath tests 176] - expected: FAIL - - [XPath tests 177] - expected: FAIL - - [XPath tests 178] - expected: FAIL - - [XPath tests 179] - expected: FAIL - - [XPath tests 180] - expected: FAIL - - [XPath tests 181] - expected: FAIL - - [XPath tests 182] - expected: FAIL - - [XPath tests 183] - expected: FAIL - - [XPath tests 184] - expected: FAIL - - [XPath tests 185] - expected: FAIL - - [XPath tests 186] - expected: FAIL - - [XPath tests 187] - expected: FAIL - - [XPath tests 188] - expected: FAIL - - [XPath tests 189] - expected: FAIL - - [XPath tests 190] - expected: FAIL - - [XPath tests 191] - expected: FAIL - - [XPath tests 192] - expected: FAIL - - [XPath tests 193] - expected: FAIL - - [XPath tests 194] - expected: FAIL - - [XPath tests 195] - expected: FAIL - - [XPath tests 196] - expected: FAIL - - [XPath tests 197] - expected: FAIL - - [XPath tests 198] - expected: FAIL - - [XPath tests 199] - expected: FAIL - - [XPath tests 200] - expected: FAIL - - [XPath tests 201] - expected: FAIL - - [XPath tests 202] - expected: FAIL - - [XPath tests 203] - expected: FAIL - - [XPath tests 204] - expected: FAIL - - [XPath tests 205] - expected: FAIL - - [XPath tests 206] - expected: FAIL - - [XPath tests 207] - expected: FAIL - - [XPath tests 208] - expected: FAIL - - [XPath tests 209] - expected: FAIL - - [XPath tests 210] - expected: FAIL - - [XPath tests 211] - expected: FAIL - - [XPath tests 212] - expected: FAIL - - [XPath tests 213] - expected: FAIL - - [XPath tests 214] - expected: FAIL - - [XPath tests 215] - expected: FAIL - - [XPath tests 216] - expected: FAIL - - [XPath tests 217] - expected: FAIL - - [XPath tests 218] - expected: FAIL - - [XPath tests 219] - expected: FAIL - - [XPath tests 220] - expected: FAIL - - [XPath tests 221] - expected: FAIL - - [XPath tests 222] - expected: FAIL - - [XPath tests 223] - expected: FAIL - - [XPath tests 224] - expected: FAIL - - [XPath tests 225] - expected: FAIL - - [XPath tests 226] - expected: FAIL - - [XPath tests 227] - expected: FAIL - - [XPath tests 228] - expected: FAIL - - [XPath tests 229] - expected: FAIL - - [XPath tests 230] - expected: FAIL - - [XPath tests 231] - expected: FAIL - - [XPath tests 232] - expected: FAIL - - [XPath tests 233] - expected: FAIL - - [XPath tests 234] - expected: FAIL - - [XPath tests 235] - expected: FAIL - - [XPath tests 236] - expected: FAIL - - [XPath tests 237] - expected: FAIL - - [XPath tests 238] - expected: FAIL - - [XPath tests 239] - expected: FAIL - - [XPath tests 240] - expected: FAIL - - [XPath tests 241] - expected: FAIL - - [XPath tests 242] - expected: FAIL - - [XPath tests 243] - expected: FAIL - - [XPath tests 244] - expected: FAIL - - [XPath tests 245] - expected: FAIL - - [XPath tests 246] - expected: FAIL - - [XPath tests 247] - expected: FAIL - - [XPath tests 248] - expected: FAIL - - [XPath tests 249] - expected: FAIL - - [XPath tests 250] - expected: FAIL - - [XPath tests 251] - expected: FAIL - - [XPath tests 252] - expected: FAIL - - [XPath tests 253] - expected: FAIL - - [XPath tests 254] - expected: FAIL - - [XPath tests 255] - expected: FAIL - - [XPath tests 256] - expected: FAIL - - [XPath tests 257] - expected: FAIL - - [XPath tests 258] - expected: FAIL - - [XPath tests 259] - expected: FAIL - - [XPath tests 260] - expected: FAIL - - [XPath tests 261] - expected: FAIL - - [XPath tests 262] - expected: FAIL - - [XPath tests 263] - expected: FAIL - - [XPath tests 264] - expected: FAIL - - [XPath tests 265] - expected: FAIL - - [XPath tests 266] - expected: FAIL - - [XPath tests 267] - expected: FAIL - - [XPath tests 268] - expected: FAIL - - [XPath tests 269] - expected: FAIL - - [XPath tests 270] - expected: FAIL - - [XPath tests 271] - expected: FAIL - - [XPath tests 272] - expected: FAIL - - [XPath tests 273] - expected: FAIL - - [XPath tests 274] - expected: FAIL - - [XPath tests 275] - expected: FAIL - - [XPath tests 276] - expected: FAIL - - [XPath tests 277] - expected: FAIL - - [XPath tests 278] - expected: FAIL - - [XPath tests 279] - expected: FAIL - - [XPath tests 280] - expected: FAIL - - [XPath tests 281] - expected: FAIL - - [XPath tests 282] - expected: FAIL - - [XPath tests 283] - expected: FAIL - - [XPath tests 284] - expected: FAIL - - [XPath tests 285] - expected: FAIL - - [XPath tests 286] - expected: FAIL - - [XPath tests 287] - expected: FAIL - - [XPath tests 288] - expected: FAIL - - [XPath tests 289] - expected: FAIL - - [XPath tests 290] - expected: FAIL - - [XPath tests 291] - expected: FAIL - - [XPath tests 292] - expected: FAIL - - [XPath tests 293] - expected: FAIL - - [XPath tests 294] - expected: FAIL - - [XPath tests 295] - expected: FAIL - - [XPath tests 296] - expected: FAIL - - [XPath tests 297] - expected: FAIL - - [XPath tests 298] - expected: FAIL - - [XPath tests 299] - expected: FAIL - - [XPath tests 300] - expected: FAIL - - [XPath tests 301] - expected: FAIL - - [XPath tests 302] - expected: FAIL - - [XPath tests 303] - expected: FAIL - - [XPath tests 304] - expected: FAIL - - [XPath tests 305] - expected: FAIL - - [XPath tests 306] - expected: FAIL - - [XPath tests 307] - expected: FAIL - - [XPath tests 308] - expected: FAIL - - [XPath tests 309] - expected: FAIL - - [XPath tests 310] - expected: FAIL - - [XPath tests 311] - expected: FAIL - - [XPath tests 312] - expected: FAIL - - [XPath tests 313] - expected: FAIL - - [XPath tests 314] - expected: FAIL - - [XPath tests 315] - expected: FAIL - - [XPath tests 316] - expected: FAIL - - [XPath tests 317] - expected: FAIL - - [XPath tests 318] - expected: FAIL - - [XPath tests 319] - expected: FAIL - - [XPath tests 320] - expected: FAIL - - [XPath tests 321] - expected: FAIL - - [XPath tests 322] - expected: FAIL - - [XPath tests 323] - expected: FAIL - - [XPath tests 324] - expected: FAIL - - [XPath tests 325] - expected: FAIL - - [XPath tests 326] - expected: FAIL - - [XPath tests 327] - expected: FAIL - - [XPath tests 328] - expected: FAIL - - [XPath tests 329] - expected: FAIL - - [XPath tests 330] - expected: FAIL - - [XPath tests 331] - expected: FAIL - - [XPath tests 332] - expected: FAIL - - [XPath tests 333] - expected: FAIL - - [XPath tests 334] - expected: FAIL - - [XPath tests 335] - expected: FAIL - - [XPath tests 336] - expected: FAIL - - [XPath tests 337] - expected: FAIL - - [XPath tests 338] - expected: FAIL - - [XPath tests 339] - expected: FAIL - - [XPath tests 340] - expected: FAIL - - [XPath tests 341] - expected: FAIL - - [XPath tests 342] - expected: FAIL - - [XPath tests 343] - expected: FAIL - - [XPath tests 344] - expected: FAIL - - [XPath tests 345] - expected: FAIL - - [XPath tests 346] - expected: FAIL - - [XPath tests 347] - expected: FAIL - - [XPath tests 348] - expected: FAIL - - [XPath tests 349] - expected: FAIL - - [XPath tests 350] - expected: FAIL - - [XPath tests 351] - expected: FAIL - - [XPath tests 352] - expected: FAIL - - [XPath tests 353] - expected: FAIL - - [XPath tests 354] - expected: FAIL - - [XPath tests 355] - expected: FAIL - - [XPath tests 356] - expected: FAIL - - [XPath tests 357] - expected: FAIL - - [XPath tests 358] - expected: FAIL - - [XPath tests 359] - expected: FAIL - - [XPath tests 360] - expected: FAIL - - [XPath tests 361] - expected: FAIL - - [XPath tests 362] - expected: FAIL - - [XPath tests 363] - expected: FAIL - - [XPath tests 364] - expected: FAIL - - [XPath tests 365] - expected: FAIL - - [XPath tests 366] - expected: FAIL - - [XPath tests 367] - expected: FAIL - - [XPath tests 368] - expected: FAIL - - [XPath tests 369] - expected: FAIL - - [XPath tests 370] - expected: FAIL - - [XPath tests 371] - expected: FAIL - - [XPath tests 372] - expected: FAIL - - [XPath tests 373] - expected: FAIL - - [XPath tests 374] - expected: FAIL - - [XPath tests 375] - expected: FAIL - - [XPath tests 376] - expected: FAIL - - [XPath tests 377] - expected: FAIL - - [XPath tests 378] - expected: FAIL - - [XPath tests 379] - expected: FAIL - - [XPath tests 380] - expected: FAIL - - [XPath tests 381] - expected: FAIL - - [XPath tests 382] - expected: FAIL - - [XPath tests 383] - expected: FAIL - - [XPath tests 384] - expected: FAIL - - [XPath tests 385] - expected: FAIL - - [XPath tests 386] - expected: FAIL - - [XPath tests 387] - expected: FAIL - - [XPath tests 388] - expected: FAIL - - [XPath tests 389] - expected: FAIL - - [XPath tests 390] - expected: FAIL - - [XPath tests 391] - expected: FAIL - - [XPath tests 392] - expected: FAIL - - [XPath tests 393] - expected: FAIL - - [XPath tests 394] - expected: FAIL - - [XPath tests 395] - expected: FAIL - - [XPath tests 396] - expected: FAIL - - [XPath tests 397] - expected: FAIL - - [XPath tests 398] - expected: FAIL - - [XPath tests 399] - expected: FAIL - - [XPath tests 400] - expected: FAIL - - [XPath tests 401] - expected: FAIL - - [XPath tests 402] - expected: FAIL - - [XPath tests 403] - expected: FAIL - - [XPath tests 404] - expected: FAIL - - [XPath tests 405] - expected: FAIL - - [XPath tests 406] - expected: FAIL - - [XPath tests 407] - expected: FAIL - - [XPath tests 408] - expected: FAIL - - [XPath tests 409] - expected: FAIL - - [XPath tests 410] - expected: FAIL - - [XPath tests 411] - expected: FAIL - - [XPath tests 412] - expected: FAIL - - [XPath tests 413] - expected: FAIL - - [XPath tests 414] - expected: FAIL - - [XPath tests 415] - expected: FAIL - - [XPath tests 416] - expected: FAIL - - [XPath tests 417] - expected: FAIL - - [XPath tests 418] - expected: FAIL - - [XPath tests 419] - expected: FAIL - - [XPath tests 420] - expected: FAIL - - [XPath tests 421] - expected: FAIL - - [XPath tests 422] - expected: FAIL - - [XPath tests 423] - expected: FAIL - - [XPath tests 424] - expected: FAIL - - [XPath tests 425] - expected: FAIL - - [XPath tests 426] - expected: FAIL - - [XPath tests 427] - expected: FAIL - - [XPath tests 428] - expected: FAIL - - [XPath tests 429] - expected: FAIL - - [XPath tests 430] - expected: FAIL - - [XPath tests 431] - expected: FAIL - - [XPath tests 432] - expected: FAIL - - [XPath tests 433] - expected: FAIL - - [XPath tests 434] - expected: FAIL - - [XPath tests 435] - expected: FAIL - - [XPath tests 436] - expected: FAIL - - [XPath tests 437] - expected: FAIL - - [XPath tests 438] - expected: FAIL - - [XPath tests 439] - expected: FAIL - - [XPath tests 440] - expected: FAIL - - [XPath tests 441] - expected: FAIL - - [XPath tests 442] - expected: FAIL - - [XPath tests 443] - expected: FAIL - - [XPath tests 444] - expected: FAIL - - [XPath tests 445] - expected: FAIL - - [XPath tests 446] - expected: FAIL - - [XPath tests 447] - expected: FAIL - - [XPath tests 448] - expected: FAIL - - [XPath tests 449] - expected: FAIL - - [XPath tests 450] - expected: FAIL - - [XPath tests 451] - expected: FAIL - - [XPath tests 452] - expected: FAIL - - [XPath tests 453] - expected: FAIL - - [XPath tests 454] - expected: FAIL - - [XPath tests 455] - expected: FAIL - - [XPath tests 456] - expected: FAIL - - [XPath tests 457] - expected: FAIL - - [XPath tests 458] - expected: FAIL - - [XPath tests 459] - expected: FAIL - - [XPath tests 460] - expected: FAIL - - [XPath tests 461] - expected: FAIL - - [XPath tests 462] - expected: FAIL - - [XPath tests 463] - expected: FAIL - - [XPath tests 464] - expected: FAIL - - [XPath tests 465] - expected: FAIL - - [XPath tests 466] - expected: FAIL - - [XPath tests 467] - expected: FAIL - - [XPath tests 468] - expected: FAIL - - [XPath tests 469] - expected: FAIL - - [XPath tests 470] - expected: FAIL - - [XPath tests 471] - expected: FAIL - - [XPath tests 472] - expected: FAIL - - [XPath tests 473] - expected: FAIL - - [XPath tests 474] - expected: FAIL - - [XPath tests 475] - expected: FAIL - - [XPath tests 476] - expected: FAIL - - [XPath tests 477] - expected: FAIL - - [XPath tests 478] - expected: FAIL - - [XPath tests 479] - expected: FAIL - - [XPath tests 480] - expected: FAIL - - [XPath tests 481] - expected: FAIL - - [XPath tests 482] - expected: FAIL - - [XPath tests 483] - expected: FAIL - - [XPath tests 484] - expected: FAIL - - [XPath tests 485] - expected: FAIL - - [XPath tests 486] - expected: FAIL - - [XPath tests 487] - expected: FAIL - - [XPath tests 488] - expected: FAIL - - [XPath tests 489] - expected: FAIL - - [XPath tests 490] - expected: FAIL - - [XPath tests 491] - expected: FAIL - - [XPath tests 492] - expected: FAIL - - [XPath tests 493] - expected: FAIL - - [XPath tests 494] - expected: FAIL - - [XPath tests 495] - expected: FAIL - - [XPath tests 496] - expected: FAIL - - [XPath tests 497] - expected: FAIL - - [XPath tests 498] - expected: FAIL - - [XPath tests 499] - expected: FAIL - - [XPath tests 500] - expected: FAIL - - [XPath tests 501] - expected: FAIL - - [XPath tests 502] - expected: FAIL - - [XPath tests 503] - expected: FAIL - - [XPath tests 504] - expected: FAIL - - [XPath tests 505] - expected: FAIL - - [XPath tests 506] - expected: FAIL - - [XPath tests 507] - expected: FAIL - - [XPath tests 508] - expected: FAIL - - [XPath tests 509] - expected: FAIL - - [XPath tests 510] - expected: FAIL - - [XPath tests 511] - expected: FAIL - - [XPath tests 512] - expected: FAIL - - [XPath tests 513] - expected: FAIL - - [XPath tests 514] - expected: FAIL - - [XPath tests 515] - expected: FAIL - - [XPath tests 516] - expected: FAIL - - [XPath tests 517] - expected: FAIL - - [XPath tests 518] - expected: FAIL - - [XPath tests 519] - expected: FAIL - - [XPath tests 520] - expected: FAIL - - [XPath tests 521] - expected: FAIL - - [XPath tests 522] - expected: FAIL - - [XPath tests 523] - expected: FAIL - - [XPath tests 524] - expected: FAIL - - [XPath tests 525] - expected: FAIL - - [XPath tests 526] - expected: FAIL - - [XPath tests 527] - expected: FAIL - - [XPath tests 528] - expected: FAIL - - [XPath tests 529] - expected: FAIL - - [XPath tests 530] - expected: FAIL - - [XPath tests 531] - expected: FAIL - - [XPath tests 532] - expected: FAIL - - [XPath tests 533] - expected: FAIL - - [XPath tests 534] - expected: FAIL - - [XPath tests 535] - expected: FAIL - - [XPath tests 536] - expected: FAIL - - [XPath tests 537] - expected: FAIL - - [XPath tests 538] - expected: FAIL - - [XPath tests 539] - expected: FAIL - - [XPath tests 540] - expected: FAIL - - [XPath tests 541] - expected: FAIL - - [XPath tests 542] - expected: FAIL - - [XPath tests 543] - expected: FAIL - - [XPath tests 544] - expected: FAIL - - [XPath tests 545] - expected: FAIL - - [XPath tests 546] - expected: FAIL - - [XPath tests 547] - expected: FAIL - - [XPath tests 548] - expected: FAIL - - [XPath tests 549] - expected: FAIL - - [XPath tests 550] - expected: FAIL - - [XPath tests 551] - expected: FAIL - - [XPath tests 552] - expected: FAIL - - [XPath tests 553] - expected: FAIL - - [XPath tests 554] - expected: FAIL - - [XPath tests 555] - expected: FAIL - - [XPath tests 556] - expected: FAIL - - [XPath tests 557] - expected: FAIL - - [XPath tests 558] - expected: FAIL - - [XPath tests 559] - expected: FAIL - - [XPath tests 560] - expected: FAIL - - [XPath tests 561] - expected: FAIL - - [XPath tests 562] - expected: FAIL - - [XPath tests 563] - expected: FAIL - - [XPath tests 564] - expected: FAIL - - [XPath tests 565] - expected: FAIL - - [XPath tests 566] - expected: FAIL - - [XPath tests 567] - expected: FAIL - - [XPath tests 568] - expected: FAIL - - [XPath tests 569] - expected: FAIL - - [XPath tests 570] - expected: FAIL - - [XPath tests 571] - expected: FAIL - - [XPath tests 572] - expected: FAIL - - [XPath tests 573] - expected: FAIL - - [XPath tests 574] - expected: FAIL - - [XPath tests 575] - expected: FAIL - - [XPath tests 576] - expected: FAIL - - [XPath tests 577] - expected: FAIL - - [XPath tests 578] - expected: FAIL - - [XPath tests 579] - expected: FAIL - - [XPath tests 580] - expected: FAIL - - [XPath tests 581] - expected: FAIL - - [XPath tests 582] - expected: FAIL - - [XPath tests 583] - expected: FAIL - - [XPath tests 584] - expected: FAIL - - [XPath tests 585] - expected: FAIL - - [XPath tests 586] - expected: FAIL - - [XPath tests 587] - expected: FAIL - - [XPath tests 588] - expected: FAIL - - [XPath tests 589] - expected: FAIL - - [XPath tests 590] - expected: FAIL - - [XPath tests 591] - expected: FAIL - - [XPath tests 592] - expected: FAIL - - [XPath tests 593] - expected: FAIL - - [XPath tests 594] - expected: FAIL - - [XPath tests 595] - expected: FAIL - - [XPath tests 596] - expected: FAIL - - [XPath tests 597] - expected: FAIL - - [XPath tests 598] - expected: FAIL - - [XPath tests 599] - expected: FAIL - - [XPath tests 600] - expected: FAIL - - [XPath tests 601] - expected: FAIL - - [XPath tests 602] - expected: FAIL - - [XPath tests 603] - expected: FAIL - - [XPath tests 604] - expected: FAIL - - [XPath tests 605] - expected: FAIL - - [XPath tests 606] - expected: FAIL - - [XPath tests 607] - expected: FAIL - - [XPath tests 608] - expected: FAIL - - [XPath tests 609] - expected: FAIL - - [XPath tests 610] - expected: FAIL - - [XPath tests 611] - expected: FAIL - - [XPath tests 612] - expected: FAIL - - [XPath tests 613] - expected: FAIL - - [XPath tests 614] - expected: FAIL - - [XPath tests 615] - expected: FAIL - - [XPath tests 616] - expected: FAIL - - [XPath tests 617] - expected: FAIL - - [XPath tests 618] - expected: FAIL - - [XPath tests 619] - expected: FAIL - - [XPath tests 620] - expected: FAIL - - [XPath tests 621] - expected: FAIL - - [XPath tests 622] - expected: FAIL - - [XPath tests 623] - expected: FAIL - - [XPath tests 624] - expected: FAIL - - [XPath tests 625] - expected: FAIL - - [XPath tests 626] - expected: FAIL - - [XPath tests 627] - expected: FAIL - - [XPath tests 628] - expected: FAIL - - [XPath tests 629] - expected: FAIL - - [XPath tests 630] - expected: FAIL - - [XPath tests 631] - expected: FAIL - - [XPath tests 632] - expected: FAIL - - [XPath tests 633] - expected: FAIL - - [XPath tests 634] - expected: FAIL - - [XPath tests 635] - expected: FAIL - - [XPath tests 636] - expected: FAIL - - [XPath tests 637] - expected: FAIL - - [XPath tests 638] - expected: FAIL - - [XPath tests 639] - expected: FAIL - - [XPath tests 640] - expected: FAIL - - [XPath tests 641] - expected: FAIL - - [XPath tests 642] - expected: FAIL - - [XPath tests 643] - expected: FAIL - - [XPath tests 644] - expected: FAIL - - [XPath tests 645] - expected: FAIL - - [XPath tests 646] - expected: FAIL - - [XPath tests 647] - expected: FAIL - - [XPath tests 648] - expected: FAIL - - [XPath tests 649] - expected: FAIL - - [XPath tests 650] - expected: FAIL - - [XPath tests 651] - expected: FAIL - - [XPath tests 652] - expected: FAIL - - [XPath tests 653] - expected: FAIL - - [XPath tests 654] - expected: FAIL - - [XPath tests 655] - expected: FAIL - - [XPath tests 656] - expected: FAIL - - [XPath tests 657] - expected: FAIL - - [XPath tests 658] - expected: FAIL - - [XPath tests 659] - expected: FAIL - - [XPath tests 660] - expected: FAIL - - [XPath tests 661] - expected: FAIL - - [XPath tests 662] - expected: FAIL - - [XPath tests 663] - expected: FAIL - - [XPath tests 664] - expected: FAIL - - [XPath tests 665] - expected: FAIL - - [XPath tests 666] - expected: FAIL - - [XPath tests 667] - expected: FAIL - - [XPath tests 668] - expected: FAIL - - [XPath tests 669] - expected: FAIL - - [XPath tests 670] - expected: FAIL - - [XPath tests 671] - expected: FAIL - - [XPath tests 672] - expected: FAIL - - [XPath tests 673] - expected: FAIL - - [XPath tests 674] - expected: FAIL - - [XPath tests 675] - expected: FAIL - - [XPath tests 676] - expected: FAIL - - [XPath tests 677] - expected: FAIL - - [XPath tests 678] - expected: FAIL - - [XPath tests 679] - expected: FAIL - - [XPath tests 680] - expected: FAIL - - [XPath tests 681] - expected: FAIL - - [XPath tests 682] - expected: FAIL - - [XPath tests 683] - expected: FAIL - - [XPath tests 684] - expected: FAIL - - [XPath tests 685] - expected: FAIL - - [XPath tests 686] - expected: FAIL - - [XPath tests 687] - expected: FAIL - - [XPath tests 688] - expected: FAIL - - [XPath tests 689] - expected: FAIL - - [XPath tests 690] - expected: FAIL - - [XPath tests 691] - expected: FAIL - - [XPath tests 692] - expected: FAIL - - [XPath tests 693] - expected: FAIL - - [XPath tests 694] - expected: FAIL - - [XPath tests 695] - expected: FAIL - - [XPath tests 696] - expected: FAIL - - [XPath tests 697] - expected: FAIL - - [XPath tests 698] - expected: FAIL - - [XPath tests 699] - expected: FAIL - - [XPath tests 700] - expected: FAIL - - [XPath tests 701] - expected: FAIL - - [XPath tests 702] - expected: FAIL - - [XPath tests 703] - expected: FAIL - - [XPath tests 704] - expected: FAIL - - [XPath tests 705] - expected: FAIL - - [XPath tests 706] - expected: FAIL - - [XPath tests 707] - expected: FAIL - - [XPath tests 708] - expected: FAIL - - [XPath tests 709] - expected: FAIL - - [XPath tests 710] - expected: FAIL - - [XPath tests 711] - expected: FAIL - - [XPath tests 712] - expected: FAIL - - [XPath tests 713] - expected: FAIL - - [XPath tests 714] - expected: FAIL - - [XPath tests 715] - expected: FAIL - - [XPath tests 716] - expected: FAIL - - [XPath tests 717] - expected: FAIL - - [XPath tests 718] - expected: FAIL - - [XPath tests 719] - expected: FAIL - - [XPath tests 720] - expected: FAIL - - [XPath tests 721] - expected: FAIL - - [XPath tests 722] - expected: FAIL - - [XPath tests 723] - expected: FAIL - - [XPath tests 724] - expected: FAIL - - [XPath tests 725] - expected: FAIL - - [XPath tests 726] - expected: FAIL - - [XPath tests 727] - expected: FAIL - - [XPath tests 728] - expected: FAIL - - [XPath tests 729] - expected: FAIL - - [XPath tests 730] - expected: FAIL - - [XPath tests 731] - expected: FAIL - - [XPath tests 732] - expected: FAIL - - [XPath tests 733] - expected: FAIL - - [XPath tests 734] - expected: FAIL - - [XPath tests 735] - expected: FAIL - - [XPath tests 736] - expected: FAIL - - [XPath tests 737] - expected: FAIL - - [XPath tests 738] - expected: FAIL - - [XPath tests 739] - expected: FAIL - - [XPath tests 740] - expected: FAIL - - [XPath tests 741] - expected: FAIL - - [XPath tests 742] - expected: FAIL - - [XPath tests 743] - expected: FAIL - - [XPath tests 744] - expected: FAIL - - [XPath tests 745] - expected: FAIL - - [XPath tests 746] - expected: FAIL - - [XPath tests 747] - expected: FAIL - - [XPath tests 748] - expected: FAIL - - [XPath tests 749] - expected: FAIL - - [XPath tests 750] - expected: FAIL - - [XPath tests 751] - expected: FAIL - - [XPath tests 752] - expected: FAIL - - [XPath tests 753] - expected: FAIL - - [XPath tests 754] - expected: FAIL - - [XPath tests 755] - expected: FAIL - - [XPath tests 756] - expected: FAIL - - [XPath tests 757] - expected: FAIL - - [XPath tests 758] - expected: FAIL - - [XPath tests 759] - expected: FAIL - - [XPath tests 760] - expected: FAIL - - [XPath tests 761] - expected: FAIL - - [XPath tests 762] - expected: FAIL - - [XPath tests 763] - expected: FAIL - - [XPath tests 764] - expected: FAIL - - [XPath tests 765] - expected: FAIL - - [XPath tests 766] - expected: FAIL - - [XPath tests 767] - expected: FAIL - - [XPath tests 768] - expected: FAIL - - [XPath tests 769] - expected: FAIL - - [XPath tests 770] - expected: FAIL - - [XPath tests 771] - expected: FAIL - - [XPath tests 772] - expected: FAIL - - [XPath tests 773] - expected: FAIL - - [XPath tests 774] - expected: FAIL - - [XPath tests 775] - expected: FAIL - - [XPath tests 776] - expected: FAIL - - [XPath tests 777] - expected: FAIL - - [XPath tests 778] - expected: FAIL - - [XPath tests 779] - expected: FAIL - - [XPath tests 780] - expected: FAIL - - [XPath tests 781] - expected: FAIL - - [XPath tests 782] - expected: FAIL - - [XPath tests 783] - expected: FAIL - - [XPath tests 784] - expected: FAIL - - [XPath tests 785] - expected: FAIL - - [XPath tests 786] - expected: FAIL - - [XPath tests 787] - expected: FAIL - - [XPath tests 788] - expected: FAIL - - [XPath tests 789] - expected: FAIL - - [XPath tests 790] - expected: FAIL - - [XPath tests 791] - expected: FAIL - - [XPath tests 792] - expected: FAIL - - [XPath tests 793] - expected: FAIL - - [XPath tests 794] - expected: FAIL - - [XPath tests 795] - expected: FAIL - - [XPath tests 796] - expected: FAIL - - [XPath tests 797] - expected: FAIL - - [XPath tests 798] - expected: FAIL - - [XPath tests 799] - expected: FAIL - - [XPath tests 800] - expected: FAIL - - [XPath tests 801] - expected: FAIL - - [XPath tests 802] - expected: FAIL - - [XPath tests 803] - expected: FAIL - - [XPath tests 804] - expected: FAIL - - [XPath tests 805] - expected: FAIL - - [XPath tests 806] - expected: FAIL - - [XPath tests 807] - expected: FAIL - - [XPath tests 808] - expected: FAIL - - [XPath tests 809] - expected: FAIL - - [XPath tests 810] - expected: FAIL - - [XPath tests 811] - expected: FAIL - - [XPath tests 812] - expected: FAIL - - [XPath tests 813] - expected: FAIL - - [XPath tests 814] - expected: FAIL - - [XPath tests 815] - expected: FAIL - - [XPath tests 816] - expected: FAIL - - [XPath tests 817] - expected: FAIL - - [XPath tests 818] - expected: FAIL - - [XPath tests 819] - expected: FAIL - - [XPath tests 820] - expected: FAIL - - [XPath tests 821] - expected: FAIL - - [XPath tests 822] - expected: FAIL - - [XPath tests 823] - expected: FAIL - - [XPath tests 824] - expected: FAIL - - [XPath tests 825] - expected: FAIL - - [XPath tests 826] - expected: FAIL - - [XPath tests 827] - expected: FAIL - - [XPath tests 828] - expected: FAIL - - [XPath tests 829] - expected: FAIL - - [XPath tests 830] - expected: FAIL - - [XPath tests 831] - expected: FAIL - - [XPath tests 832] - expected: FAIL - - [XPath tests 833] - expected: FAIL - - [XPath tests 834] - expected: FAIL - - [XPath tests 835] - expected: FAIL - - [XPath tests 836] - expected: FAIL - - [XPath tests 837] - expected: FAIL - - [XPath tests 838] - expected: FAIL - - [XPath tests 839] - expected: FAIL - - [XPath tests 840] - expected: FAIL - - [XPath tests 841] - expected: FAIL - - [XPath tests 842] - expected: FAIL - - [XPath tests 843] - expected: FAIL - - [XPath tests 844] - expected: FAIL - - [XPath tests 845] - expected: FAIL - - [XPath tests 846] - expected: FAIL - - [XPath tests 847] - expected: FAIL - - [XPath tests 848] - expected: FAIL - - [XPath tests 849] - expected: FAIL - - [XPath tests 850] - expected: FAIL - - [XPath tests 851] - expected: FAIL - - [XPath tests 852] - expected: FAIL - - [XPath tests 853] - expected: FAIL - - [XPath tests 854] - expected: FAIL - - [XPath tests 855] - expected: FAIL - - [XPath tests 856] - expected: FAIL - - [XPath tests 857] - expected: FAIL - - [XPath tests 858] - expected: FAIL - - [XPath tests 859] - expected: FAIL - - [XPath tests 860] - expected: FAIL - - [XPath tests 861] - expected: FAIL - - [XPath tests 862] - expected: FAIL - - [XPath tests 863] - expected: FAIL - - [XPath tests 864] - expected: FAIL - - [XPath tests 865] - expected: FAIL - - [XPath tests 866] - expected: FAIL - - [XPath tests 867] - expected: FAIL - - [XPath tests 868] - expected: FAIL - - [XPath tests 869] - expected: FAIL - - [XPath tests 870] - expected: FAIL - - [XPath tests 871] - expected: FAIL - - [XPath tests 872] - expected: FAIL - - [XPath tests 873] - expected: FAIL - - [XPath tests 874] - expected: FAIL - - [XPath tests 875] - expected: FAIL - - [XPath tests 876] - expected: FAIL - - [XPath tests 877] - expected: FAIL - - [XPath tests 878] - expected: FAIL - - [XPath tests 879] - expected: FAIL - - [XPath tests 880] - expected: FAIL - - [XPath tests 881] - expected: FAIL - - [XPath tests 882] - expected: FAIL - - [XPath tests 883] - expected: FAIL - - [XPath tests 884] - expected: FAIL - - [XPath tests 885] - expected: FAIL - - [XPath tests 886] - expected: FAIL - - [XPath tests 887] - expected: FAIL - - [XPath tests 888] - expected: FAIL - - [XPath tests 889] - expected: FAIL - - [XPath tests 890] - expected: FAIL - - [XPath tests 891] - expected: FAIL - - [XPath tests 892] - expected: FAIL - - [XPath tests 893] - expected: FAIL - - [XPath tests 894] - expected: FAIL - - [XPath tests 895] - expected: FAIL - - [XPath tests 896] - expected: FAIL - - [XPath tests 897] - expected: FAIL - - [XPath tests 898] - expected: FAIL - - [XPath tests 899] - expected: FAIL - - [XPath tests 900] - expected: FAIL - - [XPath tests 901] - expected: FAIL - - [XPath tests 902] - expected: FAIL - - [XPath tests 903] - expected: FAIL - - [XPath tests 904] - expected: FAIL - - [XPath tests 905] - expected: FAIL - - [XPath tests 906] - expected: FAIL - - [XPath tests 907] - expected: FAIL - - [XPath tests 908] - expected: FAIL - - [XPath tests 909] - expected: FAIL - - [XPath tests 910] - expected: FAIL - - [XPath tests 911] - expected: FAIL - - [XPath tests 912] - expected: FAIL - - [XPath tests 913] - expected: FAIL - - [XPath tests 914] - expected: FAIL - - [XPath tests 915] - expected: FAIL - - [XPath tests 916] - expected: FAIL - - [XPath tests 917] - expected: FAIL - - [XPath tests 918] - expected: FAIL - - [XPath tests 919] - expected: FAIL - - [XPath tests 920] - expected: FAIL - - [XPath tests 921] - expected: FAIL - - [XPath tests 922] - expected: FAIL - - [XPath tests 923] - expected: FAIL - - [XPath tests 924] - expected: FAIL - - [XPath tests 925] - expected: FAIL - - [XPath tests 926] - expected: FAIL - - [XPath tests 927] - expected: FAIL - - [XPath tests 928] - expected: FAIL - - [XPath tests 929] - expected: FAIL - - [XPath tests 930] - expected: FAIL - - [XPath tests 931] - expected: FAIL - - [XPath tests 932] - expected: FAIL - - [XPath tests 933] - expected: FAIL - - [XPath tests 934] - expected: FAIL - - [XPath tests 935] - expected: FAIL - - [XPath tests 936] - expected: FAIL - - [XPath tests 937] - expected: FAIL - - [XPath tests 938] - expected: FAIL - - [XPath tests 939] - expected: FAIL - - [XPath tests 940] - expected: FAIL - - [XPath tests 941] - expected: FAIL - - [XPath tests 942] - expected: FAIL - - [XPath tests 943] - expected: FAIL - - [XPath tests 944] - expected: FAIL - - [XPath tests 945] - expected: FAIL - - [XPath tests 946] - expected: FAIL - - [XPath tests 947] - expected: FAIL - - [XPath tests 948] - expected: FAIL - - [XPath tests 949] - expected: FAIL - - [XPath tests 950] - expected: FAIL - - [XPath tests 951] - expected: FAIL - - [XPath tests 952] - expected: FAIL - - [XPath tests 953] - expected: FAIL - - [XPath tests 954] - expected: FAIL - - [XPath tests 955] - expected: FAIL - - [XPath tests 956] - expected: FAIL - - [XPath tests 957] - expected: FAIL - - [XPath tests 958] - expected: FAIL - - [XPath tests 959] - expected: FAIL - - [XPath tests 960] - expected: FAIL - - [XPath tests 961] - expected: FAIL - - [XPath tests 962] - expected: FAIL - - [XPath tests 963] - expected: FAIL - - [XPath tests 964] - expected: FAIL - - [XPath tests 965] - expected: FAIL - - [XPath tests 966] - expected: FAIL - - [XPath tests 967] - expected: FAIL - - [XPath tests 968] - expected: FAIL - - [XPath tests 969] - expected: FAIL - - [XPath tests 970] - expected: FAIL - - [XPath tests 971] - expected: FAIL - - [XPath tests 972] - expected: FAIL - - [XPath tests 973] - expected: FAIL - - [XPath tests 974] - expected: FAIL - - [XPath tests 975] - expected: FAIL - - [XPath tests 976] - expected: FAIL - - [XPath tests 977] - expected: FAIL - - [XPath tests 978] - expected: FAIL - - [XPath tests 979] - expected: FAIL - - [XPath tests 980] - expected: FAIL - - [XPath tests 981] - expected: FAIL - - [XPath tests 982] - expected: FAIL - - [XPath tests 983] - expected: FAIL - - [XPath tests 984] - expected: FAIL - - [XPath tests 985] - expected: FAIL - - [XPath tests 986] - expected: FAIL - - [XPath tests 987] - expected: FAIL - - [XPath tests 988] - expected: FAIL - - [XPath tests 989] - expected: FAIL - - [XPath tests 990] - expected: FAIL - - [XPath tests 991] - expected: FAIL - - [XPath tests 992] - expected: FAIL - - [XPath tests 993] - expected: FAIL - - [XPath tests 994] - expected: FAIL - - [XPath tests 995] - expected: FAIL - - [XPath tests 996] - expected: FAIL - - [XPath tests 997] - expected: FAIL - - [XPath tests 998] - expected: FAIL - - [XPath tests 999] - expected: FAIL - - [XPath tests 1000] - expected: FAIL - - [XPath tests 1001] - expected: FAIL - - [XPath tests 1002] - expected: FAIL - - [XPath tests 1003] - expected: FAIL - - [XPath tests 1004] - expected: FAIL - - [XPath tests 1005] - expected: FAIL - - [XPath tests 1006] - expected: FAIL - - [XPath tests 1007] - expected: FAIL - - [XPath tests 1008] - expected: FAIL - - [XPath tests 1009] - expected: FAIL - - [XPath tests 1010] - expected: FAIL - - [XPath tests 1011] - expected: FAIL - - [XPath tests 1012] - expected: FAIL - - [XPath tests 1013] - expected: FAIL - - [XPath tests 1014] - expected: FAIL - - [XPath tests 1015] - expected: FAIL - - [XPath tests 1016] - expected: FAIL - - [XPath tests 1017] - expected: FAIL - - [XPath tests 1018] - expected: FAIL - - [XPath tests 1019] - expected: FAIL - - [XPath tests 1020] - expected: FAIL - - [XPath tests 1021] - expected: FAIL - - [XPath tests 1022] - expected: FAIL - - [XPath tests 1023] - expected: FAIL diff --git a/tests/wpt/meta/fetch/content-encoding/br/bad-br-body.https.any.js.ini b/tests/wpt/meta/fetch/content-encoding/br/bad-br-body.https.any.js.ini index 2a7f8c45be1..16e5901cca3 100644 --- a/tests/wpt/meta/fetch/content-encoding/br/bad-br-body.https.any.js.ini +++ b/tests/wpt/meta/fetch/content-encoding/br/bad-br-body.https.any.js.ini @@ -1,3 +1,15 @@ [bad-br-body.https.any.html] [Consuming the body of a resource with bad br content with arrayBuffer() should reject] expected: FAIL + + [Consuming the body of a resource with bad br content with blob() should reject] + expected: FAIL + + [Consuming the body of a resource with bad br content with bytes() should reject] + expected: FAIL + + [Consuming the body of a resource with bad br content with json() should reject] + expected: FAIL + + [Consuming the body of a resource with bad br content with text() should reject] + expected: FAIL diff --git a/tests/wpt/meta/fetch/content-encoding/gzip/bad-gzip-body.any.js.ini b/tests/wpt/meta/fetch/content-encoding/gzip/bad-gzip-body.any.js.ini index 24a7b7bcc7f..aec86e6cdb2 100644 --- a/tests/wpt/meta/fetch/content-encoding/gzip/bad-gzip-body.any.js.ini +++ b/tests/wpt/meta/fetch/content-encoding/gzip/bad-gzip-body.any.js.ini @@ -11,6 +11,9 @@ [Consuming the body of a resource with bad gzip content with text() should reject] expected: FAIL + [Consuming the body of a resource with bad gzip content with bytes() should reject] + expected: FAIL + [bad-gzip-body.any.worker.html] [Consuming the body of a resource with bad gzip content with arrayBuffer() should reject] @@ -25,6 +28,9 @@ [Consuming the body of a resource with bad gzip content with text() should reject] expected: FAIL + [Consuming the body of a resource with bad gzip content with bytes() should reject] + expected: FAIL + [bad-gzip-body.any.serviceworker.html] expected: ERROR diff --git a/tests/wpt/meta/fetch/content-encoding/zstd/bad-zstd-body.https.any.js.ini b/tests/wpt/meta/fetch/content-encoding/zstd/bad-zstd-body.https.any.js.ini index ed17fcbaf81..121ae28c821 100644 --- a/tests/wpt/meta/fetch/content-encoding/zstd/bad-zstd-body.https.any.js.ini +++ b/tests/wpt/meta/fetch/content-encoding/zstd/bad-zstd-body.https.any.js.ini @@ -11,6 +11,9 @@ [Consuming the body of a resource with bad zstd content with text() should reject] expected: FAIL + [Consuming the body of a resource with bad zstd content with bytes() should reject] + expected: FAIL + [bad-zstd-body.https.any.worker.html] [Consuming the body of a resource with bad zstd content with arrayBuffer() should reject] @@ -25,6 +28,9 @@ [Consuming the body of a resource with bad zstd content with text() should reject] expected: FAIL + [Consuming the body of a resource with bad zstd content with bytes() should reject] + expected: FAIL + [bad-zstd-body.https.any.sharedworker.html] expected: ERROR diff --git a/tests/wpt/meta/fetch/corb/preload-image-png-mislabeled-as-html-nosniff.tentative.sub.html.ini b/tests/wpt/meta/fetch/corb/preload-image-png-mislabeled-as-html-nosniff.tentative.sub.html.ini index 1dec4fdbf06..de37955f1db 100644 --- a/tests/wpt/meta/fetch/corb/preload-image-png-mislabeled-as-html-nosniff.tentative.sub.html.ini +++ b/tests/wpt/meta/fetch/corb/preload-image-png-mislabeled-as-html-nosniff.tentative.sub.html.ini @@ -1,4 +1,3 @@ [preload-image-png-mislabeled-as-html-nosniff.tentative.sub.html] - expected: TIMEOUT [preload-image-png-mislabeled-as-html-nosniff] - expected: TIMEOUT + expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/fetch-preflight.https.sub.any.js.ini b/tests/wpt/meta/fetch/metadata/fetch-preflight.https.sub.any.js.ini index 0147b1bc84c..0fd181c4e4f 100644 --- a/tests/wpt/meta/fetch/metadata/fetch-preflight.https.sub.any.js.ini +++ b/tests/wpt/meta/fetch/metadata/fetch-preflight.https.sub.any.js.ini @@ -1,12 +1,6 @@ [fetch-preflight.https.sub.any.html] - [Cross-site fetch with preflight: sec-fetch-site] - expected: FAIL - [fetch-preflight.https.sub.any.worker.html] - [Cross-site fetch with preflight: sec-fetch-site] - expected: FAIL - [fetch-preflight.https.sub.any.serviceworker.html] expected: ERROR diff --git a/tests/wpt/meta/fetch/metadata/fetch.https.sub.any.js.ini b/tests/wpt/meta/fetch/metadata/fetch.https.sub.any.js.ini index 31cda1be01e..7b0e181e598 100644 --- a/tests/wpt/meta/fetch/metadata/fetch.https.sub.any.js.ini +++ b/tests/wpt/meta/fetch/metadata/fetch.https.sub.any.js.ini @@ -1,12 +1,6 @@ [fetch.https.sub.any.html] - [Cross-site fetch: sec-fetch-site] - expected: FAIL - [fetch.https.sub.any.worker.html] - [Cross-site fetch: sec-fetch-site] - expected: FAIL - [fetch.https.sub.any.sharedworker.html] expected: ERROR diff --git a/tests/wpt/meta/fetch/metadata/generated/css-font-face.sub.tentative.html.ini b/tests/wpt/meta/fetch/metadata/generated/css-font-face.sub.tentative.html.ini index af4a680bb7a..2254c59cae9 100644 --- a/tests/wpt/meta/fetch/metadata/generated/css-font-face.sub.tentative.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/css-font-face.sub.tentative.html.ini @@ -49,6 +49,3 @@ [sec-fetch-storage-access - Not sent to non-trustworthy cross-site destination] expected: FAIL - - [sec-fetch-storage-access - Not sent to non-trustworthy same-site destination] - expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/element-a.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/element-a.sub.html.ini index dd0b375d338..b54747a3ab9 100644 --- a/tests/wpt/meta/fetch/metadata/generated/element-a.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/element-a.sub.html.ini @@ -2,8 +2,5 @@ [sec-fetch-site - HTTPS upgrade - no attributes] expected: FAIL - [sec-fetch-site - HTTPS downgrade-upgrade - no attributes] - expected: FAIL - [sec-fetch-site - HTTPS downgrade (header not sent) - no attributes] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/element-audio.https.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/element-audio.https.sub.html.ini index 5ccc5d709f8..2cc17405639 100644 --- a/tests/wpt/meta/fetch/metadata/generated/element-audio.https.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/element-audio.https.sub.html.ini @@ -1,27 +1,3 @@ [element-audio.https.sub.html] - [sec-fetch-site - Cross-site, no attributes] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect, no attributes] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Same Origin, no attributes] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Same-Site, no attributes] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Cross-Site, no attributes] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Cross-Site, no attributes] - expected: FAIL - - [sec-fetch-site - Same-Site -> Cross-Site, no attributes] - expected: FAIL - - [sec-fetch-site - HTTPS downgrade-upgrade, no attributes] - expected: FAIL - [sec-fetch-storage-access - Cross-site, no attributes] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/element-audio.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/element-audio.sub.html.ini index 7cc93481772..40b2df25c97 100644 --- a/tests/wpt/meta/fetch/metadata/generated/element-audio.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/element-audio.sub.html.ini @@ -2,8 +2,5 @@ [sec-fetch-site - HTTPS upgrade, no attributes] expected: FAIL - [sec-fetch-site - HTTPS downgrade-upgrade, no attributes] - expected: FAIL - [sec-fetch-site - HTTPS downgrade (header not sent), no attributes] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/element-iframe.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/element-iframe.sub.html.ini index b154a96d9de..5d39022eaf3 100644 --- a/tests/wpt/meta/fetch/metadata/generated/element-iframe.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/element-iframe.sub.html.ini @@ -2,8 +2,5 @@ [sec-fetch-site - HTTPS upgrade] expected: FAIL - [sec-fetch-site - HTTPS downgrade-upgrade] - expected: FAIL - [sec-fetch-site - HTTPS downgrade (header not sent)] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/element-img.https.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/element-img.https.sub.html.ini index a0fe191d526..fe36276121a 100644 --- a/tests/wpt/meta/fetch/metadata/generated/element-img.https.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/element-img.https.sub.html.ini @@ -1,49 +1,4 @@ [element-img.https.sub.html] - [sec-fetch-site - src - Cross-site, no attributes] - expected: FAIL - - [sec-fetch-site - srcset - Cross-site, no attributes] - expected: FAIL - - [sec-fetch-site - src - Same-Origin -> Cross-Site -> Same-Origin redirect, no attributes] - expected: FAIL - - [sec-fetch-site - srcset - Same-Origin -> Cross-Site -> Same-Origin redirect, no attributes] - expected: FAIL - - [sec-fetch-site - src - Cross-Site -> Same Origin, no attributes] - expected: FAIL - - [sec-fetch-site - srcset - Cross-Site -> Same Origin, no attributes] - expected: FAIL - - [sec-fetch-site - src - Cross-Site -> Same-Site, no attributes] - expected: FAIL - - [sec-fetch-site - srcset - Cross-Site -> Same-Site, no attributes] - expected: FAIL - - [sec-fetch-site - src - Cross-Site -> Cross-Site, no attributes] - expected: FAIL - - [sec-fetch-site - srcset - Cross-Site -> Cross-Site, no attributes] - expected: FAIL - - [sec-fetch-site - src - Same-Origin -> Cross-Site, no attributes] - expected: FAIL - - [sec-fetch-site - srcset - Same-Origin -> Cross-Site, no attributes] - expected: FAIL - - [sec-fetch-site - src - Same-Site -> Cross-Site, no attributes] - expected: FAIL - - [sec-fetch-site - srcset - Same-Site -> Cross-Site, no attributes] - expected: FAIL - - [sec-fetch-site - src - HTTPS downgrade-upgrade, no attributes] - expected: FAIL - [sec-fetch-storage-access - src - Cross-site, no attributes] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/element-img.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/element-img.sub.html.ini index cd58db1fdd2..55c8986421e 100644 --- a/tests/wpt/meta/fetch/metadata/generated/element-img.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/element-img.sub.html.ini @@ -5,12 +5,6 @@ [sec-fetch-site - srcset - HTTPS upgrade, no attributes] expected: FAIL - [sec-fetch-site - src - HTTPS downgrade-upgrade, no attributes] - expected: FAIL - - [sec-fetch-site - srcset - HTTPS downgrade-upgrade, no attributes] - expected: FAIL - [sec-fetch-site - src - HTTPS downgrade (header not sent), no attributes] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/element-link-prefetch.https.optional.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/element-link-prefetch.https.optional.sub.html.ini index ccb5ced4fc0..a0e22dd5327 100644 --- a/tests/wpt/meta/fetch/metadata/generated/element-link-prefetch.https.optional.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/element-link-prefetch.https.optional.sub.html.ini @@ -1,31 +1,4 @@ [element-link-prefetch.https.optional.sub.html] - [sec-fetch-site - Same origin no attributes] - expected: FAIL - - [sec-fetch-site - Cross-site no attributes] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect no attributes] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Same Origin no attributes] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Same-Site no attributes] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Cross-Site no attributes] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Same Origin no attributes] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Cross-Site no attributes] - expected: FAIL - - [sec-fetch-site - Same-Site -> Cross-Site no attributes] - expected: FAIL - [sec-fetch-dest attributes: as=audio] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/element-link-prefetch.optional.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/element-link-prefetch.optional.sub.html.ini index b75a39a81a0..1c920517827 100644 --- a/tests/wpt/meta/fetch/metadata/generated/element-link-prefetch.optional.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/element-link-prefetch.optional.sub.html.ini @@ -2,8 +2,5 @@ [sec-fetch-site - HTTPS upgrade no attributes] expected: FAIL - [sec-fetch-site - HTTPS downgrade-upgrade no attributes] - expected: FAIL - [sec-fetch-site - HTTPS downgrade (header not sent) no attributes] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/element-meta-refresh.https.optional.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/element-meta-refresh.https.optional.sub.html.ini index 5bc9bb2c8cf..6aad04b68d1 100644 --- a/tests/wpt/meta/fetch/metadata/generated/element-meta-refresh.https.optional.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/element-meta-refresh.https.optional.sub.html.ini @@ -5,29 +5,20 @@ [sec-fetch-site - Same site] expected: FAIL - [sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Same Origin] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Same-Site] - expected: FAIL - [sec-fetch-site - Cross-Site -> Cross-Site] expected: FAIL - [sec-fetch-site - Same-Origin -> Cross-Site] + [sec-fetch-site - Same-Site -> Same-Site] expected: FAIL - [sec-fetch-site - Same-Site -> Same-Site] + [sec-fetch-user] expected: FAIL - [sec-fetch-site - Same-Site -> Cross-Site] + [sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect] expected: FAIL - [sec-fetch-site - HTTPS downgrade-upgrade] + [sec-fetch-site - Same-Origin -> Same-Site] expected: FAIL - [sec-fetch-user] + [sec-fetch-site - Same-Site -> Same Origin] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/element-meta-refresh.optional.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/element-meta-refresh.optional.sub.html.ini index 6af80d8f7e8..67bfd020500 100644 --- a/tests/wpt/meta/fetch/metadata/generated/element-meta-refresh.optional.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/element-meta-refresh.optional.sub.html.ini @@ -2,8 +2,5 @@ [sec-fetch-site - HTTPS upgrade] expected: FAIL - [sec-fetch-site - HTTPS downgrade-upgrade] - expected: FAIL - [sec-fetch-site - HTTPS downgrade (header not sent)] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/element-picture.https.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/element-picture.https.sub.html.ini index ea347e106eb..18f6f472b28 100644 --- a/tests/wpt/meta/fetch/metadata/generated/element-picture.https.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/element-picture.https.sub.html.ini @@ -1,67 +1,4 @@ [element-picture.https.sub.html] - [sec-fetch-site - img[src\] - Cross-site, no attributes] - expected: FAIL - - [sec-fetch-site - img[srcset\] - Cross-site, no attributes] - expected: FAIL - - [sec-fetch-site - source[srcset\] - Cross-site, no attributes] - expected: FAIL - - [sec-fetch-site - img[src\] - Same-Origin -> Cross-Site -> Same-Origin redirect, no attributes] - expected: FAIL - - [sec-fetch-site - img[srcset\] - Same-Origin -> Cross-Site -> Same-Origin redirect, no attributes] - expected: FAIL - - [sec-fetch-site - source[srcset\] - Same-Origin -> Cross-Site -> Same-Origin redirect, no attributes] - expected: FAIL - - [sec-fetch-site - img[src\] - Cross-Site -> Same Origin, no attributes] - expected: FAIL - - [sec-fetch-site - img[srcset\] - Cross-Site -> Same Origin, no attributes] - expected: FAIL - - [sec-fetch-site - source[srcset\] - Cross-Site -> Same Origin, no attributes] - expected: FAIL - - [sec-fetch-site - img[src\] - Cross-Site -> Same-Site, no attributes] - expected: FAIL - - [sec-fetch-site - img[srcset\] - Cross-Site -> Same-Site, no attributes] - expected: FAIL - - [sec-fetch-site - source[srcset\] - Cross-Site -> Same-Site, no attributes] - expected: FAIL - - [sec-fetch-site - img[src\] - Cross-Site -> Cross-Site, no attributes] - expected: FAIL - - [sec-fetch-site - img[srcset\] - Cross-Site -> Cross-Site, no attributes] - expected: FAIL - - [sec-fetch-site - source[srcset\] - Cross-Site -> Cross-Site, no attributes] - expected: FAIL - - [sec-fetch-site - img[src\] - Same-Origin -> Cross-Site, no attributes] - expected: FAIL - - [sec-fetch-site - img[srcset\] - Same-Origin -> Cross-Site, no attributes] - expected: FAIL - - [sec-fetch-site - source[srcset\] - Same-Origin -> Cross-Site, no attributes] - expected: FAIL - - [sec-fetch-site - img[src\] - Same-Site -> Cross-Site, no attributes] - expected: FAIL - - [sec-fetch-site - img[srcset\] - Same-Site -> Cross-Site, no attributes] - expected: FAIL - - [sec-fetch-site - source[srcset\] - Same-Site -> Cross-Site, no attributes] - expected: FAIL - [sec-fetch-storage-access - img[src\] - Cross-site, no attributes] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/element-picture.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/element-picture.sub.html.ini index 3232ec358eb..a50427b8e81 100644 --- a/tests/wpt/meta/fetch/metadata/generated/element-picture.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/element-picture.sub.html.ini @@ -8,15 +8,6 @@ [sec-fetch-site - source[srcset\] - HTTPS upgrade, no attributes] expected: FAIL - [sec-fetch-site - img[src\] - HTTPS downgrade-upgrade, no attributes] - expected: FAIL - - [sec-fetch-site - img[srcset\] - HTTPS downgrade-upgrade, no attributes] - expected: FAIL - - [sec-fetch-site - source[srcset\] - HTTPS downgrade-upgrade, no attributes] - expected: FAIL - [sec-fetch-site - img[src\] - HTTPS downgrade (header not sent), no attributes] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/element-script.https.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/element-script.https.sub.html.ini index 1d1e07b42e1..08caf1e7589 100644 --- a/tests/wpt/meta/fetch/metadata/generated/element-script.https.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/element-script.https.sub.html.ini @@ -1,45 +1,9 @@ [element-script.https.sub.html] - [sec-fetch-site - Cross-site, no attributes] - expected: FAIL - - [sec-fetch-site - Cross-site, attributes: type=module] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect, no attributes] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect, attributes: type=module] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Same Origin, no attributes] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Same Origin, attributes: type=module] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Same-Site, no attributes] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Same-Site, attributes: type=module] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Cross-Site, no attributes] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Cross-Site, attributes: type=module] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Cross-Site, no attributes] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Cross-Site, attributes: type=module] - expected: FAIL - - [sec-fetch-site - Same-Site -> Cross-Site, no attributes] + [sec-fetch-storage-access - Cross-site, no attributes] expected: FAIL - [sec-fetch-site - Same-Site -> Cross-Site, attributes: type=module] + [sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect, attributes: type=module] expected: FAIL - [sec-fetch-storage-access - Cross-site, no attributes] + [sec-fetch-site - Same-Site -> Same Origin, attributes: type=module] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/element-script.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/element-script.sub.html.ini index ef877c37311..fc7764baeb0 100644 --- a/tests/wpt/meta/fetch/metadata/generated/element-script.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/element-script.sub.html.ini @@ -5,12 +5,6 @@ [sec-fetch-site - HTTPS upgrade, attributes: type=module] expected: FAIL - [sec-fetch-site - HTTPS downgrade-upgrade, no attributes] - expected: FAIL - - [sec-fetch-site - HTTPS downgrade-upgrade, attributes: type=module] - expected: FAIL - [sec-fetch-site - HTTPS downgrade (header not sent), no attributes] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/element-video.https.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/element-video.https.sub.html.ini index 95d4ed00243..88ae1f1a99f 100644 --- a/tests/wpt/meta/fetch/metadata/generated/element-video.https.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/element-video.https.sub.html.ini @@ -1,27 +1,3 @@ [element-video.https.sub.html] - [sec-fetch-site - Cross-site, no attributes] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect, no attributes] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Same Origin, no attributes] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Same-Site, no attributes] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Cross-Site, no attributes] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Cross-Site, no attributes] - expected: FAIL - - [sec-fetch-site - Same-Site -> Cross-Site, no attributes] - expected: FAIL - - [sec-fetch-site - HTTPS downgrade-upgrade, no attributes] - expected: FAIL - [sec-fetch-storage-access - Cross-site, no attributes] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/element-video.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/element-video.sub.html.ini index 70d776ac203..2e8748d259b 100644 --- a/tests/wpt/meta/fetch/metadata/generated/element-video.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/element-video.sub.html.ini @@ -2,8 +2,5 @@ [sec-fetch-site - HTTPS upgrade, no attributes] expected: FAIL - [sec-fetch-site - HTTPS downgrade-upgrade, no attributes] - expected: FAIL - [sec-fetch-site - HTTPS downgrade (header not sent), no attributes] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/fetch.https.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/fetch.https.sub.html.ini index 7b9d1002ec9..661fc39d370 100644 --- a/tests/wpt/meta/fetch/metadata/generated/fetch.https.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/fetch.https.sub.html.ini @@ -1,24 +1,3 @@ [fetch.https.sub.html] - [sec-fetch-site - Cross-site, init: mode=no-cors] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect, init: mode=no-cors] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Same Origin, init: mode=no-cors] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Same-Site, init: mode=no-cors] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Cross-Site, init: mode=no-cors] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Cross-Site, init: mode=no-cors] - expected: FAIL - - [sec-fetch-site - Same-Site -> Cross-Site, init: mode=no-cors] - expected: FAIL - [sec-fetch-storage-access - Cross-site, init: mode=no-cors, credentials=include] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/fetch.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/fetch.sub.html.ini index 339edb2c742..ac1516fe9e8 100644 --- a/tests/wpt/meta/fetch/metadata/generated/fetch.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/fetch.sub.html.ini @@ -2,8 +2,5 @@ [sec-fetch-site - HTTPS upgrade, no init] expected: FAIL - [sec-fetch-site - HTTPS downgrade-upgrade, no init] - expected: FAIL - [sec-fetch-site - HTTPS downgrade (header not sent), no init] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/header-refresh.https.optional.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/header-refresh.https.optional.sub.html.ini index 35af8ed67c7..3038bb3f030 100644 --- a/tests/wpt/meta/fetch/metadata/generated/header-refresh.https.optional.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/header-refresh.https.optional.sub.html.ini @@ -5,29 +5,20 @@ [sec-fetch-site - Same site] expected: FAIL - [sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Same Origin] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Same-Site] - expected: FAIL - [sec-fetch-site - Cross-Site -> Cross-Site] expected: FAIL - [sec-fetch-site - Same-Origin -> Cross-Site] + [sec-fetch-site - Same-Site -> Same-Site] expected: FAIL - [sec-fetch-site - Same-Site -> Same-Site] + [sec-fetch-user] expected: FAIL - [sec-fetch-site - Same-Site -> Cross-Site] + [sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect] expected: FAIL - [sec-fetch-site - HTTPS downgrade-upgrade] + [sec-fetch-site - Same-Origin -> Same-Site] expected: FAIL - [sec-fetch-user] + [sec-fetch-site - Same-Site -> Same Origin] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/header-refresh.optional.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/header-refresh.optional.sub.html.ini index 97d7fc206a3..2f3dc0399f8 100644 --- a/tests/wpt/meta/fetch/metadata/generated/header-refresh.optional.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/header-refresh.optional.sub.html.ini @@ -4,6 +4,3 @@ [sec-fetch-site - HTTPS upgrade] expected: FAIL - - [sec-fetch-site - HTTPS downgrade-upgrade] - expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/script-module-import-dynamic.https.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/script-module-import-dynamic.https.sub.html.ini index 9da83749a21..453ee20f6ac 100644 --- a/tests/wpt/meta/fetch/metadata/generated/script-module-import-dynamic.https.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/script-module-import-dynamic.https.sub.html.ini @@ -1,21 +1,6 @@ [script-module-import-dynamic.https.sub.html] - [sec-fetch-site - Cross-site] + [sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect] expected: FAIL - [sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Same Origin] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Same-Site] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Cross-Site] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Cross-Site] - expected: FAIL - - [sec-fetch-site - Same-Site -> Cross-Site] + [sec-fetch-site - Same-Site -> Same Origin] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/script-module-import-dynamic.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/script-module-import-dynamic.sub.html.ini index 318935e7f3d..397369ea8a6 100644 --- a/tests/wpt/meta/fetch/metadata/generated/script-module-import-dynamic.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/script-module-import-dynamic.sub.html.ini @@ -2,8 +2,5 @@ [sec-fetch-site - HTTPS upgrade] expected: FAIL - [sec-fetch-site - HTTPS downgrade-upgrade] - expected: FAIL - [sec-fetch-site - HTTPS downgrade (header not sent)] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/script-module-import-static.https.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/script-module-import-static.https.sub.html.ini index 27b82550f15..7e5e2177746 100644 --- a/tests/wpt/meta/fetch/metadata/generated/script-module-import-static.https.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/script-module-import-static.https.sub.html.ini @@ -1,21 +1,6 @@ [script-module-import-static.https.sub.html] - [sec-fetch-site - Cross-site] + [sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect] expected: FAIL - [sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Same Origin] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Same-Site] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Cross-Site] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Cross-Site] - expected: FAIL - - [sec-fetch-site - Same-Site -> Cross-Site] + [sec-fetch-site - Same-Site -> Same Origin] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/script-module-import-static.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/script-module-import-static.sub.html.ini index bc7a5e2d884..61505aa5d8a 100644 --- a/tests/wpt/meta/fetch/metadata/generated/script-module-import-static.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/script-module-import-static.sub.html.ini @@ -2,8 +2,5 @@ [sec-fetch-site - HTTPS upgrade] expected: FAIL - [sec-fetch-site - HTTPS downgrade-upgrade] - expected: FAIL - [sec-fetch-site - HTTPS downgrade (header not sent)] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/serviceworker.https.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/serviceworker.https.sub.html.ini index 107c1fb1a6c..b47a84ff066 100644 --- a/tests/wpt/meta/fetch/metadata/generated/serviceworker.https.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/serviceworker.https.sub.html.ini @@ -26,6 +26,3 @@ [sec-fetch-user - no options - updating] expected: NOTRUN - - [sec-fetch-site - Same origin, no options - registration] - expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/window-location.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/window-location.sub.html.ini index 6643b0b2cc7..8aadf7218d7 100644 --- a/tests/wpt/meta/fetch/metadata/generated/window-location.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/window-location.sub.html.ini @@ -11,18 +11,6 @@ [sec-fetch-site - HTTPS upgrade - location.replace] expected: FAIL - [sec-fetch-site - HTTPS downgrade-upgrade - location] - expected: FAIL - - [sec-fetch-site - HTTPS downgrade-upgrade - location.href] - expected: FAIL - - [sec-fetch-site - HTTPS downgrade-upgrade - location.assign] - expected: FAIL - - [sec-fetch-site - HTTPS downgrade-upgrade - location.replace] - expected: FAIL - [sec-fetch-site - HTTPS downgrade (header not sent) - location] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/worker-dedicated-importscripts.https.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/worker-dedicated-importscripts.https.sub.html.ini index c1e2dd8e89c..e7ffb2ea232 100644 --- a/tests/wpt/meta/fetch/metadata/generated/worker-dedicated-importscripts.https.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/worker-dedicated-importscripts.https.sub.html.ini @@ -1,24 +1,3 @@ [worker-dedicated-importscripts.https.sub.html] - [sec-fetch-site - Cross-site] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Same Origin] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Same-Site] - expected: FAIL - - [sec-fetch-site - Cross-Site -> Cross-Site] - expected: FAIL - - [sec-fetch-site - Same-Origin -> Cross-Site] - expected: FAIL - - [sec-fetch-site - Same-Site -> Cross-Site] - expected: FAIL - [sec-fetch-storage-access - Cross-site] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/generated/worker-dedicated-importscripts.sub.html.ini b/tests/wpt/meta/fetch/metadata/generated/worker-dedicated-importscripts.sub.html.ini index b5ee5020c7a..445be5fea02 100644 --- a/tests/wpt/meta/fetch/metadata/generated/worker-dedicated-importscripts.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/generated/worker-dedicated-importscripts.sub.html.ini @@ -2,8 +2,5 @@ [sec-fetch-site - HTTPS upgrade] expected: FAIL - [sec-fetch-site - HTTPS downgrade-upgrade] - expected: FAIL - [sec-fetch-site - HTTPS downgrade (header not sent)] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/preload.https.sub.html.ini b/tests/wpt/meta/fetch/metadata/preload.https.sub.html.ini index 5c423a2c6bf..abd3860c1e9 100644 --- a/tests/wpt/meta/fetch/metadata/preload.https.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/preload.https.sub.html.ini @@ -1,55 +1,9 @@ [preload.https.sub.html] - expected: TIMEOUT - [<link rel='preload' as='fetch' href='https://web-platform.test:8443/...'>] - expected: TIMEOUT + [preload style www.not-web-platform.test:8443: sec-fetch-dest] + expected: FAIL - [<link rel='preload' as='fetch' href='https://www.web-platform.test:8443/...'>] - expected: TIMEOUT + [preload style www.web-platform.test:8443: sec-fetch-dest] + expected: FAIL - [<link rel='preload' as='fetch' href='https://www.not-web-platform.test:8443/...'>] - expected: TIMEOUT - - [<link rel='preload' as='font' href='https://web-platform.test:8443/...'>] - expected: TIMEOUT - - [<link rel='preload' as='font' href='https://www.web-platform.test:8443/...'>] - expected: TIMEOUT - - [<link rel='preload' as='font' href='https://www.not-web-platform.test:8443/...'>] - expected: TIMEOUT - - [<link rel='preload' as='image' href='https://web-platform.test:8443/...'>] - expected: TIMEOUT - - [<link rel='preload' as='image' href='https://www.web-platform.test:8443/...'>] - expected: TIMEOUT - - [<link rel='preload' as='image' href='https://www.not-web-platform.test:8443/...'>] - expected: TIMEOUT - - [<link rel='preload' as='script' href='https://web-platform.test:8443/...'>] - expected: TIMEOUT - - [<link rel='preload' as='script' href='https://www.web-platform.test:8443/...'>] - expected: TIMEOUT - - [<link rel='preload' as='script' href='https://www.not-web-platform.test:8443/...'>] - expected: TIMEOUT - - [<link rel='preload' as='style' href='https://web-platform.test:8443/...'>] - expected: TIMEOUT - - [<link rel='preload' as='style' href='https://www.web-platform.test:8443/...'>] - expected: TIMEOUT - - [<link rel='preload' as='style' href='https://www.not-web-platform.test:8443/...'>] - expected: TIMEOUT - - [<link rel='preload' as='track' href='https://web-platform.test:8443/...'>] - expected: TIMEOUT - - [<link rel='preload' as='track' href='https://www.web-platform.test:8443/...'>] - expected: TIMEOUT - - [<link rel='preload' as='track' href='https://www.not-web-platform.test:8443/...'>] - expected: TIMEOUT + [preload style web-platform.test:8443: sec-fetch-dest] + expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/redirect/multiple-redirect-https-downgrade-upgrade.sub.html.ini b/tests/wpt/meta/fetch/metadata/redirect/multiple-redirect-https-downgrade-upgrade.sub.html.ini index 77fa4b61164..c60dc98b3b2 100644 --- a/tests/wpt/meta/fetch/metadata/redirect/multiple-redirect-https-downgrade-upgrade.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/redirect/multiple-redirect-https-downgrade-upgrade.sub.html.ini @@ -21,9 +21,6 @@ [Https downgrade-upgrade script => No headers: sec-fetch-mode] expected: FAIL - [Https downgrade-upgrade top level navigation: sec-fetch-site] - expected: FAIL - [Https downgrade-upgrade stylesheet] expected: NOTRUN @@ -33,9 +30,6 @@ [Https downgrade-upgrade embed] expected: TIMEOUT - [Https downgrade-upgrade preload] - expected: TIMEOUT - [Https downgrade-upgrade iframe: sec-fetch-mode] expected: FAIL diff --git a/tests/wpt/meta/fetch/metadata/redirect/redirect-http-upgrade.sub.html.ini b/tests/wpt/meta/fetch/metadata/redirect/redirect-http-upgrade.sub.html.ini index 838ccf7fc7f..0bce8ad0a33 100644 --- a/tests/wpt/meta/fetch/metadata/redirect/redirect-http-upgrade.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/redirect/redirect-http-upgrade.sub.html.ini @@ -6,9 +6,6 @@ [Http upgrade object] expected: NOTRUN - [Http upgrade preload] - expected: TIMEOUT - [Http upgrade stylesheet] expected: NOTRUN diff --git a/tests/wpt/meta/fetch/metadata/redirect/redirect-https-downgrade.sub.html.ini b/tests/wpt/meta/fetch/metadata/redirect/redirect-https-downgrade.sub.html.ini index 6520313bed7..7e6e1b76e96 100644 --- a/tests/wpt/meta/fetch/metadata/redirect/redirect-https-downgrade.sub.html.ini +++ b/tests/wpt/meta/fetch/metadata/redirect/redirect-https-downgrade.sub.html.ini @@ -6,9 +6,6 @@ [Https downgrade object] expected: NOTRUN - [Https downgrade preload] - expected: TIMEOUT - [Https downgrade stylesheet] expected: NOTRUN diff --git a/tests/wpt/meta/fetch/metadata/style.https.sub.html.ini b/tests/wpt/meta/fetch/metadata/style.https.sub.html.ini deleted file mode 100644 index e977bc4e881..00000000000 --- a/tests/wpt/meta/fetch/metadata/style.https.sub.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[style.https.sub.html] - [Cross-Site style: sec-fetch-site] - expected: FAIL diff --git a/tests/wpt/meta/fetch/nosniff/importscripts.html.ini b/tests/wpt/meta/fetch/nosniff/importscripts.html.ini deleted file mode 100644 index 50d9a81d542..00000000000 --- a/tests/wpt/meta/fetch/nosniff/importscripts.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[importscripts.html] - expected: ERROR - [Test importScripts()] - expected: TIMEOUT diff --git a/tests/wpt/meta/fetch/private-network-access/mixed-content-fetch.tentative.https.window.js.ini b/tests/wpt/meta/fetch/private-network-access/mixed-content-fetch.tentative.https.window.js.ini deleted file mode 100644 index 695ae5a48a0..00000000000 --- a/tests/wpt/meta/fetch/private-network-access/mixed-content-fetch.tentative.https.window.js.ini +++ /dev/null @@ -1,156 +0,0 @@ -[mixed-content-fetch.tentative.https.window.html] - [https-local to http-local: wrong targetAddressSpace "unknown".] - expected: FAIL - - [https-local to http-local: wrong targetAddressSpace "private".] - expected: FAIL - - [https-local to http-local: wrong targetAddressSpace "public".] - expected: FAIL - - [https-local to http-local: not a private network request.] - expected: FAIL - - [https-local to http-private: wrong targetAddressSpace "unknown".] - expected: FAIL - - [https-local to http-private: wrong targetAddressSpace "local".] - expected: FAIL - - [https-local to http-private: wrong targetAddressSpace "public".] - expected: FAIL - - [https-local to http-private: not a private network request.] - expected: FAIL - - [https-local to http-public: wrong targetAddressSpace "unknown".] - expected: FAIL - - [https-local to http-public: wrong targetAddressSpace "local".] - expected: FAIL - - [https-local to http-public: wrong targetAddressSpace "private".] - expected: FAIL - - [https-local to http-public: not a private network request.] - expected: FAIL - - [https-private to http-local: missing targetAddressSpace.] - expected: FAIL - - [https-private to http-local: wrong targetAddressSpace "unknown".] - expected: FAIL - - [https-private to http-local: wrong targetAddressSpace "private".] - expected: FAIL - - [https-private to http-local: wrong targetAddressSpace "public".] - expected: FAIL - - [https-private to http-local: failed preflight.] - expected: FAIL - - [https-private to http-local: success.] - expected: FAIL - - [https-private to http-private: wrong targetAddressSpace "unknown".] - expected: FAIL - - [https-private to http-private: wrong targetAddressSpace "local".] - expected: FAIL - - [https-private to http-private: wrong targetAddressSpace "public".] - expected: FAIL - - [https-private to http-private: not a private network request.] - expected: FAIL - - [https-private to http-public: wrong targetAddressSpace "unknown".] - expected: FAIL - - [https-private to http-public: wrong targetAddressSpace "local".] - expected: FAIL - - [https-private to http-public: wrong targetAddressSpace "private".] - expected: FAIL - - [https-private to http-public: not a private network request.] - expected: FAIL - - [https-public to http-local: missing targetAddressSpace.] - expected: FAIL - - [https-public to http-local: wrong targetAddressSpace "unknown".] - expected: FAIL - - [https-public to http-local: wrong targetAddressSpace "private".] - expected: FAIL - - [https-public to http-local: wrong targetAddressSpace "public".] - expected: FAIL - - [https-public to http-local: failed preflight.] - expected: FAIL - - [https-public to http-local: success.] - expected: FAIL - - [https-public to http-private: missing targetAddressSpace.] - expected: FAIL - - [https-public to http-private: wrong targetAddressSpace "unknown".] - expected: FAIL - - [https-public to http-private: wrong targetAddressSpace "local".] - expected: FAIL - - [https-public to http-private: wrong targetAddressSpace "public".] - expected: FAIL - - [https-public to http-private: failed preflight.] - expected: FAIL - - [https-public to http-private: success.] - expected: FAIL - - [https-public to http-public: wrong targetAddressSpace "unknown".] - expected: FAIL - - [https-public to http-public: wrong targetAddressSpace "local".] - expected: FAIL - - [https-public to http-public: wrong targetAddressSpace "private".] - expected: FAIL - - [https-public to http-public: not a private network request.] - expected: FAIL - - [https-treat-as-public to http-local: wrong targetAddressSpace "private".] - expected: FAIL - - [https-treat-as-public to http-private: wrong targetAddressSpace "local".] - expected: FAIL - - [https-treat-as-public to http-private: success.] - expected: FAIL - - [https-private to http-local: PUT success.] - expected: FAIL - - [https-private to http-local: no-cors success.] - expected: FAIL - - [https-public to http-local: PUT success.] - expected: FAIL - - [https-public to http-local: no-cors success.] - expected: FAIL - - [https-public to http-private: PUT success.] - expected: FAIL - - [https-public to http-private: no-cors success.] - expected: FAIL - - [https-treat-as-public to http-local: success.] - expected: FAIL diff --git a/tests/wpt/meta/fetch/private-network-access/window-open-existing.tentative.https.window.js.ini b/tests/wpt/meta/fetch/private-network-access/window-open-existing.tentative.https.window.js.ini deleted file mode 100644 index 6bcaf322518..00000000000 --- a/tests/wpt/meta/fetch/private-network-access/window-open-existing.tentative.https.window.js.ini +++ /dev/null @@ -1,72 +0,0 @@ -[window-open-existing.tentative.https.window.html?include=from-treat-as-public] - [treat-as-public-address to local: failed preflight.] - expected: FAIL - - [treat-as-public-address to local: missing CORS headers.] - expected: FAIL - - [treat-as-public-address to local: missing PNA header.] - expected: FAIL - - [treat-as-public-address to local: success.] - expected: FAIL - - [treat-as-public-address to private: failed preflight.] - expected: FAIL - - [treat-as-public-address to private: missing CORS headers.] - expected: FAIL - - [treat-as-public-address to private: missing PNA header.] - expected: FAIL - - [treat-as-public-address to private: success.] - expected: FAIL - - -[window-open-existing.tentative.https.window.html?include=from-public] - [public to local: failed preflight.] - expected: FAIL - - [public to local: missing CORS headers.] - expected: FAIL - - [public to local: missing PNA header.] - expected: FAIL - - [public to local: success.] - expected: FAIL - - [public to private: failed preflight.] - expected: FAIL - - [public to private: missing CORS headers.] - expected: FAIL - - [public to private: missing PNA header.] - expected: FAIL - - [public to private: success.] - expected: FAIL - - [public to public redirected to private: missing CORS headers.] - expected: FAIL - - [public to public to private: success.] - expected: FAIL - - -[window-open-existing.tentative.https.window.html?include=from-local] - -[window-open-existing.tentative.https.window.html?include=from-private] - [private to local: failed preflight.] - expected: FAIL - - [private to local: missing CORS headers.] - expected: FAIL - - [private to local: missing PNA header.] - expected: FAIL - - [private to local: success.] - expected: FAIL diff --git a/tests/wpt/meta/focus/focus-contenteditable-element-in-iframe-scroll-into-view.html.ini b/tests/wpt/meta/focus/focus-contenteditable-element-in-iframe-scroll-into-view.html.ini new file mode 100644 index 00000000000..1740303b284 --- /dev/null +++ b/tests/wpt/meta/focus/focus-contenteditable-element-in-iframe-scroll-into-view.html.ini @@ -0,0 +1,3 @@ +[focus-contenteditable-element-in-iframe-scroll-into-view.html] + [Check contenteditable element in an iframe scroll into view on second focusing] + expected: FAIL diff --git a/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/008.html.ini b/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/008.html.ini deleted file mode 100644 index c253f779d78..00000000000 --- a/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/008.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[008.html] - [Link with onclick form submit to javascript url and href navigation ] - expected: FAIL diff --git a/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/009.html.ini b/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/009.html.ini new file mode 100644 index 00000000000..3fb21c9b2c6 --- /dev/null +++ b/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/009.html.ini @@ -0,0 +1,3 @@ +[009.html] + [Link with onclick form submit to javascript url with document.write and href navigation ] + expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/set_timeouts/set.py.ini b/tests/wpt/meta/html/browsers/history/the-history-interface/001.html.ini index bfc9d7723d9..b0bdba7f308 100644 --- a/tests/wpt/meta/webdriver/tests/classic/set_timeouts/set.py.ini +++ b/tests/wpt/meta/html/browsers/history/the-history-interface/001.html.ini @@ -1,2 +1,2 @@ -[set.py] +[001.html] expected: TIMEOUT diff --git a/tests/wpt/meta/html/browsers/history/the-history-interface/traverse_the_history_3.html.ini b/tests/wpt/meta/html/browsers/history/the-history-interface/traverse_the_history_3.html.ini new file mode 100644 index 00000000000..a03a8322165 --- /dev/null +++ b/tests/wpt/meta/html/browsers/history/the-history-interface/traverse_the_history_3.html.ini @@ -0,0 +1,3 @@ +[traverse_the_history_3.html] + [Multiple history traversals, last would be aborted] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-colorSpaceConversion.html.ini b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-colorSpaceConversion.html.ini index 1cb6ce30242..1629ecdc8f3 100644 --- a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-colorSpaceConversion.html.ini +++ b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-colorSpaceConversion.html.ini @@ -1,5 +1,4 @@ [createImageBitmap-colorSpaceConversion.html] - expected: ERROR [createImageBitmap from a bitmap HTMLImageElement, and drawImage on the created ImageBitmap with colorSpaceConversion: none] expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-drawImage.html.ini b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-drawImage.html.ini index 9cf5b2af86a..c999a8d9b18 100644 --- a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-drawImage.html.ini +++ b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-drawImage.html.ini @@ -1,5 +1,4 @@ [createImageBitmap-drawImage.html] - expected: ERROR [createImageBitmap from an OffscreenCanvas resized, and drawImage on the created ImageBitmap] expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-flipY.html.ini b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-flipY.html.ini index 0cb93c5abc9..f279cd2dd85 100644 --- a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-flipY.html.ini +++ b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-flipY.html.ini @@ -1,5 +1,4 @@ [createImageBitmap-flipY.html] - expected: ERROR [createImageBitmap from a vector SVGImageElement imageOrientation: "none", and drawImage on the created ImageBitmap] expected: NOTRUN diff --git a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-invalid-args.html.ini b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-invalid-args.html.ini index aba246039a0..94caf82cb7f 100644 --- a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-invalid-args.html.ini +++ b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-invalid-args.html.ini @@ -1,5 +1,4 @@ [createImageBitmap-invalid-args.html] - expected: CRASH [createImageBitmap with a vector HTMLImageElement source and sw set to 0] expected: FAIL @@ -10,16 +9,13 @@ expected: FAIL [createImageBitmap with a broken image source.] - expected: NOTRUN - - [createImageBitmap with WebGLRenderingContext image source.] - expected: NOTRUN + expected: FAIL [createImageBitmap with a Blob source and sw set to 0] - expected: NOTRUN + expected: FAIL [createImageBitmap with an available but zero height image source.] - expected: NOTRUN + expected: FAIL [createImageBitmap with an HTMLVideoElement source and sh set to 0] expected: FAIL @@ -28,25 +24,19 @@ expected: FAIL [createImageBitmap with a Blob source and sh set to 0] - expected: NOTRUN + expected: FAIL [createImageBitmap with an HTMLVideoElement from a data URL source and sw set to 0] expected: FAIL - [createImageBitmap with null image source.] - expected: NOTRUN - [createImageBitmap with an ImageData source and sh set to 0] - expected: NOTRUN - - [createImageBitmap with undefined image source.] - expected: NOTRUN + expected: FAIL [createImageBitmap with an undecodable blob source.] - expected: NOTRUN + expected: FAIL [createImageBitmap with an available but undecodable image source.] - expected: NOTRUN + expected: FAIL [createImageBitmap with an HTMLVideoElement from a data URL source and oversized (unallocatable) crop region] expected: FAIL @@ -55,13 +45,13 @@ expected: FAIL [createImageBitmap with a vector SVGImageElement source and oversized (unallocatable) crop region] - expected: NOTRUN + expected: FAIL [createImageBitmap with an HTMLCanvasElement source and oversized (unallocatable) crop region] expected: FAIL [createImageBitmap with an ImageBitmap source and oversized (unallocatable) crop region] - expected: NOTRUN + expected: FAIL [createImageBitmap with an HTMLVideoElement source and oversized (unallocatable) crop region] expected: FAIL @@ -70,187 +60,100 @@ expected: FAIL [createImageBitmap with an ImageData source and sw set to 0] - expected: NOTRUN - - [createImageBitmap with an invalid OffscreenCanvas source.] - expected: NOTRUN + expected: FAIL [createImageBitmap with an OffscreenCanvas source and sh set to 0] - expected: NOTRUN + expected: FAIL [createImageBitmap with an OffscreenCanvas source and sw set to 0] - expected: NOTRUN + expected: FAIL [createImageBitmap with an HTMLVideoElement from a data URL source and sh set to 0] expected: FAIL [createImageBitmap with an ImageData source and oversized (unallocatable) crop region] - expected: NOTRUN - - [createImageBitmap with ArrayBuffer image source.] - expected: NOTRUN + expected: FAIL [createImageBitmap with a bitmap SVGImageElement source and oversized (unallocatable) crop region] - expected: NOTRUN - - [createImageBitmap with an oversized canvas source.] - expected: NOTRUN - - [createImageBitmap with Uint8Array image source.] - expected: NOTRUN + expected: FAIL [createImageBitmap with a vector SVGImageElement source and sh set to 0] - expected: NOTRUN + expected: FAIL [createImageBitmap with an HTMLCanvasElement source and sh set to 0] expected: FAIL [createImageBitmap with a closed ImageBitmap.] - expected: NOTRUN + expected: FAIL [createImageBitmap with a bitmap HTMLImageElement source and oversized (unallocatable) crop region] expected: FAIL [createImageBitmap with empty image source.] - expected: NOTRUN + expected: FAIL [createImageBitmap with empty video source.] - expected: NOTRUN + expected: FAIL [createImageBitmap with a bitmap SVGImageElement source and sw set to 0] - expected: TIMEOUT + expected: FAIL [createImageBitmap with an ImageBitmap source and sh set to 0] - expected: NOTRUN + expected: FAIL [createImageBitmap with an available but zero width image source.] - expected: NOTRUN + expected: FAIL [createImageBitmap with a vector SVGImageElement source and sw set to 0] - expected: NOTRUN + expected: FAIL [createImageBitmap with a Blob source and oversized (unallocatable) crop region] - expected: NOTRUN + expected: FAIL [createImageBitmap with a bitmap SVGImageElement source and sh set to 0] - expected: NOTRUN + expected: FAIL [createImageBitmap with an ImageBitmap source and sw set to 0] - expected: NOTRUN + expected: FAIL [createImageBitmap with a bitmap HTMLImageElement source and sw set to 0] expected: FAIL [createImageBitmap with an OffscreenCanvas source and oversized (unallocatable) crop region] - expected: NOTRUN - - [createImageBitmap with CanvasRenderingContext2D image source.] - expected: NOTRUN - - [createImageBitmap with a vector HTMLImageElement source and a value of 0 int resizeWidth] - expected: FAIL - - [createImageBitmap with a vector HTMLImageElement source and a value between 0 and 1 in resizeWidth] expected: FAIL - [createImageBitmap with an OffscreenCanvas source and a value of 0 in resizeHeight] - expected: NOTRUN - [createImageBitmap with a bitmap SVGImageElement source and a value of 0 in resizeHeight] - expected: NOTRUN - - [createImageBitmap with an ImageData source and a value between 0 and 1 in resizeWidth] - expected: NOTRUN + expected: FAIL [createImageBitmap with a vector SVGImageElement source and a value of 0 int resizeWidth] - expected: NOTRUN + expected: FAIL [createImageBitmap with an ImageBitmap source and a value between 0 and 1 in resizeWidth] - expected: NOTRUN + expected: FAIL [createImageBitmap with an ImageBitmap source and a value of 0 int resizeWidth] - expected: NOTRUN - - [createImageBitmap with an ImageData source and a value of 0 in resizeHeight] - expected: NOTRUN - - [createImageBitmap with an HTMLVideoElement source and a value between 0 and 1 in resizeWidth] expected: FAIL - [createImageBitmap with an OffscreenCanvas source and a value between 0 and 1 in resizeWidth] - expected: NOTRUN - [createImageBitmap with a vector SVGImageElement source and a value between 0 and 1 in resizeHeight] - expected: NOTRUN - - [createImageBitmap with a Blob source and a value of 0 int resizeWidth] - expected: NOTRUN - - [createImageBitmap with an HTMLVideoElement source and a value of 0 in resizeHeight] - expected: FAIL - - [createImageBitmap with an HTMLVideoElement from a data URL source and a value between 0 and 1 in resizeWidth] expected: FAIL [createImageBitmap with a vector SVGImageElement source and a value of 0 in resizeHeight] - expected: NOTRUN - - [createImageBitmap with a bitmap SVGImageElement source and a value between 0 and 1 in resizeHeight] - expected: NOTRUN - - [createImageBitmap with a Blob source and a value between 0 and 1 in resizeHeight] - expected: NOTRUN - - [createImageBitmap with a Blob source and a value between 0 and 1 in resizeWidth] - expected: NOTRUN - - [createImageBitmap with a vector HTMLImageElement source and a value between 0 and 1 in resizeHeight] expected: FAIL - [createImageBitmap with an HTMLVideoElement from a data URL source and a value of 0 in resizeHeight] + [createImageBitmap with a bitmap SVGImageElement source and a value between 0 and 1 in resizeHeight] expected: FAIL [createImageBitmap with an ImageBitmap source and a value of 0 in resizeHeight] - expected: NOTRUN - - [createImageBitmap with an ImageBitmap source and a value between 0 and 1 in resizeHeight] - expected: NOTRUN - - [createImageBitmap with a bitmap SVGImageElement source and a value between 0 and 1 in resizeWidth] - expected: NOTRUN - - [createImageBitmap with an HTMLVideoElement source and a value between 0 and 1 in resizeHeight] expected: FAIL - [createImageBitmap with an HTMLVideoElement source and a value of 0 int resizeWidth] + [createImageBitmap with an ImageBitmap source and a value between 0 and 1 in resizeHeight] expected: FAIL - [createImageBitmap with an OffscreenCanvas source and a value of 0 int resizeWidth] - expected: NOTRUN - - [createImageBitmap with a vector HTMLImageElement source and a value of 0 in resizeHeight] + [createImageBitmap with a bitmap SVGImageElement source and a value between 0 and 1 in resizeWidth] expected: FAIL - [createImageBitmap with an OffscreenCanvas source and a value between 0 and 1 in resizeHeight] - expected: NOTRUN - [createImageBitmap with a bitmap SVGImageElement source and a value of 0 int resizeWidth] - expected: NOTRUN - - [createImageBitmap with an HTMLVideoElement from a data URL source and a value of 0 int resizeWidth] - expected: FAIL - - [createImageBitmap with an ImageData source and a value between 0 and 1 in resizeHeight] - expected: NOTRUN - - [createImageBitmap with an HTMLVideoElement from a data URL source and a value between 0 and 1 in resizeHeight] expected: FAIL - [createImageBitmap with an ImageData source and a value of 0 int resizeWidth] - expected: NOTRUN - [createImageBitmap with a vector SVGImageElement source and a value between 0 and 1 in resizeWidth] - expected: NOTRUN - - [createImageBitmap with a Blob source and a value of 0 in resizeHeight] - expected: NOTRUN + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-origin.sub.html.ini b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-origin.sub.html.ini index d7226bfed74..0420669cc09 100644 --- a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-origin.sub.html.ini +++ b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-origin.sub.html.ini @@ -1,5 +1,4 @@ [createImageBitmap-origin.sub.html] - expected: TIMEOUT [redirected to cross-origin HTMLVideoElement: origin unclear 2dContext.drawImage] expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-premultiplyAlpha.html.ini b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-premultiplyAlpha.html.ini index 65a62f89001..15eea07cff8 100644 --- a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-premultiplyAlpha.html.ini +++ b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-premultiplyAlpha.html.ini @@ -1,5 +1,4 @@ [createImageBitmap-premultiplyAlpha.html] - expected: ERROR [createImageBitmap: from ImageData, unpremultiplied, drawn to canvas] expected: FAIL diff --git a/tests/wpt/meta/html/dom/idlharness.https.html.ini b/tests/wpt/meta/html/dom/idlharness.https.html.ini index 981cd249aa6..ed387df6221 100644 --- a/tests/wpt/meta/html/dom/idlharness.https.html.ini +++ b/tests/wpt/meta/html/dom/idlharness.https.html.ini @@ -5389,9 +5389,6 @@ [HTMLBaseElement interface: document.createElement("base") must inherit property "target" with the proper type] expected: FAIL - [HTMLLinkElement interface: attribute as] - expected: FAIL - [HTMLLinkElement interface: attribute sizes] expected: FAIL @@ -5407,9 +5404,6 @@ [HTMLLinkElement interface: attribute fetchPriority] expected: FAIL - [HTMLLinkElement interface: document.createElement("link") must inherit property "as" with the proper type] - expected: FAIL - [HTMLLinkElement interface: document.createElement("link") must inherit property "sizes" with the proper type] expected: FAIL @@ -5461,18 +5455,6 @@ [HTMLHeadingElement interface: document.createElement("h1") must inherit property "align" with the proper type] expected: FAIL - [HTMLHRElement interface: attribute noShade] - expected: FAIL - - [HTMLHRElement interface: attribute size] - expected: FAIL - - [HTMLHRElement interface: document.createElement("hr") must inherit property "noShade" with the proper type] - expected: FAIL - - [HTMLHRElement interface: document.createElement("hr") must inherit property "size" with the proper type] - expected: FAIL - [HTMLOListElement interface: attribute reversed] expected: FAIL @@ -6931,18 +6913,12 @@ [HTMLScriptElement interface: attribute fetchPriority] expected: FAIL - [HTMLScriptElement interface: operation supports(DOMString)] - expected: FAIL - [HTMLScriptElement interface: document.createElement("script") must inherit property "blocking" with the proper type] expected: FAIL [HTMLScriptElement interface: document.createElement("script") must inherit property "fetchPriority" with the proper type] expected: FAIL - [HTMLScriptElement interface: calling supports(DOMString) on document.createElement("script") with too few arguments must throw TypeError] - expected: FAIL - [HTMLMarqueeElement interface: existence and properties of interface object] expected: FAIL diff --git a/tests/wpt/meta/html/dom/reflection-grouping.html.ini b/tests/wpt/meta/html/dom/reflection-grouping.html.ini index 556eea039e9..ec7075bc5ab 100644 --- a/tests/wpt/meta/html/dom/reflection-grouping.html.ini +++ b/tests/wpt/meta/html/dom/reflection-grouping.html.ini @@ -383,234 +383,6 @@ [hr.tabIndex: IDL set to -2147483648] expected: FAIL - [hr.noShade: typeof IDL attribute] - expected: FAIL - - [hr.noShade: IDL get with DOM attribute unset] - expected: FAIL - - [hr.noShade: setAttribute() to ""] - expected: FAIL - - [hr.noShade: setAttribute() to " foo "] - expected: FAIL - - [hr.noShade: setAttribute() to undefined] - expected: FAIL - - [hr.noShade: setAttribute() to null] - expected: FAIL - - [hr.noShade: setAttribute() to 7] - expected: FAIL - - [hr.noShade: setAttribute() to 1.5] - expected: FAIL - - [hr.noShade: setAttribute() to "5%"] - expected: FAIL - - [hr.noShade: setAttribute() to "+100"] - expected: FAIL - - [hr.noShade: setAttribute() to ".5"] - expected: FAIL - - [hr.noShade: setAttribute() to true] - expected: FAIL - - [hr.noShade: setAttribute() to false] - expected: FAIL - - [hr.noShade: setAttribute() to object "[object Object\]"] - expected: FAIL - - [hr.noShade: setAttribute() to NaN] - expected: FAIL - - [hr.noShade: setAttribute() to Infinity] - expected: FAIL - - [hr.noShade: setAttribute() to -Infinity] - expected: FAIL - - [hr.noShade: setAttribute() to "\\0"] - expected: FAIL - - [hr.noShade: setAttribute() to object "test-toString"] - expected: FAIL - - [hr.noShade: setAttribute() to object "test-valueOf"] - expected: FAIL - - [hr.noShade: setAttribute() to "noShade"] - expected: FAIL - - [hr.noShade: IDL set to ""] - expected: FAIL - - [hr.noShade: IDL set to " foo "] - expected: FAIL - - [hr.noShade: IDL set to undefined] - expected: FAIL - - [hr.noShade: IDL set to null] - expected: FAIL - - [hr.noShade: IDL set to 7] - expected: FAIL - - [hr.noShade: IDL set to 1.5] - expected: FAIL - - [hr.noShade: IDL set to "5%"] - expected: FAIL - - [hr.noShade: IDL set to "+100"] - expected: FAIL - - [hr.noShade: IDL set to ".5"] - expected: FAIL - - [hr.noShade: IDL set to false] - expected: FAIL - - [hr.noShade: IDL set to object "[object Object\]"] - expected: FAIL - - [hr.noShade: IDL set to NaN] - expected: FAIL - - [hr.noShade: IDL set to Infinity] - expected: FAIL - - [hr.noShade: IDL set to -Infinity] - expected: FAIL - - [hr.noShade: IDL set to "\\0"] - expected: FAIL - - [hr.noShade: IDL set to object "test-toString"] - expected: FAIL - - [hr.noShade: IDL set to object "test-valueOf"] - expected: FAIL - - [hr.size: typeof IDL attribute] - expected: FAIL - - [hr.size: IDL get with DOM attribute unset] - expected: FAIL - - [hr.size: setAttribute() to ""] - expected: FAIL - - [hr.size: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "] - expected: FAIL - - [hr.size: setAttribute() to undefined] - expected: FAIL - - [hr.size: setAttribute() to 7] - expected: FAIL - - [hr.size: setAttribute() to 1.5] - expected: FAIL - - [hr.size: setAttribute() to "5%"] - expected: FAIL - - [hr.size: setAttribute() to "+100"] - expected: FAIL - - [hr.size: setAttribute() to ".5"] - expected: FAIL - - [hr.size: setAttribute() to true] - expected: FAIL - - [hr.size: setAttribute() to false] - expected: FAIL - - [hr.size: setAttribute() to object "[object Object\]"] - expected: FAIL - - [hr.size: setAttribute() to NaN] - expected: FAIL - - [hr.size: setAttribute() to Infinity] - expected: FAIL - - [hr.size: setAttribute() to -Infinity] - expected: FAIL - - [hr.size: setAttribute() to "\\0"] - expected: FAIL - - [hr.size: setAttribute() to null] - expected: FAIL - - [hr.size: setAttribute() to object "test-toString"] - expected: FAIL - - [hr.size: setAttribute() to object "test-valueOf"] - expected: FAIL - - [hr.size: IDL set to ""] - expected: FAIL - - [hr.size: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "] - expected: FAIL - - [hr.size: IDL set to undefined] - expected: FAIL - - [hr.size: IDL set to 7] - expected: FAIL - - [hr.size: IDL set to 1.5] - expected: FAIL - - [hr.size: IDL set to "5%"] - expected: FAIL - - [hr.size: IDL set to "+100"] - expected: FAIL - - [hr.size: IDL set to ".5"] - expected: FAIL - - [hr.size: IDL set to true] - expected: FAIL - - [hr.size: IDL set to false] - expected: FAIL - - [hr.size: IDL set to object "[object Object\]"] - expected: FAIL - - [hr.size: IDL set to NaN] - expected: FAIL - - [hr.size: IDL set to Infinity] - expected: FAIL - - [hr.size: IDL set to -Infinity] - expected: FAIL - - [hr.size: IDL set to "\\0"] - expected: FAIL - - [hr.size: IDL set to null] - expected: FAIL - - [hr.size: IDL set to object "test-toString"] - expected: FAIL - - [hr.size: IDL set to object "test-valueOf"] - expected: FAIL - [pre.accessKey: typeof IDL attribute] expected: FAIL diff --git a/tests/wpt/meta/html/dom/reflection-metadata.html.ini b/tests/wpt/meta/html/dom/reflection-metadata.html.ini index 8e95b7fd3c1..c9d71a7f87c 100644 --- a/tests/wpt/meta/html/dom/reflection-metadata.html.ini +++ b/tests/wpt/meta/html/dom/reflection-metadata.html.ini @@ -881,648 +881,6 @@ [link.tabIndex: IDL set to -2147483648] expected: FAIL - [link.as: typeof IDL attribute] - expected: FAIL - - [link.as: IDL get with DOM attribute unset] - expected: FAIL - - [link.as: setAttribute() to ""] - expected: FAIL - - [link.as: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "] - expected: FAIL - - [link.as: setAttribute() to undefined] - expected: FAIL - - [link.as: setAttribute() to 7] - expected: FAIL - - [link.as: setAttribute() to 1.5] - expected: FAIL - - [link.as: setAttribute() to "5%"] - expected: FAIL - - [link.as: setAttribute() to "+100"] - expected: FAIL - - [link.as: setAttribute() to ".5"] - expected: FAIL - - [link.as: setAttribute() to true] - expected: FAIL - - [link.as: setAttribute() to false] - expected: FAIL - - [link.as: setAttribute() to object "[object Object\]"] - expected: FAIL - - [link.as: setAttribute() to NaN] - expected: FAIL - - [link.as: setAttribute() to Infinity] - expected: FAIL - - [link.as: setAttribute() to -Infinity] - expected: FAIL - - [link.as: setAttribute() to "\\0"] - expected: FAIL - - [link.as: setAttribute() to null] - expected: FAIL - - [link.as: setAttribute() to object "test-toString"] - expected: FAIL - - [link.as: setAttribute() to object "test-valueOf"] - expected: FAIL - - [link.as: setAttribute() to "fetch"] - expected: FAIL - - [link.as: setAttribute() to "xfetch"] - expected: FAIL - - [link.as: setAttribute() to "fetch\\0"] - expected: FAIL - - [link.as: setAttribute() to "etch"] - expected: FAIL - - [link.as: setAttribute() to "FETCH"] - expected: FAIL - - [link.as: setAttribute() to "audio"] - expected: FAIL - - [link.as: setAttribute() to "xaudio"] - expected: FAIL - - [link.as: setAttribute() to "audio\\0"] - expected: FAIL - - [link.as: setAttribute() to "udio"] - expected: FAIL - - [link.as: setAttribute() to "AUDIO"] - expected: FAIL - - [link.as: setAttribute() to "document"] - expected: FAIL - - [link.as: setAttribute() to "xdocument"] - expected: FAIL - - [link.as: setAttribute() to "document\\0"] - expected: FAIL - - [link.as: setAttribute() to "ocument"] - expected: FAIL - - [link.as: setAttribute() to "DOCUMENT"] - expected: FAIL - - [link.as: setAttribute() to "embed"] - expected: FAIL - - [link.as: setAttribute() to "xembed"] - expected: FAIL - - [link.as: setAttribute() to "embed\\0"] - expected: FAIL - - [link.as: setAttribute() to "mbed"] - expected: FAIL - - [link.as: setAttribute() to "EMBED"] - expected: FAIL - - [link.as: setAttribute() to "font"] - expected: FAIL - - [link.as: setAttribute() to "xfont"] - expected: FAIL - - [link.as: setAttribute() to "font\\0"] - expected: FAIL - - [link.as: setAttribute() to "ont"] - expected: FAIL - - [link.as: setAttribute() to "FONT"] - expected: FAIL - - [link.as: setAttribute() to "image"] - expected: FAIL - - [link.as: setAttribute() to "ximage"] - expected: FAIL - - [link.as: setAttribute() to "image\\0"] - expected: FAIL - - [link.as: setAttribute() to "mage"] - expected: FAIL - - [link.as: setAttribute() to "IMAGE"] - expected: FAIL - - [link.as: setAttribute() to "manifest"] - expected: FAIL - - [link.as: setAttribute() to "xmanifest"] - expected: FAIL - - [link.as: setAttribute() to "manifest\\0"] - expected: FAIL - - [link.as: setAttribute() to "anifest"] - expected: FAIL - - [link.as: setAttribute() to "MANIFEST"] - expected: FAIL - - [link.as: setAttribute() to "manifeſt"] - expected: FAIL - - [link.as: setAttribute() to "object"] - expected: FAIL - - [link.as: setAttribute() to "xobject"] - expected: FAIL - - [link.as: setAttribute() to "object\\0"] - expected: FAIL - - [link.as: setAttribute() to "bject"] - expected: FAIL - - [link.as: setAttribute() to "OBJECT"] - expected: FAIL - - [link.as: setAttribute() to "report"] - expected: FAIL - - [link.as: setAttribute() to "xreport"] - expected: FAIL - - [link.as: setAttribute() to "report\\0"] - expected: FAIL - - [link.as: setAttribute() to "eport"] - expected: FAIL - - [link.as: setAttribute() to "REPORT"] - expected: FAIL - - [link.as: setAttribute() to "script"] - expected: FAIL - - [link.as: setAttribute() to "xscript"] - expected: FAIL - - [link.as: setAttribute() to "script\\0"] - expected: FAIL - - [link.as: setAttribute() to "cript"] - expected: FAIL - - [link.as: setAttribute() to "SCRIPT"] - expected: FAIL - - [link.as: setAttribute() to "ſcript"] - expected: FAIL - - [link.as: setAttribute() to "sharedworker"] - expected: FAIL - - [link.as: setAttribute() to "xsharedworker"] - expected: FAIL - - [link.as: setAttribute() to "sharedworker\\0"] - expected: FAIL - - [link.as: setAttribute() to "haredworker"] - expected: FAIL - - [link.as: setAttribute() to "SHAREDWORKER"] - expected: FAIL - - [link.as: setAttribute() to "sharedworKer"] - expected: FAIL - - [link.as: setAttribute() to "ſharedworker"] - expected: FAIL - - [link.as: setAttribute() to "style"] - expected: FAIL - - [link.as: setAttribute() to "xstyle"] - expected: FAIL - - [link.as: setAttribute() to "style\\0"] - expected: FAIL - - [link.as: setAttribute() to "tyle"] - expected: FAIL - - [link.as: setAttribute() to "STYLE"] - expected: FAIL - - [link.as: setAttribute() to "ſtyle"] - expected: FAIL - - [link.as: setAttribute() to "track"] - expected: FAIL - - [link.as: setAttribute() to "xtrack"] - expected: FAIL - - [link.as: setAttribute() to "track\\0"] - expected: FAIL - - [link.as: setAttribute() to "rack"] - expected: FAIL - - [link.as: setAttribute() to "TRACK"] - expected: FAIL - - [link.as: setAttribute() to "tracK"] - expected: FAIL - - [link.as: setAttribute() to "video"] - expected: FAIL - - [link.as: setAttribute() to "xvideo"] - expected: FAIL - - [link.as: setAttribute() to "video\\0"] - expected: FAIL - - [link.as: setAttribute() to "ideo"] - expected: FAIL - - [link.as: setAttribute() to "VIDEO"] - expected: FAIL - - [link.as: setAttribute() to "worker"] - expected: FAIL - - [link.as: setAttribute() to "xworker"] - expected: FAIL - - [link.as: setAttribute() to "worker\\0"] - expected: FAIL - - [link.as: setAttribute() to "orker"] - expected: FAIL - - [link.as: setAttribute() to "WORKER"] - expected: FAIL - - [link.as: setAttribute() to "worKer"] - expected: FAIL - - [link.as: setAttribute() to "xslt"] - expected: FAIL - - [link.as: setAttribute() to "xxslt"] - expected: FAIL - - [link.as: setAttribute() to "xslt\\0"] - expected: FAIL - - [link.as: setAttribute() to "slt"] - expected: FAIL - - [link.as: setAttribute() to "XSLT"] - expected: FAIL - - [link.as: setAttribute() to "xſlt"] - expected: FAIL - - [link.as: IDL set to ""] - expected: FAIL - - [link.as: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "] - expected: FAIL - - [link.as: IDL set to undefined] - expected: FAIL - - [link.as: IDL set to 7] - expected: FAIL - - [link.as: IDL set to 1.5] - expected: FAIL - - [link.as: IDL set to "5%"] - expected: FAIL - - [link.as: IDL set to "+100"] - expected: FAIL - - [link.as: IDL set to ".5"] - expected: FAIL - - [link.as: IDL set to true] - expected: FAIL - - [link.as: IDL set to false] - expected: FAIL - - [link.as: IDL set to object "[object Object\]"] - expected: FAIL - - [link.as: IDL set to NaN] - expected: FAIL - - [link.as: IDL set to Infinity] - expected: FAIL - - [link.as: IDL set to -Infinity] - expected: FAIL - - [link.as: IDL set to "\\0"] - expected: FAIL - - [link.as: IDL set to null] - expected: FAIL - - [link.as: IDL set to object "test-toString"] - expected: FAIL - - [link.as: IDL set to object "test-valueOf"] - expected: FAIL - - [link.as: IDL set to "fetch"] - expected: FAIL - - [link.as: IDL set to "xfetch"] - expected: FAIL - - [link.as: IDL set to "fetch\\0"] - expected: FAIL - - [link.as: IDL set to "etch"] - expected: FAIL - - [link.as: IDL set to "FETCH"] - expected: FAIL - - [link.as: IDL set to "audio"] - expected: FAIL - - [link.as: IDL set to "xaudio"] - expected: FAIL - - [link.as: IDL set to "audio\\0"] - expected: FAIL - - [link.as: IDL set to "udio"] - expected: FAIL - - [link.as: IDL set to "AUDIO"] - expected: FAIL - - [link.as: IDL set to "document"] - expected: FAIL - - [link.as: IDL set to "xdocument"] - expected: FAIL - - [link.as: IDL set to "document\\0"] - expected: FAIL - - [link.as: IDL set to "ocument"] - expected: FAIL - - [link.as: IDL set to "DOCUMENT"] - expected: FAIL - - [link.as: IDL set to "embed"] - expected: FAIL - - [link.as: IDL set to "xembed"] - expected: FAIL - - [link.as: IDL set to "embed\\0"] - expected: FAIL - - [link.as: IDL set to "mbed"] - expected: FAIL - - [link.as: IDL set to "EMBED"] - expected: FAIL - - [link.as: IDL set to "font"] - expected: FAIL - - [link.as: IDL set to "xfont"] - expected: FAIL - - [link.as: IDL set to "font\\0"] - expected: FAIL - - [link.as: IDL set to "ont"] - expected: FAIL - - [link.as: IDL set to "FONT"] - expected: FAIL - - [link.as: IDL set to "image"] - expected: FAIL - - [link.as: IDL set to "ximage"] - expected: FAIL - - [link.as: IDL set to "image\\0"] - expected: FAIL - - [link.as: IDL set to "mage"] - expected: FAIL - - [link.as: IDL set to "IMAGE"] - expected: FAIL - - [link.as: IDL set to "manifest"] - expected: FAIL - - [link.as: IDL set to "xmanifest"] - expected: FAIL - - [link.as: IDL set to "manifest\\0"] - expected: FAIL - - [link.as: IDL set to "anifest"] - expected: FAIL - - [link.as: IDL set to "MANIFEST"] - expected: FAIL - - [link.as: IDL set to "manifeſt"] - expected: FAIL - - [link.as: IDL set to "object"] - expected: FAIL - - [link.as: IDL set to "xobject"] - expected: FAIL - - [link.as: IDL set to "object\\0"] - expected: FAIL - - [link.as: IDL set to "bject"] - expected: FAIL - - [link.as: IDL set to "OBJECT"] - expected: FAIL - - [link.as: IDL set to "report"] - expected: FAIL - - [link.as: IDL set to "xreport"] - expected: FAIL - - [link.as: IDL set to "report\\0"] - expected: FAIL - - [link.as: IDL set to "eport"] - expected: FAIL - - [link.as: IDL set to "REPORT"] - expected: FAIL - - [link.as: IDL set to "script"] - expected: FAIL - - [link.as: IDL set to "xscript"] - expected: FAIL - - [link.as: IDL set to "script\\0"] - expected: FAIL - - [link.as: IDL set to "cript"] - expected: FAIL - - [link.as: IDL set to "SCRIPT"] - expected: FAIL - - [link.as: IDL set to "ſcript"] - expected: FAIL - - [link.as: IDL set to "sharedworker"] - expected: FAIL - - [link.as: IDL set to "xsharedworker"] - expected: FAIL - - [link.as: IDL set to "sharedworker\\0"] - expected: FAIL - - [link.as: IDL set to "haredworker"] - expected: FAIL - - [link.as: IDL set to "SHAREDWORKER"] - expected: FAIL - - [link.as: IDL set to "sharedworKer"] - expected: FAIL - - [link.as: IDL set to "ſharedworker"] - expected: FAIL - - [link.as: IDL set to "style"] - expected: FAIL - - [link.as: IDL set to "xstyle"] - expected: FAIL - - [link.as: IDL set to "style\\0"] - expected: FAIL - - [link.as: IDL set to "tyle"] - expected: FAIL - - [link.as: IDL set to "STYLE"] - expected: FAIL - - [link.as: IDL set to "ſtyle"] - expected: FAIL - - [link.as: IDL set to "track"] - expected: FAIL - - [link.as: IDL set to "xtrack"] - expected: FAIL - - [link.as: IDL set to "track\\0"] - expected: FAIL - - [link.as: IDL set to "rack"] - expected: FAIL - - [link.as: IDL set to "TRACK"] - expected: FAIL - - [link.as: IDL set to "tracK"] - expected: FAIL - - [link.as: IDL set to "video"] - expected: FAIL - - [link.as: IDL set to "xvideo"] - expected: FAIL - - [link.as: IDL set to "video\\0"] - expected: FAIL - - [link.as: IDL set to "ideo"] - expected: FAIL - - [link.as: IDL set to "VIDEO"] - expected: FAIL - - [link.as: IDL set to "worker"] - expected: FAIL - - [link.as: IDL set to "xworker"] - expected: FAIL - - [link.as: IDL set to "worker\\0"] - expected: FAIL - - [link.as: IDL set to "orker"] - expected: FAIL - - [link.as: IDL set to "WORKER"] - expected: FAIL - - [link.as: IDL set to "worKer"] - expected: FAIL - - [link.as: IDL set to "xslt"] - expected: FAIL - - [link.as: IDL set to "xxslt"] - expected: FAIL - - [link.as: IDL set to "xslt\\0"] - expected: FAIL - - [link.as: IDL set to "slt"] - expected: FAIL - - [link.as: IDL set to "XSLT"] - expected: FAIL - - [link.as: IDL set to "xſlt"] - expected: FAIL - [meta.accessKey: typeof IDL attribute] expected: FAIL diff --git a/tests/wpt/meta/html/semantics/document-metadata/interactions-of-styling-and-scripting/link-stylesheet-with-non-match-media-does-not-block-render.tentative.html.ini b/tests/wpt/meta/html/semantics/document-metadata/interactions-of-styling-and-scripting/link-stylesheet-with-non-match-media-does-not-block-render.tentative.html.ini deleted file mode 100644 index 9d0ab013981..00000000000 --- a/tests/wpt/meta/html/semantics/document-metadata/interactions-of-styling-and-scripting/link-stylesheet-with-non-match-media-does-not-block-render.tentative.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[link-stylesheet-with-non-match-media-does-not-block-render.tentative.html] - [\n Delayed Stylesheet imported using link tag should not block rendering\n or JS execution when media doesn't match.\n] - expected: FAIL diff --git a/tests/wpt/meta/html/semantics/embedded-content/media-elements/media_fragment_seek.html.ini b/tests/wpt/meta/html/semantics/embedded-content/media-elements/media_fragment_seek.html.ini deleted file mode 100644 index dbbc149ee4a..00000000000 --- a/tests/wpt/meta/html/semantics/embedded-content/media-elements/media_fragment_seek.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[media_fragment_seek.html] - expected: CRASH diff --git a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini index 24903b5f66f..d7e7d1b9815 100644 --- a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini +++ b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini @@ -1,4 +1,4 @@ [iframe_sandbox_popups_escaping-1.html] - expected: TIMEOUT + expected: CRASH [Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used] expected: TIMEOUT diff --git a/tests/wpt/meta/html/semantics/permission-element/negative-offset-and-margin.tentative.html.ini b/tests/wpt/meta/html/semantics/permission-element/negative-offset-and-margin.tentative.html.ini deleted file mode 100644 index 75e70650007..00000000000 --- a/tests/wpt/meta/html/semantics/permission-element/negative-offset-and-margin.tentative.html.ini +++ /dev/null @@ -1,12 +0,0 @@ -[negative-offset-and-margin.tentative.html] - [Negative margins/offset should be changed to 0px] - expected: FAIL - - [Expressions margins/offset should always return at least 0px] - expected: FAIL - - [Negative margins/offset should be changed to 4px] - expected: FAIL - - [Expressions margins/offset should always return at least 4px] - expected: FAIL diff --git a/tests/wpt/meta/html/semantics/permission-element/negative-offset.tentative.html.ini b/tests/wpt/meta/html/semantics/permission-element/negative-offset.tentative.html.ini new file mode 100644 index 00000000000..74386d1c491 --- /dev/null +++ b/tests/wpt/meta/html/semantics/permission-element/negative-offset.tentative.html.ini @@ -0,0 +1,9 @@ +[negative-offset.tentative.html] + [Negative offset should be changed to 0px] + expected: FAIL + + [Expressions offset min(-50px, 50px) should return at least 0px] + expected: FAIL + + [Expressions offset clamp(-100px, 1vw, -50px) should return at least 0px] + expected: FAIL diff --git a/tests/wpt/meta/html/semantics/permission-element/permission-icon/icon-hidden-reftest.html.ini b/tests/wpt/meta/html/semantics/permission-element/permission-icon/icon-hidden-reftest.html.ini new file mode 100644 index 00000000000..bc9fdd0cbaf --- /dev/null +++ b/tests/wpt/meta/html/semantics/permission-element/permission-icon/icon-hidden-reftest.html.ini @@ -0,0 +1,2 @@ +[icon-hidden-reftest.html] + expected: FAIL diff --git a/tests/wpt/meta/html/semantics/permission-element/permission-icon/icon-unique-per-type-reftest.html.ini b/tests/wpt/meta/html/semantics/permission-element/permission-icon/icon-unique-per-type-reftest.html.ini new file mode 100644 index 00000000000..248944bc32e --- /dev/null +++ b/tests/wpt/meta/html/semantics/permission-element/permission-icon/icon-unique-per-type-reftest.html.ini @@ -0,0 +1,2 @@ +[icon-unique-per-type-reftest.html] + expected: FAIL diff --git a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/042.html.ini b/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/042.html.ini deleted file mode 100644 index 6c2be5a1ab2..00000000000 --- a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/042.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[042.html] - [ scheduler: DOM mutation events when adding scripts: DOMNodeInserted ] - expected: FAIL diff --git a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/043.html.ini b/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/043.html.ini deleted file mode 100644 index 83a6a3fb2a9..00000000000 --- a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/043.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[043.html] - [ scheduler: DOM mutation events when adding external scripts: DOMNodeInserted ] - expected: FAIL diff --git a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/044.html.ini b/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/044.html.ini deleted file mode 100644 index 4e428ec9a29..00000000000 --- a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/044.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[044.html] - [ scheduler: DOM mutation events when adding scripts: DOMNodeInsertedIntoDocument ] - expected: FAIL diff --git a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/045.html.ini b/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/045.html.ini deleted file mode 100644 index b5409fbb4ac..00000000000 --- a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/045.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[045.html] - [ scheduler: DOM mutation events when adding external scripts: DOMNodeInsertedIntoDocument ] - expected: FAIL diff --git a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/054.html.ini b/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/054.html.ini deleted file mode 100644 index abdc47b56ae..00000000000 --- a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/054.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[054.html] - [ scheduler: removing newly inserted script from DOMNodeInserted handler - external script ] - expected: FAIL diff --git a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/055.html.ini b/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/055.html.ini deleted file mode 100644 index af2467b3e71..00000000000 --- a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/055.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[055.html] - [ scheduler: removing newly inserted script from DOMNodeInserted handler - inline script ] - expected: FAIL diff --git a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/script-supports.html.ini b/tests/wpt/meta/html/semantics/scripting-1/the-script-element/script-supports.html.ini deleted file mode 100644 index 6a60c3497ed..00000000000 --- a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/script-supports.html.ini +++ /dev/null @@ -1,15 +0,0 @@ -[script-supports.html] - [Type of HTMLScriptElement.supports is function] - expected: FAIL - - [HTMLScriptElement.supports resurns true for 'classic'] - expected: FAIL - - [HTMLScriptElement.supports resurns true for 'module'] - expected: FAIL - - [HTMLScriptElement.supports returns false for JavaScript MIME types] - expected: FAIL - - [HTMLScriptElement.supports returns false for unsupported types] - expected: FAIL diff --git a/tests/wpt/meta/html/semantics/the-button-element/command-and-commandfor/source-attribute-retargeting.tentative.html.ini b/tests/wpt/meta/html/semantics/the-button-element/command-and-commandfor/source-attribute-retargeting.tentative.html.ini new file mode 100644 index 00000000000..c882098a91c --- /dev/null +++ b/tests/wpt/meta/html/semantics/the-button-element/command-and-commandfor/source-attribute-retargeting.tentative.html.ini @@ -0,0 +1,9 @@ +[source-attribute-retargeting.tentative.html] + [CommandEvent.source and ToggleEvent.source should be retargeted during and after event dispatch.] + expected: FAIL + + [CommandEvent.source should be retargeted when manually dispatched with composed set to true.] + expected: FAIL + + [CommandEvent.source and ToggleEvent.source should not be set to null after dispatch without ShadowDOM.] + expected: FAIL diff --git a/tests/wpt/meta/html/syntax/speculative-parsing/generated/document-write/link-rel-stylesheet-nomatch-media.tentative.sub.html.ini b/tests/wpt/meta/html/syntax/speculative-parsing/generated/document-write/link-rel-stylesheet-nomatch-media.tentative.sub.html.ini deleted file mode 100644 index c80bd7eb511..00000000000 --- a/tests/wpt/meta/html/syntax/speculative-parsing/generated/document-write/link-rel-stylesheet-nomatch-media.tentative.sub.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[link-rel-stylesheet-nomatch-media.tentative.sub.html] - [Speculative parsing, document.write(): link-rel-stylesheet-nomatch-media] - expected: FAIL diff --git a/tests/wpt/meta/html/syntax/speculative-parsing/generated/document-write/meta-viewport-link-stylesheet-media.tentative.sub.html.ini b/tests/wpt/meta/html/syntax/speculative-parsing/generated/document-write/meta-viewport-link-stylesheet-media.tentative.sub.html.ini deleted file mode 100644 index 931c0b1404f..00000000000 --- a/tests/wpt/meta/html/syntax/speculative-parsing/generated/document-write/meta-viewport-link-stylesheet-media.tentative.sub.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[meta-viewport-link-stylesheet-media.tentative.sub.html] - [Speculative parsing, document.write(): meta-viewport-link-stylesheet-media] - expected: FAIL diff --git a/tests/wpt/meta/mixed-content/gen/top.http-rp/opt-in/video-tag.https.html.ini b/tests/wpt/meta/mixed-content/gen/top.http-rp/opt-in/video-tag.https.html.ini index 25b2d40022f..d6038010ff0 100644 --- a/tests/wpt/meta/mixed-content/gen/top.http-rp/opt-in/video-tag.https.html.ini +++ b/tests/wpt/meta/mixed-content/gen/top.http-rp/opt-in/video-tag.https.html.ini @@ -1,13 +1,7 @@ [video-tag.https.html] expected: TIMEOUT - [Mixed-Content: Expects allowed for video-tag to same-https origin and keep-scheme redirection from https context.] - expected: TIMEOUT - - [Mixed-Content: Expects allowed for video-tag to same-https origin and no-redirect redirection from https context.] - expected: NOTRUN - [Mixed-Content: Expects blocked for video-tag to cross-http origin and keep-scheme redirection from https context.] - expected: NOTRUN + expected: TIMEOUT [Mixed-Content: Expects blocked for video-tag to cross-http origin and no-redirect redirection from https context.] expected: NOTRUN diff --git a/tests/wpt/meta/mixed-content/gen/top.meta/opt-in/video-tag.https.html.ini b/tests/wpt/meta/mixed-content/gen/top.meta/opt-in/video-tag.https.html.ini index 933ea12e10c..a725690bbc6 100644 --- a/tests/wpt/meta/mixed-content/gen/top.meta/opt-in/video-tag.https.html.ini +++ b/tests/wpt/meta/mixed-content/gen/top.meta/opt-in/video-tag.https.html.ini @@ -1,10 +1,7 @@ [video-tag.https.html] expected: TIMEOUT - [Mixed-Content: Expects allowed for video-tag to same-https origin and no-redirect redirection from https context.] - expected: TIMEOUT - [Mixed-Content: Expects blocked for video-tag to cross-http origin and no-redirect redirection from https context.] - expected: NOTRUN + expected: TIMEOUT [Mixed-Content: Expects blocked for video-tag to same-http origin and no-redirect redirection from https context.] expected: NOTRUN diff --git a/tests/wpt/meta/navigation-timing/test-navigation-type-reload.html.ini b/tests/wpt/meta/navigation-timing/test-navigation-type-reload.html.ini index 20d32f43049..484aa044de7 100644 --- a/tests/wpt/meta/navigation-timing/test-navigation-type-reload.html.ini +++ b/tests/wpt/meta/navigation-timing/test-navigation-type-reload.html.ini @@ -16,3 +16,15 @@ [Reload fetchStart > Original fetchStart] expected: FAIL + + [Reload domComplete > Original domComplete] + expected: FAIL + + [Reload domContentLoadedEventEnd > Original domContentLoadedEventEnd] + expected: FAIL + + [Reload loadEventEnd > Original loadEventEnd] + expected: FAIL + + [Reload loadEventStart > Original loadEventStart] + expected: FAIL diff --git a/tests/wpt/meta/preload/download-resources.html.ini b/tests/wpt/meta/preload/download-resources.html.ini new file mode 100644 index 00000000000..6b2bd865fec --- /dev/null +++ b/tests/wpt/meta/preload/download-resources.html.ini @@ -0,0 +1,3 @@ +[download-resources.html] + [Makes sure that preloaded resources are downloaded] + expected: FAIL diff --git a/tests/wpt/meta/preload/dynamic-adding-preload-imagesrcset.html.ini b/tests/wpt/meta/preload/dynamic-adding-preload-imagesrcset.html.ini new file mode 100644 index 00000000000..923561e98e5 --- /dev/null +++ b/tests/wpt/meta/preload/dynamic-adding-preload-imagesrcset.html.ini @@ -0,0 +1,3 @@ +[dynamic-adding-preload-imagesrcset.html] + [Makes sure that a dynamically added preload with imagesrcset works] + expected: FAIL diff --git a/tests/wpt/meta/preload/dynamic-adding-preload.html.ini b/tests/wpt/meta/preload/dynamic-adding-preload.html.ini new file mode 100644 index 00000000000..0b703747277 --- /dev/null +++ b/tests/wpt/meta/preload/dynamic-adding-preload.html.ini @@ -0,0 +1,3 @@ +[dynamic-adding-preload.html] + [Makes sure that a dynamically added preloaded resource is downloaded] + expected: FAIL diff --git a/tests/wpt/meta/preload/link-header-modulepreload.html.ini b/tests/wpt/meta/preload/link-header-modulepreload.html.ini new file mode 100644 index 00000000000..4e8264c6c5b --- /dev/null +++ b/tests/wpt/meta/preload/link-header-modulepreload.html.ini @@ -0,0 +1,4 @@ +[link-header-modulepreload.html] + expected: TIMEOUT + [test that a header-preloaded module is loaded and consumed] + expected: TIMEOUT diff --git a/tests/wpt/meta/preload/link-header-on-subresource.html.ini b/tests/wpt/meta/preload/link-header-on-subresource.html.ini new file mode 100644 index 00000000000..ec8493325f0 --- /dev/null +++ b/tests/wpt/meta/preload/link-header-on-subresource.html.ini @@ -0,0 +1,3 @@ +[link-header-on-subresource.html] + [Makes sure that Link headers on subresources preload resources] + expected: FAIL diff --git a/tests/wpt/meta/preload/link-header-preload-delay-onload.html.ini b/tests/wpt/meta/preload/link-header-preload-delay-onload.html.ini new file mode 100644 index 00000000000..cd896c20cb8 --- /dev/null +++ b/tests/wpt/meta/preload/link-header-preload-delay-onload.html.ini @@ -0,0 +1,3 @@ +[link-header-preload-delay-onload.html] + [Makes sure that Link headers preload resources and block window.onload after resource discovery] + expected: FAIL diff --git a/tests/wpt/meta/preload/link-header-preload-imagesrcset.html.ini b/tests/wpt/meta/preload/link-header-preload-imagesrcset.html.ini new file mode 100644 index 00000000000..72652ff5764 --- /dev/null +++ b/tests/wpt/meta/preload/link-header-preload-imagesrcset.html.ini @@ -0,0 +1,3 @@ +[link-header-preload-imagesrcset.html] + [Makes sure that Link headers preload images with imagesrcset/imagesizes attributes.] + expected: FAIL diff --git a/tests/wpt/meta/preload/link-header-preload-non-html.html.ini b/tests/wpt/meta/preload/link-header-preload-non-html.html.ini new file mode 100644 index 00000000000..a69945adc84 --- /dev/null +++ b/tests/wpt/meta/preload/link-header-preload-non-html.html.ini @@ -0,0 +1,15 @@ +[link-header-preload-non-html.html] + [XHTML documents should respect preload Link headers] + expected: FAIL + + [plain text documents should respect preload Link headers] + expected: FAIL + + [image documents should respect preload Link headers] + expected: FAIL + + [media documents should respect preload Link headers] + expected: FAIL + + [invalid image documents should respect preload Link headers] + expected: FAIL diff --git a/tests/wpt/meta/preload/link-header-preload-nonce.html.ini b/tests/wpt/meta/preload/link-header-preload-nonce.html.ini new file mode 100644 index 00000000000..39ba1868a86 --- /dev/null +++ b/tests/wpt/meta/preload/link-header-preload-nonce.html.ini @@ -0,0 +1,3 @@ +[link-header-preload-nonce.html] + [with nonce] + expected: FAIL diff --git a/tests/wpt/meta/preload/link-header-preload.html.ini b/tests/wpt/meta/preload/link-header-preload.html.ini new file mode 100644 index 00000000000..d78be2ed518 --- /dev/null +++ b/tests/wpt/meta/preload/link-header-preload.html.ini @@ -0,0 +1,3 @@ +[link-header-preload.html] + [Makes sure that Link headers preload resources] + expected: FAIL diff --git a/tests/wpt/meta/preload/modulepreload-as.html.ini b/tests/wpt/meta/preload/modulepreload-as.html.ini new file mode 100644 index 00000000000..e35893aefd7 --- /dev/null +++ b/tests/wpt/meta/preload/modulepreload-as.html.ini @@ -0,0 +1,82 @@ +[modulepreload-as.html] + expected: TIMEOUT + [Modulepreload with as=""] + expected: TIMEOUT + + [Modulepreload with as="audio"] + expected: NOTRUN + + [Modulepreload with as="audioworklet"] + expected: NOTRUN + + [Modulepreload with as="document"] + expected: NOTRUN + + [Modulepreload with as="embed"] + expected: NOTRUN + + [Modulepreload with as="font"] + expected: NOTRUN + + [Modulepreload with as="frame"] + expected: NOTRUN + + [Modulepreload with as="iframe"] + expected: NOTRUN + + [Modulepreload with as="image"] + expected: NOTRUN + + [Modulepreload with as="json"] + expected: NOTRUN + + [Modulepreload with as="manifest"] + expected: NOTRUN + + [Modulepreload with as="object"] + expected: NOTRUN + + [Modulepreload with as="paintworklet"] + expected: NOTRUN + + [Modulepreload with as="report"] + expected: NOTRUN + + [Modulepreload with as="script"] + expected: NOTRUN + + [Modulepreload with as="serviceworker"] + expected: NOTRUN + + [Modulepreload with as="sharedworker"] + expected: NOTRUN + + [Modulepreload with as="style"] + expected: NOTRUN + + [Modulepreload with as="track"] + expected: NOTRUN + + [Modulepreload with as="video"] + expected: NOTRUN + + [Modulepreload with as="webidentity"] + expected: NOTRUN + + [Modulepreload with as="worker"] + expected: NOTRUN + + [Modulepreload with as="xslt"] + expected: NOTRUN + + [Modulepreload with as="fetch"] + expected: NOTRUN + + [Modulepreload with as="invalid-dest"] + expected: NOTRUN + + [Modulepreload with as="iMaGe"] + expected: NOTRUN + + [Modulepreload with as="sCrIpT"] + expected: NOTRUN diff --git a/tests/wpt/meta/preload/modulepreload-sri-importmap.html.ini b/tests/wpt/meta/preload/modulepreload-sri-importmap.html.ini new file mode 100644 index 00000000000..8fa5f224ea7 --- /dev/null +++ b/tests/wpt/meta/preload/modulepreload-sri-importmap.html.ini @@ -0,0 +1,3 @@ +[modulepreload-sri-importmap.html] + [Script should not be loaded if modulepreload's integrity is invalid] + expected: FAIL diff --git a/tests/wpt/meta/preload/modulepreload-sri.html.ini b/tests/wpt/meta/preload/modulepreload-sri.html.ini new file mode 100644 index 00000000000..afd8f2285da --- /dev/null +++ b/tests/wpt/meta/preload/modulepreload-sri.html.ini @@ -0,0 +1,3 @@ +[modulepreload-sri.html] + [Script should not be loaded if modulepreload's integrity is invalid] + expected: FAIL diff --git a/tests/wpt/meta/preload/modulepreload.html.ini b/tests/wpt/meta/preload/modulepreload.html.ini new file mode 100644 index 00000000000..2caa1eb2d78 --- /dev/null +++ b/tests/wpt/meta/preload/modulepreload.html.ini @@ -0,0 +1,85 @@ +[modulepreload.html] + expected: TIMEOUT + [link rel=modulepreload] + expected: TIMEOUT + + [same-origin link rel=modulepreload crossorigin=anonymous] + expected: NOTRUN + + [same-origin link rel=modulepreload crossorigin=use-credentials] + expected: NOTRUN + + [cross-origin link rel=modulepreload] + expected: NOTRUN + + [cross-origin link rel=modulepreload crossorigin=anonymous] + expected: NOTRUN + + [cross-origin link rel=modulepreload crossorigin=use-credentials] + expected: NOTRUN + + [link rel=modulepreload with submodules] + expected: NOTRUN + + [link rel=modulepreload for a module with syntax error] + expected: NOTRUN + + [link rel=modulepreload for a module with network error] + expected: NOTRUN + + [link rel=modulepreload with bad href attribute] + expected: NOTRUN + + [link rel=modulepreload as=script] + expected: NOTRUN + + [link rel=modulepreload with non-script-like as= value (image)] + expected: NOTRUN + + [link rel=modulepreload with non-script-like as= value (xslt)] + expected: NOTRUN + + [link rel=modulepreload with integrity match] + expected: NOTRUN + + [link rel=modulepreload with integrity match2] + expected: NOTRUN + + [link rel=modulepreload with integrity mismatch] + expected: NOTRUN + + [link rel=modulepreload with integrity mismatch2] + expected: NOTRUN + + [link rel=modulepreload with integrity mismatch3] + expected: NOTRUN + + [multiple link rel=modulepreload with same href] + expected: NOTRUN + + [multiple link rel=modulepreload with child module before parent] + expected: NOTRUN + + [link rel=modulepreload with matching media] + expected: NOTRUN + + [link rel=modulepreload with non-matching media] + expected: NOTRUN + + [link rel=modulepreload with empty media] + expected: NOTRUN + + [link rel=modulepreload with empty href] + expected: NOTRUN + + [link rel=modulepreload with empty href and invalid as= value] + expected: NOTRUN + + [link rel=modulepreload and script with non-matching crossorigin values] + expected: NOTRUN + + [link rel=modulepreload and script with non-matching crossorigin values2] + expected: NOTRUN + + [link rel=modulepreload and non-module script] + expected: NOTRUN diff --git a/tests/wpt/meta/preload/onerror-event.html.ini b/tests/wpt/meta/preload/onerror-event.html.ini new file mode 100644 index 00000000000..d328fee9519 --- /dev/null +++ b/tests/wpt/meta/preload/onerror-event.html.ini @@ -0,0 +1,3 @@ +[onerror-event.html] + [Makes sure that preloaded resources trigger the onerror event] + expected: FAIL diff --git a/tests/wpt/meta/preload/onload-event.html.ini b/tests/wpt/meta/preload/onload-event.html.ini new file mode 100644 index 00000000000..61f512cf25e --- /dev/null +++ b/tests/wpt/meta/preload/onload-event.html.ini @@ -0,0 +1,3 @@ +[onload-event.html] + [Makes sure that preloaded resources trigger the onload event] + expected: FAIL diff --git a/tests/wpt/meta/preload/preconnect.html.ini b/tests/wpt/meta/preload/preconnect.html.ini new file mode 100644 index 00000000000..f1f30712a4f --- /dev/null +++ b/tests/wpt/meta/preload/preconnect.html.ini @@ -0,0 +1,4 @@ +[preconnect.html] + expected: TIMEOUT + [Test that preconnect reduces connection time to zero] + expected: TIMEOUT diff --git a/tests/wpt/meta/preload/prefetch-document.html.ini b/tests/wpt/meta/preload/prefetch-document.html.ini new file mode 100644 index 00000000000..e79d094c754 --- /dev/null +++ b/tests/wpt/meta/preload/prefetch-document.html.ini @@ -0,0 +1,6 @@ +[prefetch-document.html] + [same-site different-origin document prefetch without 'as' should not be consumed] + expected: FAIL + + [different-site document prefetch without 'as' should not be consumed] + expected: FAIL diff --git a/tests/wpt/meta/preload/preload-csp.sub.html.ini b/tests/wpt/meta/preload/preload-csp.sub.html.ini new file mode 100644 index 00000000000..caf5ac5c562 --- /dev/null +++ b/tests/wpt/meta/preload/preload-csp.sub.html.ini @@ -0,0 +1,3 @@ +[preload-csp.sub.html] + [Preload requests are blocked by CSP.] + expected: FAIL diff --git a/tests/wpt/meta/preload/preload-default-csp.sub.html.ini b/tests/wpt/meta/preload/preload-default-csp.sub.html.ini new file mode 100644 index 00000000000..c44096ef973 --- /dev/null +++ b/tests/wpt/meta/preload/preload-default-csp.sub.html.ini @@ -0,0 +1,3 @@ +[preload-default-csp.sub.html] + [Preload requests are blocked by CSP ("default-src 'none').] + expected: FAIL diff --git a/tests/wpt/meta/preload/preload-error.sub.html.ini b/tests/wpt/meta/preload/preload-error.sub.html.ini new file mode 100644 index 00000000000..f383c31f2fd --- /dev/null +++ b/tests/wpt/meta/preload/preload-error.sub.html.ini @@ -0,0 +1,87 @@ +[preload-error.sub.html] + [404 (image): main] + expected: FAIL + + [CORS-error (image): main] + expected: FAIL + + [CSP-error (image): main] + expected: FAIL + + [CORS-error (style): main] + expected: FAIL + + [CSP-error (style): main] + expected: FAIL + + [CORS-error (script): main] + expected: FAIL + + [CSP-error (script): main] + expected: FAIL + + [CORS-error (xhr): main] + expected: FAIL + + [CSP-error (xhr): main] + expected: FAIL + + [success (fetch): main] + expected: FAIL + + [404 (fetch): main] + expected: FAIL + + [CORS (fetch): main] + expected: FAIL + + [CORS-error (fetch): main] + expected: FAIL + + [CSP-error (fetch): main] + expected: FAIL + + [MIME-error (style): main] + expected: FAIL + + [MIME-blocked (script): main] + expected: FAIL + + [MIME-blocked-nosniff (style): preload events] + expected: FAIL + + [MIME-blocked-nosniff (style): main] + expected: FAIL + + [MIME-blocked-nosniff (script): main] + expected: FAIL + + [Decode-error (script): main] + expected: FAIL + + [success (style): main] + expected: FAIL + + [404 (style): main] + expected: FAIL + + [CORS (style): main] + expected: FAIL + + [success (script): main] + expected: FAIL + + [404 (script): main] + expected: FAIL + + [success (xhr): main] + expected: FAIL + + [404 (xhr): main] + expected: FAIL + + [CORS (xhr): main] + expected: FAIL + + [Decode-error (style): main] + expected: FAIL diff --git a/tests/wpt/meta/preload/preload-font-crossorigin.html.ini b/tests/wpt/meta/preload/preload-font-crossorigin.html.ini new file mode 100644 index 00000000000..62be525e1e6 --- /dev/null +++ b/tests/wpt/meta/preload/preload-font-crossorigin.html.ini @@ -0,0 +1,12 @@ +[preload-font-crossorigin.html] + [Same origin font preload with crossorigin attribute] + expected: FAIL + + [Same origin font preload without crossorigin attribute] + expected: FAIL + + [Cross origin font preload with crossorigin attribute] + expected: FAIL + + [Cross origin font preload without crossorigin attribute] + expected: FAIL diff --git a/tests/wpt/meta/preload/preload-in-data-doc.html.ini b/tests/wpt/meta/preload/preload-in-data-doc.html.ini new file mode 100644 index 00000000000..417c49751f9 --- /dev/null +++ b/tests/wpt/meta/preload/preload-in-data-doc.html.ini @@ -0,0 +1,2 @@ +[preload-in-data-doc.html] + expected: FAIL diff --git a/tests/wpt/meta/preload/preload-nonce.sub.html.ini b/tests/wpt/meta/preload/preload-nonce.sub.html.ini new file mode 100644 index 00000000000..3325c3b01c1 --- /dev/null +++ b/tests/wpt/meta/preload/preload-nonce.sub.html.ini @@ -0,0 +1,3 @@ +[preload-nonce.sub.html] + [Preload requests without a nonce are blocked by CSP.] + expected: FAIL diff --git a/tests/wpt/meta/preload/preload-referrer-policy-subresource-header.tentative.html.ini b/tests/wpt/meta/preload/preload-referrer-policy-subresource-header.tentative.html.ini new file mode 100644 index 00000000000..fccf5758847 --- /dev/null +++ b/tests/wpt/meta/preload/preload-referrer-policy-subresource-header.tentative.html.ini @@ -0,0 +1,594 @@ +[preload-referrer-policy-subresource-header.tentative.html?isCrossOriginPreload=false&isCrossOriginResource=true] + [referrer policy ( -> , same-origin, cross-origin)] + expected: FAIL + + [referrer policy ( -> no-referrer, same-origin, cross-origin)] + expected: FAIL + + [referrer policy ( -> same-origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy ( -> origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy ( -> origin-when-cross-origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy ( -> strict-origin-when-cross-origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy ( -> unsafe-url, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (no-referrer -> , same-origin, cross-origin)] + expected: FAIL + + [referrer policy (no-referrer -> no-referrer, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (no-referrer -> same-origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (no-referrer -> origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (no-referrer -> origin-when-cross-origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (no-referrer -> strict-origin-when-cross-origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (no-referrer -> unsafe-url, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (same-origin -> , same-origin, cross-origin)] + expected: FAIL + + [referrer policy (same-origin -> no-referrer, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (same-origin -> same-origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (same-origin -> origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (same-origin -> origin-when-cross-origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (same-origin -> strict-origin-when-cross-origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (same-origin -> unsafe-url, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin -> , same-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin -> no-referrer, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin -> same-origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin -> origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin -> origin-when-cross-origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin -> strict-origin-when-cross-origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin -> unsafe-url, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> , same-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> no-referrer, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> same-origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> origin-when-cross-origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> strict-origin-when-cross-origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> unsafe-url, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> , same-origin, cross-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> no-referrer, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> same-origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> origin-when-cross-origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> strict-origin-when-cross-origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> unsafe-url, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> , same-origin, cross-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> no-referrer, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> same-origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> origin-when-cross-origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> strict-origin-when-cross-origin, same-origin, cross-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> unsafe-url, same-origin, cross-origin)] + expected: FAIL + + +[preload-referrer-policy-subresource-header.tentative.html?isCrossOriginPreload=true&isCrossOriginResource=true] + [referrer policy ( -> , cross-origin, cross-origin)] + expected: FAIL + + [referrer policy ( -> no-referrer, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy ( -> same-origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy ( -> origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy ( -> origin-when-cross-origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy ( -> strict-origin-when-cross-origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy ( -> unsafe-url, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (no-referrer -> , cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (no-referrer -> no-referrer, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (no-referrer -> same-origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (no-referrer -> origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (no-referrer -> origin-when-cross-origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (no-referrer -> strict-origin-when-cross-origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (no-referrer -> unsafe-url, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (same-origin -> , cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (same-origin -> no-referrer, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (same-origin -> same-origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (same-origin -> origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (same-origin -> origin-when-cross-origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (same-origin -> strict-origin-when-cross-origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (same-origin -> unsafe-url, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin -> , cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin -> no-referrer, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin -> same-origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin -> origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin -> origin-when-cross-origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin -> strict-origin-when-cross-origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin -> unsafe-url, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> , cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> no-referrer, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> same-origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> origin-when-cross-origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> strict-origin-when-cross-origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> unsafe-url, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> , cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> no-referrer, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> same-origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> origin-when-cross-origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> strict-origin-when-cross-origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> unsafe-url, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> , cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> no-referrer, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> same-origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> origin-when-cross-origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> strict-origin-when-cross-origin, cross-origin, cross-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> unsafe-url, cross-origin, cross-origin)] + expected: FAIL + + +[preload-referrer-policy-subresource-header.tentative.html?isCrossOriginPreload=false&isCrossOriginResource=false] + [referrer policy ( -> , same-origin, same-origin)] + expected: FAIL + + [referrer policy ( -> no-referrer, same-origin, same-origin)] + expected: FAIL + + [referrer policy ( -> same-origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy ( -> origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy ( -> origin-when-cross-origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy ( -> strict-origin-when-cross-origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy ( -> unsafe-url, same-origin, same-origin)] + expected: FAIL + + [referrer policy (no-referrer -> , same-origin, same-origin)] + expected: FAIL + + [referrer policy (no-referrer -> no-referrer, same-origin, same-origin)] + expected: FAIL + + [referrer policy (no-referrer -> same-origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (no-referrer -> origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (no-referrer -> origin-when-cross-origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (no-referrer -> strict-origin-when-cross-origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (no-referrer -> unsafe-url, same-origin, same-origin)] + expected: FAIL + + [referrer policy (same-origin -> , same-origin, same-origin)] + expected: FAIL + + [referrer policy (same-origin -> no-referrer, same-origin, same-origin)] + expected: FAIL + + [referrer policy (same-origin -> same-origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (same-origin -> origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (same-origin -> origin-when-cross-origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (same-origin -> strict-origin-when-cross-origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (same-origin -> unsafe-url, same-origin, same-origin)] + expected: FAIL + + [referrer policy (origin -> , same-origin, same-origin)] + expected: FAIL + + [referrer policy (origin -> no-referrer, same-origin, same-origin)] + expected: FAIL + + [referrer policy (origin -> same-origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (origin -> origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (origin -> origin-when-cross-origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (origin -> strict-origin-when-cross-origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (origin -> unsafe-url, same-origin, same-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> , same-origin, same-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> no-referrer, same-origin, same-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> same-origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> origin-when-cross-origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> strict-origin-when-cross-origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> unsafe-url, same-origin, same-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> , same-origin, same-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> no-referrer, same-origin, same-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> same-origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> origin-when-cross-origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> strict-origin-when-cross-origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> unsafe-url, same-origin, same-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> , same-origin, same-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> no-referrer, same-origin, same-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> same-origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> origin-when-cross-origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> strict-origin-when-cross-origin, same-origin, same-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> unsafe-url, same-origin, same-origin)] + expected: FAIL + + +[preload-referrer-policy-subresource-header.tentative.html?isCrossOriginPreload=true&isCrossOriginResource=false] + [referrer policy ( -> , cross-origin, same-origin)] + expected: FAIL + + [referrer policy ( -> no-referrer, cross-origin, same-origin)] + expected: FAIL + + [referrer policy ( -> same-origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy ( -> origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy ( -> origin-when-cross-origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy ( -> strict-origin-when-cross-origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy ( -> unsafe-url, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (no-referrer -> , cross-origin, same-origin)] + expected: FAIL + + [referrer policy (no-referrer -> no-referrer, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (no-referrer -> same-origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (no-referrer -> origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (no-referrer -> origin-when-cross-origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (no-referrer -> strict-origin-when-cross-origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (no-referrer -> unsafe-url, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (same-origin -> , cross-origin, same-origin)] + expected: FAIL + + [referrer policy (same-origin -> no-referrer, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (same-origin -> same-origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (same-origin -> origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (same-origin -> origin-when-cross-origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (same-origin -> strict-origin-when-cross-origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (same-origin -> unsafe-url, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (origin -> , cross-origin, same-origin)] + expected: FAIL + + [referrer policy (origin -> no-referrer, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (origin -> same-origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (origin -> origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (origin -> origin-when-cross-origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (origin -> strict-origin-when-cross-origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (origin -> unsafe-url, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> , cross-origin, same-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> no-referrer, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> same-origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> origin-when-cross-origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> strict-origin-when-cross-origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (origin-when-cross-origin -> unsafe-url, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> , cross-origin, same-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> no-referrer, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> same-origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> origin-when-cross-origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> strict-origin-when-cross-origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (strict-origin-when-cross-origin -> unsafe-url, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> , cross-origin, same-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> no-referrer, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> same-origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> origin-when-cross-origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> strict-origin-when-cross-origin, cross-origin, same-origin)] + expected: FAIL + + [referrer policy (unsafe-url -> unsafe-url, cross-origin, same-origin)] + expected: FAIL diff --git a/tests/wpt/meta/preload/preload-referrer-policy.html.ini b/tests/wpt/meta/preload/preload-referrer-policy.html.ini new file mode 100644 index 00000000000..5060e820c0e --- /dev/null +++ b/tests/wpt/meta/preload/preload-referrer-policy.html.ini @@ -0,0 +1,589 @@ +[preload-referrer-policy.html] + expected: TIMEOUT + [referrer policy ( -> , element, cross-origin)] + expected: FAIL + + [referrer policy ( -> , element, same-origin)] + expected: FAIL + + [referrer policy ( -> , header, cross-origin)] + expected: TIMEOUT + + [referrer policy ( -> , header, same-origin)] + expected: NOTRUN + + [referrer policy ( -> no-referrer, element, cross-origin)] + expected: NOTRUN + + [referrer policy ( -> no-referrer, element, same-origin)] + expected: NOTRUN + + [referrer policy ( -> no-referrer, header, cross-origin)] + expected: NOTRUN + + [referrer policy ( -> no-referrer, header, same-origin)] + expected: NOTRUN + + [referrer policy ( -> same-origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy ( -> same-origin, element, same-origin)] + expected: NOTRUN + + [referrer policy ( -> same-origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy ( -> same-origin, header, same-origin)] + expected: NOTRUN + + [referrer policy ( -> origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy ( -> origin, element, same-origin)] + expected: NOTRUN + + [referrer policy ( -> origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy ( -> origin, header, same-origin)] + expected: NOTRUN + + [referrer policy ( -> origin-when-cross-origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy ( -> origin-when-cross-origin, element, same-origin)] + expected: NOTRUN + + [referrer policy ( -> origin-when-cross-origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy ( -> origin-when-cross-origin, header, same-origin)] + expected: NOTRUN + + [referrer policy ( -> strict-origin-when-cross-origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy ( -> strict-origin-when-cross-origin, element, same-origin)] + expected: NOTRUN + + [referrer policy ( -> strict-origin-when-cross-origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy ( -> strict-origin-when-cross-origin, header, same-origin)] + expected: NOTRUN + + [referrer policy ( -> unsafe-url, element, cross-origin)] + expected: NOTRUN + + [referrer policy ( -> unsafe-url, element, same-origin)] + expected: NOTRUN + + [referrer policy ( -> unsafe-url, header, cross-origin)] + expected: NOTRUN + + [referrer policy ( -> unsafe-url, header, same-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> , element, cross-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> , element, same-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> , header, cross-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> , header, same-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> no-referrer, element, cross-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> no-referrer, element, same-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> no-referrer, header, cross-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> no-referrer, header, same-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> same-origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> same-origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> same-origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> same-origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> origin-when-cross-origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> origin-when-cross-origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> origin-when-cross-origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> origin-when-cross-origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> strict-origin-when-cross-origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> strict-origin-when-cross-origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> strict-origin-when-cross-origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> strict-origin-when-cross-origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> unsafe-url, element, cross-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> unsafe-url, element, same-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> unsafe-url, header, cross-origin)] + expected: NOTRUN + + [referrer policy (no-referrer -> unsafe-url, header, same-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> , element, cross-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> , element, same-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> , header, cross-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> , header, same-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> no-referrer, element, cross-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> no-referrer, element, same-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> no-referrer, header, cross-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> no-referrer, header, same-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> same-origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> same-origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> same-origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> same-origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> origin-when-cross-origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> origin-when-cross-origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> origin-when-cross-origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> origin-when-cross-origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> strict-origin-when-cross-origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> strict-origin-when-cross-origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> strict-origin-when-cross-origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> strict-origin-when-cross-origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> unsafe-url, element, cross-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> unsafe-url, element, same-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> unsafe-url, header, cross-origin)] + expected: NOTRUN + + [referrer policy (same-origin -> unsafe-url, header, same-origin)] + expected: NOTRUN + + [referrer policy (origin -> , element, cross-origin)] + expected: NOTRUN + + [referrer policy (origin -> , element, same-origin)] + expected: NOTRUN + + [referrer policy (origin -> , header, cross-origin)] + expected: NOTRUN + + [referrer policy (origin -> , header, same-origin)] + expected: NOTRUN + + [referrer policy (origin -> no-referrer, element, cross-origin)] + expected: NOTRUN + + [referrer policy (origin -> no-referrer, element, same-origin)] + expected: NOTRUN + + [referrer policy (origin -> no-referrer, header, cross-origin)] + expected: NOTRUN + + [referrer policy (origin -> no-referrer, header, same-origin)] + expected: NOTRUN + + [referrer policy (origin -> same-origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (origin -> same-origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (origin -> same-origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (origin -> same-origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (origin -> origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (origin -> origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (origin -> origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (origin -> origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (origin -> origin-when-cross-origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (origin -> origin-when-cross-origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (origin -> origin-when-cross-origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (origin -> origin-when-cross-origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (origin -> strict-origin-when-cross-origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (origin -> strict-origin-when-cross-origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (origin -> strict-origin-when-cross-origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (origin -> strict-origin-when-cross-origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (origin -> unsafe-url, element, cross-origin)] + expected: NOTRUN + + [referrer policy (origin -> unsafe-url, element, same-origin)] + expected: NOTRUN + + [referrer policy (origin -> unsafe-url, header, cross-origin)] + expected: NOTRUN + + [referrer policy (origin -> unsafe-url, header, same-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> , element, cross-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> , element, same-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> , header, cross-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> , header, same-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> no-referrer, element, cross-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> no-referrer, element, same-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> no-referrer, header, cross-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> no-referrer, header, same-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> same-origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> same-origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> same-origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> same-origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> origin-when-cross-origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> origin-when-cross-origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> origin-when-cross-origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> origin-when-cross-origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> strict-origin-when-cross-origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> strict-origin-when-cross-origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> strict-origin-when-cross-origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> strict-origin-when-cross-origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> unsafe-url, element, cross-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> unsafe-url, element, same-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> unsafe-url, header, cross-origin)] + expected: NOTRUN + + [referrer policy (origin-when-cross-origin -> unsafe-url, header, same-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> , element, cross-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> , element, same-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> , header, cross-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> , header, same-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> no-referrer, element, cross-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> no-referrer, element, same-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> no-referrer, header, cross-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> no-referrer, header, same-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> same-origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> same-origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> same-origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> same-origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> origin-when-cross-origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> origin-when-cross-origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> origin-when-cross-origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> origin-when-cross-origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> strict-origin-when-cross-origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> strict-origin-when-cross-origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> strict-origin-when-cross-origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> strict-origin-when-cross-origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> unsafe-url, element, cross-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> unsafe-url, element, same-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> unsafe-url, header, cross-origin)] + expected: NOTRUN + + [referrer policy (strict-origin-when-cross-origin -> unsafe-url, header, same-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> , element, cross-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> , element, same-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> , header, cross-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> , header, same-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> no-referrer, element, cross-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> no-referrer, element, same-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> no-referrer, header, cross-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> no-referrer, header, same-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> same-origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> same-origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> same-origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> same-origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> origin-when-cross-origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> origin-when-cross-origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> origin-when-cross-origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> origin-when-cross-origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> strict-origin-when-cross-origin, element, cross-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> strict-origin-when-cross-origin, element, same-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> strict-origin-when-cross-origin, header, cross-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> strict-origin-when-cross-origin, header, same-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> unsafe-url, element, cross-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> unsafe-url, element, same-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> unsafe-url, header, cross-origin)] + expected: NOTRUN + + [referrer policy (unsafe-url -> unsafe-url, header, same-origin)] + expected: NOTRUN diff --git a/tests/wpt/meta/preload/preload-resource-match.https.html.ini b/tests/wpt/meta/preload/preload-resource-match.https.html.ini new file mode 100644 index 00000000000..31f9bda5354 --- /dev/null +++ b/tests/wpt/meta/preload/preload-resource-match.https.html.ini @@ -0,0 +1,148 @@ +[preload-resource-match.https.html] + expected: TIMEOUT + [Loading image (no-cors) with link (anonymous) should discard the preloaded response] + expected: FAIL + + [Loading image (no-cors) with link (use-credentials) should discard the preloaded response] + expected: FAIL + + [Loading image (anonymous) with link (no-cors) should discard the preloaded response] + expected: FAIL + + [Loading image (anonymous) with link (use-credentials) should discard the preloaded response] + expected: FAIL + + [Loading image (use-credentials) with link (no-cors) should discard the preloaded response] + expected: FAIL + + [Loading image (use-credentials) with link (anonymous) should discard the preloaded response] + expected: FAIL + + [Loading font (anonymous) with link (no-cors) should discard the preloaded response] + expected: FAIL + + [Loading font (anonymous) with link (anonymous) should reuse the preloaded response] + expected: FAIL + + [Loading font (anonymous) with link (use-credentials) should discard the preloaded response] + expected: FAIL + + [Loading font (same-origin) with link (same-origin) should reuse the preloaded response] + expected: FAIL + + [Loading backgroundImage (no-cors) with link (anonymous) should discard the preloaded response] + expected: FAIL + + [Loading backgroundImage (no-cors) with link (use-credentials) should discard the preloaded response] + expected: FAIL + + [Loading fetch (same-origin) with link (same-origin) should reuse the preloaded response] + expected: FAIL + + [Loading fetch (no-cors) with link (no-cors) should reuse the preloaded response] + expected: FAIL + + [Loading fetch (no-cors) with link (anonymous) should discard the preloaded response] + expected: FAIL + + [Loading fetch (no-cors) with link (use-credentials) should discard the preloaded response] + expected: FAIL + + [Loading fetch (anonymous) with link (no-cors) should discard the preloaded response] + expected: FAIL + + [Loading fetch (anonymous) with link (anonymous) should reuse the preloaded response] + expected: FAIL + + [Loading fetch (anonymous) with link (use-credentials) should discard the preloaded response] + expected: FAIL + + [Loading fetch (use-credentials) with link (no-cors) should discard the preloaded response] + expected: FAIL + + [Loading fetch (use-credentials) with link (anonymous) should discard the preloaded response] + expected: FAIL + + [Loading fetch (use-credentials) with link (use-credentials) should reuse the preloaded response] + expected: FAIL + + [Loading script (no-cors) with link (anonymous) should discard the preloaded response] + expected: FAIL + + [Loading script (no-cors) with link (use-credentials) should discard the preloaded response] + expected: FAIL + + [Loading script (anonymous) with link (no-cors) should discard the preloaded response] + expected: FAIL + + [Loading script (anonymous) with link (use-credentials) should discard the preloaded response] + expected: FAIL + + [Loading script (use-credentials) with link (no-cors) should discard the preloaded response] + expected: FAIL + + [Loading script (use-credentials) with link (anonymous) should discard the preloaded response] + expected: TIMEOUT + + [Loading script (use-credentials) with link (use-credentials) should reuse the preloaded response] + expected: NOTRUN + + [Loading module (same-origin) with link (same-origin) should reuse the preloaded response] + expected: NOTRUN + + [Loading module (no-cors) with link (no-cors) should reuse the preloaded response] + expected: NOTRUN + + [Loading module (no-cors) with link (anonymous) should discard the preloaded response] + expected: NOTRUN + + [Loading module (no-cors) with link (use-credentials) should discard the preloaded response] + expected: NOTRUN + + [Loading module (anonymous) with link (no-cors) should discard the preloaded response] + expected: NOTRUN + + [Loading module (anonymous) with link (anonymous) should reuse the preloaded response] + expected: NOTRUN + + [Loading module (anonymous) with link (use-credentials) should discard the preloaded response] + expected: NOTRUN + + [Loading module (use-credentials) with link (no-cors) should discard the preloaded response] + expected: NOTRUN + + [Loading module (use-credentials) with link (anonymous) should discard the preloaded response] + expected: NOTRUN + + [Loading module (use-credentials) with link (use-credentials) should reuse the preloaded response] + expected: NOTRUN + + [Loading style (same-origin) with link (same-origin) should reuse the preloaded response] + expected: NOTRUN + + [Loading style (no-cors) with link (no-cors) should reuse the preloaded response] + expected: NOTRUN + + [Loading style (no-cors) with link (anonymous) should discard the preloaded response] + expected: NOTRUN + + [Loading style (no-cors) with link (use-credentials) should discard the preloaded response] + expected: NOTRUN + + [Loading style (anonymous) with link (no-cors) should discard the preloaded response] + expected: NOTRUN + + [Loading style (anonymous) with link (anonymous) should reuse the preloaded response] + expected: NOTRUN + + [Loading style (anonymous) with link (use-credentials) should discard the preloaded response] + expected: NOTRUN + + [Loading style (use-credentials) with link (no-cors) should discard the preloaded response] + expected: NOTRUN + + [Loading style (use-credentials) with link (anonymous) should discard the preloaded response] + expected: NOTRUN + + [Loading style (use-credentials) with link (use-credentials) should reuse the preloaded response] + expected: NOTRUN diff --git a/tests/wpt/meta/preload/preload-strict-dynamic.sub.html.ini b/tests/wpt/meta/preload/preload-strict-dynamic.sub.html.ini new file mode 100644 index 00000000000..6b27f8aa968 --- /dev/null +++ b/tests/wpt/meta/preload/preload-strict-dynamic.sub.html.ini @@ -0,0 +1,3 @@ +[preload-strict-dynamic.sub.html] + [static-no-nonce] + expected: FAIL diff --git a/tests/wpt/meta/preload/preload-time-to-fetch.https.html.ini b/tests/wpt/meta/preload/preload-time-to-fetch.https.html.ini new file mode 100644 index 00000000000..4c5b889edf5 --- /dev/null +++ b/tests/wpt/meta/preload/preload-time-to-fetch.https.html.ini @@ -0,0 +1,9 @@ +[preload-time-to-fetch.https.html] + [Changing a preload media attribute (non matching->matching) should trigger a fetch] + expected: FAIL + + [Removing a non-matching preload media attribute should trigger a new fetch] + expected: FAIL + + [Changing a preload media attribute (non matching->non matching) should not trigger a fetch] + expected: FAIL diff --git a/tests/wpt/meta/preload/preload-type-match.html.ini b/tests/wpt/meta/preload/preload-type-match.html.ini new file mode 100644 index 00000000000..9522c6ff530 --- /dev/null +++ b/tests/wpt/meta/preload/preload-type-match.html.ini @@ -0,0 +1,21 @@ +[preload-type-match.html] + [Preload with {as=track; type=text/vtt} should load when retrieved resource is a track] + expected: FAIL + + [Preload with {as=image; type=image/unknown} should timeout when retrieved resource is a png] + expected: FAIL + + [Preload with {as=style; type=application/css} should timeout when retrieved resource is a css] + expected: FAIL + + [Preload with {as=style; type=text/plain} should timeout when retrieved resource is a css] + expected: FAIL + + [Preload with {as=json; type=text/plain} should timeout when retrieved resource is a json] + expected: FAIL + + [Preload with {as=json; type=application/javascript} should timeout when retrieved resource is a json] + expected: FAIL + + [Preload with {as=font; type=font/not-a-font} should timeout when retrieved resource is a ttf] + expected: FAIL diff --git a/tests/wpt/meta/preload/preload-with-type.html.ini b/tests/wpt/meta/preload/preload-with-type.html.ini new file mode 100644 index 00000000000..06c2d989e10 --- /dev/null +++ b/tests/wpt/meta/preload/preload-with-type.html.ini @@ -0,0 +1,3 @@ +[preload-with-type.html] + [Makes sure that preloaded resources with a type attribute trigger the onload event] + expected: FAIL diff --git a/tests/wpt/meta/preload/preload-xhr.html.ini b/tests/wpt/meta/preload/preload-xhr.html.ini new file mode 100644 index 00000000000..f74aef3fb55 --- /dev/null +++ b/tests/wpt/meta/preload/preload-xhr.html.ini @@ -0,0 +1,6 @@ +[preload-xhr.html] + [Make an XHR request immediately after creating link rel=preload.] + expected: FAIL + + [Make an XHR request after loading link rel=preload.] + expected: FAIL diff --git a/tests/wpt/meta/preload/single-download-late-used-preload.html.ini b/tests/wpt/meta/preload/single-download-late-used-preload.html.ini new file mode 100644 index 00000000000..cd87be4bace --- /dev/null +++ b/tests/wpt/meta/preload/single-download-late-used-preload.html.ini @@ -0,0 +1,3 @@ +[single-download-late-used-preload.html] + [Ensure preloaded resources are not downloaded again when used] + expected: FAIL diff --git a/tests/wpt/meta/preload/single-download-preload.html.ini b/tests/wpt/meta/preload/single-download-preload.html.ini new file mode 100644 index 00000000000..d32846e882f --- /dev/null +++ b/tests/wpt/meta/preload/single-download-preload.html.ini @@ -0,0 +1,3 @@ +[single-download-preload.html] + [Makes sure that preloaded resources are not downloaded again when used] + expected: FAIL diff --git a/tests/wpt/meta/preload/subresource-integrity-font.html.ini b/tests/wpt/meta/preload/subresource-integrity-font.html.ini new file mode 100644 index 00000000000..3affa0fd05e --- /dev/null +++ b/tests/wpt/meta/preload/subresource-integrity-font.html.ini @@ -0,0 +1,69 @@ +[subresource-integrity-font.html] + [<crossorigin="anonymous"> Same-origin with correct sha256 hash.] + expected: FAIL + + [<crossorigin="anonymous"> Same-origin with correct sha384 hash.] + expected: FAIL + + [<crossorigin="anonymous"> Same-origin with correct sha512 hash.] + expected: FAIL + + [<crossorigin="anonymous"> Same-origin with empty integrity.] + expected: FAIL + + [<crossorigin="anonymous"> Same-origin with no integrity.] + expected: FAIL + + [<crossorigin="anonymous"> Same-origin with incorrect hash.] + expected: FAIL + + [<crossorigin="anonymous"> Same-origin with correct sha256 hash, options.] + expected: FAIL + + [<crossorigin="anonymous"> Same-origin with unknown algorithm only.] + expected: FAIL + + [<crossorigin="anonymous"> Same-origin with multiple sha256 hashes, including correct.] + expected: FAIL + + [<crossorigin="anonymous"> Same-origin with multiple sha256 hashes, including unknown algorithm.] + expected: FAIL + + [<crossorigin="anonymous"> Same-origin with sha256 mismatch, sha512 match.] + expected: FAIL + + [<crossorigin="anonymous"> Same-origin with sha256 match, sha512 mismatch.] + expected: FAIL + + [Same-origin, not CORS request, with correct sha256 hash.] + expected: FAIL + + [Same-origin, not CORS request, with incorrect sha256 hash.] + expected: FAIL + + [<crossorigin="anonymous"> Cross-origin with correct sha256 hash, ACAO: *.] + expected: FAIL + + [<crossorigin="anonymous"> Cross-origin with incorrect sha256 hash, ACAO: *.] + expected: FAIL + + [<crossorigin="anonymous"> Cross-origin with correct sha256 hash, with CORS-ineligible resource.] + expected: FAIL + + [Cross-origin, not CORS request, with correct sha256.] + expected: FAIL + + [Cross-origin, not CORS request, with incorrect sha256.] + expected: FAIL + + [<crossorigin="anonymous"> Cross-origin with empty integrity.] + expected: FAIL + + [Cross-origin, not CORS request, with empty integrity.] + expected: FAIL + + [<crossorigin="use-credentials"> Cross-origin with correct sha256 hash, CORS-eligible.] + expected: FAIL + + [<crossorigin="use-credentials"> Cross-origin with incorrect sha256 hash, CORS-eligible.] + expected: FAIL diff --git a/tests/wpt/meta/preload/subresource-integrity.html.ini b/tests/wpt/meta/preload/subresource-integrity.html.ini new file mode 100644 index 00000000000..be47ce6c6c5 --- /dev/null +++ b/tests/wpt/meta/preload/subresource-integrity.html.ini @@ -0,0 +1,195 @@ +[subresource-integrity.html] + [Same-origin script with correct sha256 hash.] + expected: FAIL + + [Same-origin script with correct sha384 hash.] + expected: FAIL + + [Same-origin script with correct sha512 hash.] + expected: FAIL + + [Same-origin script with empty integrity.] + expected: FAIL + + [Same-origin script with incorrect hash.] + expected: FAIL + + [Same-origin script with multiple sha256 hashes, including correct.] + expected: FAIL + + [Same-origin script with multiple sha256 hashes, including unknown algorithm.] + expected: FAIL + + [Same-origin script with sha256 mismatch, sha512 match] + expected: FAIL + + [Same-origin script with sha256 match, sha512 mismatch] + expected: FAIL + + [<crossorigin='anonymous'> script with correct hash, ACAO: *] + expected: FAIL + + [<crossorigin='anonymous'> script with incorrect hash, ACAO: *] + expected: FAIL + + [<crossorigin='use-credentials'> script with correct hash, CORS-eligible] + expected: FAIL + + [<crossorigin='use-credentials'> script with incorrect hash CORS-eligible] + expected: FAIL + + [<crossorigin='anonymous'> script with CORS-ineligible resource] + expected: FAIL + + [Cross-origin script, not CORS request, with correct hash] + expected: FAIL + + [Cross-origin script, not CORS request, with hash mismatch] + expected: FAIL + + [Cross-origin script, empty integrity] + expected: FAIL + + [Same-origin script with correct hash, options.] + expected: FAIL + + [Same-origin script with unknown algorithm only.] + expected: FAIL + + [Same-origin script with matching digest re-uses preload with matching digest.] + expected: FAIL + + [Same-origin script with matching digest re-uses preload with matching digest and options.] + expected: FAIL + + [Same-origin script with non-matching digest does not re-use preload with matching digest.] + expected: FAIL + + [Same-origin script with matching digest does not re-use preload with non-matching digest.] + expected: FAIL + + [Same-origin script with non-matching digest does not re-use preload with non-matching digest.] + expected: FAIL + + [Same-origin script with matching digest does not reuse preload without digest.] + expected: FAIL + + [Same-origin script with matching digest does not reuse preload with matching but stronger digest.] + expected: FAIL + + [Same-origin script with wrong digest does not reuse preload with correct and stronger digest.] + expected: FAIL + + [Same-origin script with matching digest does not reuse preload with matching but weaker digest.] + expected: FAIL + + [Same-origin script with non-matching digest reuses preload with no digest but fails.] + expected: FAIL + + [Same-origin style with correct sha256 hash.] + expected: FAIL + + [Same-origin style with correct sha384 hash.] + expected: FAIL + + [Same-origin style with correct sha512 hash.] + expected: FAIL + + [Same-origin style with empty integrity.] + expected: FAIL + + [Same-origin style with incorrect hash.] + expected: FAIL + + [Same-origin style with multiple sha256 hashes, including correct.] + expected: FAIL + + [Same-origin style with multiple sha256 hashes, including unknown algorithm.] + expected: FAIL + + [Same-origin style with sha256 mismatch, sha512 match] + expected: FAIL + + [Same-origin style with sha256 match, sha512 mismatch] + expected: FAIL + + [<crossorigin='anonymous'> style with correct hash, ACAO: *] + expected: FAIL + + [<crossorigin='anonymous'> style with incorrect hash, ACAO: *] + expected: FAIL + + [<crossorigin='use-credentials'> style with correct hash, CORS-eligible] + expected: FAIL + + [<crossorigin='use-credentials'> style with incorrect hash CORS-eligible] + expected: FAIL + + [<crossorigin='anonymous'> style with CORS-ineligible resource] + expected: FAIL + + [Cross-origin style, not CORS request, with correct hash] + expected: FAIL + + [Cross-origin style, not CORS request, with hash mismatch] + expected: FAIL + + [Cross-origin style, empty integrity] + expected: FAIL + + [Same-origin style with correct hash, options.] + expected: FAIL + + [Same-origin style with unknown algorithm only.] + expected: FAIL + + [Same-origin style with matching digest re-uses preload with matching digest.] + expected: FAIL + + [Same-origin style with matching digest re-uses preload with matching digest and options.] + expected: FAIL + + [Same-origin style with non-matching digest does not re-use preload with matching digest.] + expected: FAIL + + [Same-origin style with matching digest does not re-use preload with non-matching digest.] + expected: FAIL + + [Same-origin style with non-matching digest does not re-use preload with non-matching digest.] + expected: FAIL + + [Same-origin style with matching digest does not reuse preload without digest.] + expected: FAIL + + [Same-origin style with matching digest does not reuse preload with matching but stronger digest.] + expected: FAIL + + [Same-origin style with wrong digest does not reuse preload with correct and stronger digest.] + expected: FAIL + + [Same-origin style with matching digest does not reuse preload with matching but weaker digest.] + expected: FAIL + + [Same-origin style with non-matching digest reuses preload with no digest but fails.] + expected: FAIL + + [Same-origin image with incorrect hash.] + expected: FAIL + + [Same-origin image with sha256 match, sha512 mismatch] + expected: FAIL + + [<crossorigin='anonymous'> image with incorrect hash, ACAO: *] + expected: FAIL + + [<crossorigin='use-credentials'> image with incorrect hash CORS-eligible] + expected: FAIL + + [<crossorigin='anonymous'> image with CORS-ineligible resource] + expected: FAIL + + [Cross-origin image, not CORS request, with correct hash] + expected: FAIL + + [Cross-origin image, not CORS request, with hash mismatch] + expected: FAIL diff --git a/tests/wpt/meta/preload/supported-as-values.html.ini b/tests/wpt/meta/preload/supported-as-values.html.ini new file mode 100644 index 00000000000..8d299d0585d --- /dev/null +++ b/tests/wpt/meta/preload/supported-as-values.html.ini @@ -0,0 +1,43 @@ +[supported-as-values.html?as=track&expected=1] + [Test the supported value for <link rel=preload as="...">] + expected: FAIL + + +[supported-as-values.html?as=iframe&expected=0] + +[supported-as-values.html?as=video&expected=0] + +[supported-as-values.html?as=font&expected=1] + [Test the supported value for <link rel=preload as="...">] + expected: FAIL + + +[supported-as-values.html?as=fetch&expected=1] + [Test the supported value for <link rel=preload as="...">] + expected: FAIL + + +[supported-as-values.html?as=object&expected=0] + +[supported-as-values.html?as=image&expected=1] + [Test the supported value for <link rel=preload as="...">] + expected: FAIL + + +[supported-as-values.html?as=garbagefoobar&expected=0] + +[supported-as-values.html?as=style&expected=1] + [Test the supported value for <link rel=preload as="...">] + expected: FAIL + + +[supported-as-values.html?as=audio&expected=0] + +[supported-as-values.html?as=script&expected=1] + [Test the supported value for <link rel=preload as="...">] + expected: FAIL + + +[supported-as-values.html?as=json&expected=0] + +[supported-as-values.html?as=worklet&expected=0] diff --git a/tests/wpt/meta/resize-observer/change-layout-in-error.html.ini b/tests/wpt/meta/resize-observer/change-layout-in-error.html.ini new file mode 100644 index 00000000000..5d07f60e0b6 --- /dev/null +++ b/tests/wpt/meta/resize-observer/change-layout-in-error.html.ini @@ -0,0 +1,3 @@ +[change-layout-in-error.html] + [Changing layout in window error handler should not result in lifecyle loop when resize observer loop limit is reached.] + expected: FAIL diff --git a/tests/wpt/meta/resize-observer/zoom.html.ini b/tests/wpt/meta/resize-observer/zoom.html.ini new file mode 100644 index 00000000000..a08a15e7c82 --- /dev/null +++ b/tests/wpt/meta/resize-observer/zoom.html.ini @@ -0,0 +1,3 @@ +[zoom.html] + [ResizeObserver sizes account for zoom] + expected: FAIL diff --git a/tests/wpt/meta/shadow-dom/directionality-001.tentative.html.ini b/tests/wpt/meta/shadow-dom/directionality-001.tentative.html.ini deleted file mode 100644 index 8929df10f67..00000000000 --- a/tests/wpt/meta/shadow-dom/directionality-001.tentative.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[directionality-001.tentative.html] - expected: FAIL diff --git a/tests/wpt/meta/trusted-types/block-text-node-insertion-into-script-element.html.ini b/tests/wpt/meta/trusted-types/block-text-node-insertion-into-script-element.html.ini index 34f64b9ef70..366c956d411 100644 --- a/tests/wpt/meta/trusted-types/block-text-node-insertion-into-script-element.html.ini +++ b/tests/wpt/meta/trusted-types/block-text-node-insertion-into-script-element.html.ini @@ -17,3 +17,12 @@ [Spot tests around script + innerHTML interaction with default policy.] expected: FAIL + + [Regression test: Bypass via appendChild into off-document script element.] + expected: FAIL + + [Regression test: Bypass via appendChild into live script element.] + expected: FAIL + + [Test that default policy applies to module script.] + expected: FAIL diff --git a/tests/wpt/meta/trusted-types/block-text-node-insertion-into-svg-script-element.html.ini b/tests/wpt/meta/trusted-types/block-text-node-insertion-into-svg-script-element.html.ini index e0fbb2a6064..4d469799e85 100644 --- a/tests/wpt/meta/trusted-types/block-text-node-insertion-into-svg-script-element.html.ini +++ b/tests/wpt/meta/trusted-types/block-text-node-insertion-into-svg-script-element.html.ini @@ -10,3 +10,6 @@ [Spot tests around script + innerHTML interaction with default policy.] expected: FAIL + + [Test that default policy applies with module script. svg:script] + expected: FAIL diff --git a/tests/wpt/meta/uievents/legacy-domevents-tests/approved/ProcessingInstruction.DOMCharacterDataModified.html.ini b/tests/wpt/meta/uievents/legacy-domevents-tests/approved/ProcessingInstruction.DOMCharacterDataModified.html.ini deleted file mode 100644 index e36472cb628..00000000000 --- a/tests/wpt/meta/uievents/legacy-domevents-tests/approved/ProcessingInstruction.DOMCharacterDataModified.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[ProcessingInstruction.DOMCharacterDataModified.html] - [Test Description: DOMCharacterDataModified event fires after ProcessingInstruction.data have been modified, but the node itself has not been inserted or deleted. The proximal event target of this event shall be the ProcessingInstruction node.] - expected: FAIL diff --git a/tests/wpt/meta/uievents/legacy-domevents-tests/approved/domnodeinserted.html.ini b/tests/wpt/meta/uievents/legacy-domevents-tests/approved/domnodeinserted.html.ini deleted file mode 100644 index 27f8ad9e90f..00000000000 --- a/tests/wpt/meta/uievents/legacy-domevents-tests/approved/domnodeinserted.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[domnodeinserted.html] - expected: TIMEOUT - [Test Description: DOMNodeInserted event fires when a node has been added as a child of another node.] - expected: NOTRUN diff --git a/tests/wpt/meta/urlpattern/urlpattern-generate.tentative.any.js.ini b/tests/wpt/meta/urlpattern/urlpattern-generate.tentative.any.js.ini new file mode 100644 index 00000000000..3c01bdb3c49 --- /dev/null +++ b/tests/wpt/meta/urlpattern/urlpattern-generate.tentative.any.js.ini @@ -0,0 +1,63 @@ +[urlpattern-generate.tentative.any.worker.html] + [Pattern: {"pathname":"/foo"} Component: pathname Groups: {}] + expected: FAIL + + [Pattern: {"pathname":"/:foo"} Component: pathname Groups: {"foo":"bar"}] + expected: FAIL + + [Pattern: {"pathname":"/:foo"} Component: pathname Groups: {"foo":"🍅"}] + expected: FAIL + + [Pattern: {"hostname":"{:foo}.example.com"} Component: hostname Groups: {"foo":"🍅"}] + expected: FAIL + + [Pattern: {"pathname":"/foo/:bar"} Component: pathname Groups: {"bar":"baz"}] + expected: FAIL + + [Pattern: {"pathname":"/foo:bar"} Component: pathname Groups: {"bar":"baz"}] + expected: FAIL + + [Pattern: {"pathname":"/:foo/:bar"} Component: pathname Groups: {"foo":"baz","bar":"qux"}] + expected: FAIL + + [Pattern: "https://example.com/:foo" Component: pathname Groups: {"foo":" "}] + expected: FAIL + + [Pattern: "original-scheme://example.com/:foo" Component: pathname Groups: {"foo":" "}] + expected: FAIL + + +[urlpattern-generate.tentative.any.html] + [Pattern: {"pathname":"/foo"} Component: pathname Groups: {}] + expected: FAIL + + [Pattern: {"pathname":"/:foo"} Component: pathname Groups: {"foo":"bar"}] + expected: FAIL + + [Pattern: {"pathname":"/:foo"} Component: pathname Groups: {"foo":"🍅"}] + expected: FAIL + + [Pattern: {"hostname":"{:foo}.example.com"} Component: hostname Groups: {"foo":"🍅"}] + expected: FAIL + + [Pattern: {"pathname":"/foo/:bar"} Component: pathname Groups: {"bar":"baz"}] + expected: FAIL + + [Pattern: {"pathname":"/foo:bar"} Component: pathname Groups: {"bar":"baz"}] + expected: FAIL + + [Pattern: {"pathname":"/:foo/:bar"} Component: pathname Groups: {"foo":"baz","bar":"qux"}] + expected: FAIL + + [Pattern: "https://example.com/:foo" Component: pathname Groups: {"foo":" "}] + expected: FAIL + + [Pattern: "original-scheme://example.com/:foo" Component: pathname Groups: {"foo":" "}] + expected: FAIL + + +[urlpattern-generate.tentative.any.serviceworker.html] + expected: ERROR + +[urlpattern-generate.tentative.any.sharedworker.html] + expected: ERROR diff --git a/tests/wpt/meta/webaudio/the-audio-api/the-audiobuffersourcenode-interface/sub-sample-buffer-stitching.html.ini b/tests/wpt/meta/webaudio/the-audio-api/the-audiobuffersourcenode-interface/sub-sample-buffer-stitching.html.ini index 960779501c4..5d66c9ba352 100644 --- a/tests/wpt/meta/webaudio/the-audio-api/the-audiobuffersourcenode-interface/sub-sample-buffer-stitching.html.ini +++ b/tests/wpt/meta/webaudio/the-audio-api/the-audiobuffersourcenode-interface/sub-sample-buffer-stitching.html.ini @@ -805,3 +805,12 @@ [X Stitched sine-wave buffers at sample rate 43800 does not equal [0,0.06264832615852356,0.12505052983760834,0.18696144223213196,0.24813786149024963,0.308339387178421,0.36732959747314453,0.4248766601085663,0.480754554271698,0.5347436666488647,0.5866320133209229,0.6362156271934509,0.6832997798919678,0.7276994585990906,0.7692402601242065,0.8077589869499207...\] with an element-wise tolerance of {"absoluteThreshold":0.0038986,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[14650\]\t2.4329547374028208e-17\t8.6956524848937988e-1\t8.6956524848937988e-1\t1.0000000000000000e+0\t3.8985999999999999e-3\n\t[14651\]\t3.0547976493835449e-1\t8.9879405498504639e-1\t5.9331429004669189e-1\t6.6012262403823208e-1\t3.8985999999999999e-3\n\tMax AbsError of 8.6956524848937988e-1 at index of 14650.\n\tMax RelError of 1.0000000000000000e+0 at index of 14650.\n] expected: FAIL + + [X Stitched sine-wave buffers at sample rate 43800 does not equal [0,0.06264832615852356,0.12505052983760834,0.18696144223213196,0.24813786149024963,0.308339387178421,0.36732959747314453,0.4248766601085663,0.480754554271698,0.5347436666488647,0.5866320133209229,0.6362156271934509,0.6832997798919678,0.7276994585990906,0.7692402601242065,0.8077589869499207...\] with an element-wise tolerance of {"absoluteThreshold":0.0038986,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[14650\]\t3.3752832548824226e-34\t8.6956524848937988e-1\t8.6956524848937988e-1\t1.0000000000000000e+0\t3.8985999999999999e-3\n\t[14651\]\t3.0547976493835449e-1\t8.9879405498504639e-1\t5.9331429004669189e-1\t6.6012262403823208e-1\t3.8985999999999999e-3\n\tMax AbsError of 8.6956524848937988e-1 at index of 14650.\n\tMax RelError of 1.0000000000000000e+0 at index of 14650.\n] + expected: FAIL + + [X Stitched sine-wave buffers at sample rate 43800 does not equal [0,0.06264832615852356,0.12505052983760834,0.18696144223213196,0.24813786149024963,0.308339387178421,0.36732959747314453,0.4248766601085663,0.480754554271698,0.5347436666488647,0.5866320133209229,0.6362156271934509,0.6832997798919678,0.7276994585990906,0.7692402601242065,0.8077589869499207...\] with an element-wise tolerance of {"absoluteThreshold":0.0038986,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[14650\]\t4.5710336303710938e+2\t8.6956524848937988e-1\t4.5623379778862000e+2\t5.2466884869329283e+2\t3.8985999999999999e-3\n\t[14651\]\t3.0547976493835449e-1\t8.9879405498504639e-1\t5.9331429004669189e-1\t6.6012262403823208e-1\t3.8985999999999999e-3\n\tMax AbsError of 4.5623379778862000e+2 at index of 14650.\n\tMax RelError of 5.2466884869329283e+2 at index of 14650.\n] + expected: FAIL + + [X SNR (-9.749670615505378 dB) is not greater than or equal to 65.737. Got -9.749670615505378.] + expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/accept_alert/accept.py.ini b/tests/wpt/meta/webdriver/tests/classic/accept_alert/accept.py.ini index 00caf69c8d5..a5d10aa6fe2 100644 --- a/tests/wpt/meta/webdriver/tests/classic/accept_alert/accept.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/accept_alert/accept.py.ini @@ -1,4 +1,5 @@ [accept.py] + expected: TIMEOUT [test_null_response_value] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/dismiss_alert/dismiss.py.ini b/tests/wpt/meta/webdriver/tests/classic/dismiss_alert/dismiss.py.ini index cd2546ede8b..a2869095ca8 100644 --- a/tests/wpt/meta/webdriver/tests/classic/dismiss_alert/dismiss.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/dismiss_alert/dismiss.py.ini @@ -1,4 +1,5 @@ [dismiss.py] + expected: TIMEOUT [test_no_top_browsing_context] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/element_clear/clear.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_clear/clear.py.ini index 541ffc25ca6..6a82e9170b8 100644 --- a/tests/wpt/meta/webdriver/tests/classic/element_clear/clear.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/element_clear/clear.py.ini @@ -1,2 +1,210 @@ [clear.py] - expected: TIMEOUT + [test_null_response_value] + expected: FAIL + + [test_no_top_browsing_context] + expected: FAIL + + [test_no_browsing_context] + expected: FAIL + + [test_no_such_element_with_invalid_value] + expected: FAIL + + [test_no_such_element_with_shadow_root] + expected: FAIL + + [test_no_such_element_from_other_window_handle[open\]] + expected: FAIL + + [test_no_such_element_from_other_window_handle[closed\]] + expected: FAIL + + [test_no_such_element_from_other_frame[open\]] + expected: FAIL + + [test_no_such_element_from_other_frame[closed\]] + expected: FAIL + + [test_stale_element_reference[top_context\]] + expected: FAIL + + [test_stale_element_reference[child_context\]] + expected: FAIL + + [test_pointer_interactable] + expected: FAIL + + [test_keyboard_interactable] + expected: FAIL + + [test_input[number-42-\]] + expected: FAIL + + [test_input[range-42-50\]] + expected: FAIL + + [test_input[email-foo@example.com-\]] + expected: FAIL + + [test_input[password-password-\]] + expected: FAIL + + [test_input[search-search-\]] + expected: FAIL + + [test_input[tel-999-\]] + expected: FAIL + + [test_input[text-text-\]] + expected: FAIL + + [test_input[url-https://example.com/-\]] + expected: FAIL + + [test_input[color-#ff0000-#000000\]] + expected: FAIL + + [test_input[date-2017-12-26-\]] + expected: FAIL + + [test_input[datetime-2017-12-26T19:48-\]] + expected: FAIL + + [test_input[datetime-local-2017-12-26T19:48-\]] + expected: FAIL + + [test_input[time-19:48-\]] + expected: FAIL + + [test_input[month-2017-11-\]] + expected: FAIL + + [test_input[week-2017-W52-\]] + expected: FAIL + + [test_input_readonly[number\]] + expected: FAIL + + [test_input_readonly[range\]] + expected: FAIL + + [test_input_readonly[email\]] + expected: FAIL + + [test_input_readonly[password\]] + expected: FAIL + + [test_input_readonly[search\]] + expected: FAIL + + [test_input_readonly[tel\]] + expected: FAIL + + [test_input_readonly[text\]] + expected: FAIL + + [test_input_readonly[url\]] + expected: FAIL + + [test_input_readonly[color\]] + expected: FAIL + + [test_input_readonly[date\]] + expected: FAIL + + [test_input_readonly[datetime\]] + expected: FAIL + + [test_input_readonly[datetime-local\]] + expected: FAIL + + [test_input_readonly[time\]] + expected: FAIL + + [test_input_readonly[month\]] + expected: FAIL + + [test_input_readonly[week\]] + expected: FAIL + + [test_input_readonly[file\]] + expected: FAIL + + [test_textarea] + expected: FAIL + + [test_textarea_readonly] + expected: FAIL + + [test_input_file] + expected: FAIL + + [test_input_file_multiple] + expected: FAIL + + [test_button[button\]] + expected: FAIL + + [test_button[reset\]] + expected: FAIL + + [test_button[submit\]] + expected: FAIL + + [test_button_with_subtree] + expected: FAIL + + [test_contenteditable] + expected: FAIL + + [test_designmode] + expected: FAIL + + [test_resettable_element_focus_when_empty] + expected: FAIL + + [test_resettable_element_does_not_satisfy_validation_constraints[number-foo\]] + expected: FAIL + + [test_resettable_element_does_not_satisfy_validation_constraints[email-foo\]] + expected: FAIL + + [test_resettable_element_does_not_satisfy_validation_constraints[url-foo\]] + expected: FAIL + + [test_resettable_element_does_not_satisfy_validation_constraints[date-foo\]] + expected: FAIL + + [test_resettable_element_does_not_satisfy_validation_constraints[datetime-local-foo\]] + expected: FAIL + + [test_resettable_element_does_not_satisfy_validation_constraints[time-foo\]] + expected: FAIL + + [test_resettable_element_does_not_satisfy_validation_constraints[month-foo\]] + expected: FAIL + + [test_resettable_element_does_not_satisfy_validation_constraints[week-foo\]] + expected: FAIL + + [test_non_editable_inputs[checkbox\]] + expected: FAIL + + [test_non_editable_inputs[radio\]] + expected: FAIL + + [test_non_editable_inputs[hidden\]] + expected: FAIL + + [test_non_editable_inputs[submit\]] + expected: FAIL + + [test_non_editable_inputs[button\]] + expected: FAIL + + [test_non_editable_inputs[image\]] + expected: FAIL + + [test_scroll_into_view] + expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/element_clear/disabled.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_clear/disabled.py.ini index f6367167d66..76b124f1dca 100644 --- a/tests/wpt/meta/webdriver/tests/classic/element_clear/disabled.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/element_clear/disabled.py.ini @@ -1,5 +1,4 @@ [disabled.py] - expected: TIMEOUT [test_button[button\]] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/element_click/bubbling.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_click/bubbling.py.ini deleted file mode 100644 index d99f3672ef6..00000000000 --- a/tests/wpt/meta/webdriver/tests/classic/element_click/bubbling.py.ini +++ /dev/null @@ -1,6 +0,0 @@ -[bubbling.py] - [test_click_event_bubbles_to_parents] - expected: FAIL - - [test_spin_event_loop] - expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/element_click/center_point.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_click/center_point.py.ini index 3e3bfa2708e..48358dc41c1 100644 --- a/tests/wpt/meta/webdriver/tests/classic/element_click/center_point.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/element_click/center_point.py.ini @@ -1,4 +1,5 @@ [center_point.py] + expected: TIMEOUT [test_entirely_in_view] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/element_click/click.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_click/click.py.ini index 9cdf1e0d0da..7405df1cdfb 100644 --- a/tests/wpt/meta/webdriver/tests/classic/element_click/click.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/element_click/click.py.ini @@ -7,9 +7,3 @@ [test_no_such_element_from_other_window_handle[closed\]] expected: FAIL - - [test_no_such_element_from_other_frame[open\]] - expected: FAIL - - [test_no_such_element_from_other_frame[closed\]] - expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/element_click/events.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_click/events.py.ini deleted file mode 100644 index 8f57d96cef8..00000000000 --- a/tests/wpt/meta/webdriver/tests/classic/element_click/events.py.ini +++ /dev/null @@ -1,3 +0,0 @@ -[events.py] - [test_event_mousemove] - expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/element_click/interactability.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_click/interactability.py.ini index 982ea5ca753..9c185c61557 100644 --- a/tests/wpt/meta/webdriver/tests/classic/element_click/interactability.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/element_click/interactability.py.ini @@ -1,4 +1,5 @@ [interactability.py] + expected: TIMEOUT [test_display_none] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/element_click/shadow_dom.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_click/shadow_dom.py.ini index 92d8bfe9a3d..32fd2854998 100644 --- a/tests/wpt/meta/webdriver/tests/classic/element_click/shadow_dom.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/element_click/shadow_dom.py.ini @@ -2,14 +2,8 @@ [test_shadow_element_click[host_element\]] expected: FAIL - [test_shadow_element_click[checkbox_element\]] - expected: FAIL - [test_nested_shadow_element_click[outer_element\]] expected: FAIL [test_nested_shadow_element_click[inner_element\]] expected: FAIL - - [test_nested_shadow_element_click[checkbox\]] - expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/element_send_keys/events.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_send_keys/events.py.ini index 26b3aaa641b..5e4543ef0e9 100644 --- a/tests/wpt/meta/webdriver/tests/classic/element_send_keys/events.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/element_send_keys/events.py.ini @@ -1,7 +1,4 @@ [events.py] - [test_file_upload] - expected: FAIL - [test_form_control_send_text[input\]] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/element_send_keys/file_upload.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_send_keys/file_upload.py.ini index 4fd4b29e87f..40a4a701288 100644 --- a/tests/wpt/meta/webdriver/tests/classic/element_send_keys/file_upload.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/element_send_keys/file_upload.py.ini @@ -1,50 +1,19 @@ [file_upload.py] - expected: TIMEOUT [test_empty_text] expected: FAIL - [test_multiple_files] - expected: FAIL - [test_multiple_files_last_path_not_found] expected: FAIL - [test_multiple_files_without_multiple_attribute] - expected: FAIL - [test_multiple_files_send_twice] expected: FAIL [test_multiple_files_reset_with_element_clear] expected: FAIL - [test_single_file] - expected: FAIL - - [test_single_file_replaces_without_multiple_attribute] - expected: FAIL - [test_single_file_appends_with_multiple_attribute] expected: FAIL - [test_transparent] - expected: FAIL - - [test_obscured] - expected: FAIL - - [test_outside_viewport] - expected: FAIL - - [test_hidden] - expected: FAIL - - [test_display_none] - expected: FAIL - - [test_not_focused] - expected: FAIL - [test_focused] expected: ERROR diff --git a/tests/wpt/meta/webdriver/tests/classic/element_send_keys/send_keys.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_send_keys/send_keys.py.ini index 10a5a86e3d2..9dca7adc465 100644 --- a/tests/wpt/meta/webdriver/tests/classic/element_send_keys/send_keys.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/element_send_keys/send_keys.py.ini @@ -7,9 +7,3 @@ [test_no_such_element_from_other_window_handle[closed\]] expected: FAIL - - [test_no_such_element_from_other_frame[open\]] - expected: FAIL - - [test_no_such_element_from_other_frame[closed\]] - expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/execute_async_script/arguments.py.ini b/tests/wpt/meta/webdriver/tests/classic/execute_async_script/arguments.py.ini index 6bcbe1197f6..72a20a6f7cf 100644 --- a/tests/wpt/meta/webdriver/tests/classic/execute_async_script/arguments.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/execute_async_script/arguments.py.ini @@ -1,2 +1,78 @@ [arguments.py] - expected: TIMEOUT + [test_no_such_element_with_unknown_id] + expected: FAIL + + [test_no_such_element_from_other_window_handle[open\]] + expected: FAIL + + [test_no_such_element_from_other_window_handle[closed\]] + expected: FAIL + + [test_no_such_element_from_other_frame[open\]] + expected: FAIL + + [test_no_such_element_from_other_frame[closed\]] + expected: FAIL + + [test_no_such_shadow_root_with_unknown_id] + expected: FAIL + + [test_no_such_shadow_root_from_other_window_handle[open\]] + expected: FAIL + + [test_no_such_shadow_root_from_other_window_handle[closed\]] + expected: FAIL + + [test_no_such_shadow_root_from_other_frame[open\]] + expected: FAIL + + [test_no_such_shadow_root_from_other_frame[closed\]] + expected: FAIL + + [test_stale_element_reference[top_context\]] + expected: FAIL + + [test_stale_element_reference[child_context\]] + expected: FAIL + + [test_invalid_argument_for_window_with_invalid_type[None-frame\]] + expected: FAIL + + [test_invalid_argument_for_window_with_invalid_type[None-window\]] + expected: FAIL + + [test_invalid_argument_for_window_with_invalid_type[False-frame\]] + expected: FAIL + + [test_invalid_argument_for_window_with_invalid_type[False-window\]] + expected: FAIL + + [test_invalid_argument_for_window_with_invalid_type[42-frame\]] + expected: FAIL + + [test_invalid_argument_for_window_with_invalid_type[42-window\]] + expected: FAIL + + [test_invalid_argument_for_window_with_invalid_type[value3-frame\]] + expected: FAIL + + [test_invalid_argument_for_window_with_invalid_type[value3-window\]] + expected: FAIL + + [test_invalid_argument_for_window_with_invalid_type[value4-frame\]] + expected: FAIL + + [test_invalid_argument_for_window_with_invalid_type[value4-window\]] + expected: FAIL + + [test_no_such_window_for_window_with_invalid_value] + expected: FAIL + + [test_element_reference[frame\]] + expected: FAIL + + [test_element_reference[shadow-root\]] + expected: FAIL + + [test_element_reference[window\]] + expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/execute_async_script/execute_async.py.ini b/tests/wpt/meta/webdriver/tests/classic/execute_async_script/execute_async.py.ini index 6885d2e743e..26921d513c2 100644 --- a/tests/wpt/meta/webdriver/tests/classic/execute_async_script/execute_async.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/execute_async_script/execute_async.py.ini @@ -1,4 +1,5 @@ [execute_async.py] + expected: TIMEOUT [test_no_browsing_context] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/execute_script/arguments.py.ini b/tests/wpt/meta/webdriver/tests/classic/execute_script/arguments.py.ini index 8818990c5ef..9c6615f080f 100644 --- a/tests/wpt/meta/webdriver/tests/classic/execute_script/arguments.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/execute_script/arguments.py.ini @@ -1,5 +1,4 @@ [arguments.py] - expected: TIMEOUT [test_no_such_element_with_unknown_id] expected: FAIL @@ -78,9 +77,6 @@ [test_element_reference[frame\]] expected: FAIL - [test_element_reference[node\]] - expected: FAIL - [test_element_reference[shadow-root\]] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/execute_script/execute.py.ini b/tests/wpt/meta/webdriver/tests/classic/execute_script/execute.py.ini index 8a1571d1d7b..ff13c80a5fe 100644 --- a/tests/wpt/meta/webdriver/tests/classic/execute_script/execute.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/execute_script/execute.py.ini @@ -1,4 +1,5 @@ [execute.py] + expected: TIMEOUT [test_no_browsing_context] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/find_element/find.py.ini b/tests/wpt/meta/webdriver/tests/classic/find_element/find.py.ini index 7564f644b10..60f973b8a44 100644 --- a/tests/wpt/meta/webdriver/tests/classic/find_element/find.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/find_element/find.py.ini @@ -1,7 +1,6 @@ [find.py] - expected: TIMEOUT [test_no_browsing_context] - expected: ERROR + expected: FAIL [test_no_such_element_with_unknown_selector[not-existent\]] expected: FAIL @@ -15,18 +14,6 @@ [test_find_element[xpath-//a\]] expected: FAIL - [test_xhtml_namespace[css selector-#linkText\]] - expected: FAIL - - [test_xhtml_namespace[link text-full link text\]] - expected: FAIL - - [test_xhtml_namespace[partial link text-link text\]] - expected: FAIL - - [test_xhtml_namespace[tag name-a\]] - expected: FAIL - [test_xhtml_namespace[xpath-//*[name()='a'\]\]] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/find_element_from_shadow_root/find.py.ini b/tests/wpt/meta/webdriver/tests/classic/find_element_from_shadow_root/find.py.ini index dba98c7726b..05e490d14fe 100644 --- a/tests/wpt/meta/webdriver/tests/classic/find_element_from_shadow_root/find.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/find_element_from_shadow_root/find.py.ini @@ -1,5 +1,4 @@ [find.py] - expected: TIMEOUT [test_null_parameter_value] expected: FAIL @@ -7,7 +6,7 @@ expected: FAIL [test_no_browsing_context] - expected: ERROR + expected: FAIL [test_no_such_shadow_root_with_element] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/find_elements/find.py.ini b/tests/wpt/meta/webdriver/tests/classic/find_elements/find.py.ini index 44f232824bb..06a8b89b5b6 100644 --- a/tests/wpt/meta/webdriver/tests/classic/find_elements/find.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/find_elements/find.py.ini @@ -1,74 +1,22 @@ [find.py] - expected: TIMEOUT [test_no_browsing_context] - expected: ERROR - - [test_find_elements[css selector-#linkText\]] - expected: FAIL - - [test_find_elements[link text-full link text\]] - expected: FAIL - - [test_find_elements[partial link text-link text\]] - expected: FAIL - - [test_find_elements[tag name-a\]] expected: FAIL [test_find_elements[xpath-//a\]] expected: FAIL - [test_find_elements_link_text[<a href=#>link text</a>-link text\]] - expected: FAIL - - [test_find_elements_link_text[<a href=#> link text </a>-link text\]] - expected: FAIL - [test_find_elements_link_text[<a href=#>link<br>text</a>-link\\ntext\]] expected: FAIL - [test_find_elements_link_text[<a href=#>link&text</a>-link&text\]] - expected: FAIL - - [test_find_elements_link_text[<a href=#>LINK TEXT</a>-LINK TEXT\]] - expected: FAIL - [test_find_elements_link_text[<a href=# style='text-transform: uppercase'>link text</a>-LINK TEXT\]] expected: FAIL - [test_find_elements_partial_link_text[<a href=#>partial link text</a>-link\]] - expected: FAIL - - [test_find_elements_partial_link_text[<a href=#> partial link text </a>-link\]] - expected: FAIL - - [test_find_elements_partial_link_text[<a href=#>partial link text</a>-k t\]] - expected: FAIL - [test_find_elements_partial_link_text[<a href=#>partial link<br>text</a>-k\\nt\]] expected: FAIL - [test_find_elements_partial_link_text[<a href=#>partial link&text</a>-k&t\]] - expected: FAIL - - [test_find_elements_partial_link_text[<a href=#>PARTIAL LINK TEXT</a>-LINK\]] - expected: FAIL - [test_find_elements_partial_link_text[<a href=# style='text-transform: uppercase'>partial link text</a>-LINK\]] expected: FAIL - [test_xhtml_namespace[css selector-#linkText\]] - expected: FAIL - - [test_xhtml_namespace[link text-full link text\]] - expected: FAIL - - [test_xhtml_namespace[partial link text-link text\]] - expected: FAIL - - [test_xhtml_namespace[tag name-a\]] - expected: FAIL - [test_xhtml_namespace[xpath-//*[name()='a'\]\]] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/find_elements_from_element/find.py.ini b/tests/wpt/meta/webdriver/tests/classic/find_elements_from_element/find.py.ini index 69ec1b4bbcc..47ac0c0b589 100644 --- a/tests/wpt/meta/webdriver/tests/classic/find_elements_from_element/find.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/find_elements_from_element/find.py.ini @@ -1,77 +1,28 @@ [find.py] - expected: TIMEOUT [test_no_browsing_context] - expected: ERROR - - [test_no_such_element_with_shadow_root] expected: FAIL - [test_no_such_element_with_startnode_from_other_window_handle] + [test_no_such_element_with_shadow_root] expected: FAIL [test_no_such_element_with_startnode_from_other_frame] expected: FAIL - [test_stale_element_reference[top_context\]] - expected: FAIL - - [test_stale_element_reference[child_context\]] - expected: FAIL - [test_find_elements[xpath-//a\]] expected: FAIL - [test_find_elements_link_text[<a href=#>link text</a>-link text\]] - expected: FAIL - - [test_find_elements_link_text[<a href=#> link text </a>-link text\]] - expected: FAIL - [test_find_elements_link_text[<a href=#>link<br>text</a>-link\\ntext\]] expected: FAIL - [test_find_elements_link_text[<a href=#>link&text</a>-link&text\]] - expected: FAIL - - [test_find_elements_link_text[<a href=#>LINK TEXT</a>-LINK TEXT\]] - expected: FAIL - [test_find_elements_link_text[<a href=# style='text-transform: uppercase'>link text</a>-LINK TEXT\]] expected: FAIL - [test_find_elements_partial_link_text[<a href=#>partial link text</a>-link\]] - expected: FAIL - - [test_find_elements_partial_link_text[<a href=#> partial link text </a>-link\]] - expected: FAIL - - [test_find_elements_partial_link_text[<a href=#>partial link text</a>-k t\]] - expected: FAIL - [test_find_elements_partial_link_text[<a href=#>partial link<br>text</a>-k\\nt\]] expected: FAIL - [test_find_elements_partial_link_text[<a href=#>partial link&text</a>-k&t\]] - expected: FAIL - - [test_find_elements_partial_link_text[<a href=#>PARTIAL LINK TEXT</a>-LINK\]] - expected: FAIL - [test_find_elements_partial_link_text[<a href=# style='text-transform: uppercase'>partial link text</a>-LINK\]] expected: FAIL - [test_xhtml_namespace[css selector-#linkText\]] - expected: FAIL - - [test_xhtml_namespace[link text-full link text\]] - expected: FAIL - - [test_xhtml_namespace[partial link text-link text\]] - expected: FAIL - - [test_xhtml_namespace[tag name-a\]] - expected: FAIL - [test_xhtml_namespace[xpath-//*[name()='a'\]\]] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/find_elements_from_shadow_root/find.py.ini b/tests/wpt/meta/webdriver/tests/classic/find_elements_from_shadow_root/find.py.ini index 5328af1b701..18ed273c743 100644 --- a/tests/wpt/meta/webdriver/tests/classic/find_elements_from_shadow_root/find.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/find_elements_from_shadow_root/find.py.ini @@ -1,5 +1,4 @@ [find.py] - expected: TIMEOUT [test_null_parameter_value] expected: FAIL @@ -7,7 +6,7 @@ expected: FAIL [test_no_browsing_context] - expected: ERROR + expected: FAIL [test_no_such_shadow_root_with_element] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/get_computed_role/get.py.ini b/tests/wpt/meta/webdriver/tests/classic/get_computed_role/get.py.ini index f00172fdc5a..44749396246 100644 --- a/tests/wpt/meta/webdriver/tests/classic/get_computed_role/get.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/get_computed_role/get.py.ini @@ -8,11 +8,5 @@ [test_no_such_element_from_other_window_handle[closed\]] expected: FAIL - [test_no_such_element_from_other_frame[open\]] - expected: FAIL - - [test_no_such_element_from_other_frame[closed\]] - expected: FAIL - [test_computed_roles[<article>foo</article>-article-article\]] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/get_element_attribute/get.py.ini b/tests/wpt/meta/webdriver/tests/classic/get_element_attribute/get.py.ini index 69b4a4c7d0b..c5bc0a36f6d 100644 --- a/tests/wpt/meta/webdriver/tests/classic/get_element_attribute/get.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/get_element_attribute/get.py.ini @@ -1,35 +1,13 @@ [get.py] - expected: TIMEOUT - [test_no_top_browsing_context] - expected: FAIL - [test_no_browsing_context] - expected: ERROR - - [test_no_such_element_with_shadow_root] expected: FAIL - [test_no_such_element_from_other_window_handle[open\]] + [test_no_such_element_with_shadow_root] expected: FAIL [test_no_such_element_from_other_window_handle[closed\]] expected: FAIL - [test_no_such_element_from_other_frame[open\]] - expected: FAIL - - [test_no_such_element_from_other_frame[closed\]] - expected: FAIL - - [test_stale_element_reference[top_context\]] - expected: FAIL - - [test_stale_element_reference[child_context\]] - expected: FAIL - - [test_normal] - expected: FAIL - [test_boolean_attribute[audio-attrs0\]] expected: FAIL @@ -86,9 +64,3 @@ [test_global_boolean_attributes] expected: FAIL - - [test_anchor_href[relative\]] - expected: FAIL - - [test_anchor_href[absolute\]] - expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/get_element_css_value/get.py.ini b/tests/wpt/meta/webdriver/tests/classic/get_element_css_value/get.py.ini index d55c5312a47..0af7750e50e 100644 --- a/tests/wpt/meta/webdriver/tests/classic/get_element_css_value/get.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/get_element_css_value/get.py.ini @@ -7,9 +7,3 @@ [test_no_such_element_from_other_window_handle[closed\]] expected: FAIL - - [test_no_such_element_from_other_frame[open\]] - expected: FAIL - - [test_no_such_element_from_other_frame[closed\]] - expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/get_element_property/get.py.ini b/tests/wpt/meta/webdriver/tests/classic/get_element_property/get.py.ini index 646e2846e18..991123b881c 100644 --- a/tests/wpt/meta/webdriver/tests/classic/get_element_property/get.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/get_element_property/get.py.ini @@ -1,94 +1,12 @@ [get.py] - expected: TIMEOUT - [test_no_top_browsing_context] - expected: FAIL - [test_no_browsing_context] - expected: ERROR - - [test_no_such_element_with_shadow_root] expected: FAIL - [test_no_such_element_from_other_window_handle[open\]] + [test_no_such_element_with_shadow_root] expected: FAIL [test_no_such_element_from_other_window_handle[closed\]] expected: FAIL - [test_no_such_element_from_other_frame[open\]] - expected: FAIL - - [test_no_such_element_from_other_frame[closed\]] - expected: FAIL - - [test_stale_element_reference[top_context\]] - expected: FAIL - - [test_stale_element_reference[child_context\]] - expected: FAIL - - [test_property_non_existent] - expected: FAIL - - [test_content_attribute] - expected: FAIL - - [test_idl_attribute] - expected: FAIL - - [test_primitives["foobar"-foobar\]] - expected: FAIL - - [test_primitives[42-42\]] - expected: FAIL - - [test_primitives[js_primitive2-py_primitive2\]] - expected: FAIL - - [test_primitives[js_primitive3-py_primitive3\]] - expected: FAIL - - [test_primitives[null-None\]] - expected: FAIL - - [test_primitives[undefined-None\]] - expected: FAIL - - [test_collection_dom_token_list] - expected: FAIL - - [test_primitives_set_by_execute_script["foobar"-foobar\]] - expected: FAIL - - [test_primitives_set_by_execute_script[42-42\]] - expected: FAIL - - [test_primitives_set_by_execute_script[js_primitive2-py_primitive2\]] - expected: FAIL - - [test_primitives_set_by_execute_script[js_primitive3-py_primitive3\]] - expected: FAIL - - [test_primitives_set_by_execute_script[null-None\]] - expected: FAIL - - [test_primitives_set_by_execute_script[undefined-None\]] - expected: FAIL - - [test_web_reference[frame-WebFrame\]] - expected: FAIL - [test_web_reference[shadowRoot-ShadowRoot\]] expected: FAIL - - [test_web_reference[window-WebWindow\]] - expected: FAIL - - [test_mutated_element] - expected: FAIL - - [test_anchor_href[relative\]] - expected: FAIL - - [test_anchor_href[absolute\]] - expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/get_element_rect/get.py.ini b/tests/wpt/meta/webdriver/tests/classic/get_element_rect/get.py.ini index 67875a58cd9..10339e7291b 100644 --- a/tests/wpt/meta/webdriver/tests/classic/get_element_rect/get.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/get_element_rect/get.py.ini @@ -8,11 +8,5 @@ [test_no_such_element_from_other_window_handle[closed\]] expected: FAIL - [test_no_such_element_from_other_frame[open\]] - expected: FAIL - - [test_no_such_element_from_other_frame[closed\]] - expected: FAIL - [test_basic] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/get_element_tag_name/get.py.ini b/tests/wpt/meta/webdriver/tests/classic/get_element_tag_name/get.py.ini index 0ac8ff98d59..879854dfc56 100644 --- a/tests/wpt/meta/webdriver/tests/classic/get_element_tag_name/get.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/get_element_tag_name/get.py.ini @@ -8,11 +8,5 @@ [test_no_such_element_from_other_window_handle[closed\]] expected: FAIL - [test_no_such_element_from_other_frame[open\]] - expected: FAIL - - [test_no_such_element_from_other_frame[closed\]] - expected: FAIL - [test_get_element_tag_name] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/get_element_text/get.py.ini b/tests/wpt/meta/webdriver/tests/classic/get_element_text/get.py.ini index ad870f8f49b..66e31b2d5a7 100644 --- a/tests/wpt/meta/webdriver/tests/classic/get_element_text/get.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/get_element_text/get.py.ini @@ -8,12 +8,6 @@ [test_no_such_element_from_other_window_handle[closed\]] expected: FAIL - [test_no_such_element_from_other_frame[open\]] - expected: FAIL - - [test_no_such_element_from_other_frame[closed\]] - expected: FAIL - [test_transform_capitalize[space\]] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/is_element_enabled/enabled.py.ini b/tests/wpt/meta/webdriver/tests/classic/is_element_enabled/enabled.py.ini index 1f97f812861..9f75dbb4f9e 100644 --- a/tests/wpt/meta/webdriver/tests/classic/is_element_enabled/enabled.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/is_element_enabled/enabled.py.ini @@ -1,2 +1,18 @@ [enabled.py] - expected: TIMEOUT + [test_no_browsing_context] + expected: FAIL + + [test_no_such_element_with_shadow_root] + expected: FAIL + + [test_no_such_element_from_other_window_handle[closed\]] + expected: FAIL + + [test_stale_element_reference[child_context\]] + expected: FAIL + + [test_option_with_select[disabled\]] + expected: FAIL + + [test_optgroup_with_select[disabled\]] + expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/is_element_selected/selected.py.ini b/tests/wpt/meta/webdriver/tests/classic/is_element_selected/selected.py.ini index eb4c0299197..2c5777abee2 100644 --- a/tests/wpt/meta/webdriver/tests/classic/is_element_selected/selected.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/is_element_selected/selected.py.ini @@ -8,8 +8,5 @@ [test_no_such_element_from_other_window_handle[closed\]] expected: FAIL - [test_no_such_element_from_other_frame[open\]] - expected: FAIL - - [test_no_such_element_from_other_frame[closed\]] + [test_stale_element_reference[child_context\]] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/new_session/unhandled_prompt_behavior.py.ini b/tests/wpt/meta/webdriver/tests/classic/new_session/unhandled_prompt_behavior.py.ini index ff2e1c72126..7ea404e4f6a 100644 --- a/tests/wpt/meta/webdriver/tests/classic/new_session/unhandled_prompt_behavior.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/new_session/unhandled_prompt_behavior.py.ini @@ -1,4 +1,5 @@ [unhandled_prompt_behavior.py] + expected: TIMEOUT [test_unhandled_prompt_behavior_as_object_default[handler0-expected_capability0-True-True\]] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/key.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/key.py.ini index 0a9efbca289..42ceab66336 100644 --- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/key.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/perform_actions/key.py.ini @@ -9,16 +9,19 @@ expected: FAIL [test_backspace_erases_keys] - expected: FAIL + expected: ERROR [test_element_in_shadow_tree[outer-open\]] - expected: FAIL + expected: ERROR [test_element_in_shadow_tree[outer-closed\]] - expected: FAIL + expected: ERROR [test_element_in_shadow_tree[inner-open\]] - expected: FAIL + expected: ERROR [test_element_in_shadow_tree[inner-closed\]] - expected: FAIL + expected: ERROR + + [test_element_not_focused] + expected: ERROR diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_events.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_events.py.ini index 6dabfbb793f..ab545d924ac 100644 --- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_events.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_events.py.ini @@ -1,273 +1,12 @@ [key_events.py] - [test_modifier_key_sends_correct_events[\\ue00a-ALT\]] - expected: FAIL - - [test_modifier_key_sends_correct_events[\\ue009-CONTROL\]] - expected: FAIL - - [test_modifier_key_sends_correct_events[\\ue03d-META\]] - expected: FAIL - [test_modifier_key_sends_correct_events[\\ue008-SHIFT\]] expected: FAIL - [test_modifier_key_sends_correct_events[\\ue052-R_ALT\]] - expected: FAIL - - [test_modifier_key_sends_correct_events[\\ue051-R_CONTROL\]] - expected: FAIL - - [test_modifier_key_sends_correct_events[\\ue053-R_META\]] - expected: FAIL - - [test_modifier_key_sends_correct_events[\\ue050-R_SHIFT\]] - expected: FAIL - [test_non_printable_key_sends_events[\\ue00c-ESCAPE\]] expected: FAIL - [test_non_printable_key_sends_events[\\ue014-RIGHT\]] - expected: FAIL - - [test_printable_key_sends_correct_events[a-KeyA0\]] - expected: FAIL - - [test_printable_key_sends_correct_events[a-KeyA1\]] - expected: FAIL - - [test_printable_key_sends_correct_events["-Quote\]] - expected: FAIL - - [test_printable_key_sends_correct_events[,-Comma\]] - expected: FAIL - - [test_printable_key_sends_correct_events[\\xe0-\]] - expected: FAIL - - [test_printable_key_sends_correct_events[\\u0416-\]] - expected: FAIL - - [test_printable_key_sends_correct_events[@-Digit2\]] - expected: FAIL - - [test_printable_key_sends_correct_events[\\u2603-\]] - expected: FAIL - - [test_printable_key_sends_correct_events[\\uf6c2-\]] - expected: FAIL - - [test_sequence_of_keydown_printable_keys_sends_events] - expected: FAIL - - [test_sequence_of_keydown_printable_characters_sends_events] - expected: FAIL - - [test_special_key_sends_keydown[ADD-expected0\]] - expected: FAIL - - [test_special_key_sends_keydown[ALT-expected1\]] - expected: FAIL - - [test_special_key_sends_keydown[BACKSPACE-expected2\]] - expected: FAIL - - [test_special_key_sends_keydown[CANCEL-expected3\]] - expected: FAIL - - [test_special_key_sends_keydown[CLEAR-expected4\]] - expected: FAIL - - [test_special_key_sends_keydown[CONTROL-expected5\]] - expected: FAIL - - [test_special_key_sends_keydown[DECIMAL-expected6\]] - expected: FAIL - - [test_special_key_sends_keydown[DELETE-expected7\]] - expected: FAIL - - [test_special_key_sends_keydown[DIVIDE-expected8\]] - expected: FAIL - - [test_special_key_sends_keydown[DOWN-expected9\]] - expected: FAIL - - [test_special_key_sends_keydown[END-expected10\]] - expected: FAIL - - [test_special_key_sends_keydown[ENTER-expected11\]] - expected: FAIL - [test_special_key_sends_keydown[EQUALS-expected12\]] expected: FAIL - [test_special_key_sends_keydown[ESCAPE-expected13\]] - expected: FAIL - - [test_special_key_sends_keydown[F1-expected14\]] - expected: FAIL - - [test_special_key_sends_keydown[F10-expected15\]] - expected: FAIL - - [test_special_key_sends_keydown[F11-expected16\]] - expected: FAIL - - [test_special_key_sends_keydown[F12-expected17\]] - expected: FAIL - - [test_special_key_sends_keydown[F2-expected18\]] - expected: FAIL - - [test_special_key_sends_keydown[F3-expected19\]] - expected: FAIL - - [test_special_key_sends_keydown[F4-expected20\]] - expected: FAIL - - [test_special_key_sends_keydown[F5-expected21\]] - expected: FAIL - - [test_special_key_sends_keydown[F6-expected22\]] - expected: FAIL - - [test_special_key_sends_keydown[F7-expected23\]] - expected: FAIL - - [test_special_key_sends_keydown[F8-expected24\]] - expected: FAIL - - [test_special_key_sends_keydown[F9-expected25\]] - expected: FAIL - - [test_special_key_sends_keydown[HELP-expected26\]] - expected: FAIL - - [test_special_key_sends_keydown[HOME-expected27\]] - expected: FAIL - - [test_special_key_sends_keydown[INSERT-expected28\]] - expected: FAIL - - [test_special_key_sends_keydown[LEFT-expected29\]] - expected: FAIL - - [test_special_key_sends_keydown[META-expected30\]] - expected: FAIL - - [test_special_key_sends_keydown[MULTIPLY-expected31\]] - expected: FAIL - - [test_special_key_sends_keydown[NULL-expected32\]] - expected: FAIL - - [test_special_key_sends_keydown[NUMPAD0-expected33\]] - expected: FAIL - - [test_special_key_sends_keydown[NUMPAD1-expected34\]] - expected: FAIL - - [test_special_key_sends_keydown[NUMPAD2-expected35\]] - expected: FAIL - - [test_special_key_sends_keydown[NUMPAD3-expected36\]] - expected: FAIL - - [test_special_key_sends_keydown[NUMPAD4-expected37\]] - expected: FAIL - - [test_special_key_sends_keydown[NUMPAD5-expected38\]] - expected: FAIL - - [test_special_key_sends_keydown[NUMPAD6-expected39\]] - expected: FAIL - - [test_special_key_sends_keydown[NUMPAD7-expected40\]] - expected: FAIL - - [test_special_key_sends_keydown[NUMPAD8-expected41\]] - expected: FAIL - - [test_special_key_sends_keydown[NUMPAD9-expected42\]] - expected: FAIL - - [test_special_key_sends_keydown[PAGE_DOWN-expected43\]] - expected: FAIL - - [test_special_key_sends_keydown[PAGE_UP-expected44\]] - expected: FAIL - [test_special_key_sends_keydown[PAUSE-expected45\]] expected: FAIL - - [test_special_key_sends_keydown[RETURN-expected46\]] - expected: FAIL - - [test_special_key_sends_keydown[RIGHT-expected47\]] - expected: FAIL - - [test_special_key_sends_keydown[R_ALT-expected48\]] - expected: FAIL - - [test_special_key_sends_keydown[R_ARROWDOWN-expected49\]] - expected: FAIL - - [test_special_key_sends_keydown[R_ARROWLEFT-expected50\]] - expected: FAIL - - [test_special_key_sends_keydown[R_ARROWRIGHT-expected51\]] - expected: FAIL - - [test_special_key_sends_keydown[R_ARROWUP-expected52\]] - expected: FAIL - - [test_special_key_sends_keydown[R_CONTROL-expected53\]] - expected: FAIL - - [test_special_key_sends_keydown[R_DELETE-expected54\]] - expected: FAIL - - [test_special_key_sends_keydown[R_END-expected55\]] - expected: FAIL - - [test_special_key_sends_keydown[R_HOME-expected56\]] - expected: FAIL - - [test_special_key_sends_keydown[R_INSERT-expected57\]] - expected: FAIL - - [test_special_key_sends_keydown[R_META-expected58\]] - expected: FAIL - - [test_special_key_sends_keydown[R_PAGEDOWN-expected59\]] - expected: FAIL - - [test_special_key_sends_keydown[R_PAGEUP-expected60\]] - expected: FAIL - - [test_special_key_sends_keydown[R_SHIFT-expected61\]] - expected: FAIL - - [test_special_key_sends_keydown[SEMICOLON-expected62\]] - expected: FAIL - - [test_special_key_sends_keydown[SEPARATOR-expected63\]] - expected: FAIL - - [test_special_key_sends_keydown[SHIFT-expected64\]] - expected: FAIL - - [test_special_key_sends_keydown[SPACE-expected65\]] - expected: FAIL - - [test_special_key_sends_keydown[SUBTRACT-expected66\]] - expected: FAIL - - [test_special_key_sends_keydown[TAB-expected67\]] - expected: FAIL - - [test_special_key_sends_keydown[UP-expected68\]] - expected: FAIL - - [test_special_key_sends_keydown[ZENKAKUHANKAKU-expected69\]] - expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_modifiers.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_modifiers.py.ini index 70b4b687388..118e70b33a8 100644 --- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_modifiers.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_modifiers.py.ini @@ -1,10 +1,4 @@ [key_modifiers.py] - [test_shift_modifier_and_non_printable_keys[\\ue008\]] - expected: FAIL - - [test_shift_modifier_and_non_printable_keys[\\ue050\]] - expected: FAIL - [test_shift_modifier_generates_capital_letters[\\ue008\]] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_shortcuts.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_shortcuts.py.ini index 43e9ac6cf32..8a5f8770474 100644 --- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_shortcuts.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_shortcuts.py.ini @@ -1,3 +1,6 @@ [key_shortcuts.py] [test_mod_a_mod_c_right_mod_v_pastes_text] expected: FAIL + + [test_mod_a_mod_x_deletes_all_text] + expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_special_keys.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_special_keys.py.ini index 9f97050ec49..5e1b1b41869 100644 --- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_special_keys.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_special_keys.py.ini @@ -1,7 +1,4 @@ [key_special_keys.py] - [test_codepoint_keys_behave_correctly[\\U0001f604\]] - expected: FAIL - [test_codepoint_keys_behave_correctly[\\U0001f60d\]] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/navigation.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/navigation.py.ini index 38af76d3cf4..b7b8bf52a22 100644 --- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/navigation.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/perform_actions/navigation.py.ini @@ -1,4 +1,5 @@ [navigation.py] + expected: TIMEOUT [test_key] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_contextmenu.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_contextmenu.py.ini index e0fb2381634..62af3a877f5 100644 --- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_contextmenu.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_contextmenu.py.ini @@ -1,9 +1,9 @@ [pointer_contextmenu.py] [test_control_click[\\ue009-ctrlKey\]] - expected: ERROR + expected: FAIL [test_control_click[\\ue051-ctrlKey\]] - expected: ERROR + expected: FAIL [test_release_control_click] - expected: ERROR + expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_dblclick.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_dblclick.py.ini deleted file mode 100644 index 523d8d29edb..00000000000 --- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_dblclick.py.ini +++ /dev/null @@ -1,9 +0,0 @@ -[pointer_dblclick.py] - [test_dblclick_at_coordinates[0\]] - expected: FAIL - - [test_dblclick_at_coordinates[200\]] - expected: FAIL - - [test_no_dblclick_when_mouse_moves] - expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_modifier_click.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_modifier_click.py.ini index ebb9ef4dcc0..af13d756701 100644 --- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_modifier_click.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_modifier_click.py.ini @@ -1,21 +1,21 @@ [pointer_modifier_click.py] [test_modifier_click[\\ue00a-altKey\]] - expected: ERROR + expected: FAIL [test_modifier_click[\\ue052-altKey\]] - expected: ERROR + expected: FAIL [test_modifier_click[\\ue03d-metaKey\]] - expected: ERROR + expected: FAIL [test_modifier_click[\\ue053-metaKey\]] - expected: ERROR + expected: FAIL [test_modifier_click[\\ue008-shiftKey\]] - expected: ERROR + expected: FAIL [test_modifier_click[\\ue050-shiftKey\]] - expected: ERROR + expected: FAIL [test_many_modifiers_click] - expected: ERROR + expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_mouse.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_mouse.py.ini index 4222966b349..d4ef4398b7f 100644 --- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_mouse.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_mouse.py.ini @@ -1,4 +1,5 @@ [pointer_mouse.py] + expected: TIMEOUT [test_no_top_browsing_context] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_pen.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_pen.py.ini index 5c08076b7b2..d7922cb4283 100644 --- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_pen.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_pen.py.ini @@ -1,4 +1,5 @@ [pointer_pen.py] + expected: TIMEOUT [test_no_top_browsing_context] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_touch.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_touch.py.ini index 2dd2ee19891..85e34998125 100644 --- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_touch.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_touch.py.ini @@ -1,4 +1,5 @@ [pointer_touch.py] + expected: TIMEOUT [test_no_top_browsing_context] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/release_actions/sequence_tentative.py.ini b/tests/wpt/meta/webdriver/tests/classic/release_actions/sequence_tentative.py.ini index aed5f673813..9c048ff9b5f 100644 --- a/tests/wpt/meta/webdriver/tests/classic/release_actions/sequence_tentative.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/release_actions/sequence_tentative.py.ini @@ -1,4 +1,5 @@ [sequence_tentative.py] + expected: TIMEOUT [test_release_mouse_sequence_resets_dblclick_state[with release actions\]] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/set_window_rect/set.py.ini b/tests/wpt/meta/webdriver/tests/classic/set_window_rect/set.py.ini index 6b28c2efdf8..d530b687213 100644 --- a/tests/wpt/meta/webdriver/tests/classic/set_window_rect/set.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/set_window_rect/set.py.ini @@ -15,7 +15,7 @@ expected: FAIL [test_set_to_available_size] - expected: ERROR + expected: FAIL [test_set_smaller_than_minimum_browser_size] expected: FAIL @@ -30,10 +30,22 @@ expected: FAIL [test_negative_x_y] - expected: ERROR + expected: FAIL [test_set_to_screen_size] - expected: ERROR + expected: FAIL [test_set_larger_than_screen_size] - expected: ERROR + expected: FAIL + + [test_width_height_floats] + expected: FAIL + + [test_height_width_as_current] + expected: FAIL + + [test_height_as_current] + expected: FAIL + + [test_width_as_current] + expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/switch_to_frame/switch.py.ini b/tests/wpt/meta/webdriver/tests/classic/switch_to_frame/switch.py.ini index ee73fbf4ce8..66625728565 100644 --- a/tests/wpt/meta/webdriver/tests/classic/switch_to_frame/switch.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/switch_to_frame/switch.py.ini @@ -16,6 +16,3 @@ [test_frame_id_shadow_root] expected: FAIL - - [test_frame_id_null] - expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/switch_to_parent_frame/switch.py.ini b/tests/wpt/meta/webdriver/tests/classic/switch_to_parent_frame/switch.py.ini index ffd3d06f212..352421f84c1 100644 --- a/tests/wpt/meta/webdriver/tests/classic/switch_to_parent_frame/switch.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/switch_to_parent_frame/switch.py.ini @@ -1,6 +1,3 @@ [switch.py] - [test_switch_from_iframe] - expected: FAIL - [test_switch_from_top_level] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/switch_to_window/alerts.py.ini b/tests/wpt/meta/webdriver/tests/classic/switch_to_window/alerts.py.ini index 3e6ad0c8af9..aa34b0b2489 100644 --- a/tests/wpt/meta/webdriver/tests/classic/switch_to_window/alerts.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/switch_to_window/alerts.py.ini @@ -1,3 +1,4 @@ [alerts.py] + expected: TIMEOUT [test_retain_tab_modal_status] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/switch_to_window/switch.py.ini b/tests/wpt/meta/webdriver/tests/classic/switch_to_window/switch.py.ini index 9b0ec38199b..44ac97a7a36 100644 --- a/tests/wpt/meta/webdriver/tests/classic/switch_to_window/switch.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/switch_to_window/switch.py.ini @@ -1,4 +1,5 @@ [switch.py] + expected: TIMEOUT [test_no_top_browsing_context] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/take_element_screenshot/iframe.py.ini b/tests/wpt/meta/webdriver/tests/classic/take_element_screenshot/iframe.py.ini index dd77eca9d72..c6374102e3f 100644 --- a/tests/wpt/meta/webdriver/tests/classic/take_element_screenshot/iframe.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/take_element_screenshot/iframe.py.ini @@ -1,9 +1,3 @@ [iframe.py] [test_frame_element] expected: FAIL - - [test_source_origin[same_origin\]] - expected: FAIL - - [test_source_origin[cross_origin\]] - expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/take_screenshot/iframe.py.ini b/tests/wpt/meta/webdriver/tests/classic/take_screenshot/iframe.py.ini new file mode 100644 index 00000000000..b63f4c9fb07 --- /dev/null +++ b/tests/wpt/meta/webdriver/tests/classic/take_screenshot/iframe.py.ini @@ -0,0 +1,9 @@ +[iframe.py] + [test_always_captures_top_browsing_context] + expected: FAIL + + [test_source_origin[same_origin\]] + expected: FAIL + + [test_source_origin[cross_origin\]] + expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/take_screenshot/screenshot.py.ini b/tests/wpt/meta/webdriver/tests/classic/take_screenshot/screenshot.py.ini index f2fac7a7fa1..aef7c9d5ddc 100644 --- a/tests/wpt/meta/webdriver/tests/classic/take_screenshot/screenshot.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/take_screenshot/screenshot.py.ini @@ -4,3 +4,6 @@ [test_no_browsing_context] expected: FAIL + + [test_format_and_dimensions] + expected: FAIL diff --git a/tests/wpt/meta/websockets/stream/tentative/write.any.js.ini b/tests/wpt/meta/websockets/stream/tentative/write.any.js.ini new file mode 100644 index 00000000000..491b41e2c47 --- /dev/null +++ b/tests/wpt/meta/websockets/stream/tentative/write.any.js.ini @@ -0,0 +1,118 @@ +[write.any.sharedworker.html?wpt_flags=h2] + expected: ERROR + +[write.any.serviceworker.html?default] + expected: ERROR + +[write.any.worker.html?wpt_flags=h2] + [a write that was incomplete at close time should reject] + expected: FAIL + + [garbage collection after close with a pending write promise should not crash] + expected: FAIL + + [writing a value that cannot be stringified should cause a rejection] + expected: FAIL + + [writing a resizable ArrayBuffer should be rejected] + expected: FAIL + + [writing a view on a shared buffer should be rejected] + expected: FAIL + + +[write.any.sharedworker.html?wss] + expected: ERROR + +[write.any.html?default] + [a write that was incomplete at close time should reject] + expected: FAIL + + [garbage collection after close with a pending write promise should not crash] + expected: FAIL + + [writing a value that cannot be stringified should cause a rejection] + expected: FAIL + + [writing a resizable ArrayBuffer should be rejected] + expected: FAIL + + [writing a view on a shared buffer should be rejected] + expected: FAIL + + +[write.any.worker.html?wss] + [a write that was incomplete at close time should reject] + expected: FAIL + + [garbage collection after close with a pending write promise should not crash] + expected: FAIL + + [writing a value that cannot be stringified should cause a rejection] + expected: FAIL + + [writing a resizable ArrayBuffer should be rejected] + expected: FAIL + + [writing a view on a shared buffer should be rejected] + expected: FAIL + + +[write.any.serviceworker.html?wpt_flags=h2] + expected: ERROR + +[write.any.html?wpt_flags=h2] + [a write that was incomplete at close time should reject] + expected: FAIL + + [garbage collection after close with a pending write promise should not crash] + expected: FAIL + + [writing a value that cannot be stringified should cause a rejection] + expected: FAIL + + [writing a resizable ArrayBuffer should be rejected] + expected: FAIL + + [writing a view on a shared buffer should be rejected] + expected: FAIL + + +[write.any.serviceworker.html?wss] + expected: ERROR + +[write.any.sharedworker.html?default] + expected: ERROR + +[write.any.worker.html?default] + [a write that was incomplete at close time should reject] + expected: FAIL + + [garbage collection after close with a pending write promise should not crash] + expected: FAIL + + [writing a value that cannot be stringified should cause a rejection] + expected: FAIL + + [writing a resizable ArrayBuffer should be rejected] + expected: FAIL + + [writing a view on a shared buffer should be rejected] + expected: FAIL + + +[write.any.html?wss] + [a write that was incomplete at close time should reject] + expected: FAIL + + [garbage collection after close with a pending write promise should not crash] + expected: FAIL + + [writing a value that cannot be stringified should cause a rejection] + expected: FAIL + + [writing a resizable ArrayBuffer should be rejected] + expected: FAIL + + [writing a view on a shared buffer should be rejected] + expected: FAIL diff --git a/tests/wpt/meta/workers/constructors/Worker/Worker-constructor.html.ini b/tests/wpt/meta/workers/constructors/Worker/Worker-constructor.html.ini new file mode 100644 index 00000000000..80f9a4f15b8 --- /dev/null +++ b/tests/wpt/meta/workers/constructors/Worker/Worker-constructor.html.ini @@ -0,0 +1,2 @@ +[Worker-constructor.html] + expected: ERROR diff --git a/tests/wpt/meta/workers/tentative/SharedWorker-extendedLifetime.html.ini b/tests/wpt/meta/workers/tentative/SharedWorker-extendedLifetime.html.ini new file mode 100644 index 00000000000..086935d2b6d --- /dev/null +++ b/tests/wpt/meta/workers/tentative/SharedWorker-extendedLifetime.html.ini @@ -0,0 +1,3 @@ +[SharedWorker-extendedLifetime.html] + [SharedWorker lifetime should be extended with extendedLifetime] + expected: FAIL diff --git a/tests/wpt/meta/xhr/abort-during-done.window.js.ini b/tests/wpt/meta/xhr/abort-during-done.window.js.ini deleted file mode 100644 index cfce26bf75b..00000000000 --- a/tests/wpt/meta/xhr/abort-during-done.window.js.ini +++ /dev/null @@ -1,9 +0,0 @@ -[abort-during-done.window.html] - [XMLHttpRequest: abort() during DONE (sync)] - expected: FAIL - - [XMLHttpRequest: abort() during DONE (sync aborted in readystatechange)] - expected: FAIL - - [XMLHttpRequest: abort() during DONE (async)] - expected: FAIL diff --git a/tests/wpt/meta/xhr/abort-during-headers-received.window.js.ini b/tests/wpt/meta/xhr/abort-during-headers-received.window.js.ini deleted file mode 100644 index aa78b3966cc..00000000000 --- a/tests/wpt/meta/xhr/abort-during-headers-received.window.js.ini +++ /dev/null @@ -1,3 +0,0 @@ -[abort-during-headers-received.window.html] - [XMLHttpRequest: abort() during HEADERS_RECEIVED] - expected: FAIL diff --git a/tests/wpt/meta/xhr/abort-during-loading.window.js.ini b/tests/wpt/meta/xhr/abort-during-loading.window.js.ini deleted file mode 100644 index 33a6772164b..00000000000 --- a/tests/wpt/meta/xhr/abort-during-loading.window.js.ini +++ /dev/null @@ -1,3 +0,0 @@ -[abort-during-loading.window.html] - [XMLHttpRequest: abort() during LOADING] - expected: FAIL diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index bf19c365d17..cce286bb674 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -12850,6 +12850,13 @@ ] ] }, + "canvas-oversize-serialization.html": [ + "3330ee2b8c4e33a18a3e17151fd7c398c9a5d024", + [ + null, + {} + ] + ], "canvas.initial.reset.2dstate.html": [ "e276ed09ffcf16eff16b784c622b93665c4109ee", [ diff --git a/tests/wpt/mozilla/tests/mozilla/canvas-oversize-serialization.html b/tests/wpt/mozilla/tests/mozilla/canvas-oversize-serialization.html new file mode 100644 index 00000000000..3330ee2b8c4 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/canvas-oversize-serialization.html @@ -0,0 +1,31 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Serializing a large canvas does not panic</title> + <link rel=help href="https://html.spec.whatwg.org/multipage/#dom-canvas-todataurl"> + <link rel=help href="https://html.spec.whatwg.org/multipage/#dom-canvas-toblob"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> + +<body> +<!-- This is not a standard WPT tests, because canvas size limits are specific + to browsers. For us, failure to serialize depends on both canvas size limits + and also whether or not the image library we use (image-rs) produces an error + when we attempt serialization. --> +<canvas id="canvas" width="2000000"></canvas> + +<script> + test(function() { + assert_equals(canvas.toDataURL("image/webp", 0.5), 'data:,'); + }, "Calling toDataURL on an oversized canvas results in an empty URL."); + + async_test(function(t) { + canvas.toBlob((blob) => { + assert_equals(blob, null); + t.done(); + }, "image/webp", 0.5); + }, "Calling toBlob() on an oversized canvas results in a null blob"); +</script> +</body> +</html> diff --git a/tests/wpt/tests/client-hints/permissions-policy/WEB_FEATURES.yml b/tests/wpt/tests/client-hints/permissions-policy/WEB_FEATURES.yml new file mode 100644 index 00000000000..da7599308cc --- /dev/null +++ b/tests/wpt/tests/client-hints/permissions-policy/WEB_FEATURES.yml @@ -0,0 +1,6 @@ +features: +- name: ua-client-hints + # Note: if any permissions-policy tests are added that do not + # depend on ua-client-hints, `files` below should be updated + # accordingly. + files: "**" diff --git a/tests/wpt/tests/container-timing/resources/container-timing-helpers.js b/tests/wpt/tests/container-timing/resources/container-timing-helpers.js index a80ad964fef..8b3f21dff56 100644 --- a/tests/wpt/tests/container-timing/resources/container-timing-helpers.js +++ b/tests/wpt/tests/container-timing/resources/container-timing-helpers.js @@ -20,3 +20,19 @@ function checkContainerEntry(entry, identifier, last_element_id, beforeRender) { function checkContainerSize(entry, size) { assert_equals(entry.size, size); } + +function finishOnElementTiming(t) { + const finish_observer = new PerformanceObserver(() => { + requestAnimationFrame(() => { t.done(); }); + }); + finish_observer.observe({ entryTypes: ['element'] }); +} + +function addPaintingElementTimingAfterDoubleRAF(parent) { + requestAnimationFrame(() => requestAnimationFrame(() => { + const finish_img = document.createElement('img'); + finish_img.src = '/container-timing/resources/square100.png'; + finish_img.setAttribute('elementtiming', ''); + parent.appendChild(finish_img); + })); +} diff --git a/tests/wpt/tests/container-timing/tentative/containertiming-with-child-ignore-and-child-img.html b/tests/wpt/tests/container-timing/tentative/containertiming-with-child-ignore-and-child-img.html new file mode 100644 index 00000000000..b4fa9754c10 --- /dev/null +++ b/tests/wpt/tests/container-timing/tentative/containertiming-with-child-ignore-and-child-img.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML> +<meta charset=utf-8> +<title>Container Timing: an image inside a containertiming-ignore inside a containertiming root</title> +<body> +<style> +body { + margin: 0; +} +</style> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/container-timing/resources/container-timing-helpers.js"></script> +<script src="/element-timing/resources/element-timing-helpers.js"></script> +<script> + async_test(function (t) { + assert_implements(window.PerformanceContainerTiming, "PerformanceContainerTiming is not implemented"); + const observer = new PerformanceObserver( + function(entryList) { + assert_unreached("No entry is expected with nothing to paint"); + } + ); + observer.observe({entryTypes: ['container']}); + + finishOnElementTiming(t); + + // Add a div that is the container timing root + const div1 = document.createElement('div'); + div1.setAttribute('containertiming', 'div1_ct'); + document.body.appendChild(div1); + + // Intermediate ignore should block paint events + const div2 = document.createElement('div'); + div2.setAttribute('containertiming-ignore', ''); + div1.appendChild(div2) + + // Add image of width equal to 100 and height equal to 100. + const img = document.createElement('img'); + img.src = '/container-timing/resources/square100.png'; + img.setAttribute('id', 'img_id'); + div2.appendChild(img); + + addPaintingElementTimingAfterDoubleRAF(document.body); + }, 'Paint of the image child of container timing with ignore in the middle is not reported.'); +</script> + +</body> diff --git a/tests/wpt/tests/container-timing/tentative/containertiming-with-ignore-and-child-img.html b/tests/wpt/tests/container-timing/tentative/containertiming-with-ignore-and-child-img.html new file mode 100644 index 00000000000..20e9e4a9218 --- /dev/null +++ b/tests/wpt/tests/container-timing/tentative/containertiming-with-ignore-and-child-img.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML> +<meta charset=utf-8> +<title>Container Timing: observe with a node with containertiming and containertiming-ignore, and an image child</title> +<body> +<style> +body { + margin: 0; +} +</style> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/container-timing/resources/container-timing-helpers.js"></script> +<script src="/element-timing/resources/element-timing-helpers.js"></script> +<script> + let beforeRender; + async_test(function (t) { + assert_implements(window.PerformanceContainerTiming, "PerformanceContainerTiming is not implemented"); + const observer = new PerformanceObserver( + t.step_func_done(function(entryList) { + assert_equals(entryList.getEntries().length, 1); + const entry = entryList.getEntries()[0]; + checkContainerEntry(entry, 'div_ct', 'img_id', beforeRender) + checkRect(entry, [0, 100, 0, 100]) + checkContainerSize(entry, 10000); + }) + ); + observer.observe({entryTypes: ['container']}); + + // Add a div that is the container timing root + // and containertiming-ignore, that should be ignored as + // containertiming takes precedence. + const div = document.createElement('div'); + div.setAttribute('containertiming', 'div_ct'); + div.setAttribute('containertiming-ignore', ''); + document.body.appendChild(div); + // Add image of width equal to 100 and height equal to 100. + const img = document.createElement('img'); + img.src = '/container-timing/resources/square100.png'; + img.setAttribute('id', 'img_id'); + div.appendChild(img); + beforeRender = performance.now(); + }, 'Paint of the image child of container timing with ignore is not blocked.'); +</script> + +</body> diff --git a/tests/wpt/tests/container-timing/tentative/ignore-with-containertiming-and-child-img.html b/tests/wpt/tests/container-timing/tentative/ignore-with-containertiming-and-child-img.html new file mode 100644 index 00000000000..841b4441d4d --- /dev/null +++ b/tests/wpt/tests/container-timing/tentative/ignore-with-containertiming-and-child-img.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<meta charset=utf-8> +<title>Container Timing: an image inside a containertiming inside a containertiming-ignore</title> +<body> +<style> +body { + margin: 0; +} +</style> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/container-timing/resources/container-timing-helpers.js"></script> +<script src="/element-timing/resources/element-timing-helpers.js"></script> +<script> + let beforeRender; + async_test(function (t) { + assert_implements(window.PerformanceContainerTiming, "PerformanceContainerTiming is not implemented"); + const observer = new PerformanceObserver( + t.step_func_done(function(entryList) { + assert_equals(entryList.getEntries().length, 1); + const entry = entryList.getEntries()[0]; + checkContainerEntry(entry, 'div2_ct', 'img_id', beforeRender) + checkRect(entry, [0, 100, 0, 100]) + checkContainerSize(entry, 10000); + }) + ); + observer.observe({entryTypes: ['container']}); + + // Add a div that is the container timing root + const div1 = document.createElement('div'); + div1.setAttribute('containertiming-ignore', ''); + document.body.appendChild(div1); + + // Intermediate ignore should block paint events + const div2 = document.createElement('div'); + div2.setAttribute('containertiming', 'div2_ct'); + div1.appendChild(div2) + + // Add image of width equal to 100 and height equal to 100. + const img = document.createElement('img'); + img.src = '/container-timing/resources/square100.png'; + img.setAttribute('id', 'img_id'); + div2.appendChild(img); + + beforeRender = performance.now(); +}, 'An image inside a containertiming, inside a containertiming-ignore is still reported.'); +</script> + +</body> diff --git a/tests/wpt/tests/content-security-policy/default-src/default-src-sri_hash.sub.html b/tests/wpt/tests/content-security-policy/default-src/default-src-sri_hash.sub.html index 87fce5961fd..87389c306a5 100644 --- a/tests/wpt/tests/content-security-policy/default-src/default-src-sri_hash.sub.html +++ b/tests/wpt/tests/content-security-policy/default-src/default-src-sri_hash.sub.html @@ -7,6 +7,9 @@ <script src='/resources/testharnessreport.js' nonce='dummy'></script> <!-- CSP served: default-src {{domains[www]}}:* 'nonce-dummy' 'sha256-wIc3KtqOuTFEu6t17sIBuOswgkV406VJvhSk79Gw6U0=' 'ShA256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c=' 'sha512-rYCVMxWV5nq8IsMo+UZNObWtEiWGok/vDN8BMoEQi41s0znSes6E1Q2aag3Lw3u2J1w2rqH7uF2ws6FpQhfSOA=='; style-src 'unsafe-inline' --> + <!-- The domain here is intentionally served with `www`. In the event that the integrity check fails, + the request should be disallowed by the source list. If we were to use {{domains[]}}, + then we would not be able to observe the difference with regards to the integrity check --> <!-- ShA256 is intentionally mixed case --> </head> @@ -18,6 +21,8 @@ var port = "{{ports[http][0]}}"; if (location.protocol === "https:") port = "{{ports[https][0]}}"; + // Since {{domains[www]}} is allowed by the CSP policy, regardless of the integrity check + // the request would be allowed. var crossorigin_base = location.protocol + "//{{domains[www]}}:" + port; // Test name, src, integrity, expected to run. diff --git a/tests/wpt/tests/content-security-policy/script-src/script-src-sri_hash.sub.html b/tests/wpt/tests/content-security-policy/script-src/script-src-sri_hash.sub.html index 9216e2b0d49..e290911183d 100644 --- a/tests/wpt/tests/content-security-policy/script-src/script-src-sri_hash.sub.html +++ b/tests/wpt/tests/content-security-policy/script-src/script-src-sri_hash.sub.html @@ -7,6 +7,9 @@ <script src='/resources/testharnessreport.js' nonce='dummy'></script> <!-- CSP served: script-src {{domains[www]}}:* 'nonce-dummy' 'sha256-wIc3KtqOuTFEu6t17sIBuOswgkV406VJvhSk79Gw6U0=' 'ShA256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c=' 'sha512-rYCVMxWV5nq8IsMo+UZNObWtEiWGok/vDN8BMoEQi41s0znSes6E1Q2aag3Lw3u2J1w2rqH7uF2ws6FpQhfSOA==' --> + <!-- The domain here is intentionally served with `www`. In the event that the integrity check fails, + the request should be disallowed by the source list. If we were to use {{domains[]}}, + then we would not be able to observe the difference with regards to the integrity check --> <!-- ShA256 is intentionally mixed case --> </head> @@ -18,6 +21,8 @@ var port = "{{ports[http][0]}}"; if (location.protocol === "https:") port = "{{ports[https][0]}}"; + // Since {{domains[www]}} is allowed by the CSP policy, regardless of the integrity check + // the request would be allowed. var crossorigin_base = location.protocol + "//{{domains[www]}}:" + port; // Test name, src, integrity, expected to run. diff --git a/tests/wpt/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html b/tests/wpt/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html index c5e33dc4253..9a8ad7a4ef2 100644 --- a/tests/wpt/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html +++ b/tests/wpt/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html @@ -2,11 +2,12 @@ <html> <head> - <title>Parser-inserted scripts without a correct nonce are not allowed with `strict-dynamic` in the script-src directive.</title> + <title>Parser-inserted scripts without a correct nonce are not allowed with `Strict-Dynamic` in the script-src directive.</title> <script src='/resources/testharness.js' nonce='dummy'></script> <script src='/resources/testharnessreport.js' nonce='dummy'></script> - <!-- CSP served: script-src 'strict-dynamic' 'nonce-dummy' --> + <!-- CSP served: script-src 'Strict-Dynamic' 'nonce-dummy' --> + <!-- Strict-Dynamic is intentionally mixed case --> </head> <body> diff --git a/tests/wpt/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html.headers b/tests/wpt/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html.headers index b7918c93323..9d0b3b93d44 100644 --- a/tests/wpt/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html.headers +++ b/tests/wpt/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html.headers @@ -2,4 +2,4 @@ Expires: Mon, 26 Jul 1997 05:00:00 GMT Cache-Control: no-store, no-cache, must-revalidate Cache-Control: post-check=0, pre-check=0, false Pragma: no-cache -Content-Security-Policy: script-src 'strict-dynamic' 'nonce-dummy' +Content-Security-Policy: script-src 'Strict-Dynamic' 'nonce-dummy' diff --git a/tests/wpt/tests/cookie-store/META.yml b/tests/wpt/tests/cookie-store/META.yml index 68c30024552..4bbc6311bdc 100644 --- a/tests/wpt/tests/cookie-store/META.yml +++ b/tests/wpt/tests/cookie-store/META.yml @@ -1,4 +1,3 @@ spec: https://wicg.github.io/cookie-store/ suggested_reviewers: - - inexorabletash - - ayuishii + - dcthetall diff --git a/tests/wpt/tests/cookie-store/cookieStore_special_names.https.any.js b/tests/wpt/tests/cookie-store/cookieStore_special_names.https.any.js index e2a3df7fe33..1e12674a7f7 100644 --- a/tests/wpt/tests/cookie-store/cookieStore_special_names.https.any.js +++ b/tests/wpt/tests/cookie-store/cookieStore_special_names.https.any.js @@ -3,7 +3,7 @@ 'use strict'; -['__Secure-', '__Host-'].forEach(prefix => { +['__Secure-', '__secure-', '__Host-', '__host-'].forEach(prefix => { promise_test(async testCase => { await cookieStore.set(`${prefix}cookie-name`, `secure-cookie-value`); assert_equals( @@ -32,25 +32,27 @@ }, `cookieStore.delete with ${prefix} name on secure origin`); }); -promise_test(async testCase => { - const currentUrl = new URL(self.location.href); - const currentDomain = currentUrl.hostname; - await promise_rejects_js(testCase, TypeError, - cookieStore.set({ name: '__Host-cookie-name', value: 'cookie-value', - domain: currentDomain })); -}, 'cookieStore.set with __Host- prefix and a domain option'); +['__Host-', '__host-'].forEach(prefix => { + promise_test(async testCase => { + const currentUrl = new URL(self.location.href); + const currentDomain = currentUrl.hostname; + await promise_rejects_js(testCase, TypeError, + cookieStore.set({ name: `${prefix}cookie-name`, value: 'cookie-value', + domain: currentDomain })); + }, `cookieStore.set with ${prefix} prefix and a domain option`); -promise_test(async testCase => { - await cookieStore.set({ name: '__Host-cookie-name', value: 'cookie-value', - path: "/" }); + promise_test(async testCase => { + await cookieStore.set({ name: `${prefix}cookie-name`, value: 'cookie-value', + path: "/" }); - assert_equals( - (await cookieStore.get(`__Host-cookie-name`)).value, "cookie-value"); + assert_equals( + (await cookieStore.get(`${prefix}cookie-name`)).value, "cookie-value"); - await promise_rejects_js(testCase, TypeError, - cookieStore.set( { name: '__Host-cookie-name', value: 'cookie-value', - path: "/path" })); -}, 'cookieStore.set with __Host- prefix a path option'); + await promise_rejects_js(testCase, TypeError, + cookieStore.set( { name: `${prefix}cookie-name`, value: 'cookie-value', + path: "/path" })); + }, `cookieStore.set with ${prefix} prefix a path option`); +}); promise_test(async testCase => { let exceptionThrown = false; diff --git a/tests/wpt/tests/cookie-store/encoding.https.any.js b/tests/wpt/tests/cookie-store/encoding.https.any.js index 941639bdaec..f5d2ca15e71 100644 --- a/tests/wpt/tests/cookie-store/encoding.https.any.js +++ b/tests/wpt/tests/cookie-store/encoding.https.any.js @@ -4,15 +4,21 @@ 'use strict'; -cookie_test(async t => { +promise_test(async t => { await setCookieStringHttp('\uFEFFcookie=value; path=/'); + t.add_cleanup(async () => { + await setCookieStringHttp('\uFEFFcookie=value; path=/; Max-Age=0'); + }); const cookie = await cookieStore.get('\uFEFFcookie'); assert_equals(cookie.name, '\uFEFFcookie'); assert_equals(cookie.value, 'value'); }, 'BOM not stripped from name'); -cookie_test(async t => { +promise_test(async t => { await setCookieStringHttp('cookie=\uFEFFvalue; path=/'); + t.add_cleanup(async () => { + await setCookieStringHttp('cookie=\uFEFFvalue; path=/; Max-Age=0'); + }); const cookie = await cookieStore.get('cookie'); assert_equals(cookie.name, 'cookie'); assert_equals(cookie.value, '\uFEFFvalue'); diff --git a/tests/wpt/tests/cookie-store/httponly_cookies.https.window.js b/tests/wpt/tests/cookie-store/httponly_cookies.https.window.js index 605e94e6744..836f47da3f6 100644 --- a/tests/wpt/tests/cookie-store/httponly_cookies.https.window.js +++ b/tests/wpt/tests/cookie-store/httponly_cookies.https.window.js @@ -2,7 +2,7 @@ 'use strict'; -cookie_test(async t => { +promise_test(async t => { let eventPromise = observeNextCookieChangeEvent(); await setCookieStringHttp('HTTPONLY-cookie=value; path=/; httponly'); assert_equals( @@ -29,6 +29,9 @@ cookie_test(async t => { eventPromise = observeNextCookieChangeEvent(); await setCookieStringHttp( 'HTTPONLY-cookie=DELETED; path=/; max-age=0; httponly'); + t.add_cleanup(async () => { + await setCookieStringHttp(`HTTPONLY-cookie=DELETED; path=/; httponly; Max-Age=0`); + }); assert_equals( await getCookieString(), undefined, @@ -41,6 +44,9 @@ cookie_test(async t => { // HTTPONLY cookie changes should not have been observed; perform // a dummy change to verify that nothing else was queued up. await cookieStore.set('TEST', 'dummy'); + t.add_cleanup(async () => { + await cookieStore.delete('TEST'); + }); await verifyCookieChangeEvent( eventPromise, {changed: [{name: 'TEST', value: 'dummy'}]}, 'HttpOnly cookie deletion was not observed'); @@ -68,8 +74,11 @@ cookie_test(async t => { 'httpOnly is not an option for CookieStore.set()'); }, 'HttpOnly cookies can not be set by CookieStore'); -cookie_test(async t => { +promise_test(async t => { await setCookieStringHttp('HTTPONLY-cookie=value; path=/; httponly'); + t.add_cleanup(async () => { + await setCookieStringHttp(`HTTPONLY-cookie=DELETED; path=/; httponly; Max-Age=0`); + }); assert_equals( await getCookieString(), undefined, diff --git a/tests/wpt/tests/cookie-store/resources/cookie-test-helpers.js b/tests/wpt/tests/cookie-store/resources/cookie-test-helpers.js index 8e23ff2c422..82ca135f88e 100644 --- a/tests/wpt/tests/cookie-store/resources/cookie-test-helpers.js +++ b/tests/wpt/tests/cookie-store/resources/cookie-test-helpers.js @@ -210,10 +210,12 @@ async function cookie_test(func, description) { // Wipe cookies used by tests before and after the test. async function deleteAllCookies() { - await Promise.all((await cookieStore.getAll()).map(async ({name, value}) => { - await cookieStore.delete(name); - await cookieStore.delete({name: name, partitioned: true}); - })); + const cookies = await cookieStore.getAll(); + await Promise.all(cookies.flatMap( + ({name}) => + [cookieStore.delete(name), + cookieStore.delete({name, partitioned: true}), + ])); } return promise_test(async t => { diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-applies-to-016.html b/tests/wpt/tests/css/CSS2/lists/list-style-applies-to-016.html new file mode 100644 index 00000000000..71faf850c98 --- /dev/null +++ b/tests/wpt/tests/css/CSS2/lists/list-style-applies-to-016.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> +<link rel="help" href="https://www.w3.org/TR/CSS21/generate.html#propdef-list-style"> +<link rel="help" href="https://www.w3.org/TR/CSS21/generate.html#list-style"> +<link rel="help" href="https://github.com/servo/servo/issues/37222"> +<link rel="match" href="../../reference/single_square_list_marker.xht"> +<meta name="assert" content="The 'list-style' property applies to a list item which is a sibling of a float."> + +<p>Test passes if there is a single square below.</p> +<div style="margin-left: 1in"> + <div style="float: left"></div> + <div style="display: list-item; list-style: square"></div> +</div> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-applies-to-017.html b/tests/wpt/tests/css/CSS2/lists/list-style-applies-to-017.html new file mode 100644 index 00000000000..b5f06365bbe --- /dev/null +++ b/tests/wpt/tests/css/CSS2/lists/list-style-applies-to-017.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> +<link rel="help" href="https://www.w3.org/TR/CSS21/generate.html#propdef-list-style"> +<link rel="help" href="https://www.w3.org/TR/CSS21/generate.html#list-style"> +<link rel="help" href="https://github.com/servo/servo/issues/37222"> +<link rel="match" href="../../reference/single_square_list_marker.xht"> +<meta name="assert" content="The 'list-style' property applies to a list item which is a sibling of a float."> + +<p>Test passes if there is a single square below.</p> +<div style="float: left; width: 1in; height: 1in"></div> +<div style="display: list-item; list-style: square"></div> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-001.xht b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-001.xht index 2c82821505b..4f533018d84 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-001.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-001.xht @@ -6,6 +6,7 @@ <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-image" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> <meta name="flags" content="image" /> + <link rel="match" href="list-style-image-applies-to-ref-1.html" /> <meta name="assert" content="The 'list-style-image' property applies to elements with 'display' set to 'table-row-group'." /> <style type="text/css"> #test @@ -44,4 +45,4 @@ </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-002.xht b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-002.xht index 7af1787b87d..1d053474239 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-002.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-002.xht @@ -6,6 +6,7 @@ <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-image" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> <meta name="flags" content="image" /> + <link rel="match" href="list-style-image-applies-to-ref-1.html" /> <meta name="assert" content="The 'list-style-image' property applies to elements with 'display' set to 'table-header-group'." /> <style type="text/css"> #test @@ -44,4 +45,4 @@ </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-003.xht b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-003.xht index 1e7e58f4627..6753ebb2c66 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-003.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-003.xht @@ -6,6 +6,7 @@ <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-image" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> <meta name="flags" content="image" /> + <link rel="match" href="list-style-image-applies-to-ref-1.html" /> <meta name="assert" content="The 'list-style-image' property applies to elements with 'display' set to 'table-footer-group'." /> <style type="text/css"> #test @@ -44,4 +45,4 @@ </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-004.xht b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-004.xht index cc859de9a82..750db4a8f67 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-004.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-004.xht @@ -6,6 +6,7 @@ <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-image" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> <meta name="flags" content="image" /> + <link rel="match" href="list-style-image-applies-to-ref-1.html" /> <meta name="assert" content="The 'list-style-image' property applies to elements with 'display' set to 'table-row'." /> <style type="text/css"> #table @@ -38,4 +39,4 @@ </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-005.xht b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-005.xht index 74d1b127923..3becba1c96a 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-005.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-005.xht @@ -6,6 +6,7 @@ <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-image" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> <meta name="flags" content="image" /> + <link rel="match" href="list-style-image-applies-to-ref-2.html" /> <meta name="assert" content="The 'list-style-image' property applies to elements with 'display' set to 'table-column-group'." /> <style type="text/css"> #test @@ -43,4 +44,4 @@ </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-006.xht b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-006.xht index 81ca729695b..6a3f0685cd8 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-006.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-006.xht @@ -6,6 +6,7 @@ <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-image" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> <meta name="flags" content="image" /> + <link rel="match" href="list-style-image-applies-to-ref-2.html" /> <meta name="assert" content="The 'list-style-image' property applies to elements with 'display' set to 'table-column'." /> <style type="text/css"> #test @@ -43,4 +44,4 @@ </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-007.xht b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-007.xht index 63a8d63c782..06e0a225206 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-007.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-007.xht @@ -6,6 +6,7 @@ <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-image" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> <meta name="flags" content="image" /> + <link rel="match" href="list-style-image-applies-to-ref-1.html" /> <meta name="assert" content="The 'list-style-image' property applies to elements with 'display' set to 'table-cell'." /> <style type="text/css"> #table @@ -38,4 +39,4 @@ </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-008.xht b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-008.xht index 6d8bd5638bf..36e26233cc5 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-008.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-008.xht @@ -6,6 +6,7 @@ <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-image" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> <meta name="flags" content="image" /> + <link rel="match" href="list-style-image-applies-to-ref-1.html" /> <meta name="assert" content="The 'list-style-image' property applies to elements with 'display' set to 'inline'." /> <style type="text/css"> div @@ -26,4 +27,4 @@ <span></span> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-009.xht b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-009.xht index cc2270bc9f0..26df20ea56f 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-009.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-009.xht @@ -6,6 +6,7 @@ <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-image" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> <meta name="flags" content="image" /> + <link rel="match" href="list-style-image-applies-to-ref-1.html" /> <meta name="assert" content="The 'list-style-image' property applies to elements with 'display' set to 'block'." /> <style type="text/css"> span @@ -28,4 +29,4 @@ </span> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-010.xht b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-010.xht index 78a81194285..f8f0021ace6 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-010.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-010.xht @@ -6,6 +6,7 @@ <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-image" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> <meta name="flags" content="image" /> + <link rel="match" href="list-style-image-applies-to-ref-1.html" /> <meta name="assert" content="The 'list-style-image' property applies to elements with 'display' set to 'list-item'." /> <style type="text/css"> div @@ -20,4 +21,4 @@ <p>Test passes if there is a single blue square below.</p> <div></div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-012.xht b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-012.xht index b81db5533c7..9060209849a 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-012.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-012.xht @@ -6,6 +6,7 @@ <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-image" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> <meta name="flags" content="image" /> + <link rel="match" href="list-style-image-applies-to-ref-1.html" /> <meta name="assert" content="The 'list-style-image' property applies to elements with 'display' set to 'inline-block'." /> <style type="text/css"> div @@ -26,4 +27,4 @@ <span></span> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-013.xht b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-013.xht index 8a8c3e3da81..72c20d870c5 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-013.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-013.xht @@ -6,6 +6,7 @@ <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-image" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> <meta name="flags" content="image" /> + <link rel="match" href="list-style-image-applies-to-ref-1.html" /> <meta name="assert" content="The 'list-style-image' property applies to elements with 'display' set to 'table'." /> <style type="text/css"> #table @@ -38,4 +39,4 @@ </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-014.xht b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-014.xht index 01347df407e..b0b5aa462b7 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-014.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-014.xht @@ -6,6 +6,7 @@ <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-image" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> <meta name="flags" content="image" /> + <link rel="match" href="list-style-image-applies-to-ref-1.html" /> <meta name="assert" content="The 'list-style-image' property applies to elements with 'display' set to 'inline-table'." /> <style type="text/css"> #table @@ -38,4 +39,4 @@ </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-015.xht b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-015.xht index 7eedb682640..c18eb3dab46 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-015.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-015.xht @@ -6,6 +6,7 @@ <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-image" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> <meta name="flags" content="image" /> + <link rel="match" href="list-style-image-applies-to-ref-1.html" /> <meta name="assert" content="The 'list-style-image' property applies to elements with 'display' set to 'table-caption'." /> <style type="text/css"> #test @@ -43,4 +44,4 @@ </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-016.html b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-016.html new file mode 100644 index 00000000000..e79700053dc --- /dev/null +++ b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-016.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> +<link rel="help" href="https://www.w3.org/TR/CSS2/generate.html#propdef-list-style-image"> +<link rel="help" href="https://www.w3.org/TR/CSS21/generate.html#list-style"> +<link rel="help" href="https://github.com/servo/servo/issues/37222"> +<link rel="match" href="list-style-image-applies-to-ref-1.html"> +<meta name="assert" content="The 'list-style-image' property applies to a list item which is a sibling of a float."> + +<p>Test passes if there is a single blue square below.</p> +<div style="margin-left: 1in"> + <div style="float: left"></div> + <div style="display: list-item; list-style-image: url('support/blue15x15.png')"></div> +</div> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-017.html b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-017.html new file mode 100644 index 00000000000..bb20b720d32 --- /dev/null +++ b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-017.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> +<link rel="help" href="https://www.w3.org/TR/CSS2/generate.html#propdef-list-style-image"> +<link rel="help" href="https://www.w3.org/TR/CSS21/generate.html#list-style"> +<link rel="help" href="https://github.com/servo/servo/issues/37222"> +<link rel="match" href="list-style-image-applies-to-ref-1.html"> +<meta name="assert" content="The 'list-style-image' property applies to a list item which is a sibling of a float."> + +<p>Test passes if there is a single blue square below.</p> +<div style="float: left; width: 1in; height: 1in"></div> +<div style="display: list-item; list-style-image: url('support/blue15x15.png')"></div> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-ref-1.html b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-ref-1.html new file mode 100644 index 00000000000..3895bcc9197 --- /dev/null +++ b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-ref-1.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<title>CSS Reference</title> +<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> +<style> +div { + display: list-item; + list-style-image: url('support/blue15x15.png'); + margin-left: 96px; +} +</style> + +<p>Test passes if there is a single blue square below.</p> +<div> </div> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-ref-2.html b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-ref-2.html new file mode 100644 index 00000000000..6d7a9d5b35e --- /dev/null +++ b/tests/wpt/tests/css/CSS2/lists/list-style-image-applies-to-ref-2.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<title>CSS Reference</title> +<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> +<style> +div { + display: list-item; + margin-left: 96px; +} +</style> + +<p>Test passes if there is a single round dot below.</p> +<div> </div> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-001.xht b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-001.xht index 9889dd76956..aa5bd87601f 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-001.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-001.xht @@ -5,6 +5,7 @@ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-position" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> + <link rel="match" href="list-style-position-applies-to-ref-1.html" /> <meta name="assert" content="The 'list-style-position' property applies to elements with 'display' set to 'table-row-group'." /> <style type="text/css"> #test @@ -44,4 +45,4 @@ </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-002.xht b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-002.xht index a8c8a41aa58..51667f2d5e4 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-002.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-002.xht @@ -5,6 +5,7 @@ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-position" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> + <link rel="match" href="list-style-position-applies-to-ref-1.html" /> <meta name="assert" content="The 'list-style-position' property applies to elements with 'display' set to 'table-header-group'." /> <style type="text/css"> #test @@ -44,4 +45,4 @@ </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-003.xht b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-003.xht index d53761ba36c..d7725da936a 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-003.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-003.xht @@ -5,6 +5,7 @@ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-position" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> + <link rel="match" href="list-style-position-applies-to-ref-1.html" /> <meta name="assert" content="The 'list-style-position' property applies to elements with 'display' set to 'table-footer-group'." /> <style type="text/css"> #test @@ -44,4 +45,4 @@ </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-004.xht b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-004.xht index 23d74ebd673..7806141d7f5 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-004.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-004.xht @@ -5,6 +5,7 @@ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-position" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> + <link rel="match" href="list-style-position-applies-to-ref-1.html" /> <meta name="assert" content="The 'list-style-position' property applies to elements with 'display' set to 'table-row'." /> <style type="text/css"> #table @@ -38,4 +39,4 @@ </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-005.xht b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-005.xht index 9ec866bef8a..97235df74ea 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-005.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-005.xht @@ -5,6 +5,7 @@ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-position" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> + <link rel="match" href="list-style-position-applies-to-ref-2.html" /> <meta name="assert" content="The 'list-style-position' property applies to elements with 'display' set to 'table-column-group'." /> <style type="text/css"> #test @@ -43,4 +44,4 @@ </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-006.xht b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-006.xht index d60ed2c7f87..7253af46b8d 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-006.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-006.xht @@ -5,6 +5,7 @@ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-position" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> + <link rel="match" href="list-style-position-applies-to-ref-2.html" /> <meta name="assert" content="The 'list-style-position' property applies to elements with 'display' set to 'table-column'." /> <style type="text/css"> #test @@ -43,4 +44,4 @@ </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-007.xht b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-007.xht index c223dbabd81..956fcb6f3b2 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-007.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-007.xht @@ -5,6 +5,7 @@ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-position" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> + <link rel="match" href="list-style-position-applies-to-ref-1.html" /> <meta name="assert" content="The 'list-style-position' property applies to elements with 'display' set to 'table-cell'." /> <style type="text/css"> #table @@ -38,4 +39,4 @@ </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-008.xht b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-008.xht index 1f2e347de86..df7c23e3867 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-008.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-008.xht @@ -5,6 +5,7 @@ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-position" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> + <link rel="match" href="list-style-position-applies-to-ref-3.html" /> <meta name="assert" content="The 'list-style-position' property applies to elements with 'display' set to 'inline'." /> <style type="text/css"> div @@ -26,4 +27,4 @@ <span></span> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-009.xht b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-009.xht index 90ff3b23562..f981ec2c859 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-009.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-009.xht @@ -5,6 +5,7 @@ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-position" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> + <link rel="match" href="list-style-position-applies-to-ref-3.html" /> <meta name="assert" content="The 'list-style-position' property applies to elements with 'display' set to 'block'." /> <style type="text/css"> span @@ -28,4 +29,4 @@ </span> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-010.xht b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-010.xht index ae5dbfbc362..57881f8d80f 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-010.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-010.xht @@ -5,6 +5,7 @@ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-position" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> + <link rel="match" href="list-style-position-applies-to-ref-3.html" /> <meta name="assert" content="The 'list-style-position' property applies to elements with 'display' set to 'list-item'." /> <style type="text/css"> div @@ -20,4 +21,4 @@ <p>Test passes if there is a black dot inside an orange box below.</p> <div></div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-012.xht b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-012.xht index 25e79b3a594..da9eebf3dcb 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-012.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-012.xht @@ -5,6 +5,7 @@ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-position" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> + <link rel="match" href="list-style-position-applies-to-ref-1.html" /> <meta name="assert" content="The 'list-style-position' property applies to elements with 'display' set to 'inline-block'." /> <style type="text/css"> div @@ -26,4 +27,4 @@ <span></span> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-013.xht b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-013.xht index 5dde30618c9..9237a8d2d74 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-013.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-013.xht @@ -5,6 +5,7 @@ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-position" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> + <link rel="match" href="list-style-position-applies-to-ref-1.html" /> <meta name="assert" content="The 'list-style-position' property applies to elements with 'display' set to 'table'." /> <style type="text/css"> #table @@ -38,4 +39,4 @@ </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-014.xht b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-014.xht index b5502348702..94847350c8f 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-014.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-014.xht @@ -5,6 +5,7 @@ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-position" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> + <link rel="match" href="list-style-position-applies-to-ref-1.html" /> <meta name="assert" content="The 'list-style-position' property applies to elements with 'display' set to 'inline-table'." /> <style type="text/css"> #table @@ -38,4 +39,4 @@ </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-015.xht b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-015.xht index 53eb07dd3b7..49f2f09d09c 100644 --- a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-015.xht +++ b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-015.xht @@ -5,6 +5,7 @@ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-position" /> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#list-style" /> + <link rel="match" href="list-style-position-applies-to-ref-4.html" /> <meta name="assert" content="The 'list-style-position' property applies to elements with 'display' set to 'table-caption'." /> <style type="text/css"> #test @@ -44,4 +45,4 @@ </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-016.html b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-016.html new file mode 100644 index 00000000000..ea5b43d6112 --- /dev/null +++ b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-016.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> +<link rel="help" href="https://www.w3.org/TR/CSS2/generate.html#propdef-list-style-position"> +<link rel="help" href="https://www.w3.org/TR/CSS21/generate.html#list-style"> +<link rel="help" href="https://github.com/servo/servo/issues/37222"> +<link rel="match" href="list-style-position-applies-to-ref-3.html"> +<meta name="assert" content="The 'list-style-position' property applies to a list item which is a sibling of a float."> + +<p>Test passes if there is a black dot inside an orange box below.</p> +<div style="margin-left: 1in"> + <div style="float: left"></div> + <div style="display: list-item; list-style-position: inside; background: orange"></div> +</div> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-017.html b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-017.html new file mode 100644 index 00000000000..71a2a037ed8 --- /dev/null +++ b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-017.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> +<link rel="help" href="https://www.w3.org/TR/CSS2/generate.html#propdef-list-style-position"> +<link rel="help" href="https://www.w3.org/TR/CSS21/generate.html#list-style"> +<link rel="help" href="https://github.com/servo/servo/issues/37222"> +<link rel="match" href="list-style-position-applies-to-ref-5.html"> +<meta name="assert" content="The 'list-style-position' property applies to a list item which is a sibling of a float."> + +<p>Test passes if there is a black dot inside an orange box below.</p> +<div style="float: left; width: 1in; height: 1in"></div> +<div style="display: list-item; list-style-position: inside; background: orange"></div> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-ref-1.html b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-ref-1.html new file mode 100644 index 00000000000..a879e21ba44 --- /dev/null +++ b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-ref-1.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<title>CSS Reference</title> +<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> +<style> +div { + display: inline-block; +} +span { + background: orange; + display: list-item; + list-style-position: inside; + margin-left: 1in; +} +</style> + +<p>Test passes if there is a black dot inside an orange box below.</p> +<div><span></span></div> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-ref-2.html b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-ref-2.html new file mode 100644 index 00000000000..fc0fee30ab6 --- /dev/null +++ b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-ref-2.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<title>CSS Reference</title> +<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> +<style> +div { + display: list-item; + margin-left: 1in; +} +</style> + +<p>Test passes if there is a black dot on a white background below.</p> +<div></div> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-ref-3.html b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-ref-3.html new file mode 100644 index 00000000000..6e1af0004c3 --- /dev/null +++ b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-ref-3.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<title>CSS Reference</title> +<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> +<style> +div { + background: orange; + display: list-item; + list-style-position: inside; + margin-left: 1in; +} +</style> + +<p>Test passes if there is a black dot inside an orange box below.</p> +<div></div> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-ref-4.html b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-ref-4.html new file mode 100644 index 00000000000..bb39e6b44ac --- /dev/null +++ b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-ref-4.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<title>CSS Reference</title> +<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> +<style> +div { + background: orange; + display: list-item; + list-style-position: inside; + margin-left: 1in; + width: 5em; +} +</style> + +<p>Test passes if there is a black dot inside an orange box below.</p> +<div></div> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-ref-5.html b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-ref-5.html new file mode 100644 index 00000000000..05012d42540 --- /dev/null +++ b/tests/wpt/tests/css/CSS2/lists/list-style-position-applies-to-ref-5.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<title>CSS Reference</title> +<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> +<style> +div { + background: orange; + display: list-item; + list-style-position: inside; + padding-left: 1in; +} +</style> + +<p>Test passes if there is a black dot inside an orange box below.</p> +<div></div> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-type-applies-to-016.html b/tests/wpt/tests/css/CSS2/lists/list-style-type-applies-to-016.html new file mode 100644 index 00000000000..407f426d48a --- /dev/null +++ b/tests/wpt/tests/css/CSS2/lists/list-style-type-applies-to-016.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> +<link rel="help" href="https://www.w3.org/TR/CSS21/generate.html#propdef-list-style-type"> +<link rel="help" href="https://www.w3.org/TR/CSS21/generate.html#list-style"> +<link rel="help" href="https://github.com/servo/servo/issues/37222"> +<link rel="match" href="../../reference/single_square_list_marker.xht"> +<meta name="assert" content="The 'list-style-type' property applies to a list item which is a sibling of a float."> + +<p>Test passes if there is a single square below.</p> +<div style="margin-left: 1in"> + <div style="float: left"></div> + <div style="display: list-item; list-style-type: square"></div> +</div> diff --git a/tests/wpt/tests/css/CSS2/lists/list-style-type-applies-to-017.html b/tests/wpt/tests/css/CSS2/lists/list-style-type-applies-to-017.html new file mode 100644 index 00000000000..29e450bcbc4 --- /dev/null +++ b/tests/wpt/tests/css/CSS2/lists/list-style-type-applies-to-017.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> +<link rel="help" href="https://www.w3.org/TR/CSS21/generate.html#propdef-list-style-type"> +<link rel="help" href="https://www.w3.org/TR/CSS21/generate.html#list-style"> +<link rel="help" href="https://github.com/servo/servo/issues/37222"> +<link rel="match" href="../../reference/single_square_list_marker.xht"> +<meta name="assert" content="The 'list-style-type' property applies to a list item which is a sibling of a float."> + +<p>Test passes if there is a single square below.</p> +<div style="float: left; width: 1in; height: 1in"></div> +<div style="display: list-item; list-style-type: square"></div> diff --git a/tests/wpt/tests/css/css-anchor-position/anchor-scope-basic.html b/tests/wpt/tests/css/css-anchor-position/anchor-scope-basic.html index 47cb3b8d86a..ffe3b45ba0d 100644 --- a/tests/wpt/tests/css/css-anchor-position/anchor-scope-basic.html +++ b/tests/wpt/tests/css/css-anchor-position/anchor-scope-basic.html @@ -11,7 +11,8 @@ .anchor-a { anchor-name: --a; } .anchor-b { anchor-name: --b; } - .anchor-a, .anchor-b { + .anchor-ab { anchor-name: --a, --b; } + .anchor-a, .anchor-b, .anchor-ab { background: skyblue; height: 10px; } @@ -159,7 +160,8 @@ <div class=anchor-b></div> <div class=anchor-a></div><!--A--> <div class=scope-a> - <div class=anchor-b></div><!--B--> + <div class=anchor-b></div> + <div class=anchor-ab></div><!--B--> <div class=anchor-a></div> </div> <div class=anchored-a></div> @@ -169,7 +171,7 @@ test((t) => { inflate(t, test_scope_a); assert_equals(getComputedStyle(main.querySelector('.anchored-a')).top, '20px'); - assert_equals(getComputedStyle(main.querySelector('.anchored-b')).top, '30px'); + assert_equals(getComputedStyle(main.querySelector('.anchored-b')).top, '40px'); }, 'anchor-scope:--a scopes only --a'); </script> @@ -177,8 +179,8 @@ <div class=anchor-b></div><!--B--> <div class=anchor-a></div> <div class=scope-b> - <div class=anchor-b></div> <div class=anchor-a></div><!--A--> + <div class=anchor-b></div> </div> <div class=anchored-a></div> <div class=anchored-b></div> @@ -186,7 +188,7 @@ <script> test((t) => { inflate(t, test_scope_b); - assert_equals(getComputedStyle(main.querySelector('.anchored-a')).top, '40px'); + assert_equals(getComputedStyle(main.querySelector('.anchored-a')).top, '30px'); assert_equals(getComputedStyle(main.querySelector('.anchored-b')).top, '10px'); }, 'anchor-scope:--b scopes only --b'); </script> diff --git a/tests/wpt/tests/css/css-anchor-position/chrome-420329041-crash.html b/tests/wpt/tests/css/css-anchor-position/chrome-420329041-crash.html new file mode 100644 index 00000000000..2b236a371e5 --- /dev/null +++ b/tests/wpt/tests/css/css-anchor-position/chrome-420329041-crash.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<link rel="help" href="https://crbug.com/420329041"> +<style> + #crash { + position: absolute; + left: anchor(right); + --svg: url("data:image/svg+xml,"); + content: var(--svg); + fill: var(--svg); + } +</style> +<p>Pass if no crash</p> +<div id="crash"></div> diff --git a/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-img-ref.html b/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-img-ref.html new file mode 100644 index 00000000000..565698f79ec --- /dev/null +++ b/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-img-ref.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<style> + .target { + width: 100px; + height: 100px; + border-radius: 25px; + box-sizing: border-box; + background-image: url("/images/green.png"); + corner-shape: notch superellipse(3) bevel scoop; + } +</style> +<div class=target></div> diff --git a/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-img.html b/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-img.html new file mode 100644 index 00000000000..82662d25562 --- /dev/null +++ b/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-img.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<link rel="match" href="corner-shape-img-ref.html"> +<meta name="fuzzy" content="maxDifference=0-64;totalPixels=0-100"> +<style> + img { + width: 100px; + height: 100px; + border-radius: 25px; + box-sizing: border-box; + corner-shape: notch superellipse(3) bevel scoop; + } +</style> +<img src="/images/green.png">
\ No newline at end of file diff --git a/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html b/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html index 12cd2546bf4..2d4b56f831b 100644 --- a/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html +++ b/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html @@ -17,7 +17,7 @@ <meta name="variant" content="?corner-top-left-shape=superellipse(-4)&border-radius=40%"> <meta name="variant" content="?corner-top-left-shape=superellipse(2.5)&border-radius=20%&border-width=10px"> <meta name="variant" content="?corner-top-right-shape=scoop&border-radius=20%&border-width=10px"> -<meta name="variant" content="?corner-shape=superellipse(0.8)&border-radius=40px&border-width=10px&border-left-color=purple"> +<meta name="variant" content="?corner-shape=superellipse(0.8)&border-radius=40px&border-width=10px"> <meta name="variant" content="?corner-shape=superellipse(3)&border-radius=40px&box-shadow=10px 10px 0 10px black"> <meta name="variant" content="?border-radius=30%&corner-shape=superellipse(-1.5)&box-shadow=10px%2010px%200%2010px%20black"> <meta name="variant" content="?border-radius=40%&corner-shape=notch&box-shadow=10px%2010px%200%2010px%20yellow"> diff --git a/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-render-precise.html b/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-render-precise.html index 5293589222a..4a0c575b3b7 100644 --- a/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-render-precise.html +++ b/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-render-precise.html @@ -19,13 +19,14 @@ <meta name="variant" content="?corner-top-left-shape=superellipse(-0.5)&border-radius=40px"> <meta name="variant" content="?corner-shape=squircle&border-top-left-radius=25%&border-width=10px"> <meta name="variant" content="?corner-bottom-left-shape=bevel&border-bottom-left-radius=30px"> -<meta name="variant" content="?corner-top-left-shape=bevel&border-width=10px&border-color=black"> -<meta name="variant" content="?corner-top-right-shape=bevel&border-width=10px&border-color=black"> +<meta name="variant" content="?corner-top-left-shape=bevel&border-width=10px"> +<meta name="variant" content="?corner-top-right-shape=bevel&border-width=10px"> <meta name="variant" content="?corner-bottom-left-shape=bevel&border-width=10px&border-radius=20px"> <meta name="variant" content="?corner-bottom-right-shape=bevel&border-width=10px&border-radius=20px"> <meta name="variant" content="?corner-bottom-right-shape=bevel&corner-bottom-left-shape=bevel"> <meta name="variant" content="?border-top-left-radius=50%&corner-shape=superellipse(0.7)&border-left-width=30px&border-top-width=30px"> <meta name="variant" content="?border-radius=50%&corner-shape=bevel&box-shadow=10px%2010px%200%2010px%20black"> +<meta name="variant" content="?corner-shape=notch&border-radius=30px&border-width=30px"> <style> body { margin: 0; diff --git a/tests/wpt/tests/css/css-borders/tentative/corner-shape/resources/corner-shape.js b/tests/wpt/tests/css/css-borders/tentative/corner-shape/resources/corner-shape.js index 4757a43ad05..c08a95c7d75 100644 --- a/tests/wpt/tests/css/css-borders/tentative/corner-shape/resources/corner-shape.js +++ b/tests/wpt/tests/css/css-borders/tentative/corner-shape/resources/corner-shape.js @@ -87,10 +87,6 @@ function add_corner(ctx, ax, ay, bx, by, curvature) { * 'border-top-right-radius': [number, number], * 'border-bottom-left-radius': [number, number], * 'border-bottom-right-radius': [number, number], - * 'border-top-color': string, - * 'border-right-color': string, - * 'border-left-color': string, - * 'border-bottom-color': string, * 'border-top-width': number, * 'border-right-width': number, * 'border-bottom-width': number, @@ -109,42 +105,8 @@ function render_rect_with_corner_shapes(style, ctx, width, height) { add_corner(ctx, ...params.outer_rect, params.shape); } - function draw_inner_corner_from_params(params) { - add_corner(ctx, ...params.inner_rect, params.shape); - } - function draw_inner_corner(corner) { - draw_inner_corner_from_params(corner_params[corner]); - } - - function draw_shadow() { - if (!style.shadow || !style.shadow.length) { - return; - } - - for (const {spread, offset, color} of style.shadow) { - const params = resolve_corner_params(style, width, height, spread); - ctx.save(); - ctx.translate(...offset); - ctx.beginPath(); - ctx.lineTo(params['top-right'].inner_rect[0], params['top-right'].inner_rect[1]); - draw_inner_corner_from_params(params['top-right']); - ctx.lineTo(params['top-right'].inner_rect[2], params['top-right'].inner_rect[3]) - ctx.lineTo(params['bottom-right'].inner_rect[0], params['bottom-right'].inner_rect[1]) - draw_inner_corner_from_params(params['bottom-right']); - ctx.lineTo(params['bottom-right'].inner_rect[2], params['bottom-right'].inner_rect[3]); - ctx.lineTo(params['bottom-left'].inner_rect[0], params['bottom-left'].inner_rect[1]); - draw_inner_corner_from_params(params['bottom-left']); - ctx.lineTo(params['bottom-left'].inner_rect[2], params['bottom-left'].inner_rect[3]) - ctx.lineTo(params['top-left'].inner_rect[0], params['top-left'].inner_rect[1]) - draw_inner_corner_from_params(params['top-left']); - ctx.lineTo(params['top-left'].inner_rect[2], params['top-left'].inner_rect[3]); - ctx.lineTo(params['top-right'].inner_rect[0], params['top-right'].inner_rect[1]); - ctx.fillStyle = color; - ctx.closePath(); - ctx.fill("nonzero"); - ctx.restore(); - } + add_corner(ctx, ...corner_params[corner].inner_rect, corner_params[corner].shape); } function draw_outer_path() { @@ -157,6 +119,15 @@ function render_rect_with_corner_shapes(style, ctx, width, height) { ctx.fill("nonzero"); } + for (const {spread, offset, color} of (style.shadow || [])) { + ctx.save(); + ctx.translate(offset[0] - spread, offset[1] - spread); + ctx.scale((width + spread * 2) / width, (height + spread * 2) / height); + ctx.fillStyle = color; + draw_outer_path(); + ctx.restore(); + } + const inner_rect = [ style["border-left-width"], style["border-top-width"], @@ -164,70 +135,8 @@ function render_rect_with_corner_shapes(style, ctx, width, height) { height - style["border-bottom-width"], ]; - draw_shadow(); - { - ctx.save(); - ctx.beginPath(); - ctx.moveTo(0, 0); - ctx.lineTo(corner_params['top-left'].inner_rect[2], corner_params['top-left'].inner_rect[1]) - ctx.lineTo(corner_params['top-left'].inner_rect[2], inner_rect[1]); - ctx.lineTo(corner_params['top-right'].inner_rect[0], inner_rect[1]); - ctx.lineTo(corner_params['top-right'].inner_rect[0], corner_params['top-right'].inner_rect[3]); - ctx.lineTo(width, 0); - ctx.closePath(); - ctx.clip(); - ctx.fillStyle = style['border-top-color']; - draw_outer_path(); - ctx.restore(); - } - - { - ctx.save(); - ctx.beginPath(); - ctx.moveTo(width, 0); - ctx.lineTo(corner_params['top-right'].inner_rect[0], corner_params['top-right'].inner_rect[3]); - ctx.lineTo(inner_rect[2], corner_params['top-right'].inner_rect[3]); - ctx.lineTo(inner_rect[2], corner_params['bottom-right'].inner_rect[1]); - ctx.lineTo(corner_params['bottom-right'].inner_rect[2], corner_params['bottom-right'].inner_rect[1]); - ctx.lineTo(width, height); - ctx.closePath(); - ctx.clip(); - ctx.fillStyle = style['border-right-color']; - draw_outer_path(); - ctx.restore(); - } - - { - ctx.save(); - ctx.beginPath(); - ctx.lineTo(width, height); - ctx.lineTo(corner_params['bottom-right'].inner_rect[2], corner_params['bottom-right'].inner_rect[1]); - ctx.lineTo(corner_params['bottom-right'].inner_rect[2], inner_rect[3]); - ctx.lineTo(corner_params['bottom-left'].inner_rect[0], inner_rect[3]); - ctx.lineTo(corner_params['bottom-left'].inner_rect[0], corner_params['bottom-left'].inner_rect[3]); - ctx.lineTo(0, height); - ctx.closePath(); - ctx.clip(); - ctx.fillStyle = style['border-bottom-color']; - draw_outer_path(); - ctx.restore(); - } - - { - ctx.save(); - ctx.beginPath(); - ctx.lineTo(0, height); - ctx.lineTo(corner_params['bottom-left'].inner_rect[0], corner_params['bottom-left'].inner_rect[3]); - ctx.lineTo(inner_rect[0], corner_params['bottom-left'].inner_rect[3]); - ctx.lineTo(inner_rect[0], corner_params['top-left'].inner_rect[1]); - ctx.lineTo(corner_params['top-left'].inner_rect[2], corner_params['top-left'].inner_rect[1]) - ctx.lineTo(0, 0); - ctx.closePath(); - ctx.clip(); - ctx.fillStyle = style['border-left-color']; - draw_outer_path(); - ctx.restore(); - } + ctx.fillStyle = "black"; + draw_outer_path(); ctx.save(); ctx.beginPath(); diff --git a/tests/wpt/tests/css/css-borders/tentative/corner-shape/resources/corner-utils.js b/tests/wpt/tests/css/css-borders/tentative/corner-shape/resources/corner-utils.js index ad3b235addf..b6f329e8248 100644 --- a/tests/wpt/tests/css/css-borders/tentative/corner-shape/resources/corner-utils.js +++ b/tests/wpt/tests/css/css-borders/tentative/corner-shape/resources/corner-utils.js @@ -112,29 +112,11 @@ function resolve_corner_params(style, width, height, outset = null) { outer_rect[3] + inner_offset[3] * offset[0], ]; - let inner_shape = shape; - if (outset) { - const new_width = width + outset * 2; - const new_height = height + outset * 2; - inner_rect = [ - (outer_rect[0] / width) * new_width - outset, - (outer_rect[1] / height) * new_height - outset, - (outer_rect[2] / width) * new_width - outset, - (outer_rect[3] / height) * new_height - outset - ] - } else if (shape > 2 || shape < 0.5) { - const outer_length = Math.hypot( - outer_rect[2] - outer_rect[0], outer_rect[3] - outer_rect[1]); - const inner_length = Math.hypot( - inner_rect[2] - inner_rect[0], inner_rect[3] - inner_rect[1]) - } - return [ corner, { outer_rect, shape, - inner_shape, inset, inner_rect, inner_offset, diff --git a/tests/wpt/tests/css/css-color-hdr/parsing.html b/tests/wpt/tests/css/css-color-hdr/parsing.html index 2447891f2c4..688043039de 100644 --- a/tests/wpt/tests/css/css-color-hdr/parsing.html +++ b/tests/wpt/tests/css/css-color-hdr/parsing.html @@ -15,7 +15,6 @@ test_valid_value("dynamic-range-limit", "dynamic-range-limit-mix(no-limit 8%, standard 2%)"); test_valid_value("dynamic-range-limit", "dynamic-range-limit-mix(no-limit 99%, standard 99%)"); test_valid_value("dynamic-range-limit", "dynamic-range-limit-mix(no-limit 99%, standard 99%, constrained 10%)"); - test_valid_value("dynamic-range-limit", "dynamic-range-limit-mix(no-limit 1%)"); test_valid_value("dynamic-range-limit", "dynamic-range-limit-mix(constrained 20%, no-limit 80%)"); test_valid_value("dynamic-range-limit", "dynamic-range-limit-mix(dynamic-range-limit-mix(constrained 90%, no-limit 10%) 1%, no-limit 80%)"); test_valid_value("dynamic-range-limit", "dynamic-range-limit-mix(no-limit 1%, dynamic-range-limit-mix(constrained 2%, no-limit 10%) 80%)"); @@ -31,6 +30,7 @@ test_invalid_value("dynamic-range-limit", "hdr"); test_invalid_value("dynamic-range-limit", "sdr"); test_invalid_value("dynamic-range-limit", "low"); + test_invalid_value("dynamic-range-limit", "dynamic-range-limit-mix(no-limit 1%)"); test_invalid_value("dynamic-range-limit", "dynamic-range-limit-mix(no-limit 80% standard 20%)"); test_invalid_value("dynamic-range-limit", "dynamic-range-limit-mix(low, no-limit, 10%)"); test_invalid_value("dynamic-range-limit", "dynamic-range-limit-mix(no-limit 101%, standard 1%)"); diff --git a/tests/wpt/tests/css/css-conditional/container-queries/style-query-registered-custom-rem-change.html b/tests/wpt/tests/css/css-conditional/container-queries/style-query-registered-custom-rem-change.html new file mode 100644 index 00000000000..33808fbe198 --- /dev/null +++ b/tests/wpt/tests/css/css-conditional/container-queries/style-query-registered-custom-rem-change.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<title>CSS Container Queries Test: style() query with rem unit for registered custom property</title> +<link rel="help" href="https://drafts.csswg.org/css-conditional-5/#style-container"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="support/cq-testcommon.js"></script> +<style> + @property --length { + syntax: "<length>"; + initial-value: 0px; + inherits: false; + } + + :root, body { font-size: 16px; } + #container { --length: 100px; } + + #target { color: red; } + @container style(--length: calc(1rem * 10)) { + #target { color: green; } + } +</style> +<div id="container"> + <div id="target">Should be green</div> +</div> +<script> + test(() => { + assert_equals(getComputedStyle(target).color, "rgb(255, 0, 0)"); + }, "Initially, 1rem * 10 evaluates to 160px"); + + test(() => { + document.documentElement.style.fontSize = "10px"; + assert_equals(getComputedStyle(target).color, "rgb(0, 128, 0)"); + }, "Changing the :root font-size to 10px makes 1rem * 10 evaluate to 100px"); +</script> diff --git a/tests/wpt/tests/css/css-flexbox/flexbox_columns-ref.html b/tests/wpt/tests/css/css-flexbox/flexbox_columns-ref.html deleted file mode 100644 index b8c7a225698..00000000000 --- a/tests/wpt/tests/css/css-flexbox/flexbox_columns-ref.html +++ /dev/null @@ -1,10 +0,0 @@ -<!DOCTYPE html> -<title>flexbox | multicol</title> -<link rel="author" href="http://opera.com" title="Opera Software"> -<style> -div { - background: black; -} -</style> - -<div>x</div> diff --git a/tests/wpt/tests/css/css-flexbox/flexbox_columns.html b/tests/wpt/tests/css/css-flexbox/flexbox_columns.html deleted file mode 100644 index d39c2db55f2..00000000000 --- a/tests/wpt/tests/css/css-flexbox/flexbox_columns.html +++ /dev/null @@ -1,27 +0,0 @@ -<!DOCTYPE html> -<title>flexbox | multicol</title> -<link rel="author" href="http://opera.com" title="Opera Software"> -<link rel="help" - href="http://www.w3.org/TR/css-flexbox-1/#flex-containers"> -<link rel="match" href="flexbox_columns-ref.html"> -<style> -ul { - background: black; - padding: 0; - margin: 0; - - display: flex; - justify-content: space-around; - columns: 3; - column-rule: 1em solid red; -} -::marker { font-family:inherit; } -</style> - -<ul> - <li>one two three four</li> - <li>filler</li> - <li>filler</li> - <li>filler</li> - <li>filler</li> -</ul> diff --git a/tests/wpt/tests/css/css-forms/datetime-stacking-context-ref.html b/tests/wpt/tests/css/css-forms/datetime-stacking-context-ref.html new file mode 100644 index 00000000000..95bee383d21 --- /dev/null +++ b/tests/wpt/tests/css/css-forms/datetime-stacking-context-ref.html @@ -0,0 +1,12 @@ +<!doctype html> +<style> + #cover { + background: white; + position: fixed; + width: 100%; + height: 200px; + top: 0; + border: 1px solid black; + } +</style> +<div id="cover"></div> diff --git a/tests/wpt/tests/css/css-forms/datetime-stacking-context.html b/tests/wpt/tests/css/css-forms/datetime-stacking-context.html new file mode 100644 index 00000000000..4754cacf09d --- /dev/null +++ b/tests/wpt/tests/css/css-forms/datetime-stacking-context.html @@ -0,0 +1,16 @@ +<!doctype html> +<title>Datetime input doesn't have stacking contexts inside</title> +<link rel="help" href="https://drafts.csswg.org/css-forms/"> <!-- a bit of a stretch but... --> +<link rel="match" href="datetime-stacking-context-ref.html"> +<style> + #cover { + background: white; + position: fixed; + width: 100%; + height: 200px; + top: 0; + border: 1px solid black; + } +</style> +<div id="cover"></div> +<input type=datetime> diff --git a/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-040-ref.html b/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-040-ref.html new file mode 100644 index 00000000000..2988cf534a9 --- /dev/null +++ b/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-040-ref.html @@ -0,0 +1,88 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/css-gaps-1/#break"> +<link rel="author" title="Sam Davis Omekara Jr." href="mailto:samomekarajr@microsoft.com"> +<style> + body { + margin: 0px; + } + + .grid-container { + display: grid; + grid-template-columns: repeat(4, 100px); + grid-template-rows: repeat(4, 100px); + gap: 10px; + width: 430px; + height: 430px; + } + + .grid-item { + background-color: gray; + opacity: 0.5; + border: 1px solid #000; + } + + .col-gap { + width: 0; + border-left: solid 5px blue; + } + + .col-gap1 { + position: absolute; + top: 212.5px; + left: 102.5px; + height: 217.5px; + } + + .col-gap2 { + position: absolute; + top: 0px; + left: 212.5px; + height: 430px; + } + + .col-gap3 { + position: absolute; + top: 0px; + left: 322.5px; + height: 430px; + } + + .row-gap { + height: 0px; + border-bottom: solid 5px red; + } + + .row-gap1 { + position: absolute; + top: 102.5px; + left: 325px; + width: 105px; + } + + .row-gap2 { + position: absolute; + top: 212.5px; + left: 0px; + width: 430px; + } + + .row-gap3 { + position: absolute; + top: 322.5px; + left: 0px; + width: 430px; + } +</style> + +<div class="grid-container"> + <div class="grid-item" style="grid-column: 1 / 3; grid-row: 1 / 3;"></div> + <div class="grid-item" style="grid-column: 3 / 4; grid-row: 1 / 3;"></div> +</div> + +<div class="col-gap col-gap1"> </div> +<div class="col-gap col-gap2"> </div> +<div class="col-gap col-gap3"> </div> + +<div class="row-gap row-gap1"> </div> +<div class="row-gap row-gap2"> </div> +<div class="row-gap row-gap3"> </div> diff --git a/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-040.html b/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-040.html new file mode 100644 index 00000000000..4bab26db550 --- /dev/null +++ b/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-040.html @@ -0,0 +1,35 @@ +<!DOCTYPE html> +<title> + CSS Gap Decorations: *rule-break properly adheres to spanning-item when repeater tracks are used. +</title> +<link rel="help" href="https://drafts.csswg.org/css-gaps-1/#break"> +<link rel="match" href="grid-gap-decorations-040-ref.html"> +<link rel="author" title="Sam Davis Omekara Jr." href="mailto:samomekarajr@microsoft.com"> +<style> + body { + margin: 0px; + } + .grid-container { + display: grid; + grid-template-columns: repeat(4, 100px); + grid-template-rows: repeat(4, 100px); + gap: 10px; + + width: 430px; + height: 430px; + + column-rule: 5px solid blue; + row-rule: 5px solid red; + } + + .grid-item { + background-color: gray; + opacity: 0.5; + border: 1px solid #000; + } + +</style> +<div class="grid-container"> + <div class="grid-item" style="grid-column: 1 / 3; grid-row: 1 / 3;"></div> + <div class="grid-item" style="grid-column: 3 / 4; grid-row: 1 / 3;"></div> +</div> diff --git a/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-041-crash.html b/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-041-crash.html new file mode 100644 index 00000000000..be3e2280b5f --- /dev/null +++ b/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-041-crash.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<title> + CSS Gap Decorations: Renderer doesn't crash when gap decorations is used on grid with no rows/columns. +</title> +<link rel="help" href="https://drafts.csswg.org/css-gaps-1/"> +<link rel="author" title="Sam Davis Omekara Jr." href="mailto:samomekarajr@microsoft.com"> +<style> + .grid-container { + display: grid; + + column-rule: solid blue; + row-rule: dotted red; + } +</style> + +<div class="grid-container"></div> diff --git a/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-042-ref.html b/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-042-ref.html new file mode 100644 index 00000000000..ed44f7a2de3 --- /dev/null +++ b/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-042-ref.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/css-gaps-1/"> +<link rel="author" title="Sam Davis Omekara Jr." href="mailto:samomekarajr@microsoft.com"> +<style> + .grid-container { + display: grid; + grid-template-columns: repeat(4, 1fr); + width: 430px; + height: 430px; + } + + .grid-item { + background-color: gray; + opacity: 0.5; + border: 1px solid #000; + } +</style> + +<div class="grid-container"> + <div class="grid-item" style="grid-column: 1 / 3; grid-row: 1 / 2;"></div> + <div class="grid-item" style="grid-column: 3 / 4; grid-row: 1 / 3;"></div> + <div class="grid-item" style="grid-row: 2 / 4;"></div> + <div class="grid-item" style="grid-column: 2 / 4; grid-row: 3 / 4;"></div> + <div class="grid-item" style="grid-column: 2 / 3; grid-row: 2 / 3;"></div> + <div class="grid-item" style="grid-column: 4 / 5; grid-row: 1 / 4;"></div> + <div class="grid-item" style="grid-column: 1 / 4; grid-row: 4 / 5;"></div> + <div class="grid-item" style="grid-column: 4 / 5; grid-row: 4 / 5;"></div> +</div> diff --git a/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-042.html b/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-042.html new file mode 100644 index 00000000000..5b2b4936980 --- /dev/null +++ b/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-042.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<title> + CSS Gap Decorations: gap decorations are not painted when there are no gaps. +</title> +<link rel="help" href="https://drafts.csswg.org/css-gaps-1/"> +<link rel="match" href="grid-gap-decorations-042-ref.html"> +<link rel="author" title="Sam Davis Omekara Jr." href="mailto:samomekarajr@microsoft.com"> +<style> + .grid-container { + display: grid; + grid-template-columns: repeat(4, 1fr); + + width: 430px; + height: 430px; + + column-rule: 5px solid blue; + row-rule: 5px dotted red; + } + + .grid-item { + background-color: gray; + opacity: 0.5; + border: 1px solid #000; + } + +</style> +<div class="grid-container"> + <div class="grid-item" style="grid-column: 1 / 3; grid-row: 1 / 2;"></div> + <div class="grid-item" style="grid-column: 3 / 4; grid-row: 1 / 3;"></div> + <div class="grid-item" style="grid-row: 2 / 4;"></div> + <div class="grid-item" style="grid-column: 2 / 4; grid-row: 3 / 4;"></div> + <div class="grid-item" style="grid-column: 2 / 3; grid-row: 2 / 3;"></div> + <div class="grid-item" style="grid-column: 4 / 5; grid-row: 1 / 4;"></div> + <div class="grid-item" style="grid-column: 1 / 4; grid-row: 4 / 5;"></div> + <div class="grid-item" style="grid-column: 4 / 5; grid-row: 4 / 5;"></div> +</div> diff --git a/tests/wpt/tests/css/css-grid/grid-items/grid-item-inline-contribution-004.html b/tests/wpt/tests/css/css-grid/grid-items/grid-item-inline-contribution-004.html new file mode 100644 index 00000000000..a4e3cd6f3a4 --- /dev/null +++ b/tests/wpt/tests/css/css-grid/grid-items/grid-item-inline-contribution-004.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com"> +<link rel="author" title="Mozilla" href="https://www.mozilla.org/"> +<link rel="help" href="https://drafts.csswg.org/css-grid-2/#algo-grid-sizing"> +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/6356#issuecomment-862800005"> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1957501"> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<meta name="assert" content="Tests the min-content contribution is re-resolved during a 2nd pass."> + +<!-- + +Quoting step 3 of css-grid-2 section 12.1. Grid Sizing Algorithm: + +" + Then, if the min-content contribution of any grid item has changed based on + the row sizes and alignment calculated in step 2, re-resolve the sizes of the + grid columns with the new min-content and max-content contributions (once + only). +" + +In this testcase initially the row size is indefinite, then resolves to 100px. +Using this information we re-resolve the columns, resulting in 50px for the +first column. + +--> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div style="display: grid; width: 0; grid-template: auto / auto auto;"> + <div style="background: green; height: 100%;"> + <canvas width="5" height="10" style="height: 100%;"> + </div> + <div style="background: green"> + <div style="width: 50px; height: 100px;"></div> + </div> +</div> diff --git a/tests/wpt/tests/css/css-highlight-api/HighlightRegistry-highlightsFromPoint-ranges.html b/tests/wpt/tests/css/css-highlight-api/HighlightRegistry-highlightsFromPoint-ranges.html new file mode 100644 index 00000000000..24cf8aa6dfe --- /dev/null +++ b/tests/wpt/tests/css/css-highlight-api/HighlightRegistry-highlightsFromPoint-ranges.html @@ -0,0 +1,109 @@ +<!doctype html> +<meta name="author" title="Fernando Fiori" href="mailto:ffiori@microsoft.com"> +<meta name="assert" content="HighlightRegistry.highlightsFromPoint returns the Highlights and their corresponding Ranges and StaticRanges present at the coordinates provided as argument in the right order in multi-line text."> +<link rel="help" href="https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/highlight/HighlightsFromPointsExplainer.md"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +::highlight(example-highlight) { + background-color: rgba(0, 255, 255, 0.5); +} +body { + font-family: monospace; +} +</style> +<span id="example-span-1">0123456789</span><br> +<span id="example-span-2">0123456789</span> +<script> + const textNode1 = document.querySelector("#example-span-1"); + const textNode2 = document.querySelector("#example-span-2"); + + function test_ranges(ranges) { + assert_equals(ranges.length, 2, 'test_ranges() should be called with exactly two ranges.'); + let big_range = ranges[0].startOffset < ranges[1].startOffset ? ranges[0] : ranges[1]; + + let highlight = new Highlight(...ranges); + CSS.highlights.set("example-highlight", highlight); + + const rect = textNode1.getBoundingClientRect(); + const characterWidth = rect.width / textNode1.textContent.length; + const characterHeight = rect.height; + + // No Highlights outside of text contents. + let x = rect.left - 1; + let y = rect.top - 1; + let highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y); + assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns an empty array when the coordinates provided are outside of the text contents'); + + // Get x and y coordinates between characters '0' and '1' on the first line (not highlighted). + x = rect.left + characterWidth; + y = rect.top + characterHeight / 2; + highlights = CSS.highlights.highlightsFromPoint(x, y); + assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns an empty array when the coordinates provided are outside of the highlighted ranges'); + + // Get x and y coordinates between characters '2' and '3' on the first line. + x = rect.left + 3 * characterWidth; + highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y); + assert_equals(highlight_hit_results.length, 1, 'CSS.highlights.highlightsFromPoint() returns exactly one HighlightHitResult when the coordinates provided point at one Highlight'); + assert_equals(highlight_hit_results[0].highlight, highlight, 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the Highlight present at the coordinates provided'); + assert_array_equals(highlight_hit_results[0].ranges, [big_range], 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the ranges of the Highlight present at the coordinates provided'); + + // Get x and y coordinates between characters '6' and '7' on the first line. + x = rect.left + 7 * characterWidth; + highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y); + assert_equals(highlight_hit_results.length, 1, 'CSS.highlights.highlightsFromPoint() returns exactly one HighlightHitResult when the coordinates provided point at one Highlight'); + assert_equals(highlight_hit_results[0].highlight, highlight, 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the Highlight present at the coordinates provided'); + assert_array_equals(highlight_hit_results[0].ranges, ranges, 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the ranges of the Highlight present at the coordinates provided in the right order'); + + // Get x and y coordinates to the right of the last character of the first line. + x = rect.left + 12 * characterWidth; + highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y); + assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns an empty array when the coordinates provided are to the right of the text contents'); + + // Get x and y coordinates between characters '0' and '1' on the second line. + x = rect.left + characterWidth; + y = rect.top + 1.5 * characterHeight; + highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y); + assert_equals(highlight_hit_results.length, 1, 'CSS.highlights.highlightsFromPoint() returns exactly one HighlightHitResult when the coordinates provided point at one Highlight'); + assert_equals(highlight_hit_results[0].highlight, highlight, 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the Highlight present at the coordinates provided'); + assert_array_equals(highlight_hit_results[0].ranges, [big_range], 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the ranges of the Highlight present at the coordinates provided'); + + // Get x and y coordinates between characters '8' and '9' on the second line (not highlighted). + x = rect.left + 9 * characterWidth; + highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y); + assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns an empty array when the coordinates provided are outside of the highlighted ranges'); + + // Get x and y coordinates to the right of the last character of the second line. + x = rect.left + 12 * characterWidth; + highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y); + assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns an empty array when the coordinates provided are to the right of the text contents'); + + // Get x and y coordinates below the second line. + x = rect.left + 5 * characterWidth; + y = rect.top + 3 * characterHeight; + highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y); + assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns an empty array when the coordinates provided are below the text contents'); + } + + test(() => { + // Set a Highlight with two nested ranges in this way: + // 01[234(56789) + // 01234567]89 + let range1 = new Range(); + range1.setStart(textNode1.childNodes[0], 5); + range1.setEnd(textNode1.childNodes[0], 10); + let range2 = new Range(); + range2.setStart(textNode1.childNodes[0], 2); + range2.setEnd(textNode2.childNodes[0], 8); + + let static_range1 = new StaticRange({startContainer: textNode1.childNodes[0], startOffset: 5, endContainer: textNode1.childNodes[0], endOffset: 10}) + let static_range2 = new StaticRange({startContainer: textNode1.childNodes[0], startOffset: 2, endContainer: textNode2.childNodes[0], endOffset: 8}) + + test_ranges([range1, range2]); + test_ranges([range2, range1]); + test_ranges([static_range1, static_range2]); + test_ranges([static_range2, static_range1]); + test_ranges([static_range1, range2]); + test_ranges([range1, static_range2]); + }, 'CSS.highlights.highlightsFromPoint() returns HighlightHitResults with the Highlights and their corresponding Ranges and StaticRanges present at the given point in the right order on multi-line text.'); +</script>
\ No newline at end of file diff --git a/tests/wpt/tests/css/css-highlight-api/HighlightRegistry-highlightsFromPoint.html b/tests/wpt/tests/css/css-highlight-api/HighlightRegistry-highlightsFromPoint.html index 5bb81bea69a..5b4e7704a4d 100644 --- a/tests/wpt/tests/css/css-highlight-api/HighlightRegistry-highlightsFromPoint.html +++ b/tests/wpt/tests/css/css-highlight-api/HighlightRegistry-highlightsFromPoint.html @@ -26,7 +26,7 @@ body { test(() => { assert_equals(CSS.highlights.highlightsFromPoint(-1,-1).length, 0); - }, 'CSS.highlights.highlightsFromPoint() should return an empty vector when called with a point outside the document.'); + }, 'CSS.highlights.highlightsFromPoint() should return an empty array when called with a point outside the document.'); test(() => { // Set two Highlights in this way: 01[234[56789]] @@ -49,35 +49,38 @@ body { // No Highlights outside of text contents. let x = rect.left - 1; let y = rect.top - 1; - let highlights = CSS.highlights.highlightsFromPoint(x, y); - assert_equals(highlights.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the coordinates provided are outside of the text contents'); + let highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y); + assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns an empty array when the coordinates provided are outside of the text contents'); // Get x and y coordinates between '0' and '1'. x = rect.left + characterWidth; y = rect.top + rect.height / 2; highlights = CSS.highlights.highlightsFromPoint(x, y); - assert_equals(highlights.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the coordinates provided point at no Highlights'); + assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns an empty array when the coordinates provided point at no Highlights'); // Get x and y coordinates between '2' and '3'. x = rect.left + 3 * characterWidth; - highlights = CSS.highlights.highlightsFromPoint(x, y); - assert_equals(highlights.length, 1, 'CSS.highlights.highlightsFromPoint() returns exactly one Highlight when the coordinates provided point at one Highlight'); - assert_equals(highlights[0], highlight1, 'CSS.highlights.highlightsFromPoint() returns the Highlight present at the coordinates provided'); + highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y); + assert_equals(highlight_hit_results.length, 1, 'CSS.highlights.highlightsFromPoint() returns exactly one HighlightHitResult when the coordinates provided point at one Highlight'); + assert_equals(highlight_hit_results[0].highlight, highlight1, 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the Highlight present at the coordinates provided'); + assert_array_equals(highlight_hit_results[0].ranges, [range1], 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the ranges of the Highlight present at the coordinates provided'); // Get x and y coordinates between '6' and '7'. // Same priority for the Highlights, break tie by order of registration. x = rect.left + 7 * characterWidth; - highlights = CSS.highlights.highlightsFromPoint(x, y); - assert_equals(highlights.length, 2, 'CSS.highlights.highlightsFromPoint() returns exactly two Highlights when the coordinates provided point at two overlapping Highlights'); - assert_equals(highlights[0], highlight2, 'CSS.highlights.highlightsFromPoint() returns first the Highlight registered last when both Highlights present at the point provided have the same priority'); - assert_equals(highlights[1], highlight1, 'CSS.highlights.highlightsFromPoint() returns last the Highlight registered first when both Highlights present at the point provided have the same priority'); + highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y); + assert_equals(highlight_hit_results.length, 2, 'CSS.highlights.highlightsFromPoint() returns exactly two HighlightHitResults when the coordinates provided point at two overlapping Highlights'); + assert_equals(highlight_hit_results[0].highlight, highlight2, 'CSS.highlights.highlightsFromPoint() returns first a HighlightHitResult with the Highlight registered last when both Highlights present at the point provided have the same priority'); + assert_equals(highlight_hit_results[1].highlight, highlight1, 'CSS.highlights.highlightsFromPoint() returns last a HighlightHitResult with the Highlight registered first when both Highlights present at the point provided have the same priority'); + assert_array_equals(highlight_hit_results[0].ranges, [range2], 'CSS.highlights.highlightsFromPoint() returns first a HighlightHitResult with the ranges of the Highlight present on top at the coordinates provided'); + assert_array_equals(highlight_hit_results[1].ranges, [range1], 'CSS.highlights.highlightsFromPoint() returns last a HighlightHitResult with the ranges of the Highlight present at the bottom at the coordinates provided'); // Now highlight1 should be first because it's got higher priority. highlight1.priority = 2; highlight2.priority = 1; - highlights = CSS.highlights.highlightsFromPoint(x, y); - assert_equals(highlights.length, 2, 'CSS.highlights.highlightsFromPoint() returns exactly two Highlights when the coordinates provided point at two overlapping Highlights'); - assert_equals(highlights[0], highlight1, 'CSS.highlights.highlightsFromPoint() returns first the Highlight with higher priority when there are two Highlights present at the point provided'); - assert_equals(highlights[1], highlight2, 'CSS.highlights.highlightsFromPoint() returns last the Highlight with lower priority when there are two Highlights present at the point provided'); - }, 'CSS.highlights.highlightsFromPoint() returns Highlights present at the given point in the right order.'); + highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y); + assert_equals(highlight_hit_results.length, 2, 'CSS.highlights.highlightsFromPoint() returns exactly two HighlightHitResults when the coordinates provided point at two overlapping Highlights'); + assert_equals(highlight_hit_results[0].highlight, highlight1, 'CSS.highlights.highlightsFromPoint() returns first a HighlightHitResult with the Highlight with higher priority when there are two Highlights present at the point provided'); + assert_equals(highlight_hit_results[1].highlight, highlight2, 'CSS.highlights.highlightsFromPoint() returns last a HighlightHitResult with the Highlight with lower priority when there are two Highlights present at the point provided'); + }, 'CSS.highlights.highlightsFromPoint() returns the Highlights with their corresponding ranges present at the given point in the right order.'); </script>
\ No newline at end of file diff --git a/tests/wpt/tests/css/css-masking/animations/clip-path-interpolation-shape-arc-direction-agnostic-radius-ref.html b/tests/wpt/tests/css/css-masking/animations/clip-path-interpolation-shape-arc-direction-agnostic-radius-ref.html new file mode 100644 index 00000000000..2869d38a982 --- /dev/null +++ b/tests/wpt/tests/css/css-masking/animations/clip-path-interpolation-shape-arc-direction-agnostic-radius-ref.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html> +<head> + <title>CSS Masking: Test clip-path property and shape function with single-value arc radius</title> +</head> +<style> +@keyframes animate-shape { + from { + clip-path: shape(from 40px 100px, arc to 200px 100px of 50% 50% small cw, arc to 0 100px of 30% 30% small cw); + } + to { + clip-path: shape(from 40px 100px, arc to 200px 100px of 30% 30% small cw, arc to 0 100px of calc(10px + 45%) calc(10px + 45%) small cw); + } +} +#shape { + width: calc(500px / sqrt(2)); + height: calc(500px / sqrt(2)); + background: green; + animation: animate-shape 100s; + animation-play-state: paused; + animation-timing-function: steps(2, start); +} +</style> + +<div id="shape"></div> +</html> diff --git a/tests/wpt/tests/css/css-masking/animations/clip-path-interpolation-shape-arc-direction-agnostic-radius.html b/tests/wpt/tests/css/css-masking/animations/clip-path-interpolation-shape-arc-direction-agnostic-radius.html new file mode 100644 index 00000000000..aa91e1828a7 --- /dev/null +++ b/tests/wpt/tests/css/css-masking/animations/clip-path-interpolation-shape-arc-direction-agnostic-radius.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html> +<head> + <title>CSS Masking: Test animating single-value arc radius of the shape() function</title> + <link rel="help" href="https://drafts.csswg.org/css-shapes-2/#funcdef-shape"> + <link rel="match" href="clip-path-interpolation-shape-arc-direction-agnostic-radius-ref.html"> + <meta name="fuzzy" content="maxDifference=0-10;totalPixels=0-360"> +</head> +<style> +@keyframes animate-shape { + from { + clip-path: shape(from 40px 100px, arc to 200px 100px of 50% small cw, arc to 0 100px of 30% small cw); + } + to { + clip-path: shape(from 40px 100px, arc to 200px 100px of 30% small cw, arc to 0 100px of calc(10px + 45%) small cw); + } +} +#shape { + width: 400px; + height: 300px; + background: green; + animation: animate-shape 100s; + animation-play-state: paused; + animation-timing-function: steps(2, start); +} +</style> + +<div id="shape"></div> +</html> diff --git a/tests/wpt/tests/css/css-masking/animations/clip-path-interpolation-shape.html b/tests/wpt/tests/css/css-masking/animations/clip-path-interpolation-shape.html index 6d85c2a06b4..f725e1fc6fa 100644 --- a/tests/wpt/tests/css/css-masking/animations/clip-path-interpolation-shape.html +++ b/tests/wpt/tests/css/css-masking/animations/clip-path-interpolation-shape.html @@ -145,15 +145,28 @@ test_interpolation({ test_interpolation({ property: 'clip-path', - from: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)', - to: 'shape(from 15% 15px, arc to 5% -25px of 20px 30px, arc by 25% -15px of 20px cw rotate 270deg small, arc to 25% 20px of 10px 5px small cw)' + from: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)', + to: 'shape(from 15% 15px, arc to 5% -25px of 20px 30px, arc by 25% -15px of 20px 20px cw rotate 270deg small, arc to 25% 20px of 10px 5px small cw)' }, [ {at: -0.3, expect: 'shape(from 2% 2px, arc to 18% -12px of 7px 17px, arc by 12% -2px of 33px 33px rotate -42deg cw large , arc to 25% 20px of 10px 5px)'}, - {at: 0, expect: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px)'}, + {at: 0, expect: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px)'}, {at: 0.3, expect: 'shape(from 8% 8px, arc to 12% -18px of 13px 23px, arc by 18% -8px of 27px 27px rotate 102deg cw large, arc to 25% 20px of 10px 5px cw)'}, - {at: 0.5, expect: 'shape(from 10% 10px, arc to 10% -20px of 15px 25px, arc by 20% -10px of 25px rotate 150deg cw large, arc to 25% 20px of 10px 5px cw)'}, - {at: 1, expect: 'shape(from 15% 15px, arc to 5% -25px of 20px 30px, arc by 25% -15px of 20px rotate 270deg cw, arc to 25% 20px of 10px 5px cw)'}, - {at: 1.5, expect: 'shape(from 20% 20px, arc to 0% -30px of 25px 35px, arc by 30% -20px of 15px rotate 390deg cw, arc to 25% 20px of 10px 5px cw)'}, + {at: 0.5, expect: 'shape(from 10% 10px, arc to 10% -20px of 15px 25px, arc by 20% -10px of 25px 25px rotate 150deg cw large, arc to 25% 20px of 10px 5px cw)'}, + {at: 1, expect: 'shape(from 15% 15px, arc to 5% -25px of 20px 30px, arc by 25% -15px of 20px 20px rotate 270deg cw, arc to 25% 20px of 10px 5px cw)'}, + {at: 1.5, expect: 'shape(from 20% 20px, arc to 0% -30px of 25px 35px, arc by 30% -20px of 15px 15px rotate 390deg cw, arc to 25% 20px of 10px 5px cw)'}, +]); + +test_interpolation({ + property: 'clip-path', + from: 'shape(from 5% 5px, arc to 15% -15px of 10px, arc by 15% -5px of 30% cw rotate 30deg large, arc to 25% 20px of 10% small)', + to: 'shape(from 15% 15px, arc to 5% -25px of 15%, arc by 25% -15px of 12rem cw rotate 270deg small, arc to 15% 20px of 20% small cw)' +}, [ + {at: -0.3, expect: 'shape(from 2% 2px, arc to 18% -12px of calc(-4.5% + 13px), arc by 12% -2px of calc(39% - 57.6px) cw large rotate -42deg, arc to 28% 20px of 7%)'}, + {at: 0, expect: 'shape(from 5% 5px, arc to 15% -15px of calc(0% + 10px), arc by 15% -5px of 30% cw large rotate 30deg, arc to 25% 20px of 10%)'}, + {at: 0.3, expect: 'shape(from 8% 8px, arc to 12% -18px of calc(4.5% + 7px), arc by 18% -8px of calc(21% + 57.6px) rotate 102deg cw large, arc to 22% 20px of 13% cw)'}, + {at: 0.5, expect: 'shape(from 10% 10px, arc to 10% -20px of calc(7.5% + 5px), arc by 20% -10px of calc(15% + 96px) cw large rotate 150deg, arc to 20% 20px of 15% cw)'}, + {at: 1, expect: 'shape(from 15% 15px, arc to 5% -25px of 15%, arc by 25% -15px of calc(0% + 192px) cw rotate 270deg, arc to 15% 20px of 20% cw)'}, + {at: 1.5, expect: 'shape(from 20% 20px, arc to 0% -30px of calc(22.5% - 5px), arc by 30% -20px of calc(-15% + 288px) cw rotate 390deg, arc to 10% 20px of 25% cw)'}, ]); test_interpolation({ @@ -254,28 +267,28 @@ test_interpolation({ test_interpolation({ property: 'clip-path', - from: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)', + from: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)', to: 'path("M 15 15 A 20,30 0 0,0 5,-25 a 20,20 270 0,1 25,-15 A 10,5 0 0,0 25 20")', }, [ - {at: -0.3, expect: 'shape(from calc(6.5% - 4.5px) 2px, arc to calc(19.5% - 1.5px) -12px of 7px 17px, arc by calc(19.5% - 7.5px) -2px of 33px cw large rotate -42deg, arc to calc(32.5% - 7.5px) 20px of 10px 5px)'}, - {at: 0, expect: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)'}, - {at: 0.3, expect: 'shape(from calc(3.5% + 4.5px) 8px, arc to calc(10.5% + 1.5px) -18px of 13px 23px, arc by calc(10.5% + 7.5px) -8px of 27px cw large rotate 102deg, arc to calc(17.5% + 7.5px) 20px of 10px 5px)'}, - {at: 0.5, expect: 'shape(from calc(2.5% + 7.5px) 10px, arc to calc(7.5% + 2.5px) -20px of 15px 25px, arc by calc(7.5% + 12.5px) -10px of 25px cw large rotate 150deg, arc to calc(12.5% + 12.5px) 20px of 10px 5px)'}, - {at: 1, expect: 'shape(from calc(0% + 15px) 15px, arc to calc(0% + 5px) -25px of 20px 30px, arc by calc(0% + 25px) -15px of 20px cw rotate 270deg, arc to calc(0% + 25px) 20px of 10px 5px)'}, - {at: 1.5, expect: 'shape(from calc(-2.5% + 22.5px) 20px, arc to calc(-7.5% + 7.5px) -30px of 25px 35px, arc by calc(-7.5% + 37.5px) -20px of 15px cw rotate 390deg, arc to calc(-12.5% + 37.5px) 20px of 10px 5px)'}, + {at: -0.3, expect: 'shape(from calc(6.5% - 4.5px) 2px, arc to calc(19.5% - 1.5px) -12px of 7px 17px, arc by calc(19.5% - 7.5px) -2px of 33px 33px cw large rotate -42deg, arc to calc(32.5% - 7.5px) 20px of 10px 5px)'}, + {at: 0, expect: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)'}, + {at: 0.3, expect: 'shape(from calc(3.5% + 4.5px) 8px, arc to calc(10.5% + 1.5px) -18px of 13px 23px, arc by calc(10.5% + 7.5px) -8px of 27px 27px cw large rotate 102deg, arc to calc(17.5% + 7.5px) 20px of 10px 5px)'}, + {at: 0.5, expect: 'shape(from calc(2.5% + 7.5px) 10px, arc to calc(7.5% + 2.5px) -20px of 15px 25px, arc by calc(7.5% + 12.5px) -10px of 25px 25px cw large rotate 150deg, arc to calc(12.5% + 12.5px) 20px of 10px 5px)'}, + {at: 1, expect: 'shape(from calc(0% + 15px) 15px, arc to calc(0% + 5px) -25px of 20px 30px, arc by calc(0% + 25px) -15px of 20px 20px cw rotate 270deg, arc to calc(0% + 25px) 20px of 10px 5px)'}, + {at: 1.5, expect: 'shape(from calc(-2.5% + 22.5px) 20px, arc to calc(-7.5% + 7.5px) -30px of 25px 35px, arc by calc(-7.5% + 37.5px) -20px of 15px 15px cw rotate 390deg, arc to calc(-12.5% + 37.5px) 20px of 10px 5px)'}, ]); test_interpolation({ property: 'clip-path', from: 'path("M 5 5 A 10,20 0 0,0 15,-15 a 30,30 30 1,1 15,-5 A 10,5 0 0,0 25 20")', - to: 'shape(from 15px 15px, arc to 5px -25px of 20px 30px, arc by 25px -15px of 20px cw rotate 270deg small, arc to 25px 20px of 10px 5px small cw)' // ccw, cw, cw + to: 'shape(from 15px 15px, arc to 5px -25px of 20px 30px, arc by 25px -15px of 20px 20px cw rotate 270deg small, arc to 25px 20px of 10px 5px small cw)' // ccw, cw, cw }, [ {at: -0.3, expect: 'shape(from 2px 2px, arc to 18px -12px of 7px 17px, arc by 12px -2px of 33px 33px rotate -42deg cw large, arc to 25px 20px of 10px 5px)'}, - {at: 0, expect: 'shape(from 5px 5px, arc to 15px -15px of 10px 20px, arc by 15px -5px of 30px cw rotate 30deg large, arc to 25px 20px of 10px 5px)'}, + {at: 0, expect: 'shape(from 5px 5px, arc to 15px -15px of 10px 20px, arc by 15px -5px of 30px 30px cw rotate 30deg large, arc to 25px 20px of 10px 5px)'}, {at: 0.3, expect: 'shape(from 8px 8px, arc to 12px -18px of 13px 23px, arc by 18px -8px of 27px 27px rotate 102deg cw large, arc to 25px 20px of 10px 5px cw)'}, - {at: 0.5, expect: 'shape(from 10px 10px, arc to 10px -20px of 15px 25px, arc by 20px -10px of 25px rotate 150deg cw large, arc to 25px 20px of 10px 5px cw)'}, - {at: 1, expect: 'shape(from 15px 15px, arc to 5px -25px of 20px 30px, arc by 25px -15px of 20px rotate 270deg cw, arc to 25px 20px of 10px 5px cw)'}, - {at: 1.5, expect: 'shape(from 20px 20px, arc to 0px -30px of 25px 35px, arc by 30px -20px of 15px rotate 390deg cw, arc to 25px 20px of 10px 5px cw)'}, + {at: 0.5, expect: 'shape(from 10px 10px, arc to 10px -20px of 15px 25px, arc by 20px -10px of 25px 25px rotate 150deg cw large, arc to 25px 20px of 10px 5px cw)'}, + {at: 1, expect: 'shape(from 15px 15px, arc to 5px -25px of 20px 30px, arc by 25px -15px of 20px 20px rotate 270deg cw, arc to 25px 20px of 10px 5px cw)'}, + {at: 1.5, expect: 'shape(from 20px 20px, arc to 0px -30px of 25px 35px, arc by 30px -20px of 15px 15px rotate 390deg cw, arc to 25px 20px of 10px 5px cw)'}, ]); </script> diff --git a/tests/wpt/tests/css/css-masking/clip-path/clip-path-shape-011.html b/tests/wpt/tests/css/css-masking/clip-path/clip-path-shape-011.html new file mode 100644 index 00000000000..fc1927591e0 --- /dev/null +++ b/tests/wpt/tests/css/css-masking/clip-path/clip-path-shape-011.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> +<head> + <title>CSS Masking: Test clip-path property and shape function with single-value arc radius</title> + <link rel="help" href="https://drafts.csswg.org/css-shapes-2/#funcdef-shape"> + <link rel="match" href="reference/clip-path-shape-arc-ref.html"> + <meta name="assert" content="When providing one radius value with percentage, the percentage should be relative to the diagonal."> +<meta name="fuzzy" content="maxDifference=0-64;totalPixels=0-128"> +</head> +<style> +#shape { + width: 400px; + height: 300px; + background: green; + clip-path: shape( + from 0px 100px, + arc to 20px 100px of 10% large cw, + arc to 100px 20px of 5% small, + arc to 0 100px of calc(10px + 15%) + rotate 30deg); +} +</style> + +<body> + <div id="shape"></div> +</body> +</html> diff --git a/tests/wpt/tests/css/css-masking/clip-path/reference/clip-path-shape-arc-ref.html b/tests/wpt/tests/css/css-masking/clip-path/reference/clip-path-shape-arc-ref.html new file mode 100644 index 00000000000..9cbe55de210 --- /dev/null +++ b/tests/wpt/tests/css/css-masking/clip-path/reference/clip-path-shape-arc-ref.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> +<head> + <title>CSS Masking: Test clip-path property and shape function with single-value arc radius</title> + <link rel="help" href="https://drafts.csswg.org/css-shapes-2/#funcdef-shape"> +</head> +<style> +#shape { + /* 500/sqrt(2) ~= 353 */ + width: 353px; + height: 353px; + background: green; + clip-path: shape( + from 0px 100px, + arc to 20px 100px of 10% large cw, + arc to 100px 20px of 5% small, + arc to 0 100px of calc(10px + 15%) + rotate 30deg); +} +</style> + +<body> + <div id="shape"></div> +</body> +</html> diff --git a/tests/wpt/tests/css/css-masking/parsing/clip-path-shape-parsing.html b/tests/wpt/tests/css/css-masking/parsing/clip-path-shape-parsing.html index 5a4c7415bb4..b889ee01805 100644 --- a/tests/wpt/tests/css/css-masking/parsing/clip-path-shape-parsing.html +++ b/tests/wpt/tests/css/css-masking/parsing/clip-path-shape-parsing.html @@ -29,8 +29,10 @@ test_valid_value("clip-path", "shape(from 10px 10px, curve to 50px 20px with 10r test_valid_value("clip-path", "shape(from 10px 10px, curve by 50px 20px with 10rem 1px / 20vh 1ch)"); test_valid_value("clip-path", "shape(from 10px 10px, smooth to 50px 20px with 10rem 1%)"); test_valid_value("clip-path", "shape(from 10px 10px, smooth to 50px 1pt)"); -test_valid_value("clip-path", "shape(from 10px 10px, arc to 50px 1pt of 10px 10px)", "shape(from 10px 10px, arc to 50px 1pt of 10px)"); -test_valid_value("clip-path", "shape(from 10px 10px, arc to 50px 1pt of 10px 10px small rotate 0deg)", "shape(from 10px 10px, arc to 50px 1pt of 10px)"); +test_valid_value("clip-path", "shape(from 10px 10px, arc to 50px 1pt of 10px 10px)"); +test_valid_value("clip-path", "shape(from 10px 10px, arc to 50px 1pt of 10%)"); +test_valid_value("clip-path", "shape(from 10px 10px, arc to 50px 1pt of 10px 10px small rotate 0deg)", "shape(from 10px 10px, arc to 50px 1pt of 10px 10px)"); +test_valid_value("clip-path", "shape(from 10px 10px, arc to 50px 1pt of 10px small rotate 0deg)", "shape(from 10px 10px, arc to 50px 1pt of 10px)"); test_valid_value("clip-path", "shape(from 10% 1rem, arc to 50px 1pt of 20% cw large rotate 25deg)", "shape(from 10% 1rem, arc to 50px 1pt of 20% cw large rotate 25deg)"); test_valid_value("clip-path", "shape(evenodd from 0px 0px, close)"); diff --git a/tests/wpt/tests/css/css-multicol/column-height-009-ref.html b/tests/wpt/tests/css/css-multicol/column-height-009-ref.html index 034440ebd5c..4696d79695b 100644 --- a/tests/wpt/tests/css/css-multicol/column-height-009-ref.html +++ b/tests/wpt/tests/css/css-multicol/column-height-009-ref.html @@ -32,7 +32,7 @@ <div class="item">i<br>j</div> <div class="item">o<br>p</div> </div> - <div class="rule" style="height:100px;"></div> + <div class="rule" style="height:160px;"></div> <div class="column"> <div class="item">e<br>f</div> <div class="item">k<br>l</div> diff --git a/tests/wpt/tests/css/css-multicol/crashtests/repeated-table-column.html b/tests/wpt/tests/css/css-multicol/crashtests/repeated-table-column.html new file mode 100644 index 00000000000..0d6a1accfd1 --- /dev/null +++ b/tests/wpt/tests/css/css-multicol/crashtests/repeated-table-column.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://issues.chromium.org/issues/420267099"> +<div style="columns:2; column-fill:auto; height:100px;"> + <div style="display:table;"> + <div style="display:table-header-group; break-inside:avoid;"> + <div style="display:table;"> + <div id="col" style="display:table-column;"></div> + <div style="width:10px; height:10px;"></div> + </div> + </div> + <div style="height:150px;"></div> + </div> +</div> +<script> + col.offsetLeft; +</script> diff --git a/tests/wpt/tests/css/css-multicol/parsing/column-rule-color-invalid.html b/tests/wpt/tests/css/css-multicol/parsing/column-rule-color-invalid.html index 015defb7560..da8dba0a73c 100644 --- a/tests/wpt/tests/css/css-multicol/parsing/column-rule-color-invalid.html +++ b/tests/wpt/tests/css/css-multicol/parsing/column-rule-color-invalid.html @@ -13,7 +13,6 @@ <script> test_invalid_value("column-rule-color", "auto"); -test_invalid_value("column-rule-color", "green blue"); test_invalid_value("column-rule-color", "green, blue"); </script> </body> diff --git a/tests/wpt/tests/css/css-multicol/parsing/column-rule-style-invalid.html b/tests/wpt/tests/css/css-multicol/parsing/column-rule-style-invalid.html index db367c273f4..e8f2ab60c47 100644 --- a/tests/wpt/tests/css/css-multicol/parsing/column-rule-style-invalid.html +++ b/tests/wpt/tests/css/css-multicol/parsing/column-rule-style-invalid.html @@ -12,7 +12,6 @@ <body> <script> test_invalid_value("column-rule-style", "auto"); -test_invalid_value("column-rule-style", "double dashed"); </script> </body> </html> diff --git a/tests/wpt/tests/css/css-multicol/parsing/column-rule-width-invalid.html b/tests/wpt/tests/css/css-multicol/parsing/column-rule-width-invalid.html index 0bdbbecb8ca..77f55e09d93 100644 --- a/tests/wpt/tests/css/css-multicol/parsing/column-rule-width-invalid.html +++ b/tests/wpt/tests/css/css-multicol/parsing/column-rule-width-invalid.html @@ -18,7 +18,6 @@ test_invalid_value("column-rule-width", "10"); test_invalid_value("column-rule-width", "-20px"); test_invalid_value("column-rule-width", "30%"); -test_invalid_value("column-rule-width", "medium 40px"); </script> </body> </html> diff --git a/tests/wpt/tests/css/css-position/overlay/WEB_FEATURES.yml b/tests/wpt/tests/css/css-position/overlay/WEB_FEATURES.yml new file mode 100644 index 00000000000..a1a4402ee42 --- /dev/null +++ b/tests/wpt/tests/css/css-position/overlay/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +features: +- name: overlay + files: "**" diff --git a/tests/wpt/tests/css/css-sizing/contain-intrinsic-size/parsing/from-element.tentative.html b/tests/wpt/tests/css/css-sizing/contain-intrinsic-size/parsing/from-element.tentative.html new file mode 100644 index 00000000000..fe99ccb23d9 --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/contain-intrinsic-size/parsing/from-element.tentative.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Intrinsic Size Test: intrinsic-size with from-element</title> +<link rel="author" title="Chris Harrelson" href="mailto:chrishtr@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#intrinsic-size-override"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_valid_value("contain-intrinsic-size", "from-element"); +</script> +</body> +</html> + diff --git a/tests/wpt/tests/css/css-sizing/image-max-width-and-height-behaves-as-auto.html b/tests/wpt/tests/css/css-sizing/image-max-width-and-height-behaves-as-auto.html new file mode 100644 index 00000000000..dcb00ba6a5c --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/image-max-width-and-height-behaves-as-auto.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> +<head> +<link rel="help" href="https://www.w3.org/TR/CSS22/visudet.html#min-max-widths"> +<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio-size-transfers"> +<meta name="assert" content="When computed logical width is auto, computed logical height behaves as auto, +the used logical height should be determined with respect to any max logical width constraint."> +<link rel="match" href="../reference/ref-filled-green-100px-square-only.html"> +<style> +.container { + width: 100px; +} +img { + max-width: 100%; + height: 100%; +} +</style> +</head> +<body> + <p>Test passes if there is a filled green square.</p> + <div class="container"> + <img src="aspect-ratio/support/200x200-green.png"/> + </div> +</body> +</html> diff --git a/tests/wpt/tests/css/css-sizing/resources/iframe-contents-unsized.html b/tests/wpt/tests/css/css-sizing/resources/iframe-contents-unsized.html new file mode 100644 index 00000000000..db1931a27d5 --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/resources/iframe-contents-unsized.html @@ -0,0 +1,7 @@ +<!doctype HTML> +<head> +<style> + * { margin: 0 } +</style> +</head> +<div style="width: 100px; height: 400px"></div> diff --git a/tests/wpt/tests/css/css-sizing/resources/iframe-contents.html b/tests/wpt/tests/css/css-sizing/resources/iframe-contents.html new file mode 100644 index 00000000000..3b7406e1e40 --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/resources/iframe-contents.html @@ -0,0 +1,8 @@ +<!doctype HTML> +<head> +<style> + * { margin: 0 } +</style> +<meta name="responsive-embedded-sizing"> +</head> +<div style="width: 100px; height: 400px"></div> diff --git a/tests/wpt/tests/css/css-sizing/responsive-iframe-cross-origin-no-match-element.sub.tentative.html b/tests/wpt/tests/css/css-sizing/responsive-iframe-cross-origin-no-match-element.sub.tentative.html new file mode 100644 index 00000000000..08dda4e6b76 --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/responsive-iframe-cross-origin-no-match-element.sub.tentative.html @@ -0,0 +1,12 @@ +<!doctype HTML> +<title>Test that a cross-origin iframe is responsively sized.</title> +<link rel="author" href="mailto:chrishtr@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-sizing/"> +<link rel="match" href="responsive-iframe-unsized-ref.html"> +<style> +iframe { + border: 1px solid black; +} +</style> +<iframe frameborder=0 scrolling=no src="http://{{hosts[alt][]}}:{{ports[http][0]}}/css/css-sizing/resources/iframe-contents.html"> +</iframe> diff --git a/tests/wpt/tests/css/css-sizing/responsive-iframe-cross-origin-not-embedded-sized.sub.tentative.html b/tests/wpt/tests/css/css-sizing/responsive-iframe-cross-origin-not-embedded-sized.sub.tentative.html new file mode 100644 index 00000000000..d9b33973a04 --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/responsive-iframe-cross-origin-not-embedded-sized.sub.tentative.html @@ -0,0 +1,13 @@ +<!doctype HTML> +<title>Test that a cross-origin iframe is responsively sized.</title> +<link rel="author" href="mailto:chrishtr@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-sizing/"> +<link rel="match" href="responsive-iframe-unsized-ref.html"> +<style> +iframe { + border: 1px solid black; + contain-intrinsic-size: from-element; +} +</style> +<iframe frameborder=0 scrolling=no src="http://{{hosts[alt][]}}:{{ports[http][0]}}/css/css-sizing/resources/iframe-contents-unsized.html"> +</iframe> diff --git a/tests/wpt/tests/css/css-sizing/responsive-iframe-cross-origin.sub.tentative.html b/tests/wpt/tests/css/css-sizing/responsive-iframe-cross-origin.sub.tentative.html new file mode 100644 index 00000000000..22f6f1d1581 --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/responsive-iframe-cross-origin.sub.tentative.html @@ -0,0 +1,13 @@ +<!doctype HTML> +<title>Test that a cross-origin iframe is responsively sized.</title> +<link rel="author" href="mailto:chrishtr@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-sizing/"> +<link rel="match" href="responsive-iframe-ref.html"> +<style> +iframe { + border: 1px solid black; + contain-intrinsic-size: from-element; +} +</style> +<iframe frameborder=0 src="http://{{hosts[alt][]}}:{{ports[http][0]}}/css/css-sizing/resources/iframe-contents.html"> +</iframe> diff --git a/tests/wpt/tests/css/css-sizing/responsive-iframe-no-match-element.html b/tests/wpt/tests/css/css-sizing/responsive-iframe-no-match-element.html new file mode 100644 index 00000000000..685eb60f123 --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/responsive-iframe-no-match-element.html @@ -0,0 +1,12 @@ +<!doctype HTML> +<title>Test that a same-origin iframe is responsively sized.</title> +<link rel="author" href="mailto:chrishtr@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-sizing/"> +<link rel="match" href="responsive-iframe-unsized-ref.html"> +<style> +iframe { + border: 1px solid black; +} +</style> +<iframe frameborder=0 scrolling=no src="resources/iframe-contents.html"> +</iframe> diff --git a/tests/wpt/tests/css/css-sizing/responsive-iframe-not-embedded-sized.tentative.html b/tests/wpt/tests/css/css-sizing/responsive-iframe-not-embedded-sized.tentative.html new file mode 100644 index 00000000000..0d1f91c5789 --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/responsive-iframe-not-embedded-sized.tentative.html @@ -0,0 +1,13 @@ +<!doctype HTML> +<title>Test that a same-origin iframe is responsively sized.</title> +<link rel="author" href="mailto:chrishtr@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-sizing/"> +<link rel="match" href="responsive-iframe-unsized-ref.html"> +<style> +iframe { + border: 1px solid black; + contain-intrinsic-size: from-element; +} +</style> +<iframe frameborder=0 scrolling=no src="resources/iframe-contents-unsized.html"> +</iframe> diff --git a/tests/wpt/tests/css/css-sizing/responsive-iframe-ref.html b/tests/wpt/tests/css/css-sizing/responsive-iframe-ref.html new file mode 100644 index 00000000000..c446474f71a --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/responsive-iframe-ref.html @@ -0,0 +1,10 @@ +<!doctype HTML> +<style> +div { + width: 300px; + height: 400px; + border: 1px solid black; +} +</style> +<div> +</div> diff --git a/tests/wpt/tests/css/css-sizing/responsive-iframe-unsized-ref.html b/tests/wpt/tests/css/css-sizing/responsive-iframe-unsized-ref.html new file mode 100644 index 00000000000..2fa633e086d --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/responsive-iframe-unsized-ref.html @@ -0,0 +1,10 @@ +<!doctype HTML> +<style> +div { + width: 300px; + height: 150px; + border: 1px solid black; +} +</style> +<div> +</div> diff --git a/tests/wpt/tests/css/css-sizing/responsive-iframe.tentative.html b/tests/wpt/tests/css/css-sizing/responsive-iframe.tentative.html new file mode 100644 index 00000000000..229cf018449 --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/responsive-iframe.tentative.html @@ -0,0 +1,13 @@ +<!doctype HTML> +<title>Test that a same-origin iframe is responsively sized.</title> +<link rel="author" href="mailto:chrishtr@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-sizing/"> +<link rel="match" href="responsive-iframe-ref.html"> +<style> +iframe { + border: 1px solid black; + contain-intrinsic-size: from-element; +} +</style> +<iframe frameborder=0 src="resources/iframe-contents.html"> +</iframe> diff --git a/tests/wpt/tests/css/css-text/text-autospace/text-autospace-edit-001-ref.html b/tests/wpt/tests/css/css-text/text-autospace/text-autospace-edit-001-ref.html new file mode 100644 index 00000000000..ca95e197462 --- /dev/null +++ b/tests/wpt/tests/css/css-text/text-autospace/text-autospace-edit-001-ref.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +#container { + font-family: Ahem; + font-size: 40px; +} +</style> +<div id="container"> + <div>1国国国国国国国国国国</div> + <div>1国国国国国国国国国国</div> + <div>1国国国国国国国国国国国国</div> + <div>1国国国国国国国国国国国国</div> +</div> diff --git a/tests/wpt/tests/css/css-text/text-autospace/text-autospace-edit-001.html b/tests/wpt/tests/css/css-text/text-autospace/text-autospace-edit-001.html new file mode 100644 index 00000000000..80c46f54d20 --- /dev/null +++ b/tests/wpt/tests/css/css-text/text-autospace/text-autospace-edit-001.html @@ -0,0 +1,35 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<link rel="help" href="https://drafts.csswg.org/css-text-4/#text-autospace-property"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<link rel="match" href="text-autospace-edit-001-ref.html"> +<style> +#container { + font-family: Ahem; + font-size: 40px; +} +</style> +<div id="container"> + <div data-append="10">1国国国国国国国国国国</div> + <div data-append="11">1国国国国国国国国国国国国</div> +</div> +<script> +for (const reference of document.querySelectorAll("[data-append]")) { + // Split the `textContent` at the `data-append` offset. + const text = reference.textContent; + const offset = parseInt(reference.dataset.append); + const initiaL_text = text.substring(0, offset); + const append_text = text.substring(offset); + + // Create a `<div>` with the `initial_text`, then append `append_text` + // one character at a time, with a forced layout. + const element = document.createElement("div"); + const text_node = document.createTextNode(initiaL_text); + element.appendChild(text_node); + reference.after(element); + for (const ch of append_text) { + element.offsetTop; + text_node.appendData(ch); + } +} +</script> diff --git a/tests/wpt/tests/css/css-text/text-autospace/text-autospace-vs-001-ref.html b/tests/wpt/tests/css/css-text/text-autospace/text-autospace-vs-001-ref.html new file mode 100644 index 00000000000..b02b4f7a20d --- /dev/null +++ b/tests/wpt/tests/css/css-text/text-autospace/text-autospace-vs-001-ref.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +#container { + font-family: Ahem; + font-size: 40px; + text-autospace: no-autospace; + + span { + margin-left: calc(1em / 8); + margin-right: calc(1em / 8); + } +} +</style> +<div id="container"> + <div class="test">国︀国</div> + <div class="test">国︀<span>A</span></div> + <div class="test">A︀<span>国</span></div> + <div class="test">国󠄀国</div> + <div class="test">国󠄀<span>A</span></div> + <div class="test">A󠄀<span>国</span></div> +</div> diff --git a/tests/wpt/tests/css/css-text/text-autospace/text-autospace-vs-001.html b/tests/wpt/tests/css/css-text/text-autospace/text-autospace-vs-001.html new file mode 100644 index 00000000000..31c7bbf6073 --- /dev/null +++ b/tests/wpt/tests/css/css-text/text-autospace/text-autospace-vs-001.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<link rel="help" href="https://drafts.csswg.org/css-text-4/#text-autospace-property"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<link rel="match" href="text-autospace-vs-001-ref.html"> +<style> +#container { + font-family: Ahem; + font-size: 40px; +} +</style> +<div id="container"> + <div class="test">国︀国</div> + <div class="test">国︀A</div> + <div class="test">A︀国</div> + <div class="test">国󠄀国</div> + <div class="test">国󠄀A</div> + <div class="test">A󠄀国</div> +</div> diff --git a/tests/wpt/tests/css/css-text/word-break/reference/word-break-keep-all-u002d-ref.html b/tests/wpt/tests/css/css-text/word-break/reference/word-break-keep-all-u002d-ref.html new file mode 100644 index 00000000000..4a6553cfe83 --- /dev/null +++ b/tests/wpt/tests/css/css-text/word-break/reference/word-break-keep-all-u002d-ref.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<style> +#container { + font-size: 20px; + width: 3ch; +} +</style> +<div id="container"> + <div>AB-CD-EF</div> + <div>12-34-56</div> +</div> diff --git a/tests/wpt/tests/css/css-text/word-break/word-break-keep-all-u002d.html b/tests/wpt/tests/css/css-text/word-break/word-break-keep-all-u002d.html new file mode 100644 index 00000000000..df3ebb3f221 --- /dev/null +++ b/tests/wpt/tests/css/css-text/word-break/word-break-keep-all-u002d.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-word-break-keep-all"> +<link rel="match" href="reference/word-break-keep-all-u002d-ref.html"> +<style> +#container { + font-size: 20px; + width: 3ch; + word-break: keep-all; +} +</style> +<div id="container"> + <div>AB-CD-EF</div> + <div>12-34-56</div> +</div> diff --git a/tests/wpt/tests/css/css-transitions/transition-zero-duration-with-delay.html b/tests/wpt/tests/css/css-transitions/transition-zero-duration-with-delay.html index 0b6b9c37a9b..308d8f3784f 100644 --- a/tests/wpt/tests/css/css-transitions/transition-zero-duration-with-delay.html +++ b/tests/wpt/tests/css/css-transitions/transition-zero-duration-with-delay.html @@ -30,7 +30,6 @@ promise_test(async t => { div.style.transition = 'width 0s linear 0.3s'; // Set width back to 0 - const startTime = performance.now(); div.style.width = '0px'; // Immediate check - should NOT have changed yet const computedStart = getComputedStyle(div).width; diff --git a/tests/wpt/tests/css/css-typed-om/the-stylepropertymap/properties/column-rule-style.html b/tests/wpt/tests/css/css-typed-om/the-stylepropertymap/properties/column-rule-style.html index 8e56f621714..7098270a392 100644 --- a/tests/wpt/tests/css/css-typed-om/the-stylepropertymap/properties/column-rule-style.html +++ b/tests/wpt/tests/css/css-typed-om/the-stylepropertymap/properties/column-rule-style.html @@ -14,16 +14,36 @@ 'use strict'; runPropertyTests('column-rule-style', [ - { syntax: 'none' }, - { syntax: 'hidden' }, - { syntax: 'dotted' }, - { syntax: 'dashed' }, - { syntax: 'solid' }, - { syntax: 'double' }, - { syntax: 'groove' }, - { syntax: 'ridge' }, - { syntax: 'inset' }, - { syntax: 'outset' } + { syntax: 'none', + computed: (_, result) => assert_class_string(result, 'CSSStyleValue') + }, + { syntax: 'hidden', + computed: (_, result) => assert_class_string(result, 'CSSStyleValue') + }, + { syntax: 'dotted', + computed: (_, result) => assert_class_string(result, 'CSSStyleValue') + }, + { syntax: 'dashed', + computed: (_, result) => assert_class_string(result, 'CSSStyleValue') + }, + { syntax: 'solid', + computed: (_, result) => assert_class_string(result, 'CSSStyleValue') + }, + { syntax: 'double', + computed: (_, result) => assert_class_string(result, 'CSSStyleValue') + }, + { syntax: 'groove', + computed: (_, result) => assert_class_string(result, 'CSSStyleValue') + }, + { syntax: 'ridge', + computed: (_, result) => assert_class_string(result, 'CSSStyleValue') + }, + { syntax: 'inset', + computed: (_, result) => assert_class_string(result, 'CSSStyleValue') + }, + { syntax: 'outset', + computed: (_, result) => assert_class_string(result, 'CSSStyleValue') + } ]); </script> diff --git a/tests/wpt/tests/css/css-typed-om/the-stylepropertymap/properties/column-rule-width.html b/tests/wpt/tests/css/css-typed-om/the-stylepropertymap/properties/column-rule-width.html index bd3c0ac8f43..8f09d1cb45a 100644 --- a/tests/wpt/tests/css/css-typed-om/the-stylepropertymap/properties/column-rule-width.html +++ b/tests/wpt/tests/css/css-typed-om/the-stylepropertymap/properties/column-rule-width.html @@ -13,30 +13,29 @@ <script> 'use strict'; -function assert_is_zero_px(result) { - assert_style_value_equals(result, new CSSUnitValue(0, 'px')); -} - runPropertyTests('column-rule-width', [ - // Computed value is 0 when column-rule-style is 'none'. - // FIXME: Add separate test where column-rule-style is not 'none' or 'hidden'. { syntax: 'thin', - computed: (_, result) => assert_is_zero_px(result) + computed: (_, result) => assert_class_string(result, 'CSSStyleValue') }, { syntax: 'medium', - computed: (_, result) => assert_is_zero_px(result) + computed: (_, result) => assert_class_string(result, 'CSSStyleValue') }, { syntax: 'thick', - computed: (_, result) => assert_is_zero_px(result) + computed: (_, result) => assert_class_string(result, 'CSSStyleValue') }, { syntax: '<length>', specified: assert_is_equal_with_range_handling, - computed: (_, result) => assert_is_zero_px(result) + computed: (_, result) => assert_class_string(result, 'CSSStyleValue') }, ]); +runUnsupportedPropertyTests('column-rule-width', [ + 'thin', 'medium', 'thick', '2px', '3px', + '4px 5px', 'thin medium thick', +]); + </script> diff --git a/tests/wpt/tests/css/css-values/if-conditionals.html b/tests/wpt/tests/css/css-values/if-conditionals.html index caead7864d5..f6d981798ae 100644 --- a/tests/wpt/tests/css/css-values/if-conditionals.html +++ b/tests/wpt/tests/css/css-values/if-conditionals.html @@ -37,6 +37,21 @@ inherits: true; initial-value: 3; } + @property --angle { + syntax: "<angle>"; + inherits: true; + initial-value: 3deg; + } + @property --time { + syntax: "<time>"; + inherits: true; + initial-value: 3s; + } + @property --resolution { + syntax: "<resolution>"; + inherits: true; + initial-value: 3dpi; + } div { font-size: 30px; } @@ -511,6 +526,122 @@ [['--length', 'attr(data-foo type(<length>))']], 'false_value'); + // style() queries with range syntax in the condition, literals on both sides of equation + test_if_with_custom_properties('if(style(10em > 3px): true_value; else: false_value)', [], 'true_value'); + test_if_with_custom_properties('if(style(1em > 1px): true_value; else: false_value)', [], 'true_value'); + test_if_with_custom_properties('if(style(7px > 3px): true_value; else: false_value)', [], 'true_value'); + test_if_with_custom_properties('if(style(3px > 3px): true_value; else: false_value)', [], 'false_value'); + test_if_with_custom_properties('if(style(3turn > 3deg): true_value; else: false_value)', [], 'true_value'); + test_if_with_custom_properties('if(style(3turn <= 3deg): true_value; else: false_value)', [], 'false_value'); + test_if_with_custom_properties('if(style(3% >= 3%): true_value; else: false_value)', [], 'true_value'); + test_if_with_custom_properties('if(style(3s > 3ms): true_value; else: false_value)', [], 'true_value'); + test_if_with_custom_properties('if(style(3dppx > 96dpi): true_value; else: false_value)', [], 'true_value'); + + // style() queries with range syntax in the condition, simple custom properties in the condition + test_if_with_custom_properties('if(style(--x <= 3): true_value; else: false_value)', + [['--x', '3']], + 'true_value'); + test_if_with_custom_properties('if(style(--x >= --y): true_value; else: false_value)', + [['--x', '3'], ['--y', '3']], + 'true_value'); + test_if_with_custom_properties('if(style(--length > 3px): true_value; else: false_value)', + [['--length', '11px']], + 'true_value'); + test_if_with_custom_properties('if(style(--x > 3px): true_value; else: false_value)', + [['--x', '11px']], + 'true_value'); + test_if_with_custom_properties('if(style(--number >= 3): true_value; else: false_value)', + [['--number', '3']], + 'true_value'); + test_if_with_custom_properties('if(style(--x >= 3): true_value; else: false_value)', + [['--x', '3']], + 'true_value'); + test_if_with_custom_properties('if(style(--percentage > 3%): true_value; else: false_value)', + [['--percentage', '5%']], + 'true_value'); + test_if_with_custom_properties('if(style(--x > 3%): true_value; else: false_value)', + [['--x', '5%']], + 'true_value'); + test_if_with_custom_properties('if(style(--angle < 1turn): true_value; else: false_value)', + [['--angle', '1deg']], + 'true_value'); + test_if_with_custom_properties('if(style(--x < 1turn): true_value; else: false_value)', + [['--x', '1deg']], + 'true_value'); + test_if_with_custom_properties('if(style(--time <= 1000ms): true_value; else: false_value)', + [['--time', '1s']], + 'true_value'); + test_if_with_custom_properties('if(style(--x <= 1000ms): true_value; else: false_value)', + [['--x', '1s']], + 'true_value'); + test_if_with_custom_properties('if(style(3dppx > --resolution): true_value; else: false_value)', + [['--resolution', '96dpi']], + 'true_value'); + test_if_with_custom_properties('if(style(3dppx > --x): true_value; else: false_value)', + [['--x', '96dpi']], + 'true_value'); + + // style() queries with range syntax in the condition, invalid custom properties in the condition + test_if_with_custom_properties('if(style(--x + 1 >= --y): true_value; else: false_value)', + [['--x', '5'], ['--y', '3']], + 'false_value'); + test_if_with_custom_properties('if(style(--x >= --y + 1): true_value; else: false_value)', + [['--x', '5'], ['--y', '3']], + 'false_value'); + test_if_with_custom_properties('if(style(calc(--x + 1) >= --y): true_value; else: false_value)', + [['--x', '5'], ['--y', '3']], + 'false_value'); + test_if_with_custom_properties('if(style(--x >= calc(--y + 1)): true_value; else: false_value)', + [['--x', '5'], ['--y', '3']], + 'false_value'); + + // style() queries with range syntax in the condition, custom properties with functions in the condition + test_if_with_custom_properties('if(style(--x >= calc(3px + 3px)): true_value; else: false_value)', + [['--x', '7px']], + 'true_value'); + test_if_with_custom_properties('if(style(calc(var(--x) + 1) >= var(--y)): true_value; else: false_value)', + [['--x', '5'], ['--y', '3']], + 'true_value'); + test_if_with_custom_properties('if(style(var(--x) >= --x): true_value; else: false_value)', + [['--x', '3']], + 'true_value'); + + // style() queries with range syntax in the condition, incompatible types in the range. + test_if_with_custom_properties('if(style(3px > 3): true_value; else: false_value)', + [], + 'false_value'); + test_if_with_custom_properties('if(style(3em > 3deg): true_value; else: false_value)', + [], + 'false_value'); + test_if_with_custom_properties('if(style(1px >= 1%) or style(1px <= 1%): true_value; else: false_value)', + [], + 'false_value'); + test_if_with_custom_properties('if(style(--length > 3): true_value; else: false_value)', + [['--length', '11em']], + 'false_value'); + test_if_with_custom_properties('if(style(--number > 3px): true_value; else: false_value)', + [['--number', '11']], + 'false_value'); + test_if_with_custom_properties('if(style(--x >= 3): true_value; else: false_value)', + [['--x', '3px']], + 'false_value'); + test_if_with_custom_properties(`if(style(--length >= 30px): true_value; + else: false_value)`, + [['--length', 'attr(data-foo type(<length>))']], + 'true_value'); + + // style() queries with range syntax in the condition, double range + test_if_with_custom_properties('if(style(10px <= 10px < 11px): true_value; else: false_value)', [], 'true_value'); + test_if_with_custom_properties('if(style(3 < --x <= 5): true_value; else: false_value)', + [['--x', '5']], + 'true_value'); + test_if_with_custom_properties('if(style(--x >= --y > --z): true_value; else: false_value)', + [['--x', '3'], ['--y', '3'], ['--z', '3']], + 'false_value'); + test_if_with_custom_properties('if(style(--x >= --y > --z): true_value; else: false_value)', + [['--x', '3'], ['--y', '3'], ['--z', '1']], + 'true_value'); + // media() queries in the condition test_if(`if(media(max-width: 1px): true_value; else: false_value)`, diff --git a/tests/wpt/tests/css/css-values/tree-counting/sibling-function-container-query-invalidation.html b/tests/wpt/tests/css/css-values/tree-counting/sibling-function-container-query-invalidation.html new file mode 100644 index 00000000000..c0d6d913af0 --- /dev/null +++ b/tests/wpt/tests/css/css-values/tree-counting/sibling-function-container-query-invalidation.html @@ -0,0 +1,92 @@ +<!DOCTYPE html> +<title>CSS Values and Units Test: sibling-index() and sibling-count() changes in container queries</title> +<link rel="help" href="https://drafts.csswg.org/css-values-5/#tree-counting"> +<link rel="help" href="https://drafts.csswg.org/css-conditional-5/#container-features"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + @property --length { + syntax: "<length>"; + initial-value: 0px; + inherits: false; + } + .container { container-type: inline-size; } + #c1 { + width: 100px; + --length: 100px; + } + #c2 { + width: 400px; + --length: 600px; + } + span { + --match-100: no; + --match-600: no; + } + @container (width = calc(100px * sibling-index())) { + span { background-color: green; } + } + @container (width = calc(200px * sibling-count())) { + span { color: lime; } + } + @container style(--length: calc(100px * sibling-index())) { + span { --match-100: yes; } + } + @container style(--length: calc(300px * sibling-count())) { + span { --match-600: yes; } + } +</style> +<div style="color:black"> + <div id="rm1"></div> + <div id="rm2"></div> + <div id="c1" class="container"> + <span id="t1"></span> + </div> + <div id="c2" class="container"> + <span id="t2"></span> + </div> +</div> +<script> + test(() => { + assert_equals(getComputedStyle(t1).backgroundColor, "rgba(0, 0, 0, 0)"); + assert_equals(getComputedStyle(t1).color, "rgb(0, 0, 0)"); + }, "sibling-index() in @container width query initially not matching"); + + test(() => { + assert_equals(getComputedStyle(t1).backgroundColor, "rgba(0, 0, 0, 0)"); + assert_equals(getComputedStyle(t1).color, "rgb(0, 0, 0)"); + }, "sibling-count() in @container width query initially not matching"); + + test(() => { + assert_equals(getComputedStyle(t1).getPropertyValue("--match-100"), "no"); + assert_equals(getComputedStyle(t1).getPropertyValue("--match-600"), "no"); + }, "sibling-index() in @container style() query initially not matching"); + + test(() => { + assert_equals(getComputedStyle(t2).getPropertyValue("--match-100"), "no"); + assert_equals(getComputedStyle(t2).getPropertyValue("--match-600"), "no"); + }, "sibling-count() in @container style() query initially not matching"); + + rm1.remove(); + rm2.remove(); + + test(() => { + assert_equals(getComputedStyle(t1).backgroundColor, "rgb(0, 128, 0)"); + assert_equals(getComputedStyle(t1).color, "rgb(0, 0, 0)"); + }, "sibling-index() in @container width query matching after removal"); + + test(() => { + assert_equals(getComputedStyle(t2).backgroundColor, "rgba(0, 0, 0, 0)"); + assert_equals(getComputedStyle(t2).color, "rgb(0, 255, 0)"); + }, "sibling-count() in @container width query matching after removal"); + + test(() => { + assert_equals(getComputedStyle(t1).getPropertyValue("--match-100"), "yes"); + assert_equals(getComputedStyle(t1).getPropertyValue("--match-600"), "no"); + }, "sibling-index() in @container style() query matching after removal"); + + test(() => { + assert_equals(getComputedStyle(t2).getPropertyValue("--match-100"), "no"); + assert_equals(getComputedStyle(t2).getPropertyValue("--match-600"), "yes"); + }, "sibling-count() in @container style() query matching after removal"); +</script> diff --git a/tests/wpt/tests/css/css-values/tree-counting/sibling-index-keyframe-registered-properties-dynamic.html b/tests/wpt/tests/css/css-values/tree-counting/sibling-index-keyframe-registered-properties-dynamic.html index 77af5434a1c..ac2ed1a8af1 100644 --- a/tests/wpt/tests/css/css-values/tree-counting/sibling-index-keyframe-registered-properties-dynamic.html +++ b/tests/wpt/tests/css/css-values/tree-counting/sibling-index-keyframe-registered-properties-dynamic.html @@ -13,6 +13,7 @@ @property --length { syntax: "<length>"; initial-value: 0px; inherits: false; } @property --length-percentage { syntax: "<length-percentage>"; initial-value: 0px; inherits: false; } @property --color { syntax: "<color>"; initial-value: black; inherits: false; } + @property --list { syntax: "<integer>+"; initial-value: 0; inherits: false; } @keyframes --anim { from { @@ -25,6 +26,7 @@ --length: calc(sibling-index() * 7px); --length-percentage: calc((sibling-index() * 8px) + (sibling-count() * 5%)); --color: color(srgb 0 calc(0.2 * sibling-index()) 0); + --list: 13 sibling-index(); } to { --time: 13s; @@ -36,6 +38,7 @@ --length: 13px; --length-percentage: calc(13px + 7%); --color: red; + --list: 29 sibling-index(); } } #target { @@ -75,6 +78,9 @@ test(() => { assert_equals(getComputedStyle(target).getPropertyValue("--color"), "color(srgb 0 0.6 0)"); }, "Initially, the sibling-index() is 3 for --color"); + test(() => { + assert_equals(getComputedStyle(target).getPropertyValue("--list"), "13 3"); + }, "Initially, the sibling-index() is 3 for --list"); rm.remove(); @@ -105,5 +111,8 @@ test(() => { assert_equals(getComputedStyle(target).getPropertyValue("--color"), "color(srgb 0 0.4 0)"); }, "Removing a preceding sibling of #target reduces the sibling-index() for --color"); + test(() => { + assert_equals(getComputedStyle(target).getPropertyValue("--list"), "13 2"); + }, "Removing a preceding sibling of #target reduces the sibling-index() for --list"); </script> diff --git a/tests/wpt/tests/css/css-view-transitions/auto-name-from-id.html b/tests/wpt/tests/css/css-view-transitions/auto-name-from-id.html index d3430c93a1d..20080d7623a 100644 --- a/tests/wpt/tests/css/css-view-transitions/auto-name-from-id.html +++ b/tests/wpt/tests/css/css-view-transitions/auto-name-from-id.html @@ -34,6 +34,12 @@ main.switch #item1 { left: 100px; } +/* Make test fail if ID matches */ +::view-transition-group(item1), +::view-transition-group(item2) { + border: 2px solid red; +} + html::view-transition { background: rebeccapurple; } diff --git a/tests/wpt/tests/css/css-view-transitions/auto-name-get-animations.html b/tests/wpt/tests/css/css-view-transitions/auto-name-get-animations.html index 0442255542c..b684349a5f9 100644 --- a/tests/wpt/tests/css/css-view-transitions/auto-name-get-animations.html +++ b/tests/wpt/tests/css/css-view-transitions/auto-name-get-animations.html @@ -1,6 +1,6 @@ <!DOCTYPE html> <html > -<title>View transitions: generated names should not be visible from script</title> +<title>View transitions: generated names should be prefixed with -ua- in script</title> <link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> @@ -57,12 +57,20 @@ main.switch .item1 { }).ready; const animations = document.documentElement.getAnimations({subtree: true}); const pseudos = Array.from(new Set(animations.map(a => a.effect.pseudoElement))); + const item1GeneratedName = pseudos[0].replace("::view-transition-group(", "").slice(0, -1); + const item2GeneratedName = pseudos[3].replace("::view-transition-group(", "").slice(0, -1); + assert_true(item1GeneratedName.startsWith("-ua-"), "Item 1 generated name starts with -ua-"); + assert_true(item2GeneratedName.startsWith("-ua-"), "Item 2 generated name starts with -ua-"); assert_array_equals(pseudos, [ - "::view-transition-group(match-element)", - "::view-transition-new(match-element)", - "::view-transition-old(match-element)"]); - }, "Generated view-transition-names should not be reflected in script"); + `::view-transition-group(${item1GeneratedName})`, + `::view-transition-old(${item1GeneratedName})`, + `::view-transition-new(${item1GeneratedName})`, + `::view-transition-group(${item2GeneratedName})`, + `::view-transition-old(${item2GeneratedName})`, + `::view-transition-new(${item2GeneratedName})` + ], "Generated names should start with -ua- and pseudo-elements should be in tree order"); + }, "Generated view-transition-names should be prefixed with -ua- in script"); </script> </body>
\ No newline at end of file diff --git a/tests/wpt/tests/css/css-view-transitions/inline-child-with-composited-filter-ref.html b/tests/wpt/tests/css/css-view-transitions/inline-child-with-composited-filter-ref.html new file mode 100644 index 00000000000..9dd26f2c3b1 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/inline-child-with-composited-filter-ref.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<title>View transitions: inline child with filter (ref)</title> +<link rel="help" href="https://www.w3.org/TR/css-view-transitions-1/"> +<link rel="author" href="mailto:vmpstr@chromium.org"> +<link rel="author" href="mailto:mattwoodrow@apple.com"> + +<style> +body { margin : 0; } +#target { + width: 100px; + height: 100px; + background-color: grey; + overflow-clip-margin: 40px; + contain: paint; + view-transition-name: target; +} + +#child { + position: relative; + left: 100px; + top: 100px; + color: lightgreen; + background-color: darkgreen; + filter: blur(30px); + transform: translateZ(0px); +} +</style> + +<div id="target"> + <span id="child">INLINEBOX</span> +</div> diff --git a/tests/wpt/tests/css/css-view-transitions/inline-child-with-composited-filter.html b/tests/wpt/tests/css/css-view-transitions/inline-child-with-composited-filter.html new file mode 100644 index 00000000000..36ba9803e1e --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/inline-child-with-composited-filter.html @@ -0,0 +1,57 @@ +<!DOCTYPE html> +<html class=reftest-wait> +<title>View transitions: inline child with filter</title> +<link rel="help" href="https://www.w3.org/TR/css-view-transitions-1/"> +<link rel="author" href="mailto:vmpstr@chromium.org"> +<link rel="author" href="mailto:mattwoodrow@apple.com"> +<link rel="match" href="inline-child-with-filter-ref.html"> +<meta name=fuzzy content="maxDifference=0-2;totalPixels=0-2400"> +<script src="/common/reftest-wait.js"></script> + +<style> +body { margin : 0; } +#target { + width: 100px; + height: 100px; + background-color: grey; + overflow-clip-margin: 40px; + contain: paint; + view-transition-name: target; +} + +#child { + position: relative; + left: 100px; + top: 100px; + color: lightgreen; + background-color: darkgreen; + filter: blur(30px); + transform: translateZ(0px); +} + +html::view-transition-group(root) { animation-duration: 300s; } +html::view-transition-old(target) { + animation: unset; + opacity: 1; +} +html::view-transition-new(target) { + animation: unset; + opacity: 0; +} +</style> + +<div id="target"> + <span id="child">INLINEBOX</span> +</div> + +<script> +failIfNot(document.startViewTransition, "Missing document.startViewTransition"); + +async function runTest() { + let transition = document.startViewTransition(async () => { + document.getElementById("target").remove(); + }); + transition.ready.then(() => requestAnimationFrame(takeScreenshot)); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/inline-with-offset-from-containing-block.html b/tests/wpt/tests/css/css-view-transitions/inline-with-offset-from-containing-block.html index 31f8449ff63..77fb0570966 100644 --- a/tests/wpt/tests/css/css-view-transitions/inline-with-offset-from-containing-block.html +++ b/tests/wpt/tests/css/css-view-transitions/inline-with-offset-from-containing-block.html @@ -4,7 +4,7 @@ <link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/"> <link rel="author" href="mailto:khushalsagar@chromium.org"> <link rel="match" href="inline-with-offset-from-containing-block-ref.html"> -<meta name="fuzzy" content="maxDifference=0-255; totalPixels=0-1500"> +<meta name="fuzzy" content="maxDifference=0-255; totalPixels=0-1633"> <script src="/common/reftest-wait.js"></script> <script src="/common/rendering-utils.js"></script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/resources/auto-name-from-id.html b/tests/wpt/tests/css/css-view-transitions/navigation/resources/auto-name-from-id.html index 71ea52a273e..dc2cf8fd29b 100644 --- a/tests/wpt/tests/css/css-view-transitions/navigation/resources/auto-name-from-id.html +++ b/tests/wpt/tests/css/css-view-transitions/navigation/resources/auto-name-from-id.html @@ -29,6 +29,11 @@ html::view-transition-group(*) { animation-timing-function: steps(2, start); } +/* Make test fail if ID matches */ +::view-transition-group(green) { + border: 2px solid red; +} + #green { background: green; width: 100px; diff --git a/tests/wpt/tests/css/css-view-transitions/nested/nested-exit.tentative.html b/tests/wpt/tests/css/css-view-transitions/nested/nested-exit.tentative.html index 83570762061..847058be2b4 100644 --- a/tests/wpt/tests/css/css-view-transitions/nested/nested-exit.tentative.html +++ b/tests/wpt/tests/css/css-view-transitions/nested/nested-exit.tentative.html @@ -15,6 +15,10 @@ animation-play-state: paused; } + ::view-transition-group-children(*) { + background: inherit; + } + ::view-transition-group(parent) { background: green; visibility: hidden; diff --git a/tests/wpt/tests/css/css-view-transitions/nested/resources/compute-common.css b/tests/wpt/tests/css/css-view-transitions/nested/resources/compute-common.css index 20337ccce5f..d8f46179b40 100644 --- a/tests/wpt/tests/css/css-view-transitions/nested/resources/compute-common.css +++ b/tests/wpt/tests/css/css-view-transitions/nested/resources/compute-common.css @@ -57,6 +57,9 @@ html.no-match::view-transition { ::view-transition-group(green) { background: green; } +::view-transition-group-children(*) { + background: inherit; +} ::view-transition-group(test) { background: inherit; } diff --git a/tests/wpt/tests/css/css-view-transitions/nested/rounded-border-clipper.html b/tests/wpt/tests/css/css-view-transitions/nested/rounded-border-clipper.html index 239bcdd791d..098e5566585 100644 --- a/tests/wpt/tests/css/css-view-transitions/nested/rounded-border-clipper.html +++ b/tests/wpt/tests/css/css-view-transitions/nested/rounded-border-clipper.html @@ -33,6 +33,9 @@ ::view-transition-group(clipper) { animation-play-state: paused; +} + +::view-transition-group-children(clipper) { overflow: clip; border-radius: 20px; } diff --git a/tests/wpt/tests/css/css-view-transitions/new-content-captures-different-size.html b/tests/wpt/tests/css/css-view-transitions/new-content-captures-different-size.html index eeb7347981d..0a754c651ff 100644 --- a/tests/wpt/tests/css/css-view-transitions/new-content-captures-different-size.html +++ b/tests/wpt/tests/css/css-view-transitions/new-content-captures-different-size.html @@ -5,7 +5,7 @@ <link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/"> <link rel="author" href="mailto:vmpstr@chromium.org"> <link rel="match" href="new-content-captures-different-size-ref.html"> -<meta name=fuzzy content="maxDifference=0-100; totalPixels=0-15000"> +<meta name=fuzzy content="maxDifference=0-100; totalPixels=0-15393"> <script src="/common/reftest-wait.js"></script> <style> html { diff --git a/tests/wpt/tests/css/css-view-transitions/pseudo-with-classes-view-transition-group.html b/tests/wpt/tests/css/css-view-transitions/pseudo-with-classes-view-transition-group.html index f9fe2022258..14717728b15 100644 --- a/tests/wpt/tests/css/css-view-transitions/pseudo-with-classes-view-transition-group.html +++ b/tests/wpt/tests/css/css-view-transitions/pseudo-with-classes-view-transition-group.html @@ -17,7 +17,10 @@ view-transition-class: cls; } -:root::view-transition-group(*) { +:root::view-transition-group(*), +:root::view-transition-image-pair(*), +:root::view-transition-new(*), +:root::view-transition-old(*) { animation-play-state: paused; } diff --git a/tests/wpt/tests/css/css-view-transitions/scoped/crashtests/participating-scope.html b/tests/wpt/tests/css/css-view-transitions/scoped/crashtests/participating-scope.html new file mode 100644 index 00000000000..26979e58458 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/scoped/crashtests/participating-scope.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html class="test-wait"> +<head> +<style> +body { margin: 5px; } +#scope { contain: strict; position: relative; z-index: 0; + width: 150px; height: 100px; border: 5px solid #ccc; + view-transition-name: container; } +.item { width: 6rem; height: 4rem; margin: 10px; background: #def; + view-transition-name: a1; contain: strict; } +::view-transition-group(*), +::view-transition-old(*), +::view-transition-new(*) { animation: unset; } +</style> +</head> +<body> +<div id="scope"><div class="item"></div></div> +<script> +onload = async () => { + await scope.startViewTransition().finished; + document.documentElement.classList.remove('test-wait'); +} +</script> +</body> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/scoped/nested-scope-ref.html b/tests/wpt/tests/css/css-view-transitions/scoped/nested-scope-ref.html index 804741cd6db..951c0928687 100644 --- a/tests/wpt/tests/css/css-view-transitions/scoped/nested-scope-ref.html +++ b/tests/wpt/tests/css/css-view-transitions/scoped/nested-scope-ref.html @@ -4,7 +4,7 @@ <style> .box { position: relative; contain: strict; } -#scopeA { background: #ddd; +#scopeA { background: #ccc; left: 0; top: 0; width: 300px; height: 300px; } #partA { background: #4af; left: 30px; top: 30px; width: 240px; height: 240px; } diff --git a/tests/wpt/tests/css/css-view-transitions/scoped/nested-scope.html b/tests/wpt/tests/css/css-view-transitions/scoped/nested-scope.html index 9fff44e5e73..b9cc25c3338 100644 --- a/tests/wpt/tests/css/css-view-transitions/scoped/nested-scope.html +++ b/tests/wpt/tests/css/css-view-transitions/scoped/nested-scope.html @@ -36,11 +36,22 @@ failIfNot(scopeA.startViewTransition, "Missing element.startViewTransition"); +// This test runs simultaneous transitions on two scopes, one inside the other. +// It verifies that the inner and outer participants are both visible while both +// transitions are in progress. (This entails rendering the inner transition +// through the ::view-transition-new for the outer participant.) async function runTest() { await waitForCompositorReady(); await scopeB.startViewTransition().ready; + + // Untag partB to avoid a collision when the outer transition looks for its + // participants. (We can stop doing this once we have contain: view-transition + // or similar.) partB.classList.remove("tr"); - await scopeA.startViewTransition().ready; + + await scopeA.startViewTransition(() => { + scopeA.style.background = "#ccc"; + }).ready; requestAnimationFrame(takeScreenshot); } onload = () => runTest(); diff --git a/tests/wpt/tests/css/css-viewport/zoom/height.html b/tests/wpt/tests/css/css-viewport/zoom/height.html new file mode 100644 index 00000000000..f608765bcf1 --- /dev/null +++ b/tests/wpt/tests/css/css-viewport/zoom/height.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<title>height:inherit applies zoom</title> +<link rel="help" href="https://drafts.csswg.org/css-viewport/"> +<link rel="match" href="green-square-100px.html"> +<style> + div > div { + background-color: green; + } +</style> +<div style="height:50px"> + <div style="zoom:2; width:50px; height:inherit;"></div> +</div> diff --git a/tests/wpt/tests/css/css-viewport/zoom/inherited-length.html b/tests/wpt/tests/css/css-viewport/zoom/inherited-length.html index d83111a4352..571b533d5d6 100644 --- a/tests/wpt/tests/css/css-viewport/zoom/inherited-length.html +++ b/tests/wpt/tests/css/css-viewport/zoom/inherited-length.html @@ -10,6 +10,6 @@ div { background-color: green; } </style> -<div style="width: 100px; height: 100px;"> - <div style="zoom: 2; width: inherit;"></div> +<div style="width: 50px; height: 50px;"> + <div style="zoom: 2; width: inherit; height: inherit;"></div> </div> diff --git a/tests/wpt/tests/css/css-viewport/zoom/length-implicit-and-explicit-inheritance.html b/tests/wpt/tests/css/css-viewport/zoom/length-implicit-and-explicit-inheritance.html new file mode 100644 index 00000000000..003c7b61c09 --- /dev/null +++ b/tests/wpt/tests/css/css-viewport/zoom/length-implicit-and-explicit-inheritance.html @@ -0,0 +1,38 @@ +<!doctype html> +<meta charset="utf-8"> +<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez"> +<link rel="author" href="https://mozilla.org" title="Mozilla"> +<link rel="help" href="https://drafts.csswg.org/css-viewport/#zoom-property"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div style="zoom: 2"> + <div style="zoom: 2" id="parent"> + <!-- effective zoom of 8, inherited zoom (4) times specified zoom (2) --> + <div style="zoom: 2" id="target"></div> + </div> +</div> +<script> + const kTestCases = [ + // Explicitly inherited reset properties. + ["width", "100px", "inherit", "100px"], + ["height", "100px", "inherit", "100px"], + // Explicitly inherited properties. + ["word-spacing", "100px", "inherit", "100px"], + ["word-spacing", "100px", "unset", "100px"], + // Implicitly inherited properties. + ["word-spacing", "100px", "", "100px"], + ]; + + const parent = document.getElementById("parent"); + const target = document.getElementById("target"); + for (const [prop, parentValue, childValue, expected] of kTestCases) { + test(function(t) { + parent.style[prop] = parentValue; + target.style[prop] = childValue; + t.add_cleanup(function() { + parent.style[prop] = target.style[prop] = ""; + }); + assert_equals(getComputedStyle(target).getPropertyValue(prop), expected); + }, `${prop}: ${childValue} from ${parentValue}`); + } +</script> diff --git a/tests/wpt/tests/css/css-viewport/zoom/max-height.html b/tests/wpt/tests/css/css-viewport/zoom/max-height.html new file mode 100644 index 00000000000..6a0dcd826e2 --- /dev/null +++ b/tests/wpt/tests/css/css-viewport/zoom/max-height.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<title>max-height:inherit applies zoom</title> +<link rel="help" href="https://drafts.csswg.org/css-viewport/"> +<link rel="match" href="green-square-100px.html"> +<style> + div > div { + background-color: green; + } +</style> +<div style="max-height:50px"> + <div style="zoom:2; width:50px; height:200px; max-height:inherit;"></div> +</div> diff --git a/tests/wpt/tests/css/css-viewport/zoom/max-width.html b/tests/wpt/tests/css/css-viewport/zoom/max-width.html new file mode 100644 index 00000000000..b6d4139e30a --- /dev/null +++ b/tests/wpt/tests/css/css-viewport/zoom/max-width.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<title>max-width:inherit applies zoom</title> +<link rel="help" href="https://drafts.csswg.org/css-viewport/"> +<link rel="match" href="green-square-100px.html"> +<style> + div > div { + background-color: green; + } +</style> +<div style="max-width:50px"> + <div style="zoom:2; max-width:inherit; height:50px; width:300px;"></div> +</div> diff --git a/tests/wpt/tests/css/css-viewport/zoom/min-height.html b/tests/wpt/tests/css/css-viewport/zoom/min-height.html new file mode 100644 index 00000000000..31a47d92b21 --- /dev/null +++ b/tests/wpt/tests/css/css-viewport/zoom/min-height.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<title>min-height:inherit applies zoom</title> +<link rel="help" href="https://drafts.csswg.org/css-viewport/"> +<link rel="match" href="green-square-100px.html"> +<style> + div > div { + background-color: green; + } +</style> +<div style="min-height:50px"> + <div style="zoom:2; width:50px; min-height:inherit;"></div> +</div> diff --git a/tests/wpt/tests/css/css-viewport/zoom/min-width.html b/tests/wpt/tests/css/css-viewport/zoom/min-width.html new file mode 100644 index 00000000000..bd1cda23d3a --- /dev/null +++ b/tests/wpt/tests/css/css-viewport/zoom/min-width.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<title>min-width:inherit applies zoom</title> +<link rel="help" href="https://drafts.csswg.org/css-viewport/"> +<link rel="match" href="green-square-100px.html"> +<style> + div > div { + background-color: green; + } +</style> +<div style="min-width:50px"> + <div style="zoom:2; min-width:inherit; height:50px; width:0px"></div> +</div> diff --git a/tests/wpt/tests/css/css-writing-modes/orthogonal-cell-001-ref.html b/tests/wpt/tests/css/css-writing-modes/orthogonal-cell-001-ref.html new file mode 100644 index 00000000000..f50121ef16d --- /dev/null +++ b/tests/wpt/tests/css/css-writing-modes/orthogonal-cell-001-ref.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<meta charset=utf-8> + +<title>CSS writing-mode reference</title> + +<style> +table { margin: 10px; } +td { background: green; padding: 10px 20px 30px 40px; } +div { width: 20px; height: 40px; background: blue; } +</style> + +<p>All five green squares should look the same, with a blue rectangle towards the upper right.</p> + +<table> + <td><div></div></td> +</table> + +<table> + <td><div></div></td> +</table> + +<table> + <td><div></div></td> +</table> + +<table> + <td><div></div></td> +</table> + +<table> + <td><div></div></td> +</table> diff --git a/tests/wpt/tests/css/css-writing-modes/orthogonal-cell-001.html b/tests/wpt/tests/css/css-writing-modes/orthogonal-cell-001.html new file mode 100644 index 00000000000..12e996ac902 --- /dev/null +++ b/tests/wpt/tests/css/css-writing-modes/orthogonal-cell-001.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<meta charset=utf-8> + +<title>CSS writing-mode test: orthogonal table cells</title> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1959395"> +<link rel="match" href="orthogonal-cell-001-ref.html"> + +<style> +table { margin: 10px; } +td { background: green; padding: 10px 20px 30px 40px; } +div { width: 20px; height: 40px; background: blue; } +.htb { writing-mode: horizontal-tb; } +.vlr { writing-mode: vertical-lr; } +.vrl { writing-mode: vertical-rl; } +</style> + +<p>All five green squares should look the same, with a blue rectangle towards the upper right.</p> + +<table> + <td><div></div></td> +</table> + +<!-- The different writing modes should not disrupt the table cell/row sizing. --> +<table class=htb> + <td class=vlr><div></div></td> +</table> + +<table class=htb> + <td class=vrl><div></div></td> +</table> + +<table class=vlr> + <td class=htb><div></div></td> +</table> + +<table class=vrl> + <td class=htb><div></div></td> +</table> diff --git a/tests/wpt/tests/css/motion/animation/offset-path-interpolation-008.html b/tests/wpt/tests/css/motion/animation/offset-path-interpolation-008.html index 5fb7c7c333c..ff7d4a108c7 100644 --- a/tests/wpt/tests/css/motion/animation/offset-path-interpolation-008.html +++ b/tests/wpt/tests/css/motion/animation/offset-path-interpolation-008.html @@ -132,15 +132,15 @@ test_interpolation({ property: 'offset-path', - from: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)', - to: 'shape(from 15% 15px, arc to 5% -25px of 20px 30px, arc by 25% -15px of 20px cw rotate 270deg small, arc to 25% 20px of 10px 5px small cw)' + from: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)', + to: 'shape(from 15% 15px, arc to 5% -25px of 20px 30px, arc by 25% -15px of 20px 20px cw rotate 270deg small, arc to 25% 20px of 10px 5px small cw)' }, [ {at: -0.3, expect: 'shape(from 2% 2px, arc to 18% -12px of 7px 17px ccw small, arc by 12% -2px of 33px 33px rotate -42deg cw large , arc to 25% 20px of 10px 5px ccw small)'}, - {at: 0, expect: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)'}, + {at: 0, expect: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)'}, {at: 0.3, expect: 'shape(from 8% 8px, arc to 12% -18px of 13px 23px ccw small, arc by 18% -8px of 27px 27px rotate 102deg cw large, arc to 25% 20px of 10px 5px cw small )'}, - {at: 0.5, expect: 'shape(from 10% 10px, arc to 10% -20px of 15px 25px ccw small, arc by 20% -10px of 25px rotate 150deg cw large, arc to 25% 20px of 10px 5px cw small)'}, - {at: 1, expect: 'shape(from 15% 15px, arc to 5% -25px of 20px 30px, arc by 25% -15px of 20px rotate 270deg cw small, arc to 25% 20px of 10px 5px cw small)'}, - {at: 1.5, expect: 'shape(from 20% 20px, arc to 0% -30px of 25px 35px ccw small, arc by 30% -20px of 15px rotate 390deg cw small, arc to 25% 20px of 10px 5px cw small)'}, + {at: 0.5, expect: 'shape(from 10% 10px, arc to 10% -20px of 15px 25px ccw small, arc by 20% -10px of 25px 25px rotate 150deg cw large, arc to 25% 20px of 10px 5px cw small)'}, + {at: 1, expect: 'shape(from 15% 15px, arc to 5% -25px of 20px 30px, arc by 25% -15px of 20px 20px rotate 270deg cw small, arc to 25% 20px of 10px 5px cw small)'}, + {at: 1.5, expect: 'shape(from 20% 20px, arc to 0% -30px of 25px 35px ccw small, arc by 30% -20px of 15px 15px rotate 390deg cw small, arc to 25% 20px of 10px 5px cw small)'}, ]); test_interpolation({ @@ -235,28 +235,28 @@ test_interpolation({ property: 'offset-path', - from: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)', + from: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)', to: 'path("M 15 15 A 20,30 0 0,0 5,-25 a 20,20 270 0,1 25,-15 A 10,5 0 0,0 25 20")', }, [ - {at: -0.3, expect: 'shape(from calc(6.5% - 4.5px) 2px, arc to calc(19.5% - 1.5px) -12px of 7px 17px, arc by calc(19.5% - 7.5px) -2px of 33px cw large rotate -42deg, arc to calc(32.5% - 7.5px) 20px of 10px 5px)'}, - {at: 0, expect: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)'}, - {at: 0.3, expect: 'shape(from calc(3.5% + 4.5px) 8px, arc to calc(10.5% + 1.5px) -18px of 13px 23px, arc by calc(10.5% + 7.5px) -8px of 27px cw large rotate 102deg, arc to calc(17.5% + 7.5px) 20px of 10px 5px)'}, - {at: 0.5, expect: 'shape(from calc(2.5% + 7.5px) 10px, arc to calc(7.5% + 2.5px) -20px of 15px 25px, arc by calc(7.5% + 12.5px) -10px of 25px cw large rotate 150deg, arc to calc(12.5% + 12.5px) 20px of 10px 5px)'}, - {at: 1, expect: 'shape(from calc(0% + 15px) 15px, arc to calc(0% + 5px) -25px of 20px 30px, arc by calc(0% + 25px) -15px of 20px cw rotate 270deg, arc to calc(0% + 25px) 20px of 10px 5px)'}, - {at: 1.5, expect: 'shape(from calc(-2.5% + 22.5px) 20px, arc to calc(-7.5% + 7.5px) -30px of 25px 35px, arc by calc(-7.5% + 37.5px) -20px of 15px cw rotate 390deg, arc to calc(-12.5% + 37.5px) 20px of 10px 5px)'}, + {at: -0.3, expect: 'shape(from calc(6.5% - 4.5px) 2px, arc to calc(19.5% - 1.5px) -12px of 7px 17px, arc by calc(19.5% - 7.5px) -2px of 33px 33px cw large rotate -42deg, arc to calc(32.5% - 7.5px) 20px of 10px 5px)'}, + {at: 0, expect: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px 30px cw large rotate 30deg, arc to 25% 20px of 10px 5px)'}, + {at: 0.3, expect: 'shape(from calc(3.5% + 4.5px) 8px, arc to calc(10.5% + 1.5px) -18px of 13px 23px, arc by calc(10.5% + 7.5px) -8px of 27px 27px cw large rotate 102deg, arc to calc(17.5% + 7.5px) 20px of 10px 5px)'}, + {at: 0.5, expect: 'shape(from calc(2.5% + 7.5px) 10px, arc to calc(7.5% + 2.5px) -20px of 15px 25px, arc by calc(7.5% + 12.5px) -10px of 25px 25px cw large rotate 150deg, arc to calc(12.5% + 12.5px) 20px of 10px 5px)'}, + {at: 1, expect: 'shape(from calc(0% + 15px) 15px, arc to calc(0% + 5px) -25px of 20px 30px, arc by calc(0% + 25px) -15px of 20px 20px cw rotate 270deg, arc to calc(0% + 25px) 20px of 10px 5px)'}, + {at: 1.5, expect: 'shape(from calc(-2.5% + 22.5px) 20px, arc to calc(-7.5% + 7.5px) -30px of 25px 35px, arc by calc(-7.5% + 37.5px) -20px of 15px 15px cw rotate 390deg, arc to calc(-12.5% + 37.5px) 20px of 10px 5px)'}, ]); test_interpolation({ property: 'offset-path', from: 'path("M 5 5 A 10,20 0 0,0 15,-15 a 30,30 30 1,1 15,-5 A 10,5 0 0,0 25 20")', - to: 'shape(from 15px 15px, arc to 5px -25px of 20px 30px, arc by 25px -15px of 20px cw rotate 270deg small, arc to 25px 20px of 10px 5px small cw)' + to: 'shape(from 15px 15px, arc to 5px -25px of 20px 30px, arc by 25px -15px of 20px 20px cw rotate 270deg small, arc to 25px 20px of 10px 5px small cw)' }, [ - {at: -0.3, expect: 'shape(from 2px 2px, arc to 18px -12px of 7px 17px ccw small, arc by 12px -2px of 33px 33px rotate -42deg cw large, arc to 25px 20px of 10px 5px ccw small)'}, - {at: 0, expect: 'shape(from 5px 5px, arc to 15px -15px of 10px 20px, arc by 15px -5px of 30px cw rotate 30deg large, arc to 25px 20px of 10px 5px small)'}, + {at: -0.3, expect: 'shape(from 2px 2px, arc to 18px -12px of 7px 17px ccw small, arc by 12px -2px of 33px 33px rotate -42deg cw large, arc to 25px 20px of 10px 5px ccw small)'}, + {at: 0, expect: 'shape(from 5px 5px, arc to 15px -15px of 10px 20px, arc by 15px -5px of 30px 30px cw rotate 30deg large, arc to 25px 20px of 10px 5px small)'}, {at: 0.3, expect: 'shape(from 8px 8px, arc to 12px -18px of 13px 23px ccw small, arc by 18px -8px of 27px 27px rotate 102deg cw large, arc to 25px 20px of 10px 5px cw small)'}, - {at: 0.5, expect: 'shape(from 10px 10px, arc to 10px -20px of 15px 25px ccw small, arc by 20px -10px of 25px rotate 150deg cw large, arc to 25px 20px of 10px 5px cw small)'}, - {at: 1, expect: 'shape(from 15px 15px, arc to 5px -25px of 20px 30px, arc by 25px -15px of 20px rotate 270deg cw small, arc to 25px 20px of 10px 5px cw small)'}, - {at: 1.5, expect: 'shape(from 20px 20px, arc to 0px -30px of 25px 35px ccw small, arc by 30px -20px of 15px rotate 390deg cw small, arc to 25px 20px of 10px 5px cw small)'}, + {at: 0.5, expect: 'shape(from 10px 10px, arc to 10px -20px of 15px 25px ccw small, arc by 20px -10px of 25px 25px rotate 150deg cw large, arc to 25px 20px of 10px 5px cw small)'}, + {at: 1, expect: 'shape(from 15px 15px, arc to 5px -25px of 20px 30px, arc by 25px -15px of 20px 20px rotate 270deg cw small, arc to 25px 20px of 10px 5px cw small)'}, + {at: 1.5, expect: 'shape(from 20px 20px, arc to 0px -30px of 25px 35px ccw small, arc by 30px -20px of 15px 15px rotate 390deg cw small, arc to 25px 20px of 10px 5px cw small)'}, ]); </script> diff --git a/tests/wpt/tests/css/motion/parsing/offset-path-shape-computed.html b/tests/wpt/tests/css/motion/parsing/offset-path-shape-computed.html index c9ecc3acb06..6ced1ad395a 100644 --- a/tests/wpt/tests/css/motion/parsing/offset-path-shape-computed.html +++ b/tests/wpt/tests/css/motion/parsing/offset-path-shape-computed.html @@ -27,8 +27,8 @@ test_computed_value("offset-path", "shape(from 10px 10px, curve to 50px 20px wit test_computed_value("offset-path", "shape(from 10px 10px, curve to 50px 20px with 10rem 1px / 20% 1em)", "shape(from 10px 10px, curve to 50px 20px with 160px 1px / 20% 16px)"); test_computed_value("offset-path", "shape(from 10px 10px, smooth to 50px 20px with 10rem 1%)", "shape(from 10px 10px, smooth to 50px 20px with 160px 1%)"); test_computed_value("offset-path", "shape(from 10px 10px, smooth to 50px 3pt)", "shape(from 10px 10px, smooth to 50px 4px)"); -test_computed_value("offset-path", "shape(from 10px 10px, arc to 50px 3pt of 10px 10px)", "shape(from 10px 10px, arc to 50px 4px of 10px)"); -test_computed_value("offset-path", "shape(from 10px 10px, arc to 50px 3pt of 10px 10px small rotate 0deg)", "shape(from 10px 10px, arc to 50px 4px of 10px)"); +test_computed_value("offset-path", "shape(from 10px 10px, arc to 50px 3pt of 10px 10px)", "shape(from 10px 10px, arc to 50px 4px of 10px 10px)"); +test_computed_value("offset-path", "shape(from 10px 10px, arc to 50px 3pt of 10px small rotate 0deg)", "shape(from 10px 10px, arc to 50px 4px of 10px)"); test_computed_value("offset-path", "shape(from 10% 1rem, arc to 50px 3pt of 20% cw large rotate 25deg)", "shape(from 10% 16px, arc to 50px 4px of 20% cw large rotate 25deg)"); </script> </body> diff --git a/tests/wpt/tests/css/motion/parsing/offset-path-shape-parsing.html b/tests/wpt/tests/css/motion/parsing/offset-path-shape-parsing.html index 013cea2c821..4a3d9f16915 100644 --- a/tests/wpt/tests/css/motion/parsing/offset-path-shape-parsing.html +++ b/tests/wpt/tests/css/motion/parsing/offset-path-shape-parsing.html @@ -28,8 +28,8 @@ test_valid_value("offset-path", "shape(from 10px 10px, curve to 50px 20px with 1 test_valid_value("offset-path", "shape(from 10px 10px, curve by 50px 20px with 10rem 1px / 20vh 1ch)"); test_valid_value("offset-path", "shape(from 10px 10px, smooth to 50px 20px with 10rem 1%)"); test_valid_value("offset-path", "shape(from 10px 10px, smooth to 50px 1pt)"); -test_valid_value("offset-path", "shape(from 10px 10px, arc to 50px 1pt of 10px 10px)", "shape(from 10px 10px, arc to 50px 1pt of 10px)"); -test_valid_value("offset-path", "shape(from 10px 10px, arc to 50px 1pt of 10px 10px small rotate 0deg)", "shape(from 10px 10px, arc to 50px 1pt of 10px)"); +test_valid_value("offset-path", "shape(from 10px 10px, arc to 50px 1pt of 10px 10px)", "shape(from 10px 10px, arc to 50px 1pt of 10px 10px)"); +test_valid_value("offset-path", "shape(from 10px 10px, arc to 50px 1pt of 10px 10px small rotate 0deg)", "shape(from 10px 10px, arc to 50px 1pt of 10px 10px)"); test_valid_value("offset-path", "shape(from 10% 1rem, arc to 50px 1pt of 20% cw large rotate 25deg)", "shape(from 10% 1rem, arc to 50px 1pt of 20% cw large rotate 25deg)"); test_valid_value("offset-path", "shape(evenodd from 0px 0px, line to 10px 10px)"); test_valid_value("offset-path", "shape(nonzero from 0px 0px, line to 10px 10px)", "shape(from 0px 0px, line to 10px 10px)"); diff --git a/tests/wpt/tests/css/visited-nested-ref.html b/tests/wpt/tests/css/selectors/visited-nested-ref.html index 22f4ecf0d7b..22f4ecf0d7b 100644 --- a/tests/wpt/tests/css/visited-nested-ref.html +++ b/tests/wpt/tests/css/selectors/visited-nested-ref.html diff --git a/tests/wpt/tests/css/visited-nested.html b/tests/wpt/tests/css/selectors/visited-nested.html index 57220446c86..57220446c86 100644 --- a/tests/wpt/tests/css/visited-nested.html +++ b/tests/wpt/tests/css/selectors/visited-nested.html diff --git a/tests/wpt/tests/domxpath/fn-id.html b/tests/wpt/tests/domxpath/fn-id.html new file mode 100644 index 00000000000..617ff7216d8 --- /dev/null +++ b/tests/wpt/tests/domxpath/fn-id.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<link rel="help" href="https://www.w3.org/TR/1999/REC-xpath-19991116/#function-id"> +<body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +// Test the id() function with various scenarios +function testIdFunction(expression, xmlString, expectedIds) { + let doc = (new DOMParser()).parseFromString(xmlString, 'text/xml'); + test(() => { + let result = doc.evaluate(expression, doc.documentElement, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); + assert_equals(result.resultType, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE); + let actualIds = []; + for (let i = 0; i < result.snapshotLength; i++) { + actualIds.push(result.snapshotItem(i).getAttribute('id')); + } + actualIds.sort(); + expectedIds.sort(); + assert_array_equals(actualIds, expectedIds, `Expected IDs ${expectedIds}, got ${actualIds}`); + }, `${expression}: ${doc.documentElement.outerHTML}`); +} + +// Test single ID +testIdFunction('id("test1")', '<root><div id="test1">Match</div></root>', ['test1']); + +// Test multiple IDs in space-separated string +testIdFunction('id("test1 test2")', '<root><div id="test1">First</div><div id="test2">Second</div></root>', ['test1', 'test2']); + +// Test non-existent ID +testIdFunction('id("nonexistent")', '<root><div id="test1">No match</div></root>', []); + +// Test mixed case IDs (should be case-sensitive) +testIdFunction('id("Test1")', '<root><div id="test1">No match</div></root>', []); + +// Test multiple elements with same ID (should return all) +testIdFunction('id("duplicate")', '<root><div id="duplicate">First</div><div id="duplicate">Second</div></root>', ['duplicate', 'duplicate']); + +// Test IDs with special characters +testIdFunction('id("test-1")', '<root><div id="test-1">Match</div></root>', ['test-1']); + +// Test empty ID string +testIdFunction('id("")', '<root><div id="">Empty ID</div></root>', []); + +// Test whitespace in ID string +testIdFunction('id(" test1 ")', '<root><div id="test1">Match</div></root>', ['test1']); +</script> +</body> diff --git a/tests/wpt/tests/editing/crashtests/indent-outdent-after-closing-editable-dialog-element.html b/tests/wpt/tests/editing/crashtests/indent-outdent-after-closing-editable-dialog-element.html deleted file mode 100644 index 7f73de048d7..00000000000 --- a/tests/wpt/tests/editing/crashtests/indent-outdent-after-closing-editable-dialog-element.html +++ /dev/null @@ -1,31 +0,0 @@ -<html class="reftest-wait"> -<script> -var eventCount = 0; -document.addEventListener("DOMContentLoaded", () => { - const dialog = document.querySelector("dialog"); - const object = document.createElement("object"); - object.addEventListener("DOMSubtreeModified", () => { - dialog.show(); - dialog.focus(); - document.execCommand("selectAll"); - dialog.close(); - setTimeout(() => { - document.execCommand("selectAll"); - document.execCommand("strikeThrough"); - document.execCommand("indent"); - document.execCommand("outdent"); - eventCount--; - if (!eventCount) { - document.documentElement.removeAttribute("class"); - } - }); - eventCount++; - }); - object.setAttribute("role", "x"); // Run DOMSubtreeModified - object.setAttribute("role", "y"); // Run DOMSubtreeModified - document.execCommand("forwardDelete"); - document.execCommand("justifyRight"); -}) -</script> -<dialog id="a" contenteditable="true">a</dialog> -</html>
\ No newline at end of file diff --git a/tests/wpt/tests/editing/other/move-inserted-node-from-DOMNodeInserted-during-exec-command-insertHTML.html b/tests/wpt/tests/editing/other/move-inserted-node-from-DOMNodeInserted-during-exec-command-insertHTML.html deleted file mode 100644 index 41e012a62e9..00000000000 --- a/tests/wpt/tests/editing/other/move-inserted-node-from-DOMNodeInserted-during-exec-command-insertHTML.html +++ /dev/null @@ -1,27 +0,0 @@ -<!doctype html> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<div contenteditable> -<p id="p1"><br></p> -<p id="p2"></p> -</div> -<script> -"use strict"; -let editor = document.querySelector("[contenteditable]"); -let p1 = document.getElementById("p1"); -let p2 = document.getElementById("p2"); -p1.addEventListener("DOMNodeInserted", event => { - if (event.target.localName === "i") { - p2.appendChild(event.target); - } -}); -document.getSelection().collapse(p1, 0); -document.execCommand("insertHTML", false, - "<b>bold1</b><i>italic1</i><b>bold2</b><i>italic2</i>"); -test(function () { - assert_in_array(p1.innerHTML, ["<b>bold1</b><b>bold2</b><br>", "<b>bold1</b><b>bold2</b>"]); -}, "First <p> element should have only <b> elements"); -test(function () { - assert_equals(p2.innerHTML, "<i>italic1</i><i>italic2</i>"); -}, "Second <p> element should have only <i> elements"); -</script>
\ No newline at end of file diff --git a/tests/wpt/tests/fetch/content-encoding/br/bad-br-body.https.any.js b/tests/wpt/tests/fetch/content-encoding/br/bad-br-body.https.any.js index 43ea90a336c..af5df674da6 100644 --- a/tests/wpt/tests/fetch/content-encoding/br/bad-br-body.https.any.js +++ b/tests/wpt/tests/fetch/content-encoding/br/bad-br-body.https.any.js @@ -2,6 +2,11 @@ [ "arrayBuffer", + "blob", + "bytes", + "formData", + "json", + "text" ].forEach(method => { promise_test(t => { return fetch("resources/bad-br-body.py").then(res => { diff --git a/tests/wpt/tests/fetch/content-encoding/gzip/bad-gzip-body.any.js b/tests/wpt/tests/fetch/content-encoding/gzip/bad-gzip-body.any.js index 17bc1261a3f..77a183f408b 100644 --- a/tests/wpt/tests/fetch/content-encoding/gzip/bad-gzip-body.any.js +++ b/tests/wpt/tests/fetch/content-encoding/gzip/bad-gzip-body.any.js @@ -9,6 +9,7 @@ promise_test((test) => { [ "arrayBuffer", "blob", + "bytes", "formData", "json", "text" diff --git a/tests/wpt/tests/fetch/content-encoding/zstd/bad-zstd-body.https.any.js b/tests/wpt/tests/fetch/content-encoding/zstd/bad-zstd-body.https.any.js index 3f32e4dfba7..c59980c2c6f 100644 --- a/tests/wpt/tests/fetch/content-encoding/zstd/bad-zstd-body.https.any.js +++ b/tests/wpt/tests/fetch/content-encoding/zstd/bad-zstd-body.https.any.js @@ -9,6 +9,7 @@ promise_test((test) => { [ "arrayBuffer", "blob", + "bytes", "formData", "json", "text" diff --git a/tests/wpt/tests/fetch/local-network-access/resources/fetch-private-http.html b/tests/wpt/tests/fetch/local-network-access/resources/fetch-private-http.html index e372d90b26a..517629b758e 100644 --- a/tests/wpt/tests/fetch/local-network-access/resources/fetch-private-http.html +++ b/tests/wpt/tests/fetch/local-network-access/resources/fetch-private-http.html @@ -23,8 +23,7 @@ Promise.resolve().then(async () => { }; const targetUrl = resolveTargetUrl(target); - // TODO(crbug.com/406991278): rename address space for LNA spec - fetch(targetUrl, {targetAddressSpace: 'private'}) + fetch(targetUrl, {targetAddressSpace: 'local'}) .then(async function(response) { const body = await response.text(); const message = { diff --git a/tests/wpt/tests/fetch/local-network-access/resources/fetch-public-http-wrong-address-space.html b/tests/wpt/tests/fetch/local-network-access/resources/fetch-public-http-wrong-address-space.html index 1d149d00cb3..c15a87ff7b9 100644 --- a/tests/wpt/tests/fetch/local-network-access/resources/fetch-public-http-wrong-address-space.html +++ b/tests/wpt/tests/fetch/local-network-access/resources/fetch-public-http-wrong-address-space.html @@ -25,8 +25,7 @@ Promise.resolve().then(async () => { }; const targetUrl = resolveTargetUrl(target); - // TODO(crbug.com/406991278): rename address space for LNA spec - fetch(targetUrl, {targetAddressSpace: 'private'}) + fetch(targetUrl, {targetAddressSpace: 'local'}) .then(async function(response) { const body = await response.text(); const message = { diff --git a/tests/wpt/tests/fetch/private-network-access/mixed-content-fetch.tentative.https.window.js b/tests/wpt/tests/fetch/private-network-access/mixed-content-fetch.tentative.https.window.js deleted file mode 100644 index dbae5193b5c..00000000000 --- a/tests/wpt/tests/fetch/private-network-access/mixed-content-fetch.tentative.https.window.js +++ /dev/null @@ -1,278 +0,0 @@ -// META: script=/common/utils.js -// META: script=resources/support.sub.js -// META: timeout=long -// -// Spec: https://wicg.github.io/private-network-access -// -// These tests verify that secure contexts can fetch non-secure subresources -// from more private address spaces, avoiding mixed context checks, as long as -// they specify a valid `targetAddressSpace` fetch option that matches the -// target server's address space. - -setup(() => { - // Making sure we are in a secure context, as expected. - assert_true(window.isSecureContext); -}); - -// Given `addressSpace`, returns the other three possible IP address spaces. -function otherAddressSpaces(addressSpace) { - switch (addressSpace) { - case "local": return ["unknown", "private", "public"]; - case "private": return ["unknown", "local", "public"]; - case "public": return ["unknown", "local", "private"]; - } -} - -// Generates tests of `targetAddressSpace` for the given (source, target) -// address space pair, expecting fetches to succeed iff `targetAddressSpace` is -// correct. -// -// Scenarios exercised: -// -// - cors mode: -// - missing targetAddressSpace option -// - incorrect targetAddressSpace option (x3, see `otherAddressSpaces()`) -// - failed preflight -// - success -// - success with PUT method (non-"simple" request) -// - no-cors mode: -// - success -// -function makeTests({ source, target }) { - const sourceServer = Server.get("https", source); - const targetServer = Server.get("http", target); - - const makeTest = ({ - fetchOptions, - targetBehavior, - name, - expected - }) => { - promise_test_parallel(t => fetchTest(t, { - source: { server: sourceServer }, - target: { - server: targetServer, - behavior: targetBehavior, - }, - fetchOptions, - expected, - }), `${sourceServer.name} to ${targetServer.name}: ${name}.`); - }; - - makeTest({ - name: "missing targetAddressSpace", - targetBehavior: { - preflight: PreflightBehavior.success(token()), - response: ResponseBehavior.allowCrossOrigin(), - }, - expected: FetchTestResult.FAILURE, - }); - - const correctAddressSpace = targetServer.addressSpace; - - for (const targetAddressSpace of otherAddressSpaces(correctAddressSpace)) { - makeTest({ - name: `wrong targetAddressSpace "${targetAddressSpace}"`, - targetBehavior: { - preflight: PreflightBehavior.success(token()), - response: ResponseBehavior.allowCrossOrigin(), - }, - fetchOptions: { targetAddressSpace }, - expected: FetchTestResult.FAILURE, - }); - } - - makeTest({ - name: "failed preflight", - targetBehavior: { - preflight: PreflightBehavior.failure(), - response: ResponseBehavior.allowCrossOrigin(), - }, - fetchOptions: { targetAddressSpace: correctAddressSpace }, - expected: FetchTestResult.FAILURE, - }); - - makeTest({ - name: "success", - targetBehavior: { - preflight: PreflightBehavior.success(token()), - response: ResponseBehavior.allowCrossOrigin(), - }, - fetchOptions: { targetAddressSpace: correctAddressSpace }, - expected: FetchTestResult.SUCCESS, - }); - - makeTest({ - name: "PUT success", - targetBehavior: { - preflight: PreflightBehavior.success(token()), - response: ResponseBehavior.allowCrossOrigin(), - }, - fetchOptions: { - targetAddressSpace: correctAddressSpace, - method: "PUT", - }, - expected: FetchTestResult.SUCCESS, - }); - - makeTest({ - name: "no-cors success", - targetBehavior: { - preflight: PreflightBehavior.success(token()), - response: ResponseBehavior.allowCrossOrigin(), - }, - fetchOptions: { - targetAddressSpace: correctAddressSpace, - mode: "no-cors", - }, - expected: FetchTestResult.OPAQUE, - }); -} - -// Generates tests for the given (source, target) address space pair expecting -// that `targetAddressSpace` cannot be used to bypass mixed content. -// -// Scenarios exercised: -// -// - wrong `targetAddressSpace` (x3, see `otherAddressSpaces()`) -// - correct `targetAddressSpace` -// -function makeNoBypassTests({ source, target }) { - const sourceServer = Server.get("https", source); - const targetServer = Server.get("http", target); - - const prefix = `${sourceServer.name} to ${targetServer.name}: `; - - const correctAddressSpace = targetServer.addressSpace; - for (const targetAddressSpace of otherAddressSpaces(correctAddressSpace)) { - promise_test_parallel(t => fetchTest(t, { - source: { server: sourceServer }, - target: { - server: targetServer, - behavior: { - preflight: PreflightBehavior.success(token()), - response: ResponseBehavior.allowCrossOrigin(), - }, - }, - fetchOptions: { targetAddressSpace }, - expected: FetchTestResult.FAILURE, - }), prefix + `wrong targetAddressSpace "${targetAddressSpace}".`); - } - - promise_test_parallel(t => fetchTest(t, { - source: { server: sourceServer }, - target: { - server: targetServer, - behavior: { - preflight: PreflightBehavior.success(token()), - response: ResponseBehavior.allowCrossOrigin(), - }, - }, - fetchOptions: { targetAddressSpace: correctAddressSpace }, - expected: FetchTestResult.FAILURE, - }), prefix + 'not a private network request.'); -} - -// Source: local secure context. -// -// Fetches to the local and private address spaces cannot use -// `targetAddressSpace` to bypass mixed content, as they are not otherwise -// blocked by Private Network Access. - -makeNoBypassTests({ source: "local", target: "local" }); -makeNoBypassTests({ source: "local", target: "private" }); -makeNoBypassTests({ source: "local", target: "public" }); - -// Source: private secure context. -// -// Fetches to the local address space requires the right `targetAddressSpace` -// option, as well as a successful preflight response carrying a PNA-specific -// header. -// -// Fetches to the private address space cannot use `targetAddressSpace` to -// bypass mixed content, as they are not otherwise blocked by Private Network -// Access. - -makeTests({ source: "private", target: "local" }); - -makeNoBypassTests({ source: "private", target: "private" }); -makeNoBypassTests({ source: "private", target: "public" }); - -// Source: public secure context. -// -// Fetches to the local and private address spaces require the right -// `targetAddressSpace` option, as well as a successful preflight response -// carrying a PNA-specific header. - -makeTests({ source: "public", target: "local" }); -makeTests({ source: "public", target: "private" }); - -makeNoBypassTests({ source: "public", target: "public" }); - -// These tests verify that documents fetched from the `local` address space yet -// carrying the `treat-as-public-address` CSP directive are treated as if they -// had been fetched from the `public` address space. - -promise_test_parallel(t => fetchTest(t, { - source: { - server: Server.HTTPS_LOCAL, - treatAsPublic: true, - }, - target: { - server: Server.HTTP_LOCAL, - behavior: { - preflight: PreflightBehavior.optionalSuccess(token()), - response: ResponseBehavior.allowCrossOrigin(), - }, - }, - fetchOptions: { targetAddressSpace: "private" }, - expected: FetchTestResult.FAILURE, -}), 'https-treat-as-public to http-local: wrong targetAddressSpace "private".'); - -promise_test_parallel(t => fetchTest(t, { - source: { - server: Server.HTTPS_LOCAL, - treatAsPublic: true, - }, - target: { - server: Server.HTTP_LOCAL, - behavior: { - preflight: PreflightBehavior.optionalSuccess(token()), - response: ResponseBehavior.allowCrossOrigin(), - }, - }, - fetchOptions: { targetAddressSpace: "local" }, - expected: FetchTestResult.SUCCESS, -}), "https-treat-as-public to http-local: success."); - -promise_test_parallel(t => fetchTest(t, { - source: { - server: Server.HTTPS_LOCAL, - treatAsPublic: true, - }, - target: { - server: Server.HTTP_PRIVATE, - behavior: { - preflight: PreflightBehavior.success(token()), - response: ResponseBehavior.allowCrossOrigin(), - }, - }, - fetchOptions: { targetAddressSpace: "local" }, - expected: FetchTestResult.FAILURE, -}), 'https-treat-as-public to http-private: wrong targetAddressSpace "local".'); - -promise_test_parallel(t => fetchTest(t, { - source: { - server: Server.HTTPS_LOCAL, - treatAsPublic: true, - }, - target: { - server: Server.HTTP_PRIVATE, - behavior: { - preflight: PreflightBehavior.success(token()), - response: ResponseBehavior.allowCrossOrigin(), - }, - }, - fetchOptions: { targetAddressSpace: "private" }, - expected: FetchTestResult.SUCCESS, -}), "https-treat-as-public to http-private: success."); diff --git a/tests/wpt/tests/fetch/private-network-access/window-open-existing.tentative.https.window.js b/tests/wpt/tests/fetch/private-network-access/window-open-existing.tentative.https.window.js deleted file mode 100644 index 6a2a624fc80..00000000000 --- a/tests/wpt/tests/fetch/private-network-access/window-open-existing.tentative.https.window.js +++ /dev/null @@ -1,209 +0,0 @@ -// META: script=/common/subset-tests-by-key.js -// META: script=/common/dispatcher/dispatcher.js -// META: script=/common/utils.js -// META: script=resources/support.sub.js -// META: timeout=long -// META: variant=?include=from-local -// META: variant=?include=from-private -// META: variant=?include=from-public -// META: variant=?include=from-treat-as-public -// -// These tests verify that secure contexts can navigate to less-public address -// spaces via window.open to an existing window iff the target server responds -// affirmatively to preflight requests. - -setup(() => { - assert_true(window.isSecureContext); -}); - -// Source: secure local context. -// -// All fetches unaffected by Private Network Access. - -subsetTestByKey( - 'from-local', promise_test_parallel, - t => windowOpenExistingTest(t, { - source: {server: Server.HTTPS_LOCAL}, - target: {server: Server.HTTPS_LOCAL}, - expected: NavigationTestResult.SUCCESS, - }), - 'local to local: no preflight required.'); - -subsetTestByKey( - 'from-local', promise_test_parallel, - t => windowOpenExistingTest(t, { - source: {server: Server.HTTPS_LOCAL}, - target: {server: Server.HTTPS_PRIVATE}, - expected: NavigationTestResult.SUCCESS, - }), - 'local to private: no preflight required.'); - -subsetTestByKey( - 'from-local', promise_test_parallel, - t => windowOpenExistingTest(t, { - source: {server: Server.HTTPS_LOCAL}, - target: {server: Server.HTTPS_PUBLIC}, - expected: NavigationTestResult.SUCCESS, - }), - 'local to public: no preflight required.'); - -// Generates tests of preflight behavior for a single (source, target) pair. -// -// Scenarios: -// -// - preflight response has non-2xx HTTP code -// - preflight response is missing CORS headers -// - preflight response is missing the PNA-specific `Access-Control` header -// - success -// -function makePreflightTests({ - key, - sourceName, - sourceServer, - sourceTreatAsPublic, - targetName, - targetServer, -}) { - const prefix = - `${sourceName} to ${targetName}: `; - - const source = { - server: sourceServer, - treatAsPublic: sourceTreatAsPublic, - }; - - promise_test_parallel(t => windowOpenExistingTest(t, { - source, - target: { - server: targetServer, - behavior: { preflight: PreflightBehavior.failure() }, - }, - expected: NavigationTestResult.FAILURE, - }), prefix + "failed preflight."); - - promise_test_parallel(t => windowOpenExistingTest(t, { - source, - target: { - server: targetServer, - behavior: { preflight: PreflightBehavior.noCorsHeader(token()) }, - }, - expected: NavigationTestResult.FAILURE, - }), prefix + "missing CORS headers."); - - promise_test_parallel(t => windowOpenExistingTest(t, { - source, - target: { - server: targetServer, - behavior: { preflight: PreflightBehavior.noPnaHeader(token()) }, - }, - expected: NavigationTestResult.FAILURE, - }), prefix + "missing PNA header."); - - promise_test_parallel(t => windowOpenExistingTest(t, { - source, - target: { - server: targetServer, - behavior: { preflight: PreflightBehavior.navigation(token()) }, - }, - expected: NavigationTestResult.SUCCESS, - }), prefix + "success."); -} - -// Source: private secure context. -// -// Navigating to the local address space require a successful preflight response -// carrying a PNA-specific header. - -subsetTestByKey('from-private', makePreflightTests, { - sourceServer: Server.HTTPS_PRIVATE, - sourceName: 'private', - targetServer: Server.HTTPS_LOCAL, - targetName: 'local', -}); - -subsetTestByKey( - 'from-private', promise_test_parallel, - t => windowOpenExistingTest(t, { - source: {server: Server.HTTPS_PRIVATE}, - target: {server: Server.HTTPS_PRIVATE}, - expected: NavigationTestResult.SUCCESS, - }), - 'private to private: no preflight required.'); - -subsetTestByKey( - 'from-private', promise_test_parallel, - t => windowOpenExistingTest(t, { - source: {server: Server.HTTPS_PRIVATE}, - target: {server: Server.HTTPS_PUBLIC}, - expected: NavigationTestResult.SUCCESS, - }), - 'private to public: no preflight required.'); - -// Source: public secure context. -// -// Navigating to the local and private address spaces require a successful -// preflight response carrying a PNA-specific header. - -subsetTestByKey('from-public', makePreflightTests, { - sourceServer: Server.HTTPS_PUBLIC, - sourceName: "public", - targetServer: Server.HTTPS_LOCAL, - targetName: "local", -}); - -subsetTestByKey('from-public', makePreflightTests, { - sourceServer: Server.HTTPS_PUBLIC, - sourceName: "public", - targetServer: Server.HTTPS_PRIVATE, - targetName: "private", -}); - -subsetTestByKey( - 'from-public', promise_test_parallel, - t => windowOpenExistingTest(t, { - source: {server: Server.HTTPS_PUBLIC}, - target: {server: Server.HTTPS_PUBLIC}, - expected: NavigationTestResult.SUCCESS, - }), - 'public to public: no preflight required.'); - -// The following tests verify that `CSP: treat-as-public-address` makes -// documents behave as if they had been served from a public IP address. - -subsetTestByKey('from-treat-as-public', makePreflightTests, { - sourceServer: Server.HTTPS_LOCAL, - sourceTreatAsPublic: true, - sourceName: "treat-as-public-address", - targetServer: Server.OTHER_HTTPS_LOCAL, - targetName: "local", -}); - -subsetTestByKey("from-treat-as-public", promise_test_parallel, - t => windowOpenExistingTest(t, { - source: { - server: Server.HTTPS_LOCAL, - treatAsPublic: true, - }, - target: {server: Server.HTTPS_LOCAL}, - expected: NavigationTestResult.SUCCESS, - }), - 'treat-as-public-address to local (same-origin): no preflight required.'); - -subsetTestByKey('from-treat-as-public', makePreflightTests, { - sourceServer: Server.HTTPS_LOCAL, - sourceTreatAsPublic: true, - sourceName: 'treat-as-public-address', - targetServer: Server.HTTPS_PRIVATE, - targetName: 'private', -}); - -subsetTestByKey("from-treat-as-public", promise_test_parallel, - t => windowOpenExistingTest(t, { - source: { - server: Server.HTTPS_LOCAL, - treatAsPublic: true, - }, - target: {server: Server.HTTPS_PUBLIC}, - expected: NavigationTestResult.SUCCESS, - }), - 'treat-as-public-address to public: no preflight required.'); diff --git a/tests/wpt/tests/focus/focus-contenteditable-element-in-iframe-scroll-into-view.html b/tests/wpt/tests/focus/focus-contenteditable-element-in-iframe-scroll-into-view.html new file mode 100644 index 00000000000..1c03382201e --- /dev/null +++ b/tests/wpt/tests/focus/focus-contenteditable-element-in-iframe-scroll-into-view.html @@ -0,0 +1,74 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset=utf-8> +<meta name="viewport" content="width=device-width,initial-scale=1"> +<title>focus contenteditable element in iframe scroll into view</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<style> + +iframe { + position: absolute; + left: 250vw; +} + +.spacer { + width: 100vw; + height: 250vh; +} + +</style> +</head> +<body> + <div id="focusable-1" class="editor" contenteditable="true">focusable 1</div> + <div class="spacer"></div> + <iframe srcdoc="<div id='focusable-2' contenteditable='true'>focusable 2</div>"></iframe> + <div class="spacer"></div> +</body> +<script> + +function waitForLoad(w) { + return new Promise(resolve => w.addEventListener('load', resolve)); +} + +function waitForFrame() { + return new Promise(resolve => { + requestAnimationFrame(() => requestAnimationFrame(() => resolve())); + }); +} + +promise_test(async (t) => { + await waitForLoad(window); + const focusable_1 = document.getElementById("focusable-1"); + const iframeDocument = document.querySelector("iframe").contentDocument; + const focusable_2 = iframeDocument.getElementById("focusable-2"); + + focusable_1.focus(); + focusable_2.focus(); + await waitForFrame(); + const firstScrollX = window.scrollX; + const firstScrollY = window.scrollY; + + assert_greater_than(firstScrollX, window.innerWidth, "scroll X is greater than window.innerWidth"); + assert_greater_than(firstScrollY, window.innerHeight, "scroll Y is greater than window.innerHeight"); + + window.scroll(0, 0); + assert_equals(window.scrollX, 0, "scroll X is reset to 0"); + assert_equals(window.scrollY, 0, "scroll Y is reset to 0"); + + focusable_1.focus(); + focusable_2.focus(); + await waitForFrame(); + const secondScrollX = window.scrollX; + const secondScrollY = window.scrollY; + + // Ensure that both scroll positions are within +/- 1 + assert_approx_equals(firstScrollX, secondScrollX, 1.0, + "scroll X is within +/- 1 of a element in an iframe"); + assert_approx_equals(firstScrollY, secondScrollY, 1.0, + "scroll Y is within +/- 1 of a element in an iframe"); +}, "Check contenteditable element in an iframe scroll into view on second focusing"); + +</script> +</html> diff --git a/tests/wpt/tests/html/editing/dnd/events/ua-shadow-contents-manual.html b/tests/wpt/tests/html/editing/dnd/events/ua-shadow-contents-manual.html new file mode 100644 index 00000000000..23908ca9274 --- /dev/null +++ b/tests/wpt/tests/html/editing/dnd/events/ua-shadow-contents-manual.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html lang="en"> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<body draggable="true" style="padding:20px"> +Drag this input down quickly. Try multiple times. No errors should be reported.<br> +<input type=color> + +<script> +document.body.addEventListener('dragenter', (e) => { + let target = e.relatedTarget; + while (target) { + assert_false(target instanceof ShadowRoot,'Drag events should not expose UA shadow roots'); + // This console log can also cause DevTools crashes, so this is explicitly + // left in on purpose: + console.log(target); + target = target.parentNode; + } +}); +</script> diff --git a/tests/wpt/tests/html/rendering/non-replaced-elements/flow-content-0/slot-element-default-display.html b/tests/wpt/tests/html/rendering/non-replaced-elements/flow-content-0/slot-element-default-display.html new file mode 100644 index 00000000000..825efaa1a97 --- /dev/null +++ b/tests/wpt/tests/html/rendering/non-replaced-elements/flow-content-0/slot-element-default-display.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<title>CSS Test (Display): <slot> elements default display should be contents</title> +<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#flow-content-3"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<body> + +<script> + test(() => { + let host = document.body.appendChild(document.createElement("div")); + let slot = host.attachShadow({ mode: "open" }).appendChild(document.createElement("slot")); + let cs = getComputedStyle(slot); + assert_equals(cs.getPropertyValue("display"), "contents", "slot default display is not contents"); + document.body.removeChild(host); + }, `slot element with default display should be contents`); + +</script> diff --git a/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size-ref.html b/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size-ref.html new file mode 100644 index 00000000000..03a21eb4573 --- /dev/null +++ b/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size-ref.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> +<head> + <style> + #foo { + height: 50px; + box-sizing: border-box; + } + #bar { + border-bottom-width: 0px; + box-sizing: border-box; + } + </style> +</head> +<body> + <hr id="foo"> + <hr id="bar"> +</body> +</html> + diff --git a/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size-with-color-or-noshade-ref.html b/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size-with-color-or-noshade-ref.html new file mode 100644 index 00000000000..d6300e250d9 --- /dev/null +++ b/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size-with-color-or-noshade-ref.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html> +<head> + <style> + hr { + border-width: 25px; + } + </style> +</head> +<body> + <hr color="black"> + <hr color="totally-not-a-color"> + <hr noshade> + <hr color="black" noshade> +</body> +</html> + diff --git a/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size-with-color-or-noshade.html b/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size-with-color-or-noshade.html new file mode 100644 index 00000000000..db1d583934e --- /dev/null +++ b/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size-with-color-or-noshade.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-hr-element-2" /> +<title>hr elements: Tests behaviour of a size attribute with color/noshade attributes present</title> +<link rel="author" title="Simon Wülker" href="mailto:simon.wuelker@arcor.de"> +<link rel="match" href="/html/rendering/non-replaced-elements/the-hr-element-0/size-with-color-or-noshade-ref.html"> +<meta name="assert" content="This checks that the size attribute of a hr element changes the border widths when color/noshade attributes are present"> +<body> + <hr size=50 color="black"> + <hr size=50 color="totally-not-a-color"> + <hr size=50 noshade> + <hr size=50 color="black" noshade> +</body> +</html> + diff --git a/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size.html b/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size.html new file mode 100644 index 00000000000..2162131b853 --- /dev/null +++ b/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> +<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-hr-element-2" /> +<title>hr elements: Tests behaviour of a size attribute without color/noshade attributes</title> +<link rel="author" title="Simon Wülker" href="mailto:simon.wuelker@arcor.de"> +<link rel="match" href="/html/rendering/non-replaced-elements/the-hr-element-0/size-ref.html"> +<meta name="assert" content="This checks that the size attribute of a hr element changes its height."> +<body> + <hr size=50> + <hr size=1> +</body> +</html> + diff --git a/tests/wpt/tests/html/semantics/embedded-content/the-img-element/decode/image-decode-path-changes-svg.tentative.html b/tests/wpt/tests/html/semantics/embedded-content/the-img-element/decode/image-decode-path-changes-svg.tentative.html index 1bc53a1f18e..3ef59c37a85 100644 --- a/tests/wpt/tests/html/semantics/embedded-content/the-img-element/decode/image-decode-path-changes-svg.tentative.html +++ b/tests/wpt/tests/html/semantics/embedded-content/the-img-element/decode/image-decode-path-changes-svg.tentative.html @@ -13,25 +13,25 @@ // ------------------- promise_test(function(t) { var img = document.createElementNS('http://www.w3.org/2000/svg', 'image'); - img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/images/green.png"); + img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/images/green.png?image-decode-path-changes-1"); var promise = img.decode(); - img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/images/green.svg"); + img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/images/green.svg?image-decode-path-changes-1"); return promise_rejects_dom(t, "EncodingError", promise); }, document.title + " xlink:href changes fail decode."); promise_test(function(t) { var img = document.createElementNS('http://www.w3.org/2000/svg', 'image'); - img.setAttribute('href', "/images/green.png"); + img.setAttribute('href', "/images/green.png?image-decode-path-changes-2"); var promise = img.decode(); - img.setAttribute('href', "/images/green.svg"); + img.setAttribute('href', "/images/green.svg?image-decode-path-changes-2"); return promise_rejects_dom(t, "EncodingError", promise); }, document.title + " href changes fail decode."); promise_test(function(t) { var img = document.createElementNS('http://www.w3.org/2000/svg', 'image'); - img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/images/green.png"); + img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/images/green.png?image-decode-path-changes-3"); var first_promise = img.decode(); - img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/images/green.svg"); + img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/images/green.svg?image-decode-path-changes-3"); var second_promise = img.decode(); assert_not_equals(first_promise, second_promise); return Promise.all([ @@ -42,9 +42,9 @@ promise_test(function(t) { promise_test(function(t) { var img = document.createElementNS('http://www.w3.org/2000/svg', 'image'); - img.setAttribute('href', "/images/green.png"); + img.setAttribute('href', "/images/green.png?image-decode-path-changes-4"); var first_promise = img.decode(); - img.setAttribute('href', "/images/green.svg"); + img.setAttribute('href', "/images/green.svg?image-decode-path-changes-4"); var second_promise = img.decode(); assert_not_equals(first_promise, second_promise); return Promise.all([ @@ -55,9 +55,9 @@ promise_test(function(t) { promise_test(function(t) { var img = document.createElementNS('http://www.w3.org/2000/svg', 'image'); - img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/images/green.png"); + img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/images/green.png?image-decode-path-changes-5"); var first_promise = img.decode(); - img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/non/existent/path.png"); + img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/non/existent/path.png?image-decode-path-changes-5"); var second_promise = img.decode(); assert_not_equals(first_promise, second_promise); return Promise.all([ @@ -68,9 +68,9 @@ promise_test(function(t) { promise_test(function(t) { var img = document.createElementNS('http://www.w3.org/2000/svg', 'image'); - img.setAttribute('href', "/images/green.png"); + img.setAttribute('href', "/images/green.png?image-decode-path-changes-6"); var first_promise = img.decode(); - img.setAttribute('href', "/non/existent/path.png"); + img.setAttribute('href', "/non/existent/path.png?image-decode-path-changes-6"); var second_promise = img.decode(); assert_not_equals(first_promise, second_promise); return Promise.all([ diff --git a/tests/wpt/tests/html/semantics/embedded-content/the-img-element/decode/image-decode-with-quick-attach-svg.tentative.html b/tests/wpt/tests/html/semantics/embedded-content/the-img-element/decode/image-decode-with-quick-attach-svg.tentative.html index 0fc49e60360..fbc7143ecee 100644 --- a/tests/wpt/tests/html/semantics/embedded-content/the-img-element/decode/image-decode-with-quick-attach-svg.tentative.html +++ b/tests/wpt/tests/html/semantics/embedded-content/the-img-element/decode/image-decode-with-quick-attach-svg.tentative.html @@ -9,9 +9,11 @@ <script> "use strict"; +let png = "/images/green.png?image-decode-with-quick-attach-" + Math.random(); + promise_test(function() { var img = document.createElementNS('http://www.w3.org/2000/svg', 'image'); - img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/images/green.png"); + img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', png); const promise = img.decode().then(function(arg) { assert_equals(arg, undefined); }); diff --git a/tests/wpt/tests/html/semantics/embedded-content/the-img-element/naturalWidth-naturalHeight-unavailable.tentative.html b/tests/wpt/tests/html/semantics/embedded-content/the-img-element/naturalWidth-naturalHeight-unavailable.tentative.html index df9eb374b5a..ae6fa0e4328 100644 --- a/tests/wpt/tests/html/semantics/embedded-content/the-img-element/naturalWidth-naturalHeight-unavailable.tentative.html +++ b/tests/wpt/tests/html/semantics/embedded-content/the-img-element/naturalWidth-naturalHeight-unavailable.tentative.html @@ -1,4 +1,5 @@ <!doctype html> +<head> <meta charset="utf-8"> <title>HTMLImageElement naturalWidth/naturalHeight behavior for SVG that lacks at least one natural dimension</title> <!-- Note: this test asserts a different expectation from what the HTML spec @@ -6,7 +7,11 @@ behavior doesn't appear to be web-compatible for some of the cases here, and issue https://github.com/whatwg/html/issues/11287 is filed on addresing that. In the meantime, this test is named with ".tentative" to - indicate that it's not authoritative. --> + indicate that it's not authoritative. After the spec change is accepted, + we can remove the neighboring naturalWidth-naturalHeight.html test which + asserts the prior spec text's expectations, since this test covers the + same ground but with its expectations set according to the + soon-to-be-updated spec text. --> <link rel="help" href="https://github.com/whatwg/html/issues/11287"> <link rel="help" href="https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-naturalwidth-dev"> <link rel="help" href="https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-width"> @@ -15,7 +20,7 @@ <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <style> -.scroller { +#scroller { /* We wrap all the test content in a scroller so that it doesn't push * the textual test-results too far out of view. */ @@ -24,7 +29,7 @@ width: max-content; overflow: scroll; } -.container { +#containingBlock { /* There are a few SVG images here that size so that their margin-box fills * their containing block width. We define a specific size here so that we * can then check for it (minus the margins) in the "data-width" attribute. @@ -35,13 +40,24 @@ img { /* This styling is just cosmetic, to help visualize the images. */ border: 5px solid teal; margin: 5px; - vertical-align: top; display: block; - width: max-content; } </style> -<div class="scroller"> - <div class="container"> +<!-- We specify the img elements in a <template> and then clone them for + testing, so that we can dynamically generate and test several variants + of each img. --> +<template id="imgTemplates"> +<!-- For each img element: + * The "data-natural-{width,height}" attributes represent the expected + values of the img element's "naturalWidth" and "naturalHeight" IDL + attributes. This test implicitly expects the "width" and "height" IDL + attributes to have those same expected values; but in cases where that's + not correct, we provide the actual expected value in the + "data-{width,height}" attributes (as distinguished from + data-natural-{width,height}). + * The "title" attribute is a description of the scenario being tested, and + it must be unique to satisfy the test harness requirements. --> + <!-- FIRST PART OF TEST: No viewBox. Just a missing (or edge-casey, i.e. negative or percent-valued) values, for the width and height attrs on the root svg element in a SVG image. --> @@ -163,18 +179,37 @@ img { <img src="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='-5' height='-5' viewBox='0 0 600 200'></svg>" title="SVG image, with natural width and height being negative, and aspect ratio from viewBox" data-natural-width="0" data-natural-height="0"> +</template> +</head> +<body> +<div id="scroller"> + <div id="containingBlock"> + </div> </div> -</div> +<!-- We generate and append all of the tested <img> elements while we're inside + the <body>, so that all of the <img> elements' "load" events will block + the window onload event: --> <script> setup({explicit_done:true}); +// Clone and append a copy of the contents of imgTemplates, for testing: +let clone = imgTemplates.content.cloneNode("true"); +containingBlock.appendChild(clone); + +// After all the img elements have loaded (indicated by the window load event), +// we run the various tests: onload = function() { Array.from(document.images).forEach(img => { test(function() { + // We expect naturalWidth to match the provided data-natural-width + // (and similar for 'height'). const expectedNaturalWidth = parseFloat(img.dataset.naturalWidth); const expectedNaturalHeight = parseFloat(img.dataset.naturalHeight); assert_equals(img.naturalWidth, expectedNaturalWidth, 'naturalWidth'); assert_equals(img.naturalHeight, expectedNaturalHeight, 'naturalHeight'); + // If 'data-width' is provided, then we expect img.width to match it. + // Otherwise we expect img.width to match the 'data-natural-width'. + // (And similar for 'height'.) const expectedWidth = 'width' in img.dataset ? parseFloat(img.dataset.width) : expectedNaturalWidth; const expectedHeight = 'height' in img.dataset ? @@ -187,3 +222,4 @@ onload = function() { done(); }; </script> +</body> diff --git a/tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select/select-highlight-crash.html b/tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select/select-highlight-crash.html new file mode 100644 index 00000000000..a45120a2459 --- /dev/null +++ b/tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select/select-highlight-crash.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=help href="https://issues.chromium.org/issues/419167530"> + +<style> + @container (width) { + div::highlight(custom-highlight) { + --foo: bar; + } + } +</style> + +<select> + <div style="container-type:inline-size"></div> +</select> diff --git a/tests/wpt/tests/html/semantics/permission-element/negative-offset-and-margin.tentative.html b/tests/wpt/tests/html/semantics/permission-element/negative-offset-and-margin.tentative.html deleted file mode 100644 index 0b3d8dc9881..00000000000 --- a/tests/wpt/tests/html/semantics/permission-element/negative-offset-and-margin.tentative.html +++ /dev/null @@ -1,68 +0,0 @@ -<!DOCTYPE html> -<meta charset=utf-8> -<link rel="help" href="https://github.com/WICG/PEPC/blob/main/explainer.md#locking-the-pepc-style"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<body> -<!--The permission element should not allow setting negative outline-offset or margins under 4px. ---> -<style> - #id1 { - outline-offset: -50px; - margin-top: 3px; - margin-left: -50px; - margin-bottom: 0px; - margin-right: -50px; - } - #id2 { - outline-offset: 50px; - margin-top: 50px; - margin-left: 50px; - margin-bottom: 50px; - margin-right: 50px; - } - - /* These various expressions all result in a negative value when calculated */ - #id3 { - outline-offset: min(-50px, 50px); - margin-top: min(10%, -50px); - margin-left: clamp(-100px, 1vw, -50px); - margin-bottom: 1% - 10000px; - margin-right: max(min(-1em, 10em), -5%); - } -</style> - - -<permission id="id1" type="geolocation"></permission> -<permission id="id2" type="camera"></permission> -<permission id="id3" type="microphone"></permission> - -<script> - test(function(){ - var el_with_negatives = document.getElementById("id1"); - assert_equals(getComputedStyle(el_with_negatives).outlineOffset, "0px", "outline-offset"); - assert_equals(getComputedStyle(el_with_negatives).marginLeft, "4px", "margin-left"); - assert_equals(getComputedStyle(el_with_negatives).marginRight, "4px", "margin-right"); - assert_equals(getComputedStyle(el_with_negatives).marginTop, "4px", "margin-top"); - assert_equals(getComputedStyle(el_with_negatives).marginBottom, "4px", "margin-bottom"); - }, "Negative margins/offset should be changed to 4px"); - - test(function(){ - var el_with_positives = document.getElementById("id2"); - assert_equals(getComputedStyle(el_with_positives).outlineOffset, "50px", "outline-offset"); - assert_equals(getComputedStyle(el_with_positives).marginLeft, "50px", "margin-left"); - assert_equals(getComputedStyle(el_with_positives).marginRight, "50px", "margin-right"); - assert_equals(getComputedStyle(el_with_positives).marginTop, "50px", "margin-top"); - assert_equals(getComputedStyle(el_with_positives).marginBottom, "50px", "margin-bottom"); - }, "Positive margins/offset are unaffected"); - - test(function(){ - var el_with_negative_expr = document.getElementById("id3"); - assert_equals(getComputedStyle(el_with_negative_expr).outlineOffset, "0px", "outline-offset"); - assert_equals(getComputedStyle(el_with_negative_expr).marginLeft, "4px", "margin-left"); - assert_equals(getComputedStyle(el_with_negative_expr).marginRight, "4px", "margin-right"); - assert_equals(getComputedStyle(el_with_negative_expr).marginTop, "4px", "margin-top"); - assert_equals(getComputedStyle(el_with_negative_expr).marginBottom, "4px", "margin-bottom"); - }, "Expressions margins/offset should always return at least 4px"); -</script> -</body>
\ No newline at end of file diff --git a/tests/wpt/tests/html/semantics/permission-element/negative-offset.tentative.html b/tests/wpt/tests/html/semantics/permission-element/negative-offset.tentative.html new file mode 100644 index 00000000000..c1424ad9cc8 --- /dev/null +++ b/tests/wpt/tests/html/semantics/permission-element/negative-offset.tentative.html @@ -0,0 +1,79 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<link rel="help" href="https://github.com/WICG/PEPC/blob/main/explainer.md#locking-the-pepc-style"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<body> +<!--The permission element should not allow setting negative outline-offset. +--> +<style> + #id1 { + outline-offset: -50px; + } + #id2 { + outline-offset: 50px; + } + + /* These various expressions all result in a negative value when calculated */ + #id3 { + outline-offset: min(-50px, 50px); + } + #id4 { + outline-offset: min(10%, -50px); + } + #id5 { + outline-offset: clamp(-100px, 1vw, -50px); + } + #id6 { + outline-offset: 1% - 10000px; + } + #id7 { + outline-offset: max(min(-1em, 10em), -5%); + } +</style> + +<permission id="id1" type="geolocation"></permission> +<permission id="id2" type="camera"></permission> +<permission id="id3" type="microphone"></permission> +<permission id="id4" type="camera"></permission> +<permission id="id5" type="geolocation"></permission> +<permission id="id6" type="microphone"></permission> +<permission id="id7" type="camera microphone"></permission> + +<script> + test(function(){ + var el_with_negatives = document.getElementById("id1"); + assert_equals(getComputedStyle(el_with_negatives).outlineOffset, "0px", "outline-offset"); + }, "Negative offset should be changed to 0px"); + + test(function(){ + var el_with_positives = document.getElementById("id2"); + assert_equals(getComputedStyle(el_with_positives).outlineOffset, "50px", "outline-offset"); + }, "Positive offset are unaffected"); + + test(function(){ + var el_with_negative_expr = document.getElementById("id3"); + assert_equals(getComputedStyle(el_with_negative_expr).outlineOffset, "0px", "outline-offset"); + }, "Expressions offset min(-50px, 50px) should return at least 0px"); + + test(function(){ + var el_with_negative_expr = document.getElementById("id4"); + assert_equals(getComputedStyle(el_with_negative_expr).outlineOffset, "0px", "outline-offset"); + }, "Expressions offset outline-offset: min(10%, -50px) should return at least 0px"); + + test(function(){ + var el_with_negative_expr = document.getElementById("id5"); + assert_equals(getComputedStyle(el_with_negative_expr).outlineOffset, "0px", "outline-offset"); + }, "Expressions offset clamp(-100px, 1vw, -50px) should return at least 0px"); + + test(function(){ + var el_with_negative_expr = document.getElementById("id6"); + assert_equals(getComputedStyle(el_with_negative_expr).outlineOffset, "0px", "outline-offset"); + }, "Expressions offset 1% - 10000px should return at least 0px"); + + test(function(){ + var el_with_negative_expr = document.getElementById("id7"); + assert_equals(getComputedStyle(el_with_negative_expr).outlineOffset, "0px", "outline-offset"); + }, "Expressions offset max(min(-1em, 10em), -5%) should return at least 0px"); +</script> +</body>
\ No newline at end of file diff --git a/tests/wpt/tests/html/semantics/permission-element/no-focus.tentative.html b/tests/wpt/tests/html/semantics/permission-element/no-focus.tentative.html index 96467885183..1bf29634605 100644 --- a/tests/wpt/tests/html/semantics/permission-element/no-focus.tentative.html +++ b/tests/wpt/tests/html/semantics/permission-element/no-focus.tentative.html @@ -18,35 +18,34 @@ <script> promise_test(async() => { + invalid_permission_element.focus(); + assert_equals(document.activeElement, invalid_permission_element, + "Invalid permission element should be focusable"); + + focusable_span.focus(); valid_permission_element.focus(); - assert_equals(document.activeElement, document.body, - "Permission element should not be focused. Instead the parent element gets focus."); + assert_equals(document.activeElement, focusable_span, + "Permission element should not be focused."); + focusable_span.focus(); + await test_driver.bless('Focus with user activation', () => { + valid_permission_element.focus(); + }); + assert_equals(document.activeElement, valid_permission_element, + "Focus is allowed with user activation"); + + focusable_span.focus(); actions = new test_driver.Actions() .pointerMove(1, 1, {origin: valid_permission_element}) .pointerDown() .addTick(); await actions.send(); - assert_equals(document.activeElement, valid_permission_element, - "Users can still focus the element"); + "Users can focus the element"); focusable_span.focus(); assert_equals(document.activeElement, focusable_span, - "Other element should be focused"); - - invalid_permission_element.focus(); - assert_equals(document.activeElement, focusable_span, - "Invalid permission element should not be focused"); - - actions = new test_driver.Actions() - .pointerMove(1, 1, {origin: invalid_permission_element}) - .pointerDown() - .addTick(); - await actions.send(); - - assert_equals(document.activeElement, invalid_permission_element, - "Permission elements with an invalid-type can be focused like any other HTML element"); -}, "Permission element is not focusable by script"); + "Other element should be focused"); +}, "Permission element is not focusable by script without user activation"); </script> </body>
\ No newline at end of file diff --git a/tests/wpt/tests/html/semantics/permission-element/permission-icon/icon-hidden-reftest.html b/tests/wpt/tests/html/semantics/permission-element/permission-icon/icon-hidden-reftest.html new file mode 100644 index 00000000000..79055da1bad --- /dev/null +++ b/tests/wpt/tests/html/semantics/permission-element/permission-icon/icon-hidden-reftest.html @@ -0,0 +1,11 @@ +<!doctype html> +<title>The icon of the location permission element should not be visibe if it is set to display:none</title> +<!-- TODO: Update the link to the permission icon spec --> +<link rel="help" href="https://github.com/WICG/PEPC/blob/main/explainer.md"> +<link rel="mismatch" href="standard-location-permission-element-ref.html"> +<style> + ::permission-icon { + display: none; + } +</style> +<permission id="geolocation" type="geolocation"/> diff --git a/tests/wpt/tests/html/semantics/permission-element/permission-icon/icon-unique-per-type-reftest.html b/tests/wpt/tests/html/semantics/permission-element/permission-icon/icon-unique-per-type-reftest.html new file mode 100644 index 00000000000..d51b1c4d398 --- /dev/null +++ b/tests/wpt/tests/html/semantics/permission-element/permission-icon/icon-unique-per-type-reftest.html @@ -0,0 +1,6 @@ +<!doctype html> +<title>The camera permission element icon should be different to the location permission element</title> +<!-- TODO: Update the link to the permission icon spec --> +<link rel="help" href="https://github.com/WICG/PEPC/blob/main/explainer.md"> +<link rel="mismatch" href="standard-location-permission-element-ref.html"> +<permission id="camera" type="camera"/> diff --git a/tests/wpt/tests/html/semantics/permission-element/permission-icon/standard-location-permission-element-ref.html b/tests/wpt/tests/html/semantics/permission-element/permission-icon/standard-location-permission-element-ref.html new file mode 100644 index 00000000000..15ffe751c51 --- /dev/null +++ b/tests/wpt/tests/html/semantics/permission-element/permission-icon/standard-location-permission-element-ref.html @@ -0,0 +1,4 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>A standard permission element of type location, without any non-default styling</title> +<permission id="geolocation" type="geolocation"/> diff --git a/tests/wpt/tests/html/semantics/popovers/popover-root-crash.html b/tests/wpt/tests/html/semantics/popovers/popover-root-crash.html new file mode 100644 index 00000000000..86498607730 --- /dev/null +++ b/tests/wpt/tests/html/semantics/popovers/popover-root-crash.html @@ -0,0 +1,7 @@ +<!doctype html> +<script> + window.addEventListener("load", async () => { + document.documentElement.popover = "manual" + document.documentElement.togglePopover(true) + }) +</script> diff --git a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/042.html b/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/042.html deleted file mode 100644 index df3a2f88f29..00000000000 --- a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/042.html +++ /dev/null @@ -1,29 +0,0 @@ -<!DOCTYPE html> -<html><head> - <title> scheduler: DOM mutation events when adding scripts: DOMNodeInserted </title> - <script src="/resources/testharness.js"></script> - <script src="/resources/testharnessreport.js"></script> - <script src="testlib/testlib.js"></script> -</head> -<body> - - <div id="log">FAILED (This TC requires JavaScript enabled)</div> - - <script>log('inline script #1'); - document.addEventListener( 'DOMNodeInserted', function(){ log('DOMNodeInserted'); }, false ); - testlib.addScript('log(\'head script #1\')', {}, document.getElementsByTagName('head')[0], false); - log('end script #1'); - </script> - - <script type="text/javascript"> - log( 'inline script #2' ); - var t = async_test() - - function test() { - assert_array_equals(eventOrder, ['inline script #1', 'head script #1', 'DOMNodeInserted', 'end script #1', 'inline script #2']); - t.done(); - } - onload = t.step_func(test) - </script> - -</body></html> diff --git a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/043.html b/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/043.html deleted file mode 100644 index bcfd90cba47..00000000000 --- a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/043.html +++ /dev/null @@ -1,31 +0,0 @@ -<!DOCTYPE html> -<html><head> - <title> scheduler: DOM mutation events when adding external scripts: DOMNodeInserted </title> - <script src="/resources/testharness.js"></script> - <script src="/resources/testharnessreport.js"></script> - <script src="testlib/testlib.js"></script> -</head> -<body> - - <div id="log">FAILED (This TC requires JavaScript enabled)</div> - - <script>log('inline script #1'); - document.addEventListener( 'DOMNodeInserted', function(){ log('DOMNodeInserted'); }, false ); - testlib.addScript('', { src: 'scripts/include-1.js' }, document.getElementsByTagName('head')[0], false); - log('end script #1'); - </script> - - <script type="text/javascript"> - log( 'inline script #2' ); - var t = async_test() - - function test() { - assert_any(assert_array_equals, eventOrder, [['inline script #1', 'DOMNodeInserted', 'end script #1', 'external script #1', 'inline script #2'], - ['inline script #1', 'DOMNodeInserted', 'end script #1', 'inline script #2', 'external script #1']] - ); - t.done(); - } - onload = t.step_func(test) - </script> - -</body></html> diff --git a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/044.html b/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/044.html deleted file mode 100644 index 8d412079e45..00000000000 --- a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/044.html +++ /dev/null @@ -1,28 +0,0 @@ -<!DOCTYPE html> -<html><head> - <title> scheduler: DOM mutation events when adding scripts: DOMNodeInsertedIntoDocument </title> - <script src="/resources/testharness.js"></script> - <script src="/resources/testharnessreport.js"></script> - <script src="testlib/testlib.js"></script> -</head> -<body> - - <div id="log">FAILED (This TC requires JavaScript enabled)</div> - - <script>log('inline script #1'); - testlib.addScript('log(\'head script #1\')', {}, document.getElementsByTagName('head')[0], false, function(s){s.addEventListener( 'DOMNodeInsertedIntoDocument', function(){ log('DOMNodeInsertedIntoDocument'); }, false ); } ); - log('end script #1'); - </script> - - <script type="text/javascript"> - log( 'inline script #2' ); - var t = async_test() - - function test() { - assert_array_equals(eventOrder, ['inline script #1', 'head script #1', 'DOMNodeInsertedIntoDocument', 'end script #1', 'inline script #2']); - t.done(); - } - onload = t.step_func(test) - </script> - -</body></html> diff --git a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/045.html b/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/045.html deleted file mode 100644 index 254e0d13662..00000000000 --- a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/045.html +++ /dev/null @@ -1,28 +0,0 @@ -<!DOCTYPE html> -<html><head> - <title> scheduler: DOM mutation events when adding external scripts: DOMNodeInsertedIntoDocument </title> - <script src="/resources/testharness.js"></script> - <script src="/resources/testharnessreport.js"></script> - <script src="testlib/testlib.js"></script> -</head> -<body> - - <div id="log">FAILED (This TC requires JavaScript enabled)</div> - - <script>log('inline script #1'); - testlib.addScript('', {src:'scripts/include-1.js'}, document.getElementsByTagName('head')[0], false, function(s){s.addEventListener( 'DOMNodeInsertedIntoDocument', function(){ log('DOMNodeInsertedIntoDocument'); }, false);}); - log('end script #1'); - </script> - - <script type="text/javascript"> - log( 'inline script #2' ); - var t = async_test() - - onload = t.step_func(function() { - assert_any(assert_array_equals, eventOrder, [['inline script #1', 'DOMNodeInsertedIntoDocument', 'end script #1', 'external script #1', 'inline script #2'], - ['inline script #1', 'DOMNodeInsertedIntoDocument', 'end script #1', 'inline script #2', 'external script #1']]); - t.done(); - }); - </script> - -</body></html> diff --git a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/054.html b/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/054.html deleted file mode 100644 index 29ede23414e..00000000000 --- a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/054.html +++ /dev/null @@ -1,33 +0,0 @@ -<!DOCTYPE html> -<html><head> - <title> scheduler: removing newly inserted script from DOMNodeInserted handler - external script </title> - <script src="/resources/testharness.js"></script> - <script src="/resources/testharnessreport.js"></script> - <script src="testlib/testlib.js"></script> -</head> -<body> - - <div id="log">FAILED (This TC requires JavaScript enabled)</div> - - <script>log('inline script #1'); - document.addEventListener( 'DOMNodeInserted', function listener(e){ - log('DOMNodeInserted event'); - e.target.parentNode.removeChild(e.target); - document.removeEventListener('DOMNodeInserted', listener); - }, false ); - var script=testlib.addScript('', { src:'scripts/include-1.js?'+Math.random() }, document.getElementsByTagName('body')[0], true ); - log('end script #1'); - </script> - <script type="text/javascript"> - log( 'inline script #2' ); - var t = async_test() - - function test() { - assert_any(assert_array_equals, eventOrder, [['inline script #1', 'DOMNodeInserted event', 'end script #1', 'inline script #2', 'external script #1'], - ['inline script #1', 'DOMNodeInserted event', 'end script #1', 'external script #1', 'inline script #2']]); - t.done(); - } - onload = t.step_func(test); - </script> - -</body></html> diff --git a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/055.html b/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/055.html deleted file mode 100644 index c837d78174b..00000000000 --- a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/055.html +++ /dev/null @@ -1,32 +0,0 @@ -<!DOCTYPE html> -<html><head> - <title> scheduler: removing newly inserted script from DOMNodeInserted handler - inline script </title> - <script src="/resources/testharness.js"></script> - <script src="/resources/testharnessreport.js"></script> - <script src="testlib/testlib.js"></script> -</head> -<body> - - <div id="log">FAILED (This TC requires JavaScript enabled)</div> - - <script>log('inline script #1'); - document.addEventListener( 'DOMNodeInserted', function listener(e){ - log('DOMNodeInserted event'); - e.target.parentNode.removeChild(e.target); - document.removeEventListener('DOMNodeInserted', listener); - }, false ); - var script=testlib.addScript('log(\'added script\')', { }, document.getElementsByTagName('body')[0], true ); - log('end script #1'); - </script> - <script type="text/javascript"> - log( 'inline script #2' ); - var t = async_test() - - function test() { - assert_array_equals(eventOrder, ['inline script #1', 'added script', 'DOMNodeInserted event', 'end script #1', 'inline script #2']); - t.done(); - } - onload = t.step_func(test); - </script> - -</body></html> diff --git a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/json-module/invalid-content-type.any.js b/tests/wpt/tests/html/semantics/scripting-1/the-script-element/json-module/invalid-content-type.any.js index d15fa3f1b70..d0bb6aa9fb1 100644 --- a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/json-module/invalid-content-type.any.js +++ b/tests/wpt/tests/html/semantics/scripting-1/the-script-element/json-module/invalid-content-type.any.js @@ -7,6 +7,12 @@ const content_types = [ "text/json+blah", "application/blahjson", "image/json", + "text+json", + "json+json", + "text/json/json+json", + "text/html;+json", + "text/html+json+xml", + "text/json/json", ]; for (const content_type of content_types) { promise_test(async test => { diff --git a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/json-module/valid-content-type.html b/tests/wpt/tests/html/semantics/scripting-1/the-script-element/json-module/valid-content-type.html index 3232b84d271..fdeba93ba89 100644 --- a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/json-module/valid-content-type.html +++ b/tests/wpt/tests/html/semantics/scripting-1/the-script-element/json-module/valid-content-type.html @@ -19,6 +19,8 @@ const t3 = async_test("text/html+json"); const t4 = async_test("image/svg+json"); const t5 = async_test("text/json;boundary=something"); const t6 = async_test("text/json;foo=bar"); +const t7 = async_test("text/json;+json"); +const t8 = async_test("text/html+xml+json"); </script> <script type="module" onerror="t1.step(() => assert_unreached(event))"> import v from "../serve-with-content-type.py?fn=json-module/module.json&ct=text/json" with { type: "json"}; @@ -43,4 +45,12 @@ check(t5, v); <script type="module" onerror="t6.step(() => assert_unreached(event))"> import v from "../serve-with-content-type.py?fn=json-module/module.json&ct=text/json;foo=bar" with { type: "json"}; check(t6, v); +</script> +<script type="module" onerror="t7.step(() => assert_unreached(event))"> +import v from "../serve-with-content-type.py?fn=json-module/module.json&ct=text/json;%2Bjson" with { type: "json"}; +check(t7, v); +</script> +<script type="module" onerror="t8.step(() => assert_unreached(event))"> +import v from "../serve-with-content-type.py?fn=json-module/module.json&ct=text/html%2Bxml%2Bjson" with { type: "json"}; +check(t8, v); </script>
\ No newline at end of file diff --git a/tests/wpt/tests/html/semantics/the-button-element/command-and-commandfor/source-attribute-retargeting.tentative.html b/tests/wpt/tests/html/semantics/the-button-element/command-and-commandfor/source-attribute-retargeting.tentative.html new file mode 100644 index 00000000000..885b75a3387 --- /dev/null +++ b/tests/wpt/tests/html/semantics/the-button-element/command-and-commandfor/source-attribute-retargeting.tentative.html @@ -0,0 +1,132 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<div id=popover popover=auto>popover</div> +<div id=host> + <template shadowrootmode=open> + <button id=shadow-button command=show-popover>button in shadowroot</button> + </template> +</div> + +<script> +promise_test(async () => { + const popover = document.getElementById('popover'); + const host = document.getElementById('host'); + const shadowButton = host.shadowRoot.getElementById('shadow-button'); + shadowButton.commandForElement = popover; + + const eventNames = ['beforetoggle', 'toggle', 'command']; + const eventNameToEvent = {}; + const eventNameToCaptureSource = {}; + const eventNameToBubbleSource = {}; + + for (const eventName of eventNames) { + popover.addEventListener(eventName, event => { + eventNameToEvent[eventName] = event; + eventNameToBubbleSource[eventName] = event.source; + }); + popover.addEventListener(eventName, event => { + eventNameToCaptureSource[eventName] = event.source; + }, {capture: true}); + } + + shadowButton.click(); + await new Promise(requestAnimationFrame); + await new Promise(requestAnimationFrame); + + for (const eventName of eventNames) { + const event = eventNameToEvent[eventName]; + assert_true(!!event, `A ${eventName} event should have been fired.`); + assert_equals(eventNameToCaptureSource[eventName], host, + `${eventName}.source during capture.`); + assert_equals(eventNameToBubbleSource[eventName], host, + `${eventName}.source during bubble.`); + assert_not_equals(event.source, shadowButton, + `${eventName}.source shouldn't leak the shadow button.`); + assert_equals(event.source, host, + `${eventName}.source after dispatch.`); + } +}, 'CommandEvent.source and ToggleEvent.source should be retargeted during and after event dispatch.'); +</script> + +<div id=host2> + <template shadowrootmode=open> + <div id=source>source</div> + <div id=innerhost> + <template shadowrootmode=open> + <div id=target>target</div> + </template> + </div> + </template> +</div> + +<script> +// This does not test ToggleEvent because ToggleEventInit does not have a source attribute. +promise_test(async () => { + const host2 = document.getElementById('host2'); + const source = host2.shadowRoot.getElementById('source'); + const innerhost = host2.shadowRoot.getElementById('innerhost'); + const target = innerhost.shadowRoot.getElementById('target'); + + const targets = [host2, innerhost, target]; + const targetToEvent = new Map(); + const targetToCaptureSource = new Map(); + const targetToBubbleSource = new Map(); + + for (const target of targets) { + target.addEventListener('command', event => { + targetToEvent.set(target, event); + targetToBubbleSource.set(target, event.source); + }); + target.addEventListener('command', event => { + targetToCaptureSource.set(target, event.source); + }, {capture: true}); + } + + const commandEvent = new CommandEvent('command', {composed: true, source}); + target.dispatchEvent(commandEvent); + + for (const target of targets) { + const expectedSource = target == host2 ? host2 : source; + assert_true(targetToEvent.has(target), + `${target.id}: event should have fired.`); + assert_equals(targetToCaptureSource.get(target), expectedSource, + `${target.id}: event.source at capture.`); + assert_equals(targetToBubbleSource.get(target), expectedSource, + `${target.id}: event.source at bubble.`); + assert_equals(targetToEvent.get(target).source, host2, + `${target.id}: event.source after dispatch.`); + } +}, 'CommandEvent.source should be retargeted when manually dispatched with composed set to true.'); +</script> + +<div id=popover3 popover=auto>popover 3</div> +<button id=button3 commandfor=popover3 command=show-popover>show popover 3</button> + +<script> +promise_test(async () => { + const button = document.getElementById('button3'); + const popover = document.getElementById('popover3'); + + const eventNames = ['beforetoggle', 'toggle', 'command']; + const eventNameToEvent = {}; + for (const eventName of eventNames) { + popover.addEventListener(eventName, event => { + eventNameToEvent[eventName] = event; + }); + } + + button.click(); + await new Promise(requestAnimationFrame); + await new Promise(requestAnimationFrame); + + for (const eventName of eventNames) { + const event = eventNameToEvent[eventName]; + assert_true(!!event, `${eventName} should have been fired.`); + assert_equals(event.source, button, + `${eventName}.source should be the invoker button after dispatch.`); + } +}, 'CommandEvent.source and ToggleEvent.source should not be set to null after dispatch without ShadowDOM.'); +</script> diff --git a/tests/wpt/tests/html/webappapis/system-state-and-capabilities/the-navigator-object/WEB_FEATURES.yml b/tests/wpt/tests/html/webappapis/system-state-and-capabilities/the-navigator-object/WEB_FEATURES.yml index a1af3e21a48..7a364e14095 100644 --- a/tests/wpt/tests/html/webappapis/system-state-and-capabilities/the-navigator-object/WEB_FEATURES.yml +++ b/tests/wpt/tests/html/webappapis/system-state-and-capabilities/the-navigator-object/WEB_FEATURES.yml @@ -2,3 +2,7 @@ features: - name: pdf-viewer files: - plugins-and-mimetypes.html +- name: ua-client-hints + files: + - navigator_user_agent.tentative.html + - navigator_user_agent.https.tentative.html diff --git a/tests/wpt/tests/interfaces/scoped-custom-elements-registry.idl b/tests/wpt/tests/interfaces/scoped-custom-elements-registry.idl new file mode 100644 index 00000000000..46ca2d6b9c4 --- /dev/null +++ b/tests/wpt/tests/interfaces/scoped-custom-elements-registry.idl @@ -0,0 +1,38 @@ +[Exposed=Window] +partial interface CustomElementRegistry { + constructor(); + undefined initialize(Node root); +}; + +[Exposed=Window] +partial interface HTMLTemplateElement { + [CEReactions] attribute DOMString shadowRootCustomElementRegistry; +}; + +[Exposed=Window] +partial interface Document { + readonly attribute CustomElementRegistry? customElementRegistry; +}; + +[Exposed=Window] +partial interface Element { + readonly attribute CustomElementRegistry? customElementRegistry; +}; + +[Exposed=Window] +partial interface ShadowRoot { + readonly attribute CustomElementRegistry? customElementRegistry; +}; + +dictionary ImportNodeOptions { + CustomElementRegistry customElementRegistry; + boolean selfOnly = false; +}; + +partial dictionary ShadowRootInit { + CustomElementRegistry customElementRegistry; +}; + +partial dictionary ElementCreationOptions { + CustomElementRegistry customElementRegistry; +}; diff --git a/tests/wpt/tests/layout-instability/WEB_FEATURES.yml b/tests/wpt/tests/layout-instability/WEB_FEATURES.yml new file mode 100644 index 00000000000..335b072c186 --- /dev/null +++ b/tests/wpt/tests/layout-instability/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +features: +- name: layout-instability + files: "**" diff --git a/tests/wpt/tests/lint.ignore b/tests/wpt/tests/lint.ignore index 10b5dadba74..60b0f65a6f4 100644 --- a/tests/wpt/tests/lint.ignore +++ b/tests/wpt/tests/lint.ignore @@ -126,6 +126,7 @@ CONSOLE: webaudio/resources/audit.js:41 # Intentional use of console.* CONSOLE: infrastructure/webdriver/bidi/subscription.html CONSOLE: infrastructure/webdriver/bidi/subscription.window.js +CONSOLE: html/editing/dnd/events/ua-shadow-contents-manual.html # use of console in a public library - annotation-model ensures # it is not actually used diff --git a/tests/wpt/tests/network-error-logging/support/nel.sub.js b/tests/wpt/tests/network-error-logging/support/nel.sub.js index 26ddd897c2f..f9dfec1dad8 100644 --- a/tests/wpt/tests/network-error-logging/support/nel.sub.js +++ b/tests/wpt/tests/network-error-logging/support/nel.sub.js @@ -18,6 +18,7 @@ function releaseNELLock() { function nel_test(callback, name, properties) { promise_test(async t => { await obtainNELLock(); + await assertNELIsImplemented(); await clearReportingAndNELConfigurations(); await callback(t); await releaseNELLock(); @@ -27,6 +28,7 @@ function nel_test(callback, name, properties) { function nel_iframe_test(callback, name, properties) { promise_test(async t => { await obtainNELLock(); + await assertNELIsImplemented(); await clearReportingAndNELConfigurationsInIframe(); await callback(t); await releaseNELLock(); @@ -251,9 +253,10 @@ function _isSubsetOf(obj1, obj2) { * expected. */ -async function reportExists(expected, retain_reports) { - var timeout = - document.querySelector("meta[name=timeout][content=long]") ? 50 : 1; +async function reportExists(expected, retain_reports, timeout) { + if (!timeout) { + timeout = document.querySelector("meta[name=timeout][content=long]") ? 50 : 1; + } var reportLocation = "/reporting/resources/report.py?op=retrieve_report&timeout=" + timeout + "&reportID=" + reportID; @@ -295,3 +298,13 @@ async function reportsExist(expected_reports, retain_reports) { } return true; } + +// this runs first to avoid testing on browsers not implementing NEL +async function assertNELIsImplemented() { + await fetchResourceWithBasicPolicy(); + // Assert that the report was generated + assert_implements(await reportExists({ + url: getURLForResourceWithBasicPolicy(), + type: "network-error" + }, false, 1), "'Basic NEL support: missing network-error report'"); +} diff --git a/tests/wpt/tests/pointerevents/persistentDeviceId/get-persistendeviceid-from-pointer-mouse-event.tentative.html b/tests/wpt/tests/pointerevents/persistentDeviceId/get-persistendeviceid-from-pointer-mouse-event.tentative.html new file mode 100644 index 00000000000..66fb63d54d1 --- /dev/null +++ b/tests/wpt/tests/pointerevents/persistentDeviceId/get-persistendeviceid-from-pointer-mouse-event.tentative.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="/resources/testdriver-vendor.js"></script> + +<style> + div { + user-select: none; // Prevents text selection on drag. + } +</style> +<div id="logger" draggable="false"></div> +<div id="console"></div> +<!-- This test documents the current behavior in Chrome for some + pointerType == "mouse" events --> +<script> + function CheckDeviceIdOne(event) { + assert_equals(event.persistentDeviceId, 1, event.type + " deviceId is 1"); + } + + function CheckDeviceIdZero(event) { + assert_equals(event.persistentDeviceId, 0, event.type + " deviceId is 0"); + } + + window.addEventListener("pointerdown", CheckDeviceIdOne, false); + window.addEventListener("pointermove", CheckDeviceIdOne, false); + window.addEventListener("pointerover", CheckDeviceIdOne, false); + window.addEventListener("pointerup", CheckDeviceIdOne, false); + window.addEventListener("click", CheckDeviceIdZero, false); + + promise_test(async () => { + let actions = new test_driver.Actions() + .addPointer("TestPointer", "mouse") + .pointerDown() + .pointerMove(100, 100) + .pointerUp(); + + await actions.send(); + + }, 'PointerEvent.persistentDeviceId'); +</script> diff --git a/tests/wpt/tests/preload/preload-csp.sub.html b/tests/wpt/tests/preload/preload-csp.sub.html index a1b57b78b41..2238d6cafe8 100644 --- a/tests/wpt/tests/preload/preload-csp.sub.html +++ b/tests/wpt/tests/preload/preload-csp.sub.html @@ -24,13 +24,13 @@ promise_test(async (t) => { for (const link of links) { if (link.rel === 'preload') { const r = /\?key=([a-zA-Z0-9\-]+)$/; - keys.push(link.href.match(r)[1]); + keys.push([link.href, link.as, link.href.match(r)[1]]); } } await new Promise((resolve) => step_timeout(resolve, 3000)); - for (const key of keys) { - assert_false(await hasArrivedAtServer(key)); + for (const [href, type, key] of keys) { + assert_false(await hasArrivedAtServer(key), `Preload with href ${href}, type ${type} and key ${key} should not have arrived at the server.`); } }, 'Preload requests are blocked by CSP.'); </script> diff --git a/tests/wpt/tests/resize-observer/zoom.html b/tests/wpt/tests/resize-observer/zoom.html new file mode 100644 index 00000000000..77b4bc49fa7 --- /dev/null +++ b/tests/wpt/tests/resize-observer/zoom.html @@ -0,0 +1,55 @@ +<!doctype html> +<link rel="help" href="https://drafts.csswg.org/css-viewport/#zoom-om"> +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/9398"> +<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez"> +<link rel="author" href="https://mozilla.org" title="Mozilla"> +<title>ResizeObserver sizes account for zoom</title> +<meta name="viewport" content="width=device-width,initial-scale=1"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + div { + width: 100px; + height: 100px; + border: 5px solid; + padding: 5px; + margin: 5px; + box-sizing: border-box; + } +</style> +<div></div> +<div style="zoom: 2"></div> +<div style="zoom: 4"></div> +<script> +promise_test(async function() { + let { promise, resolve } = Promise.withResolvers(); + let observer = new ResizeObserver(entries => { + resolve(entries); + }); + for (let div of document.querySelectorAll("div")) { + observer.observe(div); + } + let entries = await promise; + observer.disconnect(); + assert_equals(entries.length, 3, "Should have three entries"); + for (let entry of entries) { + assert_equals(entry.contentRect.top, 5, "content-rect top should be scaled by zoom"); + assert_equals(entry.contentRect.left, 5, "content-rect left should be scaled by zoom"); + assert_equals(entry.contentRect.width, 80, "content-rect width should be scaled by zoom"); + assert_equals(entry.contentRect.height, 80, "content-rect height should be scaled by zoom"); + + for (let sizeArray of [entry.borderBoxSize, entry.contentBoxSize, entry.devicePixelContentBoxSize]) { + assert_equals(sizeArray.length, 1, "Should have one box"); + } + let borderBoxSize = entry.borderBoxSize[0]; + let contentBoxSize = entry.contentBoxSize[0]; + let devicePixelContentBoxSize = entry.devicePixelContentBoxSize[0]; + assert_equals(borderBoxSize.inlineSize, 100, "border inline size should be scaled by zoom"); + assert_equals(borderBoxSize.blockSize, 100, "border block size should be scaled by zoom"); + assert_equals(contentBoxSize.inlineSize, 80, "content inline size should be scaled by zoom"); + assert_equals(contentBoxSize.blockSize, 80, "content block size should be scaled by zoom"); + assert_equals(devicePixelContentBoxSize.inlineSize, 80 * entry.target.currentCSSZoom * window.devicePixelRatio, "dev-px size should _not_ be scaled by zoom"); + assert_equals(devicePixelContentBoxSize.blockSize, 80 * entry.target.currentCSSZoom * window.devicePixelRatio, "dev-px size should _not_ be scaled by zoom"); + } +}); +</script> diff --git a/tests/wpt/tests/resource-timing/content-encoding.https.html b/tests/wpt/tests/resource-timing/content-encoding.https.html index 0d67bfc7d4f..80473552f08 100644 --- a/tests/wpt/tests/resource-timing/content-encoding.https.html +++ b/tests/wpt/tests/resource-timing/content-encoding.https.html @@ -33,10 +33,10 @@ run_same_origin_test("/resource-timing/resources/foo.text.zst", "zstd"); run_same_origin_test("/resource-timing/resources/compressed-js.py?content_encoding=deflate", "deflate"); run_same_origin_test("/resource-timing/resources/compressed-js.py?content_encoding=gzip", "gzip"); - // Unrecognized content encoding value should be transformed to "unknown". - run_same_origin_test("/resource-timing/resources/compressed-js.py?content_encoding=unrecognizedname", "unknown"); - // "identity" is not allowed in response header and should be transformed to "unknown". - run_same_origin_test("/resource-timing/resources/compressed-js.py?content_encoding=identity", "unknown"); + // Unrecognized content encoding value should be transformed to "@unknown". + run_same_origin_test("/resource-timing/resources/compressed-js.py?content_encoding=unrecognizedname", "@unknown"); + // "identity" is not allowed in response header and should be transformed to "@unknown". + run_same_origin_test("/resource-timing/resources/compressed-js.py?content_encoding=identity", "@unknown"); // Mult-encodinging and formatting tests. run_same_origin_test("/resource-timing/resources/content-encoding-headers.py?content_encoding=gzip, deflate,Apple", "multiple"); run_same_origin_test("/resource-timing/resources/content-encoding-headers.py?content_encoding=gzip, ", "multiple"); diff --git a/tests/wpt/tests/resources/testdriver-actions.js.headers b/tests/wpt/tests/resources/testdriver-actions.js.headers new file mode 100644 index 00000000000..5e8f640c665 --- /dev/null +++ b/tests/wpt/tests/resources/testdriver-actions.js.headers @@ -0,0 +1,2 @@ +Content-Type: text/javascript; charset=utf-8 +Cache-Control: max-age=3600 diff --git a/tests/wpt/tests/scroll-animations/animation-trigger/animation-trigger-repeat.tentative.html b/tests/wpt/tests/scroll-animations/animation-trigger/animation-trigger-repeat.tentative.html index cfbe9d3c933..6c01e762e5a 100644 --- a/tests/wpt/tests/scroll-animations/animation-trigger/animation-trigger-repeat.tentative.html +++ b/tests/wpt/tests/scroll-animations/animation-trigger/animation-trigger-repeat.tentative.html @@ -21,7 +21,7 @@ } .target { animation: myAnim linear 0.5s both; - animation-trigger: repeat; + animation-trigger-type: repeat; animation-trigger-range: 250px 300px; animation-trigger-exit-range: 200px 350px; } @@ -76,6 +76,7 @@ // let target; async function testRepeatAnimationTrigger(test, rangeBoundaries) { + const initial_transform = getComputedStyle(target).transform; // Just short of the trigger range start, no trigger action expected. await testAnimationTrigger(test, () => { return rangeBoundaries.exitTriggerRangeAbove(); @@ -91,15 +92,14 @@ return rangeBoundaries.enterTriggerRange(); }, target, ["animationstart", "animationend"], [true, true]); - // This is a repeat trigger, exiting the exit range resets the animation. - // We waited for an animationend event in the previous step so we won't - // see an animationcancel event here. But, by inspecting - // style.transform, we should see that the animation was reset. + // This is a repeat trigger, exiting the exit range resets the + // animation. By inspecting style.transform, we should see that the + // animation was reset. await testAnimationTrigger(test, () => { return rangeBoundaries.exitExitRangeAbove(); }, target, ["animationstart", "animationend", "animationcancel"], [false, false, false]); - assert_equals(getComputedStyle(target).transform, "none"); + assert_equals(getComputedStyle(target).transform, initial_transform); // This is a repeat trigger, re-entering plays the animation. await testAnimationTrigger(test, async () => { @@ -109,7 +109,7 @@ // Exit the range. return rangeBoundaries.exitExitRangeBelow(); }, target, ["animationstart", "animationend", "animationcancel"], - [true, false, true]); + [true, false, false]); } const CSS_TRIGGER_START_PX = 250; @@ -127,7 +127,7 @@ CSS_EXIT_END_PX, scroller); await testRepeatAnimationTrigger(test, rangeBoundaries); - }, "once animation triggered via scroll() timeline."); + }, "repeat animation triggered via scroll() timeline."); promise_test(async (test) => { scroller = view_scroller; @@ -142,7 +142,7 @@ COVER_START_OFFSET + CSS_EXIT_END_PX, scroller); await testRepeatAnimationTrigger(test, rangeBoundaries); - }, "once animation triggered via view() timeline."); + }, "repeat animation triggered via view() timeline."); promise_test(async (test) => { scroller = deferred_scroller; @@ -157,7 +157,7 @@ COVER_START_OFFSET + CSS_EXIT_END_PX, scroller); await testRepeatAnimationTrigger(test, rangeBoundaries); - }, "once animation triggered via deferred (view) timeline."); + }, "repeat animation triggered via deferred (view) timeline."); </script> </body> </html> diff --git a/tests/wpt/tests/shadow-dom/HighlightRegistry-highlightsFromPoint.html b/tests/wpt/tests/shadow-dom/HighlightRegistry-highlightsFromPoint.html index 5244f923e34..4098bc5a994 100644 --- a/tests/wpt/tests/shadow-dom/HighlightRegistry-highlightsFromPoint.html +++ b/tests/wpt/tests/shadow-dom/HighlightRegistry-highlightsFromPoint.html @@ -1,7 +1,7 @@ <!doctype html> <body> <meta name="author" title="Fernando Fiori" href="mailto:ffiori@microsoft.com"> -<meta name="assert" content="HighlightRegistry.highlightsFromPoint returns the Highlights present at at a given point inside the shadow roots passed as argument."> +<meta name="assert" content="HighlightRegistry.highlightsFromPoint returns HighlightHitResults with the Highlights and their corresponding ranges present at a given point inside the shadow roots passed as argument."> <link rel="help" href="https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/highlight/HighlightsFromPointsExplainer.md"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> @@ -57,25 +57,28 @@ body { // Get x and y coordinates between '0' and '1'. let x = spanBoundingRectangle.left + characterWidth; let y = spanBoundingRectangle.top + spanBoundingRectangle.height / 2; - let highlights = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]}); - assert_equals(highlights.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the coordinates provided point at no Highlights'); + let highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]}); + assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the coordinates provided point at no Highlights'); // Get x and y coordinates between '2' and '3'. x = spanBoundingRectangle.left + 3 * characterWidth; - highlights = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]}); - assert_equals(highlights.length, 1, 'CSS.highlights.highlightsFromPoint() returns exactly one Highlight when the given coordinates point at a Highlight under the shadow root provided'); - assert_equals(highlights[0], highlight, 'CSS.highlights.highlightsFromPoint() returns the Highlight present at the given coordinates when it\'s under the shadow root provided'); + highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]}); + assert_equals(highlight_hit_results.length, 1, 'CSS.highlights.highlightsFromPoint() returns exactly one Highlight when the given coordinates point at a Highlight under the shadow root provided'); + assert_equals(highlight_hit_results[0].highlight, highlight, 'CSS.highlights.highlightsFromPoint() returns the Highlight present at the given coordinates when it\'s under the shadow root provided'); + assert_array_equals(highlight_hit_results[0].ranges, [range], 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the ranges of the Highlight present at the coordinates provided'); - highlights = CSS.highlights.highlightsFromPoint(x, y); - assert_equals(highlights.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the coordinates provided point at one Highlight in the shadow DOM but shadowRoots provided is empty'); + highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y); + assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the coordinates provided point at one Highlight in the shadow DOM but shadowRoots provided is empty'); // Get x and y coordinates between '6' and '7'. // Same priority for the Highlights, break tie by order of registration. x = spanBoundingRectangle.left + 7 * characterWidth; - highlights = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]}); - assert_equals(highlights.length, 2, 'CSS.highlights.highlightsFromPoint() returns exactly two Highlights when the coordinates provided point at two overlapping Highlights'); - assert_equals(highlights[0], highlight2, 'CSS.highlights.highlightsFromPoint() returns first the Highlight registered last when both Highlights present at the point provided have the same priority'); - assert_equals(highlights[1], highlight, 'CSS.highlights.highlightsFromPoint() returns last the Highlight registered first when both Highlights present at the point provided have the same priority'); + highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]}); + assert_equals(highlight_hit_results.length, 2, 'CSS.highlights.highlightsFromPoint() returns exactly two Highlights when the coordinates provided point at two overlapping Highlights'); + assert_equals(highlight_hit_results[0].highlight, highlight2, 'CSS.highlights.highlightsFromPoint() returns first the Highlight registered last when both Highlights present at the point provided have the same priority'); + assert_equals(highlight_hit_results[1].highlight, highlight, 'CSS.highlights.highlightsFromPoint() returns last the Highlight registered first when both Highlights present at the point provided have the same priority'); + assert_array_equals(highlight_hit_results[0].ranges, [range2], 'CSS.highlights.highlightsFromPoint() returns first a HighlightHitResult with the ranges of the Highlight present on top at the coordinates provided'); + assert_array_equals(highlight_hit_results[1].ranges, [range], 'CSS.highlights.highlightsFromPoint() returns last a HighlightHitResult with the ranges of the Highlight present at the bottom at the coordinates provided'); }, 'CSS.highlights.highlightsFromPoint() returns Highlights present at a given point inside a shadow tree in the right order.'); test(() => { @@ -109,23 +112,25 @@ body { // Get x and y coordinates between '0' and '1' in the first line. let x = spanBoundingRectangle.left + characterWidth; let y = container.getBoundingClientRect().top + characterHeight / 2.0; - let highlights = CSS.highlights.highlightsFromPoint(x, y); - assert_equals(highlights.length, 1, 'CSS.highlights.highlightsFromPoint() returns one Highlight present at the coordinates provided'); - assert_equals(highlights[0], highlight, 'CSS.highlights.highlightsFromPoint() returns the Highlight present at the given coordinates even when no shadowRoots are provided because it\'s outside the shadow DOM'); + let highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y); + assert_equals(highlight_hit_results.length, 1, 'CSS.highlights.highlightsFromPoint() returns one Highlight present at the coordinates provided'); + assert_equals(highlight_hit_results[0].highlight, highlight, 'CSS.highlights.highlightsFromPoint() returns the Highlight present at the given coordinates even when no shadowRoots are provided because it\'s outside the shadow DOM'); + assert_array_equals(highlight_hit_results[0].ranges, [range], 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the ranges of the Highlight present at the coordinates provided'); // Now move y to the second line (inside shadow DOM). y += characterHeight; - highlights = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]}); - assert_equals(highlights.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the given coordinates point at text under the shadow root provided even when there is a Highlight set with a Range that starts and ends in the regular DOM surrounding it, even when shadowRoots are provided'); + highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]}); + assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the given coordinates point at text under the shadow root provided even when there is a Highlight set with a Range that starts and ends in the regular DOM surrounding it, even when shadowRoots are provided'); - highlights = CSS.highlights.highlightsFromPoint(x, y); - assert_equals(highlights.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the given coordinates point at text under the shadow root provided even when there is a Highlight set with a Range that starts and ends in the regular DOM surrounding it'); + highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y); + assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the given coordinates point at text under the shadow root provided even when there is a Highlight set with a Range that starts and ends in the regular DOM surrounding it'); // Now move y to the third line. y += characterHeight; - highlights = CSS.highlights.highlightsFromPoint(x, y); - assert_equals(highlights.length, 1, 'CSS.highlights.highlightsFromPoint() returns one Highlight present at the coordinates provided'); - assert_equals(highlights[0], highlight, 'CSS.highlights.highlightsFromPoint() returns the Highlight present at the given coordinates because it\'s outside of the shadow DOM'); + highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y); + assert_equals(highlight_hit_results.length, 1, 'CSS.highlights.highlightsFromPoint() returns one Highlight present at the coordinates provided'); + assert_equals(highlight_hit_results[0].highlight, highlight, 'CSS.highlights.highlightsFromPoint() returns the Highlight present at the given coordinates because it\'s outside of the shadow DOM'); + assert_array_equals(highlight_hit_results[0].ranges, [range], 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the ranges of the Highlight present at the coordinates provided'); // Set a Highlight with a range like this one: // [0123456789 @@ -138,13 +143,13 @@ body { // Set x and y coordinates between '0' and '1' in the first line. y = container.getBoundingClientRect().top + characterHeight / 2.0; - highlights = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]}); - assert_equals(highlights.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the given coordinates point at text in the light DOM that is not highlighted even when there is a Highlight set with a StaticRange that starts in the light DOM and ends in the shadow DOM surrounding it'); + highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]}); + assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the given coordinates point at text in the light DOM that is not highlighted even when there is a Highlight set with a StaticRange that starts in the light DOM and ends in the shadow DOM surrounding it'); // Now move y to the second line (inside shadow DOM). y += characterHeight; - highlights = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]}); - assert_equals(highlights.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the given coordinates point at text in the shadow DOM that is not highlighted even when there is a Highlight set with a StaticRange that starts in the light DOM and ends in the shadow DOM surrounding it'); + highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]}); + assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the given coordinates point at text in the shadow DOM that is not highlighted even when there is a Highlight set with a StaticRange that starts in the light DOM and ends in the shadow DOM surrounding it'); }, 'CSS.highlights.highlightsFromPoint() doesn\'t return Highlights that are not painted at the given coordinates even when they fall inside the Highlights\' ranges'); </script> </body> diff --git a/tests/wpt/tests/soft-navigation-heuristics/first-interaction-not-softnav.tentative.html b/tests/wpt/tests/soft-navigation-heuristics/first-interaction-not-softnav.tentative.html index e0262021836..2c9e2aa7c01 100644 --- a/tests/wpt/tests/soft-navigation-heuristics/first-interaction-not-softnav.tentative.html +++ b/tests/wpt/tests/soft-navigation-heuristics/first-interaction-not-softnav.tentative.html @@ -1,36 +1,37 @@ -<!DOCTYPE HTML> +<!doctype html> <html> -<head> -<meta charset="utf-8"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/resources/testdriver.js"></script> -<script src="/resources/testdriver-vendor.js"></script> -<script src="resources/soft-navigation-helper.js"></script> -</head> -<body> - <main id=main> - <p><a id=firstlink>Click me!</a></p> - <p><a id=secondlink>Then click me!</a></p> - </main> - <script> - (async () => { - if (test_driver) { - const firstlink = document.getElementById("firstlink"); - const clickPromise = new Promise(r => { - firstlink.addEventListener("click", r); - }); - test_driver.click(firstlink); - await clickPromise; - } - })(); - const secondlink = document.getElementById("secondlink"); - testSoftNavigation({ - addContent: () => { - addImageToMain(); - }, - link: secondlink, - test: "first interaction in the middle of a soft navigation"}); - </script> -</body> + <head> + <meta charset="utf-8" /> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/resources/testdriver.js"></script> + <script src="/resources/testdriver-vendor.js"></script> + <script src="resources/soft-navigation-helper.js"></script> + </head> + <body> + <main id="main"> + <p><a id="firstlink">Click me!</a></p> + <p><a id="secondlink">Then click me!</a></p> + </main> + <script> + const secondlink = document.getElementById("secondlink"); + testSoftNavigation({ + preTestWork: async () => { + if (test_driver) { + const firstlink = document.getElementById("firstlink"); + const clickPromise = new Promise((r) => { + firstlink.addEventListener("click", r); + }); + test_driver.click(firstlink); + await clickPromise; + } + }, + addContent: () => { + addImageToMain(); + }, + link: secondlink, + test: "first interaction before a soft navigation", + }); + </script> + </body> </html> diff --git a/tests/wpt/tests/soft-navigation-heuristics/innertext.tentative.html b/tests/wpt/tests/soft-navigation-heuristics/innertext.tentative.html deleted file mode 100644 index 7716488f25a..00000000000 --- a/tests/wpt/tests/soft-navigation-heuristics/innertext.tentative.html +++ /dev/null @@ -1,37 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> -<meta charset="utf-8"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/resources/testdriver.js"></script> -<script src="/resources/testdriver-vendor.js"></script> -<script src="resources/soft-navigation-helper.js"></script> -</head> -<body> - <main id=main> - <a id=link>Click me!</a> - <!-- This test fails if the paragraph below already has content. The reason - is that secondary paints are not being properly recorded, and hence don't - count for soft navigation heuristics. --> - <p id="softnav-content"></p> - </main> - <script> - const link = document.getElementById("link"); - testSoftNavigation({ - addContent: async () => { - document.getElementById("softnav-content").innerText = - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, ' + - 'sed do eiusmod tempor incididunt ut labore et dolore magna ' + - 'aliqua. Ut enim ad minim veniam, quis nostrud exercitation ' + - 'ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis ' + - 'aute irure dolor in reprehenderit in voluptate velit esse ' + - 'cillum dolore eu fugiat nulla pariatur. Excepteur sint ' + - 'occaecat cupidatat non proident, sunt in culpa qui officia ' + - 'deserunt mollit anim id est laborum.'; - }, - link: link, - test: "Soft navigation when only innerText was modified"}); - </script> -</body> -</html> diff --git a/tests/wpt/tests/soft-navigation-heuristics/resources/soft-navigation-helper.js b/tests/wpt/tests/soft-navigation-heuristics/resources/soft-navigation-helper.js index 48e7b58d8d1..5860738225b 100644 --- a/tests/wpt/tests/soft-navigation-heuristics/resources/soft-navigation-helper.js +++ b/tests/wpt/tests/soft-navigation-heuristics/resources/soft-navigation-helper.js @@ -48,7 +48,11 @@ const testSoftNavigation = options => { const eventType = readValue(options.eventType, 'click'); const interactionFunc = options.interactionFunc; const eventPrepWork = options.eventPrepWork; + const preTestWork = options.preTestWork; promise_test(async t => { + if (preTestWork) { + await preTestWork(); + } await withTimeoutMessage( t, waitInitialLCP(), 'Timed out waiting for initial LCP'); const preClickLcp = await withTimeoutMessage( diff --git a/tests/wpt/tests/soft-navigation-heuristics/smoke/tentative/dom.html b/tests/wpt/tests/soft-navigation-heuristics/smoke/tentative/dom.html index 66d23b22788..2e3c3809df6 100644 --- a/tests/wpt/tests/soft-navigation-heuristics/smoke/tentative/dom.html +++ b/tests/wpt/tests/soft-navigation-heuristics/smoke/tentative/dom.html @@ -61,6 +61,20 @@ document.body.appendChild(cloned); history.pushState({}, "", "/template-element"); } + + // Uses Element.innerText to add to the DOM, without overriding existing text. + // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/innerText + function elementInnerTextInitial() { + document.getElementById("element-inner-text-initial-dest").innerText = "Hello, World."; + history.pushState({}, "", "/element-inner-text-initial"); + } + + // Uses Element.innerText to add to the DOM, overriding existing text. + // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/innerText + function elementInnerTextOverride() { + document.getElementById("element-inner-text-override-dest").innerText = "Hello, World."; + history.pushState({}, "", "/element-inner-text-override"); + } </script> </head> <body> @@ -70,6 +84,14 @@ <div id="document-import-node" onclick="documentImportNode()">Click here!</div> <div id="document-adopt-node" onclick="documentAdoptNode()">Click here!</div> <div id="template-element" onclick="templateElement()">Click here!</div> + <div id="element-inner-text-initial" onclick="elementInnerTextInitial()"> + Click here! + <div id="element-inner-text-initial-dest"></div> + </div> + <div id="element-inner-text-override" onclick="elementInnerTextOverride()"> + Click here! + <div id="element-inner-text-override-dest">Some text already there.</div> + </div> <iframe id="iframe-example" srcdoc="<div id='import-this'>Hello, World.</div>"></iframe> @@ -111,6 +133,14 @@ "Soft Navigation Detection supports Document.adoptNode.", ); test_template("template-element", "Soft Navigation Detection supports template elements."); + test_template( + "element-inner-text-initial", + "Soft Navigation Detection supports Element.innerText when it does not override existing text.", + ); + test_template( + "element-inner-text-override", + "Soft Navigation Detection supports Element.innerText when it overrides existing text.", + ); </script> </body> </html> diff --git a/tests/wpt/tests/soft-navigation-heuristics/smoke/tentative/resources/other_window.html b/tests/wpt/tests/soft-navigation-heuristics/smoke/tentative/resources/other_window.html new file mode 100644 index 00000000000..406d39c3691 --- /dev/null +++ b/tests/wpt/tests/soft-navigation-heuristics/smoke/tentative/resources/other_window.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<meta charset="utf-8"> + +<h1>This is some text</h1> + +<script> + function navigate() { + history.pushState({}, "", "/different-url"); + } + + async function getNextSoftNavEntry() { + return new Promise(resolve => { + new PerformanceObserver((list, observer) => { + observer.disconnect(); + resolve(list.getEntries()[0]); + }).observe({ type: "soft-navigation" }); + }); + } +</script> diff --git a/tests/wpt/tests/soft-navigation-heuristics/smoke/tentative/window-open-cross-scheduling.html b/tests/wpt/tests/soft-navigation-heuristics/smoke/tentative/window-open-cross-scheduling.html new file mode 100644 index 00000000000..1a41be6ddd2 --- /dev/null +++ b/tests/wpt/tests/soft-navigation-heuristics/smoke/tentative/window-open-cross-scheduling.html @@ -0,0 +1,45 @@ +<!doctype html> +<html> + <head> + <meta charset="utf-8" /> + <title>Scheduling soft navigations across windows.</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/resources/testdriver.js"></script> + <script src="/resources/testdriver-vendor.js"></script> + <script></script> + </head> + <body> + <button id="button" onclick="navigateChild()">Press Me!</button> + + <script> + const child = window.open('resources/other_window.html'); + const childLoaded = new Promise(resolve => child.onload = resolve); + + function navigateChild() { + // `child.navigate()` is a function declared in the `other_window.html`. + child.navigate(); + } + + promise_test(async (t) => { + await childLoaded; + + if (test_driver) { + test_driver.click(document.getElementById("button")); + } + + new PerformanceObserver((list, observer) => t.step(() => { + observer.disconnect(); + assert_unreached("Parent window should not detect a soft-navigation."); + })).observe({ type: "soft-navigation" }); + + child.getNextSoftNavEntry().then((entry) => { + assert_unreached("Child window should not detect a soft-navigation."); + }); + + await new Promise(resolve => t.step_timeout(resolve, 2000)); + + }, "Opening a new window and updating a URL in it shouldn't crash"); + </script> + </body> +</html> diff --git a/tests/wpt/tests/speculation-rules/prefetch/no-prefetch-for-post.https.html b/tests/wpt/tests/speculation-rules/prefetch/no-prefetch-for-post.https.html new file mode 100644 index 00000000000..7739f4f8c71 --- /dev/null +++ b/tests/wpt/tests/speculation-rules/prefetch/no-prefetch-for-post.https.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/dispatcher/dispatcher.js"></script> +<script src="/common/utils.js"></script> +<script src="../resources/utils.js"></script> +<script src="resources/utils.sub.js"></script> +<script> + setup(() => assertSpeculationRulesIsSupported()); + + promise_test(async t => { + let agent = await spawnWindow(t); + let nextUrl = agent.getExecutorURL({ executor: 'post-navigation-handler.py', protocol: 'https', page: 2 }); + await agent.forceSinglePrefetch(nextUrl); + + await agent.execute_script(async (nextUrl) => { + window.executor.suspend(() => { + navigate_by_form_generated_post(nextUrl); + }); + }, [nextUrl]); + + assert_not_prefetched(await agent.getRequestHeaders()); + }, "post navigations should not use cached prefetch"); +</script> diff --git a/tests/wpt/tests/speculation-rules/prefetch/resources/executor.sub.html b/tests/wpt/tests/speculation-rules/prefetch/resources/executor.sub.html index bb2d58dc9c9..b89c45e4f5c 100644 --- a/tests/wpt/tests/speculation-rules/prefetch/resources/executor.sub.html +++ b/tests/wpt/tests/speculation-rules/prefetch/resources/executor.sub.html @@ -82,6 +82,13 @@ async function start_non_eager_prefetch_on_pointerdown(id) { await new test_driver.Actions().addPointer("mouse").pointerMove(0, 0, {origin: target}).pointerDown().pointerMove(0, 0).pointerUp().send(); } +async function navigate_by_form_generated_post(url) { + let form = document.createElement('form'); + form.method = 'POST'; + form.action = url; + document.body.appendChild(form); + form.submit(); +} // The fetch request's URL sent to the server. window.requestUrl = reverse_html_escape( diff --git a/tests/wpt/tests/speculation-rules/prefetch/resources/post-navigation-handler.py b/tests/wpt/tests/speculation-rules/prefetch/resources/post-navigation-handler.py new file mode 100644 index 00000000000..1749517710e --- /dev/null +++ b/tests/wpt/tests/speculation-rules/prefetch/resources/post-navigation-handler.py @@ -0,0 +1,10 @@ +import os +from wptserve.pipes import template + +# This is used only to accept POST navigations. +def main(request, response): + response.headers.set(b"Content-Type", b"text/html") + response.headers.set(b"Cache-Control", b"no-store") + response.content = template( + request, + open(os.path.join(os.path.dirname(__file__), "executor.sub.html"), "rb").read())
\ No newline at end of file diff --git a/tests/wpt/tests/speculation-rules/prerender/headers.https.html b/tests/wpt/tests/speculation-rules/prerender/headers.https.html new file mode 100644 index 00000000000..2ef6b5ce072 --- /dev/null +++ b/tests/wpt/tests/speculation-rules/prerender/headers.https.html @@ -0,0 +1,159 @@ +<!DOCTYPE html> +<title>Sec-Purpose header on prerendered page</title> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script src="/common/utils.js"></script> +<script src="/common/dispatcher/dispatcher.js"></script> +<script src="/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js"></script> +<script src="../resources/utils.js"></script> +<script src="resources/utils.js"></script> + +<body> +<script> +setup(() => assertSpeculationRulesIsSupported()); + +promise_test(async () => { + const rcHelper = new RemoteContextHelper(); + const referrerRC = await rcHelper.addWindow(undefined, { features: 'noopener' }); + const prerenderedRC = await addPrerenderRC(referrerRC); + + const prerenderedHeaders = await prerenderedRC.getRequestHeaders(); + assertHeaders(prerenderedHeaders, true, true, 'prerendered page'); + + const iframeRC = await prerenderedRC.addIframe(); + const iframeHeaders = await iframeRC.getRequestHeaders(); + assertHeaders(iframeHeaders, true, false, 'iframe'); + + // No test for cross-origin iframe, since those requests are delayed until + // after activation. See below. + + const imageHeaders = await insertImageAndGetRequestHeaders(prerenderedRC); + assertHeaders(imageHeaders, true, false, 'image'); + + const crossOriginImageHeaders = await insertImageAndGetRequestHeaders( + prerenderedRC, + get_host_info().HTTPS_REMOTE_ORIGIN + ); + assertHeaders(crossOriginImageHeaders, true, false, 'cross-origin image'); + + const fetchHeaders = await doFetchAndGetRequestHeaders(prerenderedRC); + assertHeaders(fetchHeaders, true, false, 'fetch'); + + const crossOriginFetchHeaders = await doFetchAndGetRequestHeaders( + prerenderedRC, + get_host_info().HTTPS_REMOTE_ORIGIN + ); + assertHeaders(crossOriginFetchHeaders, true, false, 'cross-origin fetch'); + + const navigatedToRC = await prerenderedRC.navigateToNew(); + const navigatedToHeaders = await navigatedToRC.getRequestHeaders(); + assertHeaders(navigatedToHeaders, true, false, 'navigated-to page'); +}, 'Headers before activation, including prerendered page navigation'); + +promise_test(async () => { + const rcHelper = new RemoteContextHelper(); + const referrerRC = await rcHelper.addWindow(undefined, { features: 'noopener' }); + const prerenderedRC = await addPrerenderRC(referrerRC); + + // Add the iframe now, but only check its headers after activation. + const crossOriginIframeBeforeActivationRC = await prerenderedRC.addIframe({ origin: 'HTTPS_REMOTE_ORIGIN' }); + + await activatePrerenderRC(referrerRC, prerenderedRC); + + const crossOriginIframeBeforeActivationHeaders = await crossOriginIframeBeforeActivationRC.getRequestHeaders(); + assertHeaders(crossOriginIframeBeforeActivationHeaders, true, false, 'cross-origin iframe before activation'); + + const iframeRC = await prerenderedRC.addIframe(); + const iframeHeaders = await iframeRC.getRequestHeaders(); + assertHeaders(iframeHeaders, false, false, 'post-activation iframe'); + + const imageHeaders = await insertImageAndGetRequestHeaders(prerenderedRC); + assertHeaders(imageHeaders, false, false, 'post-activation image'); + + const crossOriginImageHeaders = await insertImageAndGetRequestHeaders( + prerenderedRC, + get_host_info().HTTPS_REMOTE_ORIGIN + ); + assertHeaders(crossOriginImageHeaders, false, false, 'cross-origin image'); + + const fetchHeaders = await doFetchAndGetRequestHeaders(prerenderedRC); + assertHeaders(fetchHeaders, false, false, 'post-activation fetch'); + + const crossOriginFetchHeaders = await doFetchAndGetRequestHeaders( + prerenderedRC, + get_host_info().HTTPS_REMOTE_ORIGIN + ); + assertHeaders(crossOriginFetchHeaders, false, false, 'cross-origin fetch'); +}, 'Headers after activation (plus cross-origin iframe before activation)'); + +async function insertImageAndGetRequestHeaders(rc, hostname) { + const uuid = token(); + const url = (new URL(`resources/image-with-headers-stash.py?image=${uuid}`, location.href)); + const headersURL = (new URL(`resources/image-with-headers-stash.py?read=${uuid}`, location.href)); + + if (hostname !== undefined) { + url.hostname = hostname; + headersURL.hostname = hostname; + } + + await rc.executeScript(async (url) => { + const img = new Image(); + img.src = url; + const promise = new Promise(resolve => img.onload = resolve); + document.body.append(img); + return promise; + }, [url]); + + const headersJSON = await (await fetch(headersURL)).json(); + assert_not_equals(headersJSON, null, 'image headers should not be null'); + return new Headers(headersJSON); +} + +async function doFetchAndGetRequestHeaders(rc, hostname) { + const uuid = token(); + const url = (new URL(`resources/image-with-headers-stash.py?image=${uuid}`, location.href)); + const headersURL = (new URL(`resources/image-with-headers-stash.py?read=${uuid}`, location.href)); + + if (hostname !== undefined) { + url.hostname = hostname; + headersURL.hostname = hostname; + } + + await rc.executeScript(async (url) => { + return fetch(url, { mode: "cors" }); + }, [url]); + + const headersJSON = await (await fetch(headersURL)).json(); + assert_not_equals(headersJSON, null, 'fetch headers should not be null'); + return new Headers(headersJSON); +} + +function assertHeaders(headers, secPurposeIsPrefetchPrerender, secSpeculationTagsIsPresent, label) { + if (secPurposeIsPrefetchPrerender) { + assert_equals( + headers.get('Sec-Purpose'), + 'prefetch;prerender', + `${label} Sec-Purpose` + ); + } else { + assert_false( + headers.has('Sec-Purpose'), + `${label} Sec-Purpose should not be present` + ); + } + if (secSpeculationTagsIsPresent) { + assert_equals( + headers.get('Sec-Speculation-Tags'), + 'null', + `${label} Sec-Speculation-Tags` + ); + } else { + assert_false( + headers.has('Sec-Speculation-Tags'), + `${label} Sec-Speculation-Tags should not be present` + ); + } +} +</script> diff --git a/tests/wpt/tests/speculation-rules/prerender/resources/image-with-headers-stash.py b/tests/wpt/tests/speculation-rules/prerender/resources/image-with-headers-stash.py new file mode 100644 index 00000000000..dcb8838d4a1 --- /dev/null +++ b/tests/wpt/tests/speculation-rules/prerender/resources/image-with-headers-stash.py @@ -0,0 +1,45 @@ +# Supports two operations: +# - ?image=uuid: Returns an image, and records the request headers that were +# used to get that image. +# - ?read=uuid: Returns the request headers in the stash keyed by a given uuid. + +import os +import json + +from wptserve.utils import isomorphic_decode + +def main(request, response): + if b"image" in request.GET: + uuid = request.GET[b"image"] + + header_pairs = [] + for header_name in request.headers.keys(): + # ensure the header name/value are unicode strings + name = header_name.lower().decode("utf-8") + for header_value in request.headers.get_list(header_name): + value = header_value.decode("utf-8") + header_pairs.append([name, value]) + + request_headers = json.dumps(header_pairs) + request.server.stash.put(uuid, request_headers) + + # Return a basic image. + response_headers = [ + (b"Content-Type", b"image/png"), + (b"Access-Control-Allow-Origin", b"*") + ] + image_path = os.path.join( + os.path.dirname(isomorphic_decode(__file__)), + u"../../../common/square.png" + ) + return (200, response_headers, open(image_path, mode='rb').read()) + + elif b"read" in request.GET: + uuid = request.GET[b"read"] + stash_value = request.server.stash.take(uuid) + + if stash_value is None: + stash_value = "null" + return (200, [(b"Content-Type", b"application/json")], str(stash_value)) + + return (404 , [], "Not found") diff --git a/tests/wpt/tests/svg/embedded/image-modify-href-4.svg b/tests/wpt/tests/svg/embedded/image-modify-href-4.svg new file mode 100644 index 00000000000..f7e550e5def --- /dev/null +++ b/tests/wpt/tests/svg/embedded/image-modify-href-4.svg @@ -0,0 +1,30 @@ +<svg xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:h="http://www.w3.org/1999/xhtml" width="200" height="200" class="reftest-wait" onload="test()"> + <metadata> + <title>modifying xlink:href on an SVG image</title> + <h:link rel="match" href="reference/green-rect-100x100.svg"/> + </metadata> + <script href="/common/reftest-wait.js"></script> + <script href="/common/rendering-utils.js"></script> + <script> + const SVG_NS = "http://www.w3.org/2000/svg"; + + async function test() { + await waitForAtLeastOneFrame(); + + const doc = document.implementation.createDocument(SVG_NS, "svg"); + + const image = doc.createElementNS(SVG_NS, "image"); + image.setAttribute("width", 100); + image.setAttribute("height", 100); + image.setAttribute("href", "reference/green-rect-100x100.svg"); + doc.documentElement.appendChild(image); + + document.documentElement.appendChild(document.adoptNode(image)); + + await waitForAtLeastOneFrame(); + takeScreenshot(); + } + </script> +</svg> diff --git a/tests/wpt/tests/tools/third_party_modified/mozlog/mozlog/handlers/base.py b/tests/wpt/tests/tools/third_party_modified/mozlog/mozlog/handlers/base.py index 7cea14c7a44..707b539ec76 100644 --- a/tests/wpt/tests/tools/third_party_modified/mozlog/mozlog/handlers/base.py +++ b/tests/wpt/tests/tools/third_party_modified/mozlog/mozlog/handlers/base.py @@ -18,7 +18,7 @@ class BaseHandler(object): def __init__(self, inner): self.message_handler = MessageHandler() if hasattr(inner, "message_handler"): - self.message_handler.wrapped.append(inner) + self.message_handler.wrapped.append(inner.message_handler) class LogLevelFilter(BaseHandler): diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/firefox_android.py b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/firefox_android.py index 7bb2e57d417..d0cd7411af0 100644 --- a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/firefox_android.py +++ b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/firefox_android.py @@ -381,6 +381,9 @@ class FirefoxAndroidBrowser(Browser): class FirefoxAndroidWdSpecBrowser(FirefoxWdSpecBrowser): def __init__(self, logger, config=None, device_serial=None, adb_binary=None, **kwargs): + if "profile_creator_cls" not in kwargs: + kwargs["profile_creator_cls"] = ProfileCreator + super().__init__(logger, config=config, **kwargs) self.config = config diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/headless_shell.py b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/headless_shell.py index b6f7a40f8a9..ccd5620365a 100644 --- a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/headless_shell.py +++ b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/headless_shell.py @@ -3,6 +3,7 @@ from .base import require_arg from .base import get_timeout_multiplier # noqa: F401 from .chrome import ChromeBrowser # noqa: F401 +from .chrome import browser_kwargs as browser_kwargs # noqa: F401 from .chrome import executor_kwargs as chrome_executor_kwargs from ..executors.base import WdspecExecutor # noqa: F401 from ..executors.executorchrome import ( # noqa: F401 @@ -35,13 +36,6 @@ def check_args(**kwargs): require_arg(kwargs, "webdriver_binary") -def browser_kwargs(logger, test_type, run_info_data, config, **kwargs): - return {"binary": kwargs["binary"], - "webdriver_binary": kwargs["webdriver_binary"], - "webdriver_args": kwargs.get("webdriver_args"), - "debug_info": kwargs["debug_info"]} - - def executor_kwargs(logger, test_type, test_environment, run_info_data, subsuite, **kwargs): executor_kwargs = chrome_executor_kwargs(logger, test_type, test_environment, run_info_data, diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/servo.py b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/servo.py index 266aec8fced..07441780ccc 100644 --- a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/servo.py +++ b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/servo.py @@ -37,11 +37,11 @@ def check_args(**kwargs): require_arg(kwargs, "binary") -def browser_kwargs(logger, test_type, run_info_data, config, **kwargs): +def browser_kwargs(logger, test_type, run_info_data, config, subsuite, **kwargs): return { "binary": kwargs["binary"], "debug_info": kwargs["debug_info"], - "binary_args": kwargs["binary_args"], + "binary_args": kwargs["binary_args"] + subsuite.config.get("binary_args", []), "user_stylesheets": kwargs.get("user_stylesheets"), "ca_certificate_path": config.ssl_config["ca_cert_path"], } @@ -68,7 +68,7 @@ def env_options(): def update_properties(): - return ["debug", "os", "processor"], {"os": ["version"], "processor": ["bits"]} + return ["debug", "os", "processor", "subsuite"], {"os": ["version"], "processor": ["bits"]} class ServoBrowser(NullBrowser): diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/servodriver.py b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/servodriver.py index 5011a8fd859..f72f2257a38 100644 --- a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/servodriver.py +++ b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/servodriver.py @@ -39,10 +39,10 @@ def check_args(**kwargs): require_arg(kwargs, "binary") -def browser_kwargs(logger, test_type, run_info_data, config, **kwargs): +def browser_kwargs(logger, test_type, run_info_data, config, subsuite, **kwargs): return { "binary": kwargs["binary"], - "binary_args": kwargs["binary_args"], + "binary_args": kwargs["binary_args"] + subsuite.config.get("binary_args", []), "debug_info": kwargs["debug_info"], "server_config": config, "user_stylesheets": kwargs.get("user_stylesheets"), @@ -67,7 +67,7 @@ def env_options(): def update_properties(): - return (["debug", "os", "processor"], {"os": ["version"], "processor": ["bits"]}) + return (["debug", "os", "processor", "subsuite"], {"os": ["version"], "processor": ["bits"]}) def write_hosts_file(config): diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorchrome.py b/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorchrome.py index 1e588d5bfbf..3284e6c8091 100644 --- a/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorchrome.py +++ b/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorchrome.py @@ -304,6 +304,10 @@ class ChromeDriverTestharnessExecutor(WebDriverTestharnessExecutor): test_window = self.protocol.testharness.persistent_test_window = None if not test_window: test_window = super().get_or_create_test_window(protocol) + if self.reuse_window: + self.logger.info(f"Created new test window {test_window}") + # Without `--reuse-window`, each testharness test always creates a + # new window, so tracing that event is not interesting. if self.reuse_window: self.protocol.testharness.persistent_test_window = test_window return test_window diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/testrunner.py b/tests/wpt/tests/tools/wptrunner/wptrunner/testrunner.py index 19c814bb6c9..be310944fd8 100644 --- a/tests/wpt/tests/tools/wptrunner/wptrunner/testrunner.py +++ b/tests/wpt/tests/tools/wptrunner/wptrunner/testrunner.py @@ -313,7 +313,7 @@ class TestSource: if not self.current_group.group or len(self.current_group.group) == 0: try: self.current_group = self.test_queue.get() - self.logger.debug(f"Got new test group subsuite:{self.current_group[1]} " + self.logger.debug(f"Got new test group subsuite:{self.current_group[1]!r} " f"test_type:{self.current_group[2]}") except Empty: return testloader.TestGroup(None, None, None, None) @@ -473,11 +473,11 @@ class TestRunnerManager(threading.Thread): if skipped_tests: self.logger.critical( - f"Tests left in the queue: {subsuite}:{skipped_tests[0].id!r} " + f"Tests left in the queue: {subsuite!r}:{skipped_tests[0].id!r} " f"and {len(skipped_tests) - 1} others" ) for test in skipped_tests[1:]: - self.logger.debug(f"Test left in the queue: {subsuite}:{test.id!r}") + self.logger.debug(f"Test left in the queue: {subsuite!r}:{test.id!r}") force_stop = (not isinstance(self.state, RunnerManagerState.stop) or self.state.force_stop) @@ -900,7 +900,7 @@ class TestRunnerManager(threading.Thread): if test is None: return RunnerManagerState.stop(force_stop) if subsuite != self.state.subsuite: - self.logger.info(f"Restarting browser for new subsuite:{subsuite}") + self.logger.info(f"Restarting browser for new subsuite:{subsuite!r}") restart = True elif self.restart_on_new_group and test_group is not self.state.test_group: self.logger.info("Restarting browser for new test group") diff --git a/tests/wpt/tests/trusted-types/block-text-node-insertion-into-script-element.html b/tests/wpt/tests/trusted-types/block-text-node-insertion-into-script-element.html index 65b40b933ff..1a1256d05a8 100644 --- a/tests/wpt/tests/trusted-types/block-text-node-insertion-into-script-element.html +++ b/tests/wpt/tests/trusted-types/block-text-node-insertion-into-script-element.html @@ -49,12 +49,12 @@ assert_equals(s.text, ""); // Try to insertAdjacentText into the <script>, starting from the <p> - await checkMessage(_ => + await checkMessage(t, _ => p.insertAdjacentText("beforebegin", "postMessage('beforebegin should be blocked', '*');") ); assert_true(s.text.includes("postMessage")); - await checkMessage(_ => + await checkMessage(t, _ => p.insertAdjacentText("afterend", "postMessage('afterend should be blocked', '*');") ); @@ -74,12 +74,12 @@ container.appendChild(s); // Try to insertAdjacentText into the <script>, starting from the <p> - await checkMessage(_ => + await checkMessage(t, _ => p.insertAdjacentText("beforebegin", "postMessage('beforebegin should be blocked', '*');") ); assert_true(s.textContent.includes("postMessage")); - await checkMessage(_ => + await checkMessage(t, _ => p.insertAdjacentText("afterend", "postMessage('afterend should be blocked', '*');") ); @@ -94,7 +94,7 @@ let text = document.createTextNode("postMessage('appendChild with a " + "text node should be blocked', '*');"); s.appendChild(text); - await checkMessage(_ => container.appendChild(s)); + await checkMessage(t, _ => container.appendChild(s)); }, "Regression test: Bypass via appendChild into off-document script element."); // Variant: Create a <script> element and insert it into the document. Then @@ -106,7 +106,7 @@ container.appendChild(s); let text = document.createTextNode("postMessage('appendChild with a live " + "text node should be blocked', '*');"); - await checkMessage(_ => s.appendChild(text)); + await checkMessage(t, _ => s.appendChild(text)); }, "Regression test: Bypass via appendChild into live script element."); promise_test(async t => { @@ -150,7 +150,7 @@ let text = document.createTextNode("postMessage('default', '*');"); s.appendChild(text); await no_trusted_type_violation_for(async _ => - await checkMessage(_ => container.appendChild(s), 1) + await checkMessage(t, _ => container.appendChild(s), 1) ); assert_array_equals(seenSinks, ["HTMLScriptElement text"]); }, "Test that default policy applies."); @@ -158,10 +158,22 @@ promise_test(async t => { t.add_cleanup(clearSeenSinks); let s = createScriptElement(); + s.setAttribute("type", "module") + let text = document.createTextNode("postMessage('default', '*');"); + s.appendChild(text); + await no_trusted_type_violation_for(async _ => + await checkMessage(t, _ => container.appendChild(s), 1) + ); + assert_array_equals(seenSinks, ["HTMLScriptElement text"]); + }, "Test that default policy applies to module script."); + + promise_test(async t => { + t.add_cleanup(clearSeenSinks); + let s = createScriptElement(); let text = document.createTextNode("fail"); s.appendChild(text); await trusted_type_violation_without_exception_for(async _ => - await checkMessage(_ => container.appendChild(s), 0) + await checkMessage(t, _ => container.appendChild(s), 0) ); assert_array_equals(seenSinks, ["HTMLScriptElement text"]); }, "Test a failing default policy."); diff --git a/tests/wpt/tests/trusted-types/block-text-node-insertion-into-svg-script-element.html b/tests/wpt/tests/trusted-types/block-text-node-insertion-into-svg-script-element.html index f4ff2435035..18c6af8f5ef 100644 --- a/tests/wpt/tests/trusted-types/block-text-node-insertion-into-svg-script-element.html +++ b/tests/wpt/tests/trusted-types/block-text-node-insertion-into-svg-script-element.html @@ -49,12 +49,12 @@ container.appendChild(s); // Try to insertAdjacentText into the <script>, starting from the <p> - await checkMessage(_ => + await checkMessage(t, _ => p.insertAdjacentText("beforebegin", "postMessage('beforebegin should be blocked', '*');") ); assert_true(s.textContent.includes("postMessage")); - await checkMessage(_ => + await checkMessage(t, _ => p.insertAdjacentText("afterend", "postMessage('afterend should be blocked', '*');") ); @@ -69,7 +69,7 @@ let text = document.createTextNode("postMessage('appendChild with a " + "text node should be blocked', '*');"); s.appendChild(text); - await checkMessage(_ => container.appendChild(s)); + await checkMessage(t, _ => container.appendChild(s)); }, "Regression test: Bypass via appendChild into off-document script element. svg:script"); // Variant: Create a <script> element and insert it into the document. Then @@ -81,7 +81,7 @@ container.appendChild(s); let text = document.createTextNode("postMessage('appendChild with a live " + "text node should be blocked', '*');"); - await checkMessage(_ => s.appendChild(text)); + await checkMessage(t, _ => s.appendChild(text)); }, "Regression test: Bypass via appendChild into live script element. svg:script"); promise_test(async t => { @@ -125,7 +125,7 @@ let text = document.createTextNode("postMessage('default', '*');"); s.appendChild(text); await no_trusted_type_violation_for(async _ => - await checkMessage(_ => container.appendChild(s), 1) + await checkMessage(t, _ => container.appendChild(s), 1) ); assert_array_equals(seenSinks, ["SVGScriptElement text"]); }, "Test that default policy applies. svg:script"); @@ -133,10 +133,22 @@ promise_test(async t => { t.add_cleanup(clearSeenSinks); let s = createScriptElement(); + s.setAttribute("type", "module"); + let text = document.createTextNode("postMessage('default', '*');"); + s.appendChild(text); + await no_trusted_type_violation_for(async _ => + await checkMessage(t, _ => container.appendChild(s), 1) + ); + assert_array_equals(seenSinks, ["SVGScriptElement text"]); + }, "Test that default policy applies with module script. svg:script"); + + promise_test(async t => { + t.add_cleanup(clearSeenSinks); + let s = createScriptElement(); let text = document.createTextNode("fail"); s.appendChild(text); await trusted_type_violation_without_exception_for(async _ => - await checkMessage(_ => container.appendChild(s), 0) + await checkMessage(t, _ => container.appendChild(s), 0) ); assert_array_equals(seenSinks, ["SVGScriptElement text"]); }, "Test a failing default policy. svg:script"); diff --git a/tests/wpt/tests/trusted-types/resources/block-text-node-insertion.js b/tests/wpt/tests/trusted-types/resources/block-text-node-insertion.js index e9797756417..dd85483a44f 100644 --- a/tests/wpt/tests/trusted-types/resources/block-text-node-insertion.js +++ b/tests/wpt/tests/trusted-types/resources/block-text-node-insertion.js @@ -14,10 +14,13 @@ // - includes "count": Count these, and later check against expect_count. // - includes "done": Unregister the event handler and finish the test. // - all else: Reject, as this is probably an error in the test. - function checkMessage(fn, expect_count) { + function checkMessage(t, fn, expect_count) { return new Promise((resolve, reject) => { let count = 0; globalThis.addEventListener("message", function handler(e) { + t.add_cleanup(() => { + globalThis.removeEventListener("message", handler); + }); if (e.data.includes("block")) { reject(`'block' received (${e.data})`); } else if (e.data.includes("count")) { @@ -35,6 +38,6 @@ } }); fn(); - postMessage("done", "*"); + requestAnimationFrame(_ => requestAnimationFrame(_ => postMessage("done", "*"))); }); } diff --git a/tests/wpt/tests/ua-client-hints/WEB_FEATURES.yml b/tests/wpt/tests/ua-client-hints/WEB_FEATURES.yml new file mode 100644 index 00000000000..2d331cf4060 --- /dev/null +++ b/tests/wpt/tests/ua-client-hints/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +features: +- name: ua-client-hints + files: "**" diff --git a/tests/wpt/tests/uievents/legacy-domevents-tests/approved/ProcessingInstruction.DOMCharacterDataModified.html b/tests/wpt/tests/uievents/legacy-domevents-tests/approved/ProcessingInstruction.DOMCharacterDataModified.html deleted file mode 100644 index 2da0a389e2e..00000000000 --- a/tests/wpt/tests/uievents/legacy-domevents-tests/approved/ProcessingInstruction.DOMCharacterDataModified.html +++ /dev/null @@ -1,32 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<title> ProcessingInstruction.data and DOMCharacterDataModified event </title> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -</head> -<body> -<div id=log></div> - -<iframe id="helper" style="display: none"></iframe> - -<script> - var description = "Test Description: " + - "DOMCharacterDataModified event fires after ProcessingInstruction.data have been modified, " + - "but the node itself has not been inserted or deleted. The proximal event target of this " + - "event shall be the ProcessingInstruction node."; - - var t = async_test(description); - - var HELPER = document.getElementById("helper"); - - HELPER.onload = t.step_func(function() - { - assert_true(HELPER.contentWindow.TestResult); - t.done(); - }); - - HELPER.src = "./support/ProcessingInstruction.DOMCharacterDataModified.xml"; -</script> -</body> -</html> diff --git a/tests/wpt/tests/uievents/legacy-domevents-tests/approved/domnodeinserted.html b/tests/wpt/tests/uievents/legacy-domevents-tests/approved/domnodeinserted.html deleted file mode 100644 index e5064d8d46c..00000000000 --- a/tests/wpt/tests/uievents/legacy-domevents-tests/approved/domnodeinserted.html +++ /dev/null @@ -1,26 +0,0 @@ -<!DOCTYPE html> -<title>MutationEvent: DOMNodeInserted Event Type</title> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<div id=log></div> - -<div id="target" style="display: none"></div> - -<script> -var EVENT = "DOMNodeInserted"; -var TARGET; -var NODE; - -var t = async_test("Test Description: DOMNodeInserted event fires when a node has been added as a child of another node."); - -TARGET = document.getElementById("target"); - -TARGET.addEventListener(EVENT, t.step_func(function(evt) -{ - assert_equals(evt.type, EVENT); - t.done(); -}), true); - -NODE = document.createElement("INPUT"); -TARGET.appendChild(NODE); -</script> diff --git a/tests/wpt/tests/urlpattern/resources/urlpattern-generate-test-data.json b/tests/wpt/tests/urlpattern/resources/urlpattern-generate-test-data.json new file mode 100644 index 00000000000..c118f0a73b5 --- /dev/null +++ b/tests/wpt/tests/urlpattern/resources/urlpattern-generate-test-data.json @@ -0,0 +1,116 @@ +[ + { + "pattern": { "pathname": "/foo" }, + "component": "invalid", + "groups": {}, + "expected": null + }, + { + "pattern": { "pathname": "/foo" }, + "component": "pathname", + "groups": {}, + "expected": "/foo" + }, + { + "pattern": { "pathname": "/:foo" }, + "component": "pathname", + "groups": { "foo": "bar" }, + "expected": "/bar" + }, + { + "pattern": { "pathname": "/:foo" }, + "component": "pathname", + "groups": { "foo": "🍅" }, + "expected": "/%F0%9F%8D%85" + }, + { + "pattern": { "hostname": "{:foo}.example.com" }, + "component": "hostname", + "groups": { "foo": "🍅" }, + "expected": "xn--fi8h.example.com" + }, + { + "pattern": { "pathname": "/:foo" }, + "component": "pathname", + "groups": {}, + "expected": null + }, + { + "pattern": { "pathname": "/foo/:bar" }, + "component": "pathname", + "groups": { "bar": "baz" }, + "expected": "/foo/baz" + }, + { + "pattern": { "pathname": "/foo:bar" }, + "component": "pathname", + "groups": { "bar": "baz" }, + "expected": "/foobaz" + }, + { + "pattern": { "pathname": "/:foo/:bar" }, + "component": "pathname", + "groups": { "foo": "baz", "bar": "qux" }, + "expected": "/baz/qux" + }, + { + "pattern": "https://example.com/:foo", + "component": "pathname", + "groups": { "foo": " " }, + "expected": "/%20" + }, + { + "pattern": "original-scheme://example.com/:foo", + "component": "pathname", + "groups": { "foo": " " }, + "expected": "/ " + }, + { + "pattern": { "pathname": "/:foo" }, + "component": "pathname", + "groups": { "foo": "bar/baz" }, + "expected": null + }, + { + "pattern": { "pathname": "*" }, + "component": "pathname", + "groups": {}, + "expected": null + }, + { + "pattern": { "pathname": "/{foo}+" }, + "component": "pathname", + "groups": {}, + "expected": null + }, + { + "pattern": { "pathname": "/{foo}?" }, + "component": "pathname", + "groups": {}, + "expected": null + }, + { + "pattern": { "pathname": "/{foo}*" }, + "component": "pathname", + "groups": {}, + "expected": null + }, + { + "pattern": { "pathname": "/(regexp)" }, + "component": "pathname", + "groups": {}, + "expected": null + }, + { + "pattern": { "pathname": "/([^\\/]+?)" }, + "component": "pathname", + "groups": {}, + "expected": null + }, + { + "pattern": { "port": "([^\\:]+?)" }, + "component": "port", + "groups": {}, + "expected": null + } +] diff --git a/tests/wpt/tests/urlpattern/urlpattern-generate.tentative.any.js b/tests/wpt/tests/urlpattern/urlpattern-generate.tentative.any.js new file mode 100644 index 00000000000..1f6962942d8 --- /dev/null +++ b/tests/wpt/tests/urlpattern/urlpattern-generate.tentative.any.js @@ -0,0 +1,26 @@ +// META: global=window,worker + +function runTests(data) { + for (let entry of data) { + test(function () { + const pattern = new URLPattern(entry.pattern); + + if (entry.expected === null) { + assert_throws_js(TypeError, _ => pattern.generate(entry.component, entry.groups), + 'generate() should fail with TypeError'); + return; + } + + const result = pattern.generate(entry.component, entry.groups); + assert_equals(result, entry.expected); + }, `Pattern: ${JSON.stringify(entry.pattern)} ` + + `Component: ${entry.component} ` + + `Groups: ${JSON.stringify(entry.groups)}`); + } +} + +promise_test(async function () { + const response = await fetch('resources/urlpattern-generate-test-data.json'); + const data = await response.json(); + runTests(data); +}, 'Loading data...'); diff --git a/tests/wpt/tests/webnn/conformance_tests/cumulative_sum.https.any.js b/tests/wpt/tests/webnn/conformance_tests/cumulative_sum.https.any.js index 85e1ab427d2..34a625152b2 100644 --- a/tests/wpt/tests/webnn/conformance_tests/cumulative_sum.https.any.js +++ b/tests/wpt/tests/webnn/conformance_tests/cumulative_sum.https.any.js @@ -26,13 +26,14 @@ const getCumulativeSumPrecisionTolerance = (graphResources) => { const axis = args[1][Object.keys(args[1])[0]]; let tolerance = inputShape[axis] - 1; - const toleranceValueDict = {float32: tolerance, int32: 0}; + const toleranceValueDict = {float32: tolerance, float16: tolerance, int32: 0}; const expectedDataType = getExpectedDataTypeOfSingleOutput(graphResources.expectedOutputs); return {metricType: 'ULP', value: toleranceValueDict[expectedDataType]}; }; const cumulativeSumTests = [ + // float32 tests { 'name': 'cumulativeSum with float32 input and default options.', 'graph': { @@ -51,7 +52,7 @@ const cumulativeSumTests = [ 'name': 'cumulativeSum', 'arguments': [ {'input': 'cumulativeSumInput'}, - {'axis': 3}, + {'axis': 3} ], 'outputs': 'cumulativeSumOutput' }], @@ -68,32 +69,41 @@ const cumulativeSumTests = [ } }, { - 'name': 'cumulativeSum with int32 input and axis = 2.', + 'name': 'cumulativeSum with float32 input and set exclusive to true.', 'graph': { 'inputs': { 'cumulativeSumInput': { - 'data': [2, 1, 3, 5, 3, 8, 7, 3, 9, 6, 2, 4], - 'descriptor': {shape: [1, 1, 3, 4], dataType: 'int32'} + 'data': [ + 60.42374038696289, -86.92247772216797, -19.496112823486328, + -15.150615692138672, 13.455190658569336, 45.433597564697266, + 61.082862854003906, 70.71882629394531, -31.278579711914062, + 56.08354187011719, 38.992767333984375, -3.27536940574646 + ], + 'descriptor': {shape: [1, 1, 3, 4], dataType: 'float32'} } }, 'operators': [{ 'name': 'cumulativeSum', 'arguments': [ {'input': 'cumulativeSumInput'}, - {'axis': 2}, + {'axis': 3}, + {'options': {'exclusive': true}} ], 'outputs': 'cumulativeSumOutput' }], 'expectedOutputs': { 'cumulativeSumOutput': { - 'data': [2, 1, 3, 5, 5, 9, 10, 8, 14, 15, 12, 12], - 'descriptor': {shape: [1, 1, 3, 4], dataType: 'int32'} + 'data': [ + 0.0, 60.4237404, -26.4987373, -45.994854, 0.0, 13.4551907, + 58.8887863, 119.9716568, 0.0, -31.2785797, 24.8049622, 63.7977295 + ], + 'descriptor': {shape: [1, 1, 3, 4], dataType: 'float32'} } } } }, { - 'name': 'cumulativeSum with float32 input and set exclusive to true.', + 'name': 'cumulativeSum with float32 input and set reversed to true.', 'graph': { 'inputs': { 'cumulativeSumInput': { @@ -111,56 +121,141 @@ const cumulativeSumTests = [ 'arguments': [ {'input': 'cumulativeSumInput'}, {'axis': 3}, - {'options': {'exclusive': true}}, + {'options': {'reversed': true}} ], 'outputs': 'cumulativeSumOutput' }], 'expectedOutputs': { 'cumulativeSumOutput': { 'data': [ - 0.0, 60.4237404, -26.4987373, -45.994854, 0.0, 13.4551907, - 58.8887863, 119.9716568, 0.0, -31.2785797, 24.8049622, 63.7977295 + -61.1454659, -121.5692139, -34.6467285, -15.1506157, 190.6904907, + 177.2352905, 131.8016968, 70.7188263, 60.5223618, 91.8009415, + 35.7173996, -3.2753694 ], 'descriptor': {shape: [1, 1, 3, 4], dataType: 'float32'} } } } }, + + // float16 tests { - 'name': 'cumulativeSum with float32 input and set reversed to true.', + 'name': 'cumulativeSum with float16 input and default options.', 'graph': { 'inputs': { 'cumulativeSumInput': { 'data': [ - 60.42374038696289, -86.92247772216797, -19.496112823486328, - -15.150615692138672, 13.455190658569336, 45.433597564697266, - 61.082862854003906, 70.71882629394531, -31.278579711914062, - 56.08354187011719, 38.992767333984375, -3.27536940574646 + 60.4375, -86.9375, -19.5, -15.1484375, 13.453125, 45.4375, 61.09375, + 70.75, -31.28125, 56.09375, 39, -3.275390625 ], - 'descriptor': {shape: [1, 1, 3, 4], dataType: 'float32'} + 'descriptor': {shape: [1, 1, 3, 4], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'cumulativeSum', + 'arguments': [{'input': 'cumulativeSumInput'}, {'axis': 3}], + 'outputs': 'cumulativeSumOutput' + }], + 'expectedOutputs': { + 'cumulativeSumOutput': { + 'data': [ + 60.4375, -26.5, -46, -61.15625, 13.453125, 58.875, 120, 190.75, + -31.28125, 24.8125, 63.8125, 60.53125 + ], + 'descriptor': {shape: [1, 1, 3, 4], dataType: 'float16'} + } + } + } + }, + { + 'name': 'cumulativeSum with float16 input and set exclusive to true.', + 'graph': { + 'inputs': { + 'cumulativeSumInput': { + 'data': [ + 60.4375, -86.9375, -19.5, -15.1484375, 13.453125, 45.4375, 61.09375, + 70.75, -31.28125, 56.09375, 39, -3.275390625 + ], + 'descriptor': {shape: [1, 1, 3, 4], dataType: 'float16'} } }, 'operators': [{ 'name': 'cumulativeSum', 'arguments': [ - {'input': 'cumulativeSumInput'}, - {'axis': 3}, - {'options': {'reversed': true}}, + {'input': 'cumulativeSumInput'}, {'axis': 3}, + {'options': {'exclusive': true}} ], 'outputs': 'cumulativeSumOutput' }], 'expectedOutputs': { 'cumulativeSumOutput': { 'data': [ - -61.1454659, -121.5692139, -34.6467285, -15.1506157, 190.6904907, - 177.2352905, 131.8016968, 70.7188263, 60.5223618, 91.8009415, - 35.7173996, -3.2753694 + 0, 60.4375, -26.5, -46, 0, 13.453125, 58.875, 120, 0, -31.28125, + 24.8125, 63.8125 ], - 'descriptor': {shape: [1, 1, 3, 4], dataType: 'float32'} + 'descriptor': {shape: [1, 1, 3, 4], dataType: 'float16'} } } } }, + { + 'name': 'cumulativeSum with float16 input and set reversed to true.', + 'graph': { + 'inputs': { + 'cumulativeSumInput': { + 'data': [ + 60.4375, -86.9375, -19.5, -15.1484375, 13.453125, 45.4375, 61.09375, + 70.75, -31.28125, 56.09375, 39, -3.275390625 + ], + 'descriptor': {shape: [1, 1, 3, 4], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'cumulativeSum', + 'arguments': [ + {'input': 'cumulativeSumInput'}, {'axis': 3}, + {'options': {'reversed': true}} + ], + 'outputs': 'cumulativeSumOutput' + }], + 'expectedOutputs': { + 'cumulativeSumOutput': { + 'data': [ + -61.15625, -121.5625, -34.65625, -15.1484375, 190.75, 177.25, + 131.875, 70.75, 60.53125, 91.8125, 35.71875, -3.275390625 + ], + 'descriptor': {shape: [1, 1, 3, 4], dataType: 'float16'} + } + } + } + }, + + // int32 tests + { + 'name': 'cumulativeSum with int32 input and axis = 2.', + 'graph': { + 'inputs': { + 'cumulativeSumInput': { + 'data': [2, 1, 3, 5, 3, 8, 7, 3, 9, 6, 2, 4], + 'descriptor': {shape: [1, 1, 3, 4], dataType: 'int32'} + } + }, + 'operators': [{ + 'name': 'cumulativeSum', + 'arguments': [ + {'input': 'cumulativeSumInput'}, + {'axis': 2} + ], + 'outputs': 'cumulativeSumOutput' + }], + 'expectedOutputs': { + 'cumulativeSumOutput': { + 'data': [2, 1, 3, 5, 5, 9, 10, 8, 14, 15, 12, 12], + 'descriptor': {shape: [1, 1, 3, 4], dataType: 'int32'} + } + } + } + } ]; if (navigator.ml) { diff --git a/tests/wpt/tests/webnn/conformance_tests/linear.https.any.js b/tests/wpt/tests/webnn/conformance_tests/linear.https.any.js index 9231aaf9eca..1f13fe170d4 100644 --- a/tests/wpt/tests/webnn/conformance_tests/linear.https.any.js +++ b/tests/wpt/tests/webnn/conformance_tests/linear.https.any.js @@ -19,6 +19,7 @@ // MLOperand linear(MLOperand input, optional MLLinearOptions options = {}); const linearTests = [ + // float32 tests { 'name': 'linear float32 1D constant tensor default options', 'graph': { @@ -542,6 +543,474 @@ const linearTests = [ } } } + }, + + // float16 tests + { + 'name': 'linear float16 1D constant tensor default options', + 'graph': { + 'inputs': { + 'linearInput': { + 'data': [ + -1.1220703125, -6.60546875, -1.955078125, -4.59765625, + 4.234375, 3.09765625, 3.74609375, -4.48828125, + 6.40625, -4.35546875, -5.8203125, 3.720703125, + -6.33203125, 8.578125, -6.765625, 6.43359375, + -9.7109375, 2.642578125, 5.21484375, 9.65625, + -8.71875, -0.453369140625, 9.9921875, -6.46875 + ], + 'descriptor': {shape: [24], dataType: 'float16'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'linear', + 'arguments': [{'input': 'linearInput'}], + 'outputs': 'linearOutput' + }], + 'expectedOutputs': { + 'linearOutput': { + 'data': [ + -1.1220703125, -6.60546875, -1.955078125, -4.59765625, + 4.234375, 3.09765625, 3.74609375, -4.48828125, + 6.40625, -4.35546875, -5.8203125, 3.720703125, + -6.33203125, 8.578125, -6.765625, 6.43359375, + -9.7109375, 2.642578125, 5.21484375, 9.65625, + -8.71875, -0.453369140625, 9.9921875, -6.46875 + ], + 'descriptor': {shape: [24], dataType: 'float16'} + } + } + } + }, + { + 'name': 'linear float16 0D tensor default options', + 'graph': { + 'inputs': { + 'linearInput': { + 'data': [-1.1220703125], + 'descriptor': {shape: [], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'linear', + 'arguments': [{'input': 'linearInput'}], + 'outputs': 'linearOutput' + }], + 'expectedOutputs': { + 'linearOutput': { + 'data': [-1.1220703125], + 'descriptor': {shape: [], dataType: 'float16'} + } + } + } + }, + { + 'name': 'linear float16 1D tensor default options', + 'graph': { + 'inputs': { + 'linearInput': { + 'data': [ + -1.1220703125, -6.60546875, -1.955078125, -4.59765625, + 4.234375, 3.09765625, 3.74609375, -4.48828125, + 6.40625, -4.35546875, -5.8203125, 3.720703125, + -6.33203125, 8.578125, -6.765625, 6.43359375, + -9.7109375, 2.642578125, 5.21484375, 9.65625, + -8.71875, -0.453369140625, 9.9921875, -6.46875 + ], + 'descriptor': {shape: [24], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'linear', + 'arguments': [{'input': 'linearInput'}], + 'outputs': 'linearOutput' + }], + 'expectedOutputs': { + 'linearOutput': { + 'data': [ + -1.1220703125, -6.60546875, -1.955078125, -4.59765625, + 4.234375, 3.09765625, 3.74609375, -4.48828125, + 6.40625, -4.35546875, -5.8203125, 3.720703125, + -6.33203125, 8.578125, -6.765625, 6.43359375, + -9.7109375, 2.642578125, 5.21484375, 9.65625, + -8.71875, -0.453369140625, 9.9921875, -6.46875 + ], + 'descriptor': {shape: [24], dataType: 'float16'} + } + } + } + }, + { + 'name': 'linear float16 2D tensor default options', + 'graph': { + 'inputs': { + 'linearInput': { + 'data': [ + -1.1220703125, -6.60546875, -1.955078125, -4.59765625, + 4.234375, 3.09765625, 3.74609375, -4.48828125, + 6.40625, -4.35546875, -5.8203125, 3.720703125, + -6.33203125, 8.578125, -6.765625, 6.43359375, + -9.7109375, 2.642578125, 5.21484375, 9.65625, + -8.71875, -0.453369140625, 9.9921875, -6.46875 + ], + 'descriptor': {shape: [4, 6], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'linear', + 'arguments': [{'input': 'linearInput'}], + 'outputs': 'linearOutput' + }], + 'expectedOutputs': { + 'linearOutput': { + 'data': [ + -1.1220703125, -6.60546875, -1.955078125, -4.59765625, + 4.234375, 3.09765625, 3.74609375, -4.48828125, + 6.40625, -4.35546875, -5.8203125, 3.720703125, + -6.33203125, 8.578125, -6.765625, 6.43359375, + -9.7109375, 2.642578125, 5.21484375, 9.65625, + -8.71875, -0.453369140625, 9.9921875, -6.46875 + ], + 'descriptor': {shape: [4, 6], dataType: 'float16'} + } + } + } + }, + { + 'name': 'linear float16 3D tensor default options', + 'graph': { + 'inputs': { + 'linearInput': { + 'data': [ + -1.1220703125, -6.60546875, -1.955078125, -4.59765625, + 4.234375, 3.09765625, 3.74609375, -4.48828125, + 6.40625, -4.35546875, -5.8203125, 3.720703125, + -6.33203125, 8.578125, -6.765625, 6.43359375, + -9.7109375, 2.642578125, 5.21484375, 9.65625, + -8.71875, -0.453369140625, 9.9921875, -6.46875 + ], + 'descriptor': {shape: [2, 3, 4], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'linear', + 'arguments': [{'input': 'linearInput'}], + 'outputs': 'linearOutput' + }], + 'expectedOutputs': { + 'linearOutput': { + 'data': [ + -1.1220703125, -6.60546875, -1.955078125, -4.59765625, + 4.234375, 3.09765625, 3.74609375, -4.48828125, + 6.40625, -4.35546875, -5.8203125, 3.720703125, + -6.33203125, 8.578125, -6.765625, 6.43359375, + -9.7109375, 2.642578125, 5.21484375, 9.65625, + -8.71875, -0.453369140625, 9.9921875, -6.46875 + ], + 'descriptor': {shape: [2, 3, 4], dataType: 'float16'} + } + } + } + }, + { + 'name': 'linear float16 4D tensor default options', + 'graph': { + 'inputs': { + 'linearInput': { + 'data': [ + -1.1220703125, -6.60546875, -1.955078125, -4.59765625, + 4.234375, 3.09765625, 3.74609375, -4.48828125, + 6.40625, -4.35546875, -5.8203125, 3.720703125, + -6.33203125, 8.578125, -6.765625, 6.43359375, + -9.7109375, 2.642578125, 5.21484375, 9.65625, + -8.71875, -0.453369140625, 9.9921875, -6.46875 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'linear', + 'arguments': [{'input': 'linearInput'}], + 'outputs': 'linearOutput' + }], + 'expectedOutputs': { + 'linearOutput': { + 'data': [ + -1.1220703125, -6.60546875, -1.955078125, -4.59765625, + 4.234375, 3.09765625, 3.74609375, -4.48828125, + 6.40625, -4.35546875, -5.8203125, 3.720703125, + -6.33203125, 8.578125, -6.765625, 6.43359375, + -9.7109375, 2.642578125, 5.21484375, 9.65625, + -8.71875, -0.453369140625, 9.9921875, -6.46875 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'} + } + } + } + }, + { + 'name': 'linear float16 5D tensor default options', + 'graph': { + 'inputs': { + 'linearInput': { + 'data': [ + -1.1220703125, -6.60546875, -1.955078125, -4.59765625, + 4.234375, 3.09765625, 3.74609375, -4.48828125, + 6.40625, -4.35546875, -5.8203125, 3.720703125, + -6.33203125, 8.578125, -6.765625, 6.43359375, + -9.7109375, 2.642578125, 5.21484375, 9.65625, + -8.71875, -0.453369140625, 9.9921875, -6.46875 + ], + 'descriptor': {shape: [2, 1, 4, 1, 3], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'linear', + 'arguments': [{'input': 'linearInput'}], + 'outputs': 'linearOutput' + }], + 'expectedOutputs': { + 'linearOutput': { + 'data': [ + -1.1220703125, -6.60546875, -1.955078125, -4.59765625, + 4.234375, 3.09765625, 3.74609375, -4.48828125, + 6.40625, -4.35546875, -5.8203125, 3.720703125, + -6.33203125, 8.578125, -6.765625, 6.43359375, + -9.7109375, 2.642578125, 5.21484375, 9.65625, + -8.71875, -0.453369140625, 9.9921875, -6.46875 + ], + 'descriptor': {shape: [2, 1, 4, 1, 3], dataType: 'float16'} + } + } + } + }, + { + 'name': + 'linear float16 4D tensor specified options.alpha and default options.beta', + 'graph': { + 'inputs': { + 'linearInput': { + 'data': [ + -1.1220703125, -6.60546875, -1.955078125, -4.59765625, + 4.234375, 3.09765625, 3.74609375, -4.48828125, + 6.40625, -4.35546875, -5.8203125, 3.720703125, + -6.33203125, 8.578125, -6.765625, 6.43359375, + -9.7109375, 2.642578125, 5.21484375, 9.65625, + -8.71875, -0.453369140625, 9.9921875, -6.46875 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'linear', + 'arguments': [ + {'input': 'linearInput'}, {'options': {'alpha': 7.398793812746618}} + ], + 'outputs': 'linearOutput' + }], + 'expectedOutputs': { + 'linearOutput': { + 'data': [ + -8.3046875, -48.875, -14.46875, -34.03125, 31.328125, + 22.921875, 27.71875, -33.21875, 47.40625, -32.21875, + -43.0625, 27.53125, -46.84375, 63.46875, -50.0625, + 47.59375, -71.875, 19.546875, 38.59375, 71.4375, + -64.5, -3.353515625, 73.9375, -47.875 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'} + } + } + } + }, + { + 'name': + 'linear float16 positive 4D tensor specified positive options.beta and default options.alpha', + 'graph': { + 'inputs': { + 'linearInput': { + 'data': [ + 5.09765625, 3.380859375, 8.0546875, 8.078125, 0.470703125, + 5.2421875, 3.828125, 5.37109375, 6.1015625, 3.75, + 0.748046875, 1.8935546875, 1.9052734375, 7.86328125, 4.58203125, + 9.375, 6.5859375, 9.34375, 5.16015625, 0.80615234375, + 9.1328125, 3.193359375, 5.75, 4.11328125 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'linear', + 'arguments': [ + {'input': 'linearInput'}, {'options': {'beta': 5.919095653700928}} + ], + 'outputs': 'linearOutput' + }], + 'expectedOutputs': { + 'linearOutput': { + 'data': [ + 11.015625, 9.296875, 13.9765625, 14, 6.390625, + 11.1640625, 9.75, 11.2890625, 12.0234375, 9.671875, + 6.66796875, 7.8125, 7.82421875, 13.78125, 10.5, + 15.296875, 12.5078125, 15.265625, 11.078125, 6.7265625, + 15.0546875, 9.109375, 11.671875, 10.03125 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'} + } + } + } + }, + { + 'name': + 'linear float16 negative 4D tensor specified negative options.beta and default options.alpha', + 'graph': { + 'inputs': { + 'linearInput': { + 'data': [ + -5.09765625, -3.380859375, -8.0546875, -8.078125, + -0.470703125, -5.2421875, -3.828125, -5.37109375, + -6.1015625, -3.75, -0.748046875, -1.8935546875, + -1.9052734375, -7.86328125, -4.58203125, -9.375, + -6.5859375, -9.34375, -5.16015625, -0.80615234375, + -9.1328125, -3.193359375, -5.75, -4.11328125 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'linear', + 'arguments': [ + {'input': 'linearInput'}, {'options': {'beta': -5.919095653700928}} + ], + 'outputs': 'linearOutput' + }], + 'expectedOutputs': { + 'linearOutput': { + 'data': [ + -11.015625, -9.296875, -13.9765625, -14, -6.390625, + -11.1640625, -9.75, -11.2890625, -12.0234375, -9.671875, + -6.66796875, -7.8125, -7.82421875, -13.78125, -10.5, + -15.296875, -12.5078125, -15.265625, -11.078125, -6.7265625, + -15.0546875, -9.109375, -11.671875, -10.03125 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'} + } + } + } + }, + { + 'name': + 'linear float16 positive 4D tensor all options (positive options.alpha and positive options.beta)', + 'graph': { + 'inputs': { + 'linearInput': { + 'data': [ + 5.09765625, 3.380859375, 8.0546875, 8.078125, 0.470703125, + 5.2421875, 3.828125, 5.37109375, 6.1015625, 3.75, + 0.748046875, 1.8935546875, 1.9052734375, 7.86328125, 4.58203125, + 9.375, 6.5859375, 9.34375, 5.16015625, 0.80615234375, + 9.1328125, 3.193359375, 5.75, 4.11328125 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'linear', + 'arguments': [ + {'input': 'linearInput'}, + {'options': {'alpha': 7.398793812746618, 'beta': 5.919095653700928}} + ], + 'outputs': 'linearOutput' + }], + 'expectedOutputs': { + 'linearOutput': { + 'data': [ + 43.625, 30.9375, 65.5, 65.6875, 9.3984375, 44.71875, + 34.25, 45.65625, 51.0625, 33.65625, 11.453125, 19.921875, + 20.015625, 64.125, 39.8125, 75.3125, 54.65625, 75.0625, + 44.09375, 11.8828125, 73.5, 29.546875, 48.46875, 36.34375 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'} + } + } + } + }, + { + 'name': + 'linear float16 positive 4D tensor all options (negative options.alpha and negative options.beta)', + 'graph': { + 'inputs': { + 'linearInput': { + 'data': [ + 5.09765625, 3.380859375, 8.0546875, 8.078125, 0.470703125, + 5.2421875, 3.828125, 5.37109375, 6.1015625, 3.75, + 0.748046875, 1.8935546875, 1.9052734375, 7.86328125, 4.58203125, + 9.375, 6.5859375, 9.34375, 5.16015625, 0.80615234375, + 9.1328125, 3.193359375, 5.75, 4.11328125 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'linear', + 'arguments': [ + {'input': 'linearInput'}, + {'options': {'alpha': -7.398793812746618, 'beta': -5.919095653700928}} + ], + 'outputs': 'linearOutput' + }], + 'expectedOutputs': { + 'linearOutput': { + 'data': [ + -43.625, -30.9375, -65.5, -65.6875, -9.3984375, + -44.71875, -34.25, -45.65625, -51.0625, -33.65625, + -11.453125, -19.921875, -20.015625, -64.125, -39.8125, + -75.3125, -54.65625, -75.0625, -44.09375, -11.8828125, + -73.5, -29.546875, -48.46875, -36.34375 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'} + } + } + } + }, + { + 'name': + 'linear float16 negative 4D tensor all options (positive options.alpha and negative options.beta)', + 'graph': { + 'inputs': { + 'linearInput': { + 'data': [ + -5.09765625, -3.380859375, -8.0546875, -8.078125, + -0.470703125, -5.2421875, -3.828125, -5.37109375, + -6.1015625, -3.75, -0.748046875, -1.8935546875, + -1.9052734375, -7.86328125, -4.58203125, -9.375, + -6.5859375, -9.34375, -5.16015625, -0.80615234375, + -9.1328125, -3.193359375, -5.75, -4.11328125 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'linear', + 'arguments': [ + {'input': 'linearInput'}, + {'options': {'alpha': 7.398793812746618, 'beta': -5.919095653700928}} + ], + 'outputs': 'linearOutput' + }], + 'expectedOutputs': { + 'linearOutput': { + 'data': [ + -43.625, -30.9375, -65.5, -65.6875, -9.3984375, + -44.71875, -34.25, -45.65625, -51.0625, -33.65625, + -11.453125, -19.921875, -20.015625, -64.125, -39.8125, + -75.3125, -54.65625, -75.0625, -44.09375, -11.8828125, + -73.5, -29.546875, -48.46875, -36.34375 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'} + } + } + } } ]; diff --git a/tests/wpt/tests/webnn/conformance_tests/qdq_subgraph.https.any.js b/tests/wpt/tests/webnn/conformance_tests/qdq_subgraph.https.any.js index ac384c917b3..996a6b472c5 100644 --- a/tests/wpt/tests/webnn/conformance_tests/qdq_subgraph.https.any.js +++ b/tests/wpt/tests/webnn/conformance_tests/qdq_subgraph.https.any.js @@ -141,6 +141,283 @@ const subgraphTests = [ } }, { + 'name': 'dequantizeLinear -> conv2d -> clamp -> quantizeLinear', + 'graph': { + 'inputs': { + 'input': { + 'data': [0.05605664849281311, 0.7114229798316956, 0.6529743671417236], + 'descriptor': {shape: [1, 1, 1, 3], dataType: 'float32'}, + 'constant': false + }, + 'inputScale': { + 'data': [0.003921568859368563], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'inputZeroPoint': { + 'data': [-128], + 'descriptor': {shape: [1], dataType: 'int8'}, + 'constant': true + }, + 'filter': { + 'data': [2, 3, 4], + 'descriptor': {shape: [1, 1, 1, 3], dataType: 'int8'}, + 'constant': true + }, + 'filterScale': { + 'data': [0.023458752938762234], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'filterZeroPoint': { + 'data': [0], + 'descriptor': {shape: [1], dataType: 'int8'}, + 'constant': true + }, + 'bias': { + 'data': [1], + 'descriptor': {shape: [1], dataType: 'int32'}, + 'constant': true + }, + 'biasScale': { + 'data': [0.000091995115004270], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'biasZeroPoint': { + 'data': [0], + 'descriptor': {shape: [1], dataType: 'int32'}, + 'constant': true + }, + 'outputScale': { + 'data': [0.003921568859368563], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'outputZeroPoint': { + 'data': [0], + 'descriptor': {shape: [1], dataType: 'int8'}, + 'constant': true + }, + }, + 'operators': [ + { + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'input'}, + {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'} + ], + 'outputs': 'quantizedInput' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'quantizedInput'}, + {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'} + ], + 'outputs': 'dequantizedInput' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'filter'}, + {'scale': 'filterScale', 'zeroPoint': 'filterZeroPoint'} + ], + 'outputs': 'dequantizedFilter' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'bias'}, + {'scale': 'biasScale', 'zeroPoint': 'biasZeroPoint'} + ], + 'outputs': 'dequantizedBias' + }, + { + 'name': 'conv2d', + 'arguments': [ + {'input': 'dequantizedInput'}, {'filter': 'dequantizedFilter'}, { + 'options': { + 'inputLayout': 'nhwc', + 'bias': 'dequantizedBias', + 'filterLayout': 'ohwi' + } + } + ], + 'outputs': 'conv2dOutput' + }, + { + 'name': 'clamp', + 'arguments': [ + {'input': 'conv2dOutput'}, + {'options': {'minValue': 0, 'maxValue': 6}} + ], + 'outputs': 'clampOutput' + }, + { + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'clampOutput'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'quantizedClampOutput' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'quantizedClampOutput'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'output' + } + ], + 'expectedOutputs': { + 'output': { + 'data': [0.11372549831867218], + 'descriptor': {shape: [1, 1, 1, 1], dataType: 'float32'} + } + } + } + }, + { + 'name': 'dequantizeLinear -> conv2d -> relu -> quantizeLinear', + 'graph': { + 'inputs': { + 'input': { + 'data': [0.05605664849281311, 0.7114229798316956, 0.6529743671417236], + 'descriptor': {shape: [1, 1, 1, 3], dataType: 'float32'}, + 'constant': false + }, + 'inputScale': { + 'data': [0.003921568859368563], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'inputZeroPoint': { + 'data': [-128], + 'descriptor': {shape: [1], dataType: 'int8'}, + 'constant': true + }, + 'filter': { + 'data': [2, 3, 4], + 'descriptor': {shape: [1, 1, 1, 3], dataType: 'int8'}, + 'constant': true + }, + 'filterScale': { + 'data': [0.7114229798316956], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'filterZeroPoint': { + 'data': [-128], + 'descriptor': {shape: [1], dataType: 'int8'}, + 'constant': true + }, + 'bias': { + 'data': [1], + 'descriptor': {shape: [1], dataType: 'int32'}, + 'constant': true + }, + 'biasScale': { + 'data': [0.000091995115004270], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'biasZeroPoint': { + 'data': [0], + 'descriptor': {shape: [1], dataType: 'int32'}, + 'constant': true + }, + 'outputScale': { + 'data': [0.003921568859368563], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'outputZeroPoint': { + 'data': [0], + 'descriptor': {shape: [1], dataType: 'int8'}, + 'constant': true + }, + }, + 'operators': [ + { + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'input'}, + {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'} + ], + 'outputs': 'quantizedInput' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'quantizedInput'}, + {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'} + ], + 'outputs': 'dequantizedInput' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'filter'}, + {'scale': 'filterScale', 'zeroPoint': 'filterZeroPoint'} + ], + 'outputs': 'dequantizedFilter' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'bias'}, + {'scale': 'biasScale', 'zeroPoint': 'biasZeroPoint'} + ], + 'outputs': 'dequantizedBias' + }, + { + 'name': 'conv2d', + 'arguments': [ + {'input': 'dequantizedInput'}, {'filter': 'dequantizedFilter'}, { + 'options': { + 'inputLayout': 'nhwc', + 'bias': 'dequantizedBias', + 'filterLayout': 'ohwi' + } + } + ], + 'outputs': 'conv2dOutput' + }, + { + 'name': 'relu', + 'arguments': [ + {'input': 'conv2dOutput'} + ], + 'outputs': 'reluOutput' + }, + { + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'reluOutput'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'quantizedReluOutput' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'quantizedReluOutput'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'output' + } + ], + 'expectedOutputs': { + 'output': { + 'data': [0.49803924560546875], + 'descriptor': {shape: [1, 1, 1, 1], dataType: 'float32'} + } + } + } + }, + { 'name': 'quantized element-wise binary add', 'graph': { 'inputs': { @@ -1846,6 +2123,423 @@ const subgraphTests = [ } } }, + { + 'name': 'quantized reduceMax', + 'graph': { + 'inputs': { + 'input': { + 'data': [ + 1.6811466217041016, 0.0479511022567749, 0.33355462551116943, + -0.1988269537687301, -0.0041167140007019, -0.0634240251779556, + ], + 'descriptor': {shape: [2, 3], dataType: 'float32'}, + 'constant': false + }, + 'inputScale': { + 'data': [0.003921568859368563], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'inputZeroPoint': { + 'data': [0], + 'descriptor': {shape: [1], dataType: 'int8'}, + 'constant': true + }, + 'outputScale': { + 'data': [0.003921568859368563], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'outputZeroPoint': { + 'data': [0], + 'descriptor': {shape: [1], dataType: 'int8'}, + 'constant': true + }, + }, + 'operators': [ + { + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'input'}, + {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'} + ], + 'outputs': 'quantizedInput' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'quantizedInput'}, + {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'} + ], + 'outputs': 'dequantizedInput' + }, + { + 'name': 'reduceMax', + 'arguments': [{'input': 'dequantizedInput'}, {'options': {'axes': [1]}}], + 'outputs': 'reduceMaxOutput' + }, + { + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'reduceMaxOutput'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'quantizedReduceMaxOutput' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'quantizedReduceMaxOutput'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'output' + } + ], + 'expectedOutputs': { + 'output': { + 'data': [ + 0.49803924560546875, -0.003921568859368563, + ], + 'descriptor': {shape: [2], dataType: 'float32'} + } + } + } + }, + { + 'name': 'quantized reduceMin', + 'graph': { + 'inputs': { + 'input': { + 'data': [ + 1.6811466217041016, 0.0479511022567749, 0.33355462551116943, + -0.1988269537687301, -0.0041167140007019, -0.0634240251779556, + ], + 'descriptor': {shape: [2, 3], dataType: 'float32'}, + 'constant': false + }, + 'inputScale': { + 'data': [0.003921568859368563], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'inputZeroPoint': { + 'data': [0], + 'descriptor': {shape: [1], dataType: 'int8'}, + 'constant': true + }, + 'outputScale': { + 'data': [0.003921568859368563], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'outputZeroPoint': { + 'data': [0], + 'descriptor': {shape: [1], dataType: 'int8'}, + 'constant': true + }, + }, + 'operators': [ + { + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'input'}, + {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'} + ], + 'outputs': 'quantizedInput' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'quantizedInput'}, + {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'} + ], + 'outputs': 'dequantizedInput' + }, + { + 'name': 'reduceMin', + 'arguments': [{'input': 'dequantizedInput'}, {'options': {'axes': [1]}}], + 'outputs': 'reduceMinOutput' + }, + { + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'reduceMinOutput'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'quantizedReduceMinOutput' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'quantizedReduceMinOutput'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'output' + } + ], + 'expectedOutputs': { + 'output': { + 'data': [ + 0.0470588281750679, -0.20000001788139343, + ], + 'descriptor': {shape: [2], dataType: 'float32'} + } + } + } + }, + { + 'name': 'quantized reduceMean', + 'graph': { + 'inputs': { + 'input': { + 'data': [ + 1.6811466217041016, 0.0479511022567749, 0.33355462551116943, + -0.1988269537687301, -0.0041167140007019, -0.0634240251779556, + ], + 'descriptor': {shape: [2, 3], dataType: 'float32'}, + 'constant': false + }, + 'inputScale': { + 'data': [0.003921568859368563], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'inputZeroPoint': { + 'data': [0], + 'descriptor': {shape: [1], dataType: 'int8'}, + 'constant': true + }, + 'outputScale': { + 'data': [0.003921568859368563], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'outputZeroPoint': { + 'data': [0], + 'descriptor': {shape: [1], dataType: 'int8'}, + 'constant': true + }, + }, + 'operators': [ + { + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'input'}, + {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'} + ], + 'outputs': 'quantizedInput' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'quantizedInput'}, + {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'} + ], + 'outputs': 'dequantizedInput' + }, + { + 'name': 'reduceMean', + 'arguments': [{'input': 'dequantizedInput'}, {'options': {'axes': [1]}}], + 'outputs': 'reduceMeanOutput' + }, + { + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'reduceMeanOutput'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'quantizedReduceMeanOutput' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'quantizedReduceMeanOutput'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'output' + } + ], + 'expectedOutputs': { + 'output': { + 'data': [ + 0.29411765933036804, -0.09019608050584793, + ], + 'descriptor': {shape: [2], dataType: 'float32'} + } + } + } + }, + { + 'name': 'quantized reduceSum', + 'graph': { + 'inputs': { + 'input': { + 'data': [ + 1.6811466217041016, 0.0479511022567749, 0.33355462551116943, + -0.1988269537687301, -0.0041167140007019, -0.0634240251779556, + ], + 'descriptor': {shape: [2, 3], dataType: 'float32'}, + 'constant': false + }, + 'inputScale': { + 'data': [0.003921568859368563], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'inputZeroPoint': { + 'data': [0], + 'descriptor': {shape: [1], dataType: 'int8'}, + 'constant': true + }, + 'outputScale': { + 'data': [0.003921568859368563], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'outputZeroPoint': { + 'data': [0], + 'descriptor': {shape: [1], dataType: 'int8'}, + 'constant': true + }, + }, + 'operators': [ + { + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'input'}, + {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'} + ], + 'outputs': 'quantizedInput' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'quantizedInput'}, + {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'} + ], + 'outputs': 'dequantizedInput' + }, + { + 'name': 'reduceSum', + 'arguments': [{'input': 'dequantizedInput'}, {'options': {'axes': [1]}}], + 'outputs': 'reduceSumOutput' + }, + { + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'reduceSumOutput'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'quantizedReduceSumOutput' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'quantizedReduceSumOutput'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'output' + } + ], + 'expectedOutputs': { + 'output': { + 'data': [ + 0.49803924560546875, -0.2666666805744171, + ], + 'descriptor': {shape: [2], dataType: 'float32'} + } + } + } + }, + { + 'name': 'quantized resample2d', + 'graph': { + 'inputs': { + 'input': { + 'data': [ + 1.6811466217041016, 0.0479511022567749, 0.33355462551116943, + -0.1988269537687301, -0.0041167140007019, -0.0634240251779556, + ], + 'descriptor': {shape: [1, 2, 3, 1], dataType: 'float32'}, + 'constant': false + }, + 'inputScale': { + 'data': [0.003921568859368563], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'inputZeroPoint': { + 'data': [0], + 'descriptor': {shape: [1], dataType: 'int8'}, + 'constant': true + }, + 'outputScale': { + 'data': [0.003921568859368563], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'outputZeroPoint': { + 'data': [0], + 'descriptor': {shape: [1], dataType: 'int8'}, + 'constant': true + }, + }, + 'operators': [ + { + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'input'}, + {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'} + ], + 'outputs': 'quantizedInput' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'quantizedInput'}, + {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'} + ], + 'outputs': 'dequantizedInput' + }, + { + 'name': 'resample2d', + 'arguments': [{'input': 'dequantizedInput'}, {'options': {'sizes': [4, 6], 'axes': [1, 2]}}], + 'outputs': 'resample2dOutput' + }, + { + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'resample2dOutput'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'quantizedResample2dOutput' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'quantizedResample2dOutput'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'output' + } + ], + 'expectedOutputs': { + 'output': { + 'data': [ + 0.49803924560546875, 0.49803924560546875, 0.0470588281750679, + 0.0470588281750679, 0.3333333432674408, 0.3333333432674408, + 0.49803924560546875, 0.49803924560546875, 0.0470588281750679, + 0.0470588281750679, 0.3333333432674408, 0.3333333432674408, + -0.20000001788139343, -0.20000001788139343, -0.003921568859368563, + -0.003921568859368563, -0.062745101749897, -0.062745101749897, + -0.20000001788139343, -0.20000001788139343, -0.003921568859368563, + -0.003921568859368563, -0.062745101749897, -0.062745101749897, + ], + 'descriptor': {shape: [1, 4, 6, 1], dataType: 'float32'} + } + } + } + }, ]; if (navigator.ml) { diff --git a/tests/wpt/tests/webnn/conformance_tests/subgraph.https.any.js b/tests/wpt/tests/webnn/conformance_tests/subgraph.https.any.js index 9b21d6e4f94..8a0b7faa92f 100644 --- a/tests/wpt/tests/webnn/conformance_tests/subgraph.https.any.js +++ b/tests/wpt/tests/webnn/conformance_tests/subgraph.https.any.js @@ -2523,6 +2523,45 @@ const subgraphTests = [ } } }, + { + 'name': 'float16 graph with float32 input and output', + 'graph': { + 'inputs': { + 'input': { + 'data': [1, 2, 3, 4], + 'descriptor': {shape: [4], dataType: 'float32'} + }, + 'weight': { + 'data': [2], + 'descriptor': {shape: [], dataType: 'float16'}, + 'constant': true + } + }, + 'operators': [ + { + 'name': 'cast', + 'arguments': [{'input': 'input'}, {'type': 'float16'}], + 'outputs': 'castOutput', + }, + { + 'name': 'add', + 'arguments': [{'a': 'castOutput'}, {'b': 'weight'}], + 'outputs': 'addOutput' + }, + { + 'name': 'cast', + 'arguments': [{'input': 'addOutput'}, {'type': 'float32'}], + 'outputs': 'output' + }, + ], + 'expectedOutputs': { + 'output': { + 'data': [3, 4, 5, 6], + 'descriptor': {shape: [4], dataType: 'float32'} + } + } + } + }, ]; if (navigator.ml) { diff --git a/tests/wpt/tests/webrtc-encoded-transform/tentative/RTCEncodedAudioFrame-metadata.https.html b/tests/wpt/tests/webrtc-encoded-transform/tentative/RTCEncodedAudioFrame-metadata.https.html index df4577c5614..1e148fe1b29 100644 --- a/tests/wpt/tests/webrtc-encoded-transform/tentative/RTCEncodedAudioFrame-metadata.https.html +++ b/tests/wpt/tests/webrtc-encoded-transform/tentative/RTCEncodedAudioFrame-metadata.https.html @@ -8,6 +8,7 @@ <script src='../../mediacapture-streams/permission-helper.js'></script> <script src="../../webrtc/RTCPeerConnection-helper.js"></script> <script src="../../service-workers/service-worker/resources/test-helpers.sub.js"></script> +<script src='RTCEncodedFrame-timestamps-helper.js'></script> <script> "use strict"; @@ -130,4 +131,56 @@ promise_test(async t => { return framesReceivedCorrectly; }, "Constructing audio frame with bad metadata argument before sending does not work"); + +promise_test(async t => { + const kCaptureTime = 12345; + const pc1 = new RTCPeerConnection({encodedInsertableStreams:true}); + t.add_cleanup(() => pc1.close()); + const pc2 = new RTCPeerConnection({encodedInsertableStreams:true}); + t.add_cleanup(() => pc2.close()); + + exchangeIceCandidates(pc1, pc2); + + let numFrames = 0; + let audioLevelRead = new Promise((resolve, reject) => { + pc2.ontrack = t.step_func(e => { + const receiverTransformer = new TransformStream({ + async transform(encodedFrame, controller) { + const metadata = encodedFrame.getMetadata(); + if (metadata.captureTime < kCaptureTime - 1 || metadata.captureTime > kCaptureTime + 1) { + reject("Unexpected captureTime"); + } + controller.enqueue(encodedFrame); + if (++numFrames == 10) + resolve(); + } + }); + const receiverStreams = e.receiver.createEncodedStreams(); + receiverStreams.readable + .pipeThrough(receiverTransformer) + .pipeTo(receiverStreams.writable); + }); + }); + + const stream = await navigator.mediaDevices.getUserMedia({audio:true}); + t.add_cleanup(() => stream.getTracks().forEach(track => track.stop())); + const sender = pc1.addTrack(stream.getAudioTracks()[0]); + const senderStreams = sender.createEncodedStreams(); + const senderTransformer = new TransformStream({ + async transform(encodedFrame, controller) { + let metadata = encodedFrame.getMetadata(); + metadata.captureTime = kCaptureTime; + controller.enqueue(new RTCEncodedAudioFrame(encodedFrame, {metadata})); + } + }); + senderStreams.readable + .pipeThrough(senderTransformer) + .pipeTo(senderStreams.writable); + + await addAbsCaptureTimeAndExchangeOffer(pc1, pc2); + await checkAbsCaptureTimeAndExchangeAnswer(pc1, pc2, true); + + await audioLevelRead; +}, 'Basic simulcast setup with three spatial layers'); + </script> diff --git a/tests/wpt/tests/webrtc/RTCConfiguration-iceServers.html b/tests/wpt/tests/webrtc/RTCConfiguration-iceServers.html index bc7831361ab..65a6015f52a 100644 --- a/tests/wpt/tests/webrtc/RTCConfiguration-iceServers.html +++ b/tests/wpt/tests/webrtc/RTCConfiguration-iceServers.html @@ -34,11 +34,14 @@ DOMString credential; }; */ + // RFC 8489 limits the length of the TURN username to 509 bytes: + // https://datatracker.ietf.org/doc/html/rfc8489#section-14.3 + const kUsernameOfMaxPermittedLength = 'a'.repeat(509); test(() => { const pc = new RTCPeerConnection(); assert_array_equals(pc.getConfiguration().iceServers, []); - }, 'new RTCPeerConnection() should have default configuration.iceServers of undefined'); + }, 'new RTCPeerConnection() should have default configuration.iceServers of []'); config_test(makePc => { makePc({}); @@ -181,6 +184,15 @@ }, `with one turns server, one turn server, username, credential should succeed`); + config_test(makePc => { + assert_equals(kUsernameOfMaxPermittedLength.length, 509); + const pc = makePc({ iceServers: [{ + urls: 'turn:turn.example.net', + username: kUsernameOfMaxPermittedLength, + credential: 'cred' + }] }); + }, `with a turn server and a username of 509 characters should succeed`); + /* 4.3.2. To set a configuration 11.4. If scheme name is turn or turns, and either of server.username or @@ -232,6 +244,16 @@ }] })); }, 'with turns server and only credential should throw InvalidAccessError'); + config_test(makePc => { + assert_equals(kUsernameOfMaxPermittedLength.length, 509); + assert_throws_dom('InvalidAccessError', () => + makePc({ iceServers: [{ + urls: 'turns:turn.example.net', + username: kUsernameOfMaxPermittedLength + 'a', + credential: 'cred' + }] })); + }, `with a turn server and a username of 510 characters throw InvalidAccessError`); + /* 4.3.2. To set a configuration 11.3. For each url in server.urls parse url and obtain scheme name. @@ -284,6 +306,8 @@ assert_throws_dom("SyntaxError", () => makePc({ iceServers: [{ urls: 'turn://example.org/foo?x=y' + // `username` and `credential` are not passed because the invalid url + // should be rejected before the check for those arguments. }] })); }, 'with invalid turn url should throw SyntaxError'); diff --git a/tests/wpt/tests/websockets/stream/tentative/remote-close.any.js b/tests/wpt/tests/websockets/stream/tentative/remote-close.any.js index b7fd321914a..c3e7ad5f9fb 100644 --- a/tests/wpt/tests/websockets/stream/tentative/remote-close.any.js +++ b/tests/wpt/tests/websockets/stream/tentative/remote-close.any.js @@ -48,7 +48,8 @@ promise_test(async t => { const closedError = await wss.closed.then(t.unreached_func('closed should reject'), e => e); assert_equals(closedError.constructor, WebSocketError, 'error should be WebSocketError'); assert_equals(closedError.closeCode, 4567, 'closeCode should be set'); - promise_rejects_js(t, WebSocketError, writePromise, 'write() should reject'); + await promise_rejects_dom( + t, 'InvalidStateError', writePromise, 'write() should reject'); }, 'close with unwritten data should not be considered clean'); promise_test(async t => { diff --git a/tests/wpt/tests/websockets/stream/tentative/write.any.js b/tests/wpt/tests/websockets/stream/tentative/write.any.js new file mode 100644 index 00000000000..43af7da614c --- /dev/null +++ b/tests/wpt/tests/websockets/stream/tentative/write.any.js @@ -0,0 +1,96 @@ +// META: script=../../constants.sub.js +// META: script=resources/url-constants.js +// META: script=/common/gc.js +// META: global=window,worker +// META: variant=?default +// META: variant=?wss +// META: variant=?wpt_flags=h2 + +'use strict'; + +const GOODBYE_MESSAGE = 'Goodbye'; // Must match echo_exit_wsh.py + +// This message needs to be large enough that writing it cannot complete +// synchronously, and to fill up the TCP send buffer and any user agent internal +// send buffers so that the user agent has to receive the "Close" frame from the +// server before it can complete sending this message. +const BIG_MESSAGE_SIZE = 8 * 1024 * 1024; + +// Common setup used by two tests. Sends a "Goodbye" message to tell the server +// to close the WebSocket, and immediately afterwards a big message that cannot +// be completely sent before the connection closes. Waits for the "Goodbye" +// message to be sent and the connection to be closed before returning. `t` is +// the test object provided by promse_test. +async function sendGoodbyeThenBigMessage(t) { + const wss = new WebSocketStream(BASEURL + '/echo_exit'); + const { writable } = await wss.opened; + const writer = writable.getWriter(); + const bigMessage = new Uint8Array(BIG_MESSAGE_SIZE); + const goodbyePromise = writer.write(GOODBYE_MESSAGE); + const bigMessagePromise = writer.write(bigMessage); + await goodbyePromise; + // testharness.js doesn't know about WebSocketError yet. + await wss.closed.then( + t.unreached_func('closed promise should reject'), + e => assert_equals( + e.constructor, WebSocketError, + 'a WebSocketError should be thrown')); + return { writer, bigMessagePromise }; +} + +promise_test(async t => { + const { writer, bigMessagePromise } = await sendGoodbyeThenBigMessage(t); + await promise_rejects_dom( + t, 'InvalidStateError', bigMessagePromise, + 'write() should reject with an InvalidStateError'); + const invalidStateError = await bigMessagePromise.then( + t.unreached_func('write() promise should reject'), e => e); + await promise_rejects_exactly( + t, invalidStateError, writer.write('word'), + 'stream should be errored with same object'); +}, 'a write that was incomplete at close time should reject'); + +promise_test(async t => { + const { bigMessagePromise } = await sendGoodbyeThenBigMessage(t); + // For some reason 5 is the magic number that causes garbage collection to + // really really collect garbage. + for (let i = 0; i < 5; ++i) { + await garbageCollect(); + } + await promise_rejects_dom( + t, 'InvalidStateError', bigMessagePromise, + 'write() should reject with an InvalidStateError'); +}, 'garbage collection after close with a pending write promise should not ' + + 'crash'); + +promise_test(async t => { + const wss = new WebSocketStream(ECHOURL); + const { writable } = await wss.opened; + const writer = writable.getWriter(); + const cannotStringify = { toString() { return this; } }; + await promise_rejects_js( + t, TypeError, writer.write(cannotStringify), 'write() should reject'); +}, 'writing a value that cannot be stringified should cause a rejection'); + +promise_test(async t => { + const wss = new WebSocketStream(ECHOURL); + const { writable } = await wss.opened; + const writer = writable.getWriter(); + const buffer = new ArrayBuffer(1024, { maxByteLength: 65536 }); + await promise_rejects_js( + t, TypeError, writer.write(buffer), 'write() should reject'); +}, 'writing a resizable ArrayBuffer should be rejected'); + +promise_test(async t => { + const wss = new WebSocketStream(ECHOURL); + const { writable } = await wss.opened; + const writer = writable.getWriter(); + const memory = new WebAssembly.Memory({ + initial: 4096, + maximum: 65536, + shared: true, + }); + const view = new Uint8Array(memory.buffer); + await promise_rejects_js( + t, TypeError, writer.write(view), 'write() should reject'); +}, 'writing a view on a shared buffer should be rejected'); diff --git a/tests/wpt/tests/workers/WEB_FEATURES.yml b/tests/wpt/tests/workers/WEB_FEATURES.yml new file mode 100644 index 00000000000..1687ef742e2 --- /dev/null +++ b/tests/wpt/tests/workers/WEB_FEATURES.yml @@ -0,0 +1,6 @@ +features: +- name: ua-client-hints + files: + - WorkerNavigator_userAgentData.http.html + - WorkerNavigator_userAgentData.https.html + - WorkerNavigator_userAgentData.https.tentative.html diff --git a/tests/wpt/tests/workers/tentative/SharedWorker-extendedLifetime.html b/tests/wpt/tests/workers/tentative/SharedWorker-extendedLifetime.html new file mode 100644 index 00000000000..3c76eddd764 --- /dev/null +++ b/tests/wpt/tests/workers/tentative/SharedWorker-extendedLifetime.html @@ -0,0 +1,61 @@ +<!DOCTYPE html> +<title>SharedWorker extendedLifetime</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/utils.js"></script> +<script src="/common/dispatcher/dispatcher.js"></script> +<script> + +let request_id = 0; + +const connectToSharedWorker = async () => { + await window.pageShowPromise; + window.worker = new SharedWorker( + '/workers/tentative/resources/shared-worker-memory.js', + {extendedLifetime: true}); + worker.port.start(); +}; + +const postAndWait = async (data) => { + return new Promise(resolve => { + const listener = event => { + if (event.data.reqid !== data.reqid) { + return; + } + worker.port.removeEventListener('message', listener); + resolve(event.data); + }; + worker.port.addEventListener('message', listener); + worker.port.postMessage(data); + }); +}; + +promise_test(async t => { + // SharedWorker is started with the extendedLifetime option. + // random message is stored there, which can be read later. + const uuid = token(); + const ctx = new RemoteContext(token()); + const popup = window.open(remoteExecutorUrl(ctx.context_id)); + await ctx.execute_script(connectToSharedWorker); + const popup_response = await ctx.execute_script(postAndWait, [{ + reqid: request_id++, + op: 'store', + data: uuid, + }]); + assert_equals(popup_response.status, 'OK'); + popup.close(); + + // Wait for a second. + await new Promise(resolve => setTimeout(resolve, 1)); + + const ctx2 = new RemoteContext(token()); + const popup2 = window.open(remoteExecutorUrl(ctx2.context_id)); + await ctx2.execute_script(connectToSharedWorker); + const popup2_response = await ctx2.execute_script(postAndWait, [{ + reqid: request_id++, + op: 'load', + }]); + assert_equals(popup2_response.status, 'OK'); + assert_equals(popup2_response.data, uuid); +}, "SharedWorker lifetime should be extended with extendedLifetime"); +</script> diff --git a/tests/wpt/tests/workers/tentative/resources/shared-worker-memory.js b/tests/wpt/tests/workers/tentative/resources/shared-worker-memory.js new file mode 100644 index 00000000000..b1504f38c50 --- /dev/null +++ b/tests/wpt/tests/workers/tentative/resources/shared-worker-memory.js @@ -0,0 +1,30 @@ +'use strict'; + +let stored_data = null; + +function processMessage(e) { + function respond(data) { + e.currentTarget.postMessage(Object.assign(data, {reqid: e.data.reqid})); + } + + switch (e.data.op) { + case 'load': { + respond({ack: 'load', status: 'OK', data: stored_data}); + break; + } + case 'store': { + try { + stored_data = e.data.data + } catch (err) { + respond({ack: 'store', status: 'ERROR', error: err.name}); + return; + } + respond({ack: 'store', status: 'OK'}); + break; + } + } +} + +self.addEventListener('connect', e => { + e.ports[0].onmessage = processMessage; +}); diff --git a/tests/wpt/webgl/meta/conformance/textures/misc/tex-video-using-tex-unit-non-zero.html.ini b/tests/wpt/webgl/meta/conformance/textures/misc/tex-video-using-tex-unit-non-zero.html.ini index 5b9d4a0e1b9..f8ab654ff94 100644 --- a/tests/wpt/webgl/meta/conformance/textures/misc/tex-video-using-tex-unit-non-zero.html.ini +++ b/tests/wpt/webgl/meta/conformance/textures/misc/tex-video-using-tex-unit-non-zero.html.ini @@ -3,9 +3,3 @@ expected: TIMEOUT [Overall test] expected: NOTRUN - - [WebGL test #0] - expected: FAIL - - [WebGL test #1] - expected: FAIL diff --git a/tests/wpt/webgl/meta/conformance/textures/misc/texture-srgb-upload.html.ini b/tests/wpt/webgl/meta/conformance/textures/misc/texture-srgb-upload.html.ini index 4afbf9ef9a0..a3acae77b7a 100644 --- a/tests/wpt/webgl/meta/conformance/textures/misc/texture-srgb-upload.html.ini +++ b/tests/wpt/webgl/meta/conformance/textures/misc/texture-srgb-upload.html.ini @@ -1,4 +1,4 @@ [texture-srgb-upload.html] - expected: TIMEOUT + expected: ERROR [Overall test] expected: NOTRUN diff --git a/tests/wpt/webgl/meta/conformance/textures/misc/texture-upload-size.html.ini b/tests/wpt/webgl/meta/conformance/textures/misc/texture-upload-size.html.ini index 435cfbe0d5c..e9f1c0ae3f3 100644 --- a/tests/wpt/webgl/meta/conformance/textures/misc/texture-upload-size.html.ini +++ b/tests/wpt/webgl/meta/conformance/textures/misc/texture-upload-size.html.ini @@ -13,3 +13,75 @@ [WebGL test #588] expected: FAIL + + [WebGL test #53] + expected: FAIL + + [WebGL test #55] + expected: FAIL + + [WebGL test #57] + expected: FAIL + + [WebGL test #59] + expected: FAIL + + [WebGL test #69] + expected: FAIL + + [WebGL test #71] + expected: FAIL + + [WebGL test #73] + expected: FAIL + + [WebGL test #75] + expected: FAIL + + [WebGL test #85] + expected: FAIL + + [WebGL test #87] + expected: FAIL + + [WebGL test #89] + expected: FAIL + + [WebGL test #91] + expected: FAIL + + [WebGL test #101] + expected: FAIL + + [WebGL test #103] + expected: FAIL + + [WebGL test #105] + expected: FAIL + + [WebGL test #107] + expected: FAIL + + [WebGL test #117] + expected: FAIL + + [WebGL test #119] + expected: FAIL + + [WebGL test #121] + expected: FAIL + + [WebGL test #123] + expected: FAIL + + [WebGL test #133] + expected: FAIL + + [WebGL test #135] + expected: FAIL + + [WebGL test #137] + expected: FAIL + + [WebGL test #139] + expected: FAIL |